mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-19 09:34:18 +01:00
Add support for ifnull scalar function
This commit is contained in:
@@ -70,7 +70,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| format(FORMAT,...) | No | |
|
||||
| glob(X,Y) | No | |
|
||||
| hex(X) | No | |
|
||||
| ifnull(X,Y) | No | |
|
||||
| ifnull(X,Y) | Yes | |
|
||||
| iif(X,Y,Z) | No | |
|
||||
| instr(X,Y) | No | |
|
||||
| last_insert_rowid() | No | |
|
||||
|
||||
@@ -41,6 +41,7 @@ impl AggFunc {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ScalarFunc {
|
||||
Coalesce,
|
||||
IfNull,
|
||||
Like,
|
||||
Abs,
|
||||
Upper,
|
||||
@@ -63,6 +64,7 @@ impl ToString for ScalarFunc {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
ScalarFunc::Coalesce => "coalesce".to_string(),
|
||||
ScalarFunc::IfNull => "ifnull".to_string(),
|
||||
ScalarFunc::Like => "like(2)".to_string(),
|
||||
ScalarFunc::Abs => "abs".to_string(),
|
||||
ScalarFunc::Upper => "upper".to_string(),
|
||||
@@ -104,6 +106,7 @@ impl Func {
|
||||
"sum" => Ok(Func::Agg(AggFunc::Sum)),
|
||||
"total" => Ok(Func::Agg(AggFunc::Total)),
|
||||
"coalesce" => Ok(Func::Scalar(ScalarFunc::Coalesce)),
|
||||
"ifnull" => Ok(Func::Scalar(ScalarFunc::IfNull)),
|
||||
"like" => Ok(Func::Scalar(ScalarFunc::Like)),
|
||||
"abs" => Ok(Func::Scalar(ScalarFunc::Abs)),
|
||||
"upper" => Ok(Func::Scalar(ScalarFunc::Upper)),
|
||||
|
||||
@@ -205,6 +205,35 @@ pub fn translate_expr(
|
||||
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::IfNull => {
|
||||
let args = match args {
|
||||
Some(args) if args.len() == 2 => args,
|
||||
Some(_) => crate::bail_parse_error!(
|
||||
"{} function requires exactly 2 arguments",
|
||||
srf.to_string()
|
||||
),
|
||||
None => crate::bail_parse_error!(
|
||||
"{} function requires arguments",
|
||||
srf.to_string()
|
||||
),
|
||||
};
|
||||
|
||||
let temp_reg = program.alloc_register();
|
||||
translate_expr(program, select, &args[0], temp_reg, cursor_hint)?;
|
||||
program.emit_insn(Insn::NotNull {
|
||||
reg: temp_reg,
|
||||
target_pc: program.offset() + 2,
|
||||
});
|
||||
|
||||
translate_expr(program, select, &args[1], temp_reg, cursor_hint)?;
|
||||
program.emit_insn(Insn::Copy {
|
||||
src_reg: temp_reg,
|
||||
dst_reg: target_register,
|
||||
amount: 0,
|
||||
});
|
||||
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::Like => {
|
||||
let args = if let Some(args) = args {
|
||||
if args.len() < 2 {
|
||||
|
||||
@@ -53,7 +53,7 @@ pub fn insn_to_str(
|
||||
0,
|
||||
OwnedValue::Text(Rc::new("".to_string())),
|
||||
0,
|
||||
format!("r[{}] -> {}", reg, target_pc),
|
||||
format!("r[{}]!=NULL -> goto {}", reg, target_pc),
|
||||
),
|
||||
Insn::IfPos {
|
||||
reg,
|
||||
@@ -678,7 +678,7 @@ pub fn insn_to_str(
|
||||
*amount as i32,
|
||||
OwnedValue::Text(Rc::new("".to_string())),
|
||||
0,
|
||||
"".to_string(),
|
||||
format!("r[{}]=r[{}]", dst_reg, src_reg),
|
||||
),
|
||||
};
|
||||
format!(
|
||||
|
||||
@@ -1186,6 +1186,7 @@ impl Program {
|
||||
state.pc += 1;
|
||||
}
|
||||
Func::Scalar(ScalarFunc::Coalesce) => {}
|
||||
Func::Scalar(ScalarFunc::IfNull) => {}
|
||||
Func::Scalar(ScalarFunc::Like) => {
|
||||
let start_reg = *start_reg;
|
||||
assert!(
|
||||
|
||||
@@ -19,6 +19,16 @@ do_execsql_test abs-null {
|
||||
select abs(null);
|
||||
} {}
|
||||
|
||||
db null {}
|
||||
|
||||
do_execsql_test ifnull-1 {
|
||||
select ifnull(1, 2);
|
||||
} {1}
|
||||
|
||||
do_execsql_test ifnull-2 {
|
||||
select ifnull(null, 2);
|
||||
} {2}
|
||||
|
||||
do_execsql_test upper {
|
||||
select upper('Limbo')
|
||||
} {LIMBO}
|
||||
|
||||
Reference in New Issue
Block a user