mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-23 09:54:26 +01:00
Merge 'Add support for concat scalar function' from Kim Seon Woo
Add support for concat scalar function
### EXPLAIN SELECT concat('a', 1.5, 'b')

## Related issue
https://github.com/penberg/limbo/issues/144
Closes #291
This commit is contained in:
@@ -65,7 +65,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| changes() | No | |
|
||||
| char(X1,X2,...,XN) | Yes | |
|
||||
| coalesce(X,Y,...) | Yes | |
|
||||
| concat(X,...) | No | |
|
||||
| concat(X,...) | Yes | |
|
||||
| concat_ws(SEP,X,...) | No | |
|
||||
| format(FORMAT,...) | No | |
|
||||
| glob(X,Y) | No | |
|
||||
@@ -165,7 +165,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| json_insert(json,path,value,...) | | |
|
||||
| jsonb_insert(json,path,value,...) | | |
|
||||
| json_object(label1,value1,...) | | |
|
||||
| jsonb_object(label1,value1,...) | | |
|
||||
| jsonb_object(label1,value1,...) | | |
|
||||
| json_patch(json1,json2) | | |
|
||||
| jsonb_patch(json1,json2) | | |
|
||||
| json_pretty(json) | | |
|
||||
|
||||
@@ -42,6 +42,7 @@ impl AggFunc {
|
||||
pub enum ScalarFunc {
|
||||
Char,
|
||||
Coalesce,
|
||||
Concat,
|
||||
IfNull,
|
||||
Like,
|
||||
Abs,
|
||||
@@ -67,6 +68,7 @@ impl ToString for ScalarFunc {
|
||||
match self {
|
||||
ScalarFunc::Char => "char".to_string(),
|
||||
ScalarFunc::Coalesce => "coalesce".to_string(),
|
||||
ScalarFunc::Concat => "concat".to_string(),
|
||||
ScalarFunc::IfNull => "ifnull".to_string(),
|
||||
ScalarFunc::Like => "like(2)".to_string(),
|
||||
ScalarFunc::Abs => "abs".to_string(),
|
||||
@@ -111,6 +113,7 @@ impl Func {
|
||||
"total" => Ok(Func::Agg(AggFunc::Total)),
|
||||
"char" => Ok(Func::Scalar(ScalarFunc::Char)),
|
||||
"coalesce" => Ok(Func::Scalar(ScalarFunc::Coalesce)),
|
||||
"concat" => Ok(Func::Scalar(ScalarFunc::Concat)),
|
||||
"ifnull" => Ok(Func::Scalar(ScalarFunc::IfNull)),
|
||||
"like" => Ok(Func::Scalar(ScalarFunc::Like)),
|
||||
"abs" => Ok(Func::Scalar(ScalarFunc::Abs)),
|
||||
|
||||
@@ -220,6 +220,26 @@ pub fn translate_expr(
|
||||
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::Concat => {
|
||||
let args = if let Some(args) = args {
|
||||
args
|
||||
} else {
|
||||
crate::bail_parse_error!(
|
||||
"{} function with no arguments",
|
||||
srf.to_string()
|
||||
);
|
||||
};
|
||||
for arg in args.iter() {
|
||||
let reg = program.alloc_register();
|
||||
translate_expr(program, select, arg, reg, cursor_hint)?;
|
||||
}
|
||||
program.emit_insn(Insn::Function {
|
||||
start_reg: target_register,
|
||||
dest: target_register,
|
||||
func: crate::vdbe::Func::Scalar(srf),
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::IfNull => {
|
||||
let args = match args {
|
||||
Some(args) if args.len() == 2 => args,
|
||||
|
||||
@@ -1192,6 +1192,12 @@ impl Program {
|
||||
state.pc += 1;
|
||||
}
|
||||
Func::Scalar(ScalarFunc::Coalesce) => {}
|
||||
Func::Scalar(ScalarFunc::Concat) => {
|
||||
let start_reg = *start_reg;
|
||||
let result = exec_concat(&state.registers[start_reg..]);
|
||||
state.registers[*dest] = result;
|
||||
state.pc += 1;
|
||||
}
|
||||
Func::Scalar(ScalarFunc::IfNull) => {}
|
||||
Func::Scalar(ScalarFunc::Like) => {
|
||||
let start_reg = *start_reg;
|
||||
@@ -1615,6 +1621,19 @@ fn exec_upper(reg: &OwnedValue) -> Option<OwnedValue> {
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_concat(registers: &[OwnedValue]) -> OwnedValue {
|
||||
let mut result = String::new();
|
||||
for reg in registers {
|
||||
match reg {
|
||||
OwnedValue::Text(text) => result.push_str(text),
|
||||
OwnedValue::Integer(i) => result.push_str(&i.to_string()),
|
||||
OwnedValue::Float(f) => result.push_str(&f.to_string()),
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
OwnedValue::Text(Rc::new(result))
|
||||
}
|
||||
|
||||
fn exec_abs(reg: &OwnedValue) -> Option<OwnedValue> {
|
||||
match reg {
|
||||
OwnedValue::Integer(x) => {
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_execsql_test concat-1 {
|
||||
select concat('l', 'i');
|
||||
} {li}
|
||||
|
||||
do_execsql_test concat-2 {
|
||||
select concat('l', 1);
|
||||
} {l1}
|
||||
|
||||
do_execsql_test concat-3 {
|
||||
select concat('l', 1.5);
|
||||
} {l1.5}
|
||||
|
||||
do_execsql_test concat-4 {
|
||||
select concat('l', null, 'i');
|
||||
} {li}
|
||||
|
||||
do_execsql_test char {
|
||||
select char(108, 105)
|
||||
} {li}
|
||||
|
||||
Reference in New Issue
Block a user