mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-29 05:54:21 +01:00
Merge 'core/translate: Add if alias and allow iff to have more arguments' from Pavan Nambi
closes #3689 Closes #3690
This commit is contained in:
@@ -752,7 +752,7 @@ impl Func {
|
||||
"total_changes" => Ok(Self::Scalar(ScalarFunc::TotalChanges)),
|
||||
"glob" => Ok(Self::Scalar(ScalarFunc::Glob)),
|
||||
"ifnull" => Ok(Self::Scalar(ScalarFunc::IfNull)),
|
||||
"iif" => Ok(Self::Scalar(ScalarFunc::Iif)),
|
||||
"if" | "iif" => Ok(Self::Scalar(ScalarFunc::Iif)),
|
||||
"instr" => Ok(Self::Scalar(ScalarFunc::Instr)),
|
||||
"like" => Ok(Self::Scalar(ScalarFunc::Like)),
|
||||
"abs" => Ok(Self::Scalar(ScalarFunc::Abs)),
|
||||
|
||||
@@ -1143,51 +1143,66 @@ pub fn translate_expr(
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::Iif => {
|
||||
if args.len() != 3 {
|
||||
crate::bail_parse_error!(
|
||||
"{} requires exactly 3 arguments",
|
||||
srf.to_string()
|
||||
);
|
||||
let args = expect_arguments_min!(args, 2, srf);
|
||||
|
||||
let iif_end_label = program.allocate_label();
|
||||
let condition_reg = program.alloc_register();
|
||||
|
||||
for pair in args.chunks_exact(2) {
|
||||
let condition_expr = &pair[0];
|
||||
let value_expr = &pair[1];
|
||||
let next_check_label = program.allocate_label();
|
||||
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
condition_expr,
|
||||
condition_reg,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
|
||||
program.emit_insn(Insn::IfNot {
|
||||
reg: condition_reg,
|
||||
target_pc: next_check_label,
|
||||
jump_if_null: true,
|
||||
});
|
||||
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
value_expr,
|
||||
target_register,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
program.emit_insn(Insn::Goto {
|
||||
target_pc: iif_end_label,
|
||||
});
|
||||
|
||||
program.preassign_label_to_next_insn(next_check_label);
|
||||
}
|
||||
let temp_reg = program.alloc_register();
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
&args[0],
|
||||
temp_reg,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
let jump_target_when_false = program.allocate_label();
|
||||
program.emit_insn(Insn::IfNot {
|
||||
reg: temp_reg,
|
||||
target_pc: jump_target_when_false,
|
||||
jump_if_null: true,
|
||||
});
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
&args[1],
|
||||
target_register,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
let jump_target_result = program.allocate_label();
|
||||
program.emit_insn(Insn::Goto {
|
||||
target_pc: jump_target_result,
|
||||
});
|
||||
program.preassign_label_to_next_insn(jump_target_when_false);
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
&args[2],
|
||||
target_register,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
program.preassign_label_to_next_insn(jump_target_result);
|
||||
|
||||
if args.len() % 2 != 0 {
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
referenced_tables,
|
||||
args.last().unwrap(),
|
||||
target_register,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
} else {
|
||||
program.emit_insn(Insn::Null {
|
||||
dest: target_register,
|
||||
dest_end: None,
|
||||
});
|
||||
}
|
||||
|
||||
program.preassign_label_to_next_insn(iif_end_label);
|
||||
Ok(target_register)
|
||||
}
|
||||
|
||||
ScalarFunc::Glob | ScalarFunc::Like => {
|
||||
if args.len() < 2 {
|
||||
crate::bail_parse_error!(
|
||||
|
||||
@@ -1023,7 +1023,58 @@ do_execsql_test sum-8 {
|
||||
} {1.2}
|
||||
|
||||
|
||||
# https://github.com/tursodatabase/turso/issues/3689
|
||||
do_execsql_test iif-3-args-true {
|
||||
select iif(1 < 2, 'yes', 'no');
|
||||
} {yes}
|
||||
|
||||
do_execsql_test iif-3-args-false {
|
||||
select iif(1 > 2, 'yes', 'no');
|
||||
} {no}
|
||||
|
||||
do_execsql_test iif-2-args-true {
|
||||
select iif(1 < 2, 'yes');
|
||||
} {yes}
|
||||
|
||||
do_execsql_test iif-2-args-false-is-null {
|
||||
select iif(1 > 2, 'yes');
|
||||
} {}
|
||||
|
||||
do_execsql_test iif-multi-args-finds-first-true {
|
||||
select iif(0, 'a', 1, 'b', 2, 'c', 'default');
|
||||
} {b}
|
||||
|
||||
do_execsql_test iif-multi-args-falls-to-else {
|
||||
select iif(0, 'a', 0, 'b', 0, 'c', 'default');
|
||||
} {default}
|
||||
|
||||
do_execsql_test if-alias-3-args-true {
|
||||
select if(1 < 2, 'yes', 'no');
|
||||
} {yes}
|
||||
|
||||
do_execsql_test if-alias-3-args-false {
|
||||
select if(1 > 2, 'yes', 'no');
|
||||
} {no}
|
||||
|
||||
do_execsql_test if-alias-2-args-true {
|
||||
select if(1 < 2, 'ok');
|
||||
} {ok}
|
||||
|
||||
do_execsql_test if-alias-multi-args-finds-first-true {
|
||||
select if(0, 'a', 1, 'b', 'c');
|
||||
} {b}
|
||||
|
||||
do_execsql_test if-alias-multi-args-falls-to-else {
|
||||
select if(0, 'a', 0, 'b', 'c');
|
||||
} {c}
|
||||
|
||||
do_execsql_test if-alias-multi-args-no-else-is-null {
|
||||
select if(0, 'a', 0, 'b');
|
||||
} {}
|
||||
|
||||
|
||||
# TODO: sqlite seems not enable soundex() by default unless build it with SQLITE_SOUNDEX enabled.
|
||||
# do_execsql_test soundex-text {
|
||||
# select soundex('Pfister'), soundex('husobee'), soundex('Tymczak'), soundex('Ashcraft'), soundex('Robert'), soundex('Rupert'), soundex('Rubin'), soundex('Kant'), soundex('Knuth'), soundex('x'), soundex('');
|
||||
# } {P236|H210|T522|A261|R163|R163|R150|K530|K530|X000|0000}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user