mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-27 11:54:30 +01:00
Merge 'core: Fix resolve_function() error messages' from Pekka Enberg
We need to return the original function name, not normalized one to be compatible with SQLite. Spotted by SQLite TCL tests. Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Closes #2017
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2222,6 +2222,8 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
|
||||
@@ -616,7 +616,8 @@ impl Func {
|
||||
}
|
||||
}
|
||||
pub fn resolve_function(name: &str, arg_count: usize) -> Result<Self, LimboError> {
|
||||
match name {
|
||||
let normalized_name = crate::util::normalize_ident(name);
|
||||
match normalized_name.as_str() {
|
||||
"avg" => {
|
||||
if arg_count != 1 {
|
||||
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::function::JsonFunc;
|
||||
use crate::function::{Func, FuncCtx, MathFuncArity, ScalarFunc, VectorFunc};
|
||||
use crate::functions::datetime;
|
||||
use crate::schema::{Affinity, Table, Type};
|
||||
use crate::util::{exprs_are_equivalent, normalize_ident, parse_numeric_literal};
|
||||
use crate::util::{exprs_are_equivalent, parse_numeric_literal};
|
||||
use crate::vdbe::builder::CursorKey;
|
||||
use crate::vdbe::{
|
||||
builder::ProgramBuilder,
|
||||
@@ -680,8 +680,7 @@ pub fn translate_expr(
|
||||
order_by: _,
|
||||
} => {
|
||||
let args_count = if let Some(args) = args { args.len() } else { 0 };
|
||||
let func_name = normalize_ident(name.0.as_str());
|
||||
let func_type = resolver.resolve_function(&func_name, args_count);
|
||||
let func_type = resolver.resolve_function(&name.0, args_count);
|
||||
|
||||
if func_type.is_none() {
|
||||
crate::bail_parse_error!("unknown function {}", name.0);
|
||||
|
||||
@@ -51,8 +51,7 @@ pub fn resolve_aggregates(
|
||||
} else {
|
||||
0
|
||||
};
|
||||
match Func::resolve_function(normalize_ident(name.0.as_str()).as_str(), args_count)
|
||||
{
|
||||
match Func::resolve_function(&name.0, args_count) {
|
||||
Ok(Func::Agg(f)) => {
|
||||
let distinctness = Distinctness::from_ast(distinctness.as_ref());
|
||||
if !schema.indexes_enabled() && distinctness.is_distinct() {
|
||||
@@ -84,9 +83,7 @@ pub fn resolve_aggregates(
|
||||
}
|
||||
}
|
||||
Expr::FunctionCallStar { name, .. } => {
|
||||
if let Ok(Func::Agg(f)) =
|
||||
Func::resolve_function(normalize_ident(name.0.as_str()).as_str(), 0)
|
||||
{
|
||||
if let Ok(Func::Agg(f)) = Func::resolve_function(&name.0, 0) {
|
||||
aggs.push(Aggregate {
|
||||
func: f,
|
||||
args: vec![],
|
||||
|
||||
@@ -340,10 +340,7 @@ fn prepare_one_select_plan(
|
||||
if distinctness.is_distinct() && args_count != 1 {
|
||||
crate::bail_parse_error!("DISTINCT aggregate functions must have exactly one argument");
|
||||
}
|
||||
match Func::resolve_function(
|
||||
normalize_ident(name.0.as_str()).as_str(),
|
||||
args_count,
|
||||
) {
|
||||
match Func::resolve_function(&name.0, args_count) {
|
||||
Ok(Func::Agg(f)) => {
|
||||
let agg_args = match (args, &f) {
|
||||
(None, crate::function::AggFunc::Count0) => {
|
||||
@@ -442,49 +439,44 @@ fn prepare_one_select_plan(
|
||||
ast::Expr::FunctionCallStar {
|
||||
name,
|
||||
filter_over: _,
|
||||
} => {
|
||||
match Func::resolve_function(
|
||||
normalize_ident(name.0.as_str()).as_str(),
|
||||
0,
|
||||
) {
|
||||
Ok(Func::Agg(f)) => {
|
||||
let agg = Aggregate {
|
||||
func: f,
|
||||
args: vec![ast::Expr::Literal(ast::Literal::Numeric(
|
||||
"1".to_string(),
|
||||
))],
|
||||
original_expr: expr.clone(),
|
||||
distinctness: Distinctness::NonDistinct,
|
||||
};
|
||||
aggregate_expressions.push(agg.clone());
|
||||
plan.result_columns.push(ResultSetColumn {
|
||||
alias: maybe_alias.as_ref().map(|alias| match alias {
|
||||
ast::As::Elided(alias) => alias.0.clone(),
|
||||
ast::As::As(alias) => alias.0.clone(),
|
||||
}),
|
||||
expr: expr.clone(),
|
||||
contains_aggregates: true,
|
||||
});
|
||||
} => match Func::resolve_function(&name.0, 0) {
|
||||
Ok(Func::Agg(f)) => {
|
||||
let agg = Aggregate {
|
||||
func: f,
|
||||
args: vec![ast::Expr::Literal(ast::Literal::Numeric(
|
||||
"1".to_string(),
|
||||
))],
|
||||
original_expr: expr.clone(),
|
||||
distinctness: Distinctness::NonDistinct,
|
||||
};
|
||||
aggregate_expressions.push(agg.clone());
|
||||
plan.result_columns.push(ResultSetColumn {
|
||||
alias: maybe_alias.as_ref().map(|alias| match alias {
|
||||
ast::As::Elided(alias) => alias.0.clone(),
|
||||
ast::As::As(alias) => alias.0.clone(),
|
||||
}),
|
||||
expr: expr.clone(),
|
||||
contains_aggregates: true,
|
||||
});
|
||||
}
|
||||
Ok(_) => {
|
||||
crate::bail_parse_error!(
|
||||
"Invalid aggregate function: {}",
|
||||
name.0
|
||||
);
|
||||
}
|
||||
Err(e) => match e {
|
||||
crate::LimboError::ParseError(e) => {
|
||||
crate::bail_parse_error!("{}", e);
|
||||
}
|
||||
Ok(_) => {
|
||||
_ => {
|
||||
crate::bail_parse_error!(
|
||||
"Invalid aggregate function: {}",
|
||||
name.0
|
||||
);
|
||||
}
|
||||
Err(e) => match e {
|
||||
crate::LimboError::ParseError(e) => {
|
||||
crate::bail_parse_error!("{}", e);
|
||||
}
|
||||
_ => {
|
||||
crate::bail_parse_error!(
|
||||
"Invalid aggregate function: {}",
|
||||
name.0
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
expr => {
|
||||
let contains_aggregates =
|
||||
resolve_aggregates(schema, expr, &mut aggregate_expressions)?;
|
||||
|
||||
Reference in New Issue
Block a user