mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-19 17:34:19 +01:00
Fix delimiter handling in group_concat and string_agg
Non-literal delimiters must be translated by AggArgumentSource.
This commit is contained in:
@@ -312,33 +312,26 @@ pub fn translate_aggregation_step(
|
|||||||
crate::bail_parse_error!("group_concat bad number of arguments");
|
crate::bail_parse_error!("group_concat bad number of arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
let delimiter_reg = program.alloc_register();
|
let delimiter_reg = if num_args == 2 {
|
||||||
|
|
||||||
let delimiter_expr: ast::Expr;
|
|
||||||
|
|
||||||
if num_args == 2 {
|
|
||||||
match &agg_arg_source.args()[1] {
|
match &agg_arg_source.args()[1] {
|
||||||
arg @ ast::Expr::Column { .. } => {
|
ast::Expr::Column { .. } => {
|
||||||
delimiter_expr = arg.clone();
|
agg_arg_source.translate(program, referenced_tables, resolver, 1)?
|
||||||
}
|
}
|
||||||
ast::Expr::Literal(ast::Literal::String(s)) => {
|
ast::Expr::Literal(ast::Literal::String(s)) => {
|
||||||
delimiter_expr = ast::Expr::Literal(ast::Literal::String(s.to_string()));
|
let delimiter_expr =
|
||||||
|
ast::Expr::Literal(ast::Literal::String(s.to_string()));
|
||||||
|
translate_const_arg(program, referenced_tables, resolver, &delimiter_expr)?
|
||||||
}
|
}
|
||||||
_ => crate::bail_parse_error!("Incorrect delimiter parameter"),
|
_ => crate::bail_parse_error!("Incorrect delimiter parameter"),
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
delimiter_expr = ast::Expr::Literal(ast::Literal::String(String::from("\",\"")));
|
let delimiter_expr =
|
||||||
}
|
ast::Expr::Literal(ast::Literal::String(String::from("\",\"")));
|
||||||
|
translate_const_arg(program, referenced_tables, resolver, &delimiter_expr)?
|
||||||
|
};
|
||||||
|
|
||||||
let expr_reg = agg_arg_source.translate(program, referenced_tables, resolver, 0)?;
|
let expr_reg = agg_arg_source.translate(program, referenced_tables, resolver, 0)?;
|
||||||
handle_distinct(program, agg_arg_source.aggregate(), expr_reg);
|
handle_distinct(program, agg_arg_source.aggregate(), expr_reg);
|
||||||
translate_expr(
|
|
||||||
program,
|
|
||||||
Some(referenced_tables),
|
|
||||||
&delimiter_expr,
|
|
||||||
delimiter_reg,
|
|
||||||
resolver,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
program.emit_insn(Insn::AggStep {
|
program.emit_insn(Insn::AggStep {
|
||||||
acc_reg: target_register,
|
acc_reg: target_register,
|
||||||
@@ -418,24 +411,18 @@ pub fn translate_aggregation_step(
|
|||||||
crate::bail_parse_error!("string_agg bad number of arguments");
|
crate::bail_parse_error!("string_agg bad number of arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
let delimiter_reg = program.alloc_register();
|
let delimiter_reg = match &agg_arg_source.args()[1] {
|
||||||
|
ast::Expr::Column { .. } => {
|
||||||
let delimiter_expr = match &agg_arg_source.args()[1] {
|
agg_arg_source.translate(program, referenced_tables, resolver, 1)?
|
||||||
arg @ ast::Expr::Column { .. } => arg.clone(),
|
}
|
||||||
ast::Expr::Literal(ast::Literal::String(s)) => {
|
ast::Expr::Literal(ast::Literal::String(s)) => {
|
||||||
ast::Expr::Literal(ast::Literal::String(s.to_string()))
|
let delimiter_expr = ast::Expr::Literal(ast::Literal::String(s.to_string()));
|
||||||
|
translate_const_arg(program, referenced_tables, resolver, &delimiter_expr)?
|
||||||
}
|
}
|
||||||
_ => crate::bail_parse_error!("Incorrect delimiter parameter"),
|
_ => crate::bail_parse_error!("Incorrect delimiter parameter"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let expr_reg = agg_arg_source.translate(program, referenced_tables, resolver, 0)?;
|
let expr_reg = agg_arg_source.translate(program, referenced_tables, resolver, 0)?;
|
||||||
translate_expr(
|
|
||||||
program,
|
|
||||||
Some(referenced_tables),
|
|
||||||
&delimiter_expr,
|
|
||||||
delimiter_reg,
|
|
||||||
resolver,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
program.emit_insn(Insn::AggStep {
|
program.emit_insn(Insn::AggStep {
|
||||||
acc_reg: target_register,
|
acc_reg: target_register,
|
||||||
@@ -506,3 +493,19 @@ pub fn translate_aggregation_step(
|
|||||||
};
|
};
|
||||||
Ok(dest)
|
Ok(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn translate_const_arg(
|
||||||
|
program: &mut ProgramBuilder,
|
||||||
|
referenced_tables: &TableReferences,
|
||||||
|
resolver: &Resolver,
|
||||||
|
expr: &ast::Expr,
|
||||||
|
) -> Result<usize> {
|
||||||
|
let target_register = program.alloc_register();
|
||||||
|
translate_expr(
|
||||||
|
program,
|
||||||
|
Some(referenced_tables),
|
||||||
|
expr,
|
||||||
|
target_register,
|
||||||
|
resolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ do_execsql_test select-group-concat-with-column-delimiter {
|
|||||||
SELECT group_concat(name, id) FROM products;
|
SELECT group_concat(name, id) FROM products;
|
||||||
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
||||||
|
|
||||||
|
do_execsql_test select-group-concat-with-column-delimiter-group-by {
|
||||||
|
SELECT group_concat(name, id) FROM products GROUP BY '1';
|
||||||
|
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
||||||
|
|
||||||
do_execsql_test select-string-agg-with-delimiter {
|
do_execsql_test select-string-agg-with-delimiter {
|
||||||
SELECT string_agg(name, ',') FROM products;
|
SELECT string_agg(name, ',') FROM products;
|
||||||
} {hat,cap,shirt,sweater,sweatshirt,shorts,jeans,sneakers,boots,coat,accessories}
|
} {hat,cap,shirt,sweater,sweatshirt,shorts,jeans,sneakers,boots,coat,accessories}
|
||||||
@@ -96,6 +100,10 @@ do_execsql_test select-string-agg-with-column-delimiter {
|
|||||||
SELECT string_agg(name, id) FROM products;
|
SELECT string_agg(name, id) FROM products;
|
||||||
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
||||||
|
|
||||||
|
do_execsql_test select-string-agg-with-column-delimiter-group-by {
|
||||||
|
SELECT string_agg(name, id) FROM products GROUP BY '1';
|
||||||
|
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
|
||||||
|
|
||||||
do_execsql_test select-agg-unary-negative {
|
do_execsql_test select-agg-unary-negative {
|
||||||
SELECT -max(age) FROM users;
|
SELECT -max(age) FROM users;
|
||||||
} {-100}
|
} {-100}
|
||||||
|
|||||||
Reference in New Issue
Block a user