mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-12 03:34:20 +01:00
Add substring scala function with 2 arg
This commit is contained in:
@@ -107,7 +107,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| substr(X,Y,Z) | No | |
|
||||
| substr(X,Y) | No | |
|
||||
| substring(X,Y,Z) | Yes | |
|
||||
| substring(X,Y) | No | |
|
||||
| substring(X,Y) | Yes | |
|
||||
| total_changes() | No | |
|
||||
| trim(X) | Yes | |
|
||||
| trim(X,Y) | Yes | |
|
||||
|
||||
@@ -304,9 +304,9 @@ pub fn translate_expr(
|
||||
}
|
||||
ScalarFunc::Substring => {
|
||||
let args = if let Some(args) = args {
|
||||
if args.len() != 3 {
|
||||
if !(args.len() == 2 || args.len() == 3) {
|
||||
crate::bail_parse_error!(
|
||||
"{} function with not exactly 3 arguments",
|
||||
"{} function with wrong number of arguments",
|
||||
srf.to_string()
|
||||
)
|
||||
}
|
||||
@@ -324,7 +324,9 @@ pub fn translate_expr(
|
||||
|
||||
translate_expr(program, select, &args[0], str_reg, cursor_hint)?;
|
||||
translate_expr(program, select, &args[1], start_reg, cursor_hint)?;
|
||||
translate_expr(program, select, &args[2], length_reg, cursor_hint)?;
|
||||
if args.len() == 3 {
|
||||
translate_expr(program, select, &args[2], length_reg, cursor_hint)?;
|
||||
}
|
||||
|
||||
program.emit_insn(Insn::Function {
|
||||
start_reg: str_reg,
|
||||
|
||||
@@ -1650,20 +1650,31 @@ fn exec_minmax<'a>(
|
||||
}
|
||||
|
||||
fn exec_substring(str_value: &OwnedValue, start_value: &OwnedValue, length_value: &OwnedValue) -> OwnedValue {
|
||||
match (str_value, start_value, length_value) {
|
||||
(OwnedValue::Text(str), OwnedValue::Integer(start), OwnedValue::Integer(length)) => {
|
||||
let start = *start as usize;
|
||||
if (start as usize) > str.len() {
|
||||
OwnedValue::Text(Rc::new("".to_string()))
|
||||
} else {
|
||||
let length = *length as usize;
|
||||
let start_idx = start - 1;
|
||||
let end = start_idx + length;
|
||||
let substring = &str[start_idx..end.min(str.len())];
|
||||
OwnedValue::Text(Rc::new(substring.to_string()))
|
||||
}
|
||||
if let (OwnedValue::Text(str), OwnedValue::Integer(start), OwnedValue::Integer(length)) = (str_value, start_value, length_value) {
|
||||
let start = *start as usize;
|
||||
if start > str.len() {
|
||||
return OwnedValue::Text(Rc::new("".to_string()));
|
||||
}
|
||||
_ => OwnedValue::Null,
|
||||
|
||||
let start_idx = start - 1;
|
||||
let str_len = str.len();
|
||||
let end = if *length != -1 { start_idx + *length as usize } else { str_len };
|
||||
let substring = &str[start_idx..end.min(str_len)];
|
||||
|
||||
OwnedValue::Text(Rc::new(substring.to_string()))
|
||||
} else if let (OwnedValue::Text(str), OwnedValue::Integer(start)) = (str_value, start_value) {
|
||||
let start = *start as usize;
|
||||
if start > str.len() {
|
||||
return OwnedValue::Text(Rc::new("".to_string()));
|
||||
}
|
||||
|
||||
let start_idx = start - 1;
|
||||
let str_len = str.len();
|
||||
let substring = &str[start_idx..str_len];
|
||||
|
||||
OwnedValue::Text(Rc::new(substring.to_string()))
|
||||
} else {
|
||||
OwnedValue::Null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2190,5 +2201,17 @@ mod tests {
|
||||
let length_value = OwnedValue::Integer(3);
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("")));
|
||||
assert_eq!(exec_substring(&str_value, &start_value, &length_value), expected_val);
|
||||
|
||||
let str_value = OwnedValue::Text(Rc::new("limbo".to_string()));
|
||||
let start_value = OwnedValue::Integer(3);
|
||||
let length_value = OwnedValue::Null;
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("mbo")));
|
||||
assert_eq!(exec_substring(&str_value, &start_value, &length_value), expected_val);
|
||||
|
||||
let str_value = OwnedValue::Text(Rc::new("limbo".to_string()));
|
||||
let start_value = OwnedValue::Integer(10);
|
||||
let length_value = OwnedValue::Null;
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("")));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,18 +239,26 @@ do_execsql_test max-null {
|
||||
select max(null,null)
|
||||
} {}
|
||||
|
||||
do_execsql_test substr {
|
||||
do_execsql_test substr-3-args {
|
||||
SELECT substr('limbo', 1, 3);
|
||||
} {lim}
|
||||
|
||||
do_execsql_test substr-exceed-length {
|
||||
do_execsql_test substr-3-args-exceed-length {
|
||||
SELECT substr('limbo', 1, 10);
|
||||
} {limbo}
|
||||
|
||||
do_execsql_test substr-start-exceed-length {
|
||||
do_execsql_test substr-3-args-start-exceed-length {
|
||||
SELECT substr('limbo', 10, 3);
|
||||
} {}
|
||||
|
||||
do_execsql_test substr-2-args {
|
||||
SELECT substr('limbo', 3);
|
||||
} {mbo}
|
||||
|
||||
do_execsql_test substr-2-args-exceed-length {
|
||||
SELECT substr('limbo', 10);
|
||||
} {}
|
||||
|
||||
do_execsql_test date-current-date {
|
||||
SELECT length(date('now')) = 10;
|
||||
} {1}
|
||||
|
||||
Reference in New Issue
Block a user