Merge 'Add support for substr scalar function' from Kim Seon Woo

Add support for `substr` scalar function. We can reuse the `substring` logic which is already implemted.

## Related issue
https://github.com/penberg/limbo/issues/144

Closes #289
This commit is contained in:
Pekka Enberg
2024-08-16 14:36:55 +03:00
5 changed files with 23 additions and 4 deletions

View File

@@ -104,8 +104,8 @@ This document describes the SQLite compatibility status of Limbo:
| sqlite_offset(X) | No | |
| sqlite_source_id() | No | |
| sqlite_version() | No | |
| substr(X,Y,Z) | No | |
| substr(X,Y) | No | |
| substr(X,Y,Z) | Yes | |
| substr(X,Y) | Yes | |
| substring(X,Y,Z) | Yes | |
| substring(X,Y) | Yes | |
| total_changes() | No | |

View File

@@ -54,6 +54,7 @@ pub enum ScalarFunc {
Length,
Min,
Max,
Substr,
Substring,
Date,
Time,
@@ -77,6 +78,7 @@ impl ToString for ScalarFunc {
ScalarFunc::Length => "length".to_string(),
ScalarFunc::Min => "min".to_string(),
ScalarFunc::Max => "max".to_string(),
ScalarFunc::Substr => "substr".to_string(),
ScalarFunc::Substring => "substring".to_string(),
ScalarFunc::Date => "date".to_string(),
ScalarFunc::Time => "time".to_string(),
@@ -117,6 +119,7 @@ impl Func {
"rtrim" => Ok(Func::Scalar(ScalarFunc::RTrim)),
"round" => Ok(Func::Scalar(ScalarFunc::Round)),
"length" => Ok(Func::Scalar(ScalarFunc::Length)),
"substr" => Ok(Func::Scalar(ScalarFunc::Substr)),
"substring" => Ok(Func::Scalar(ScalarFunc::Substring)),
"date" => Ok(Func::Scalar(ScalarFunc::Date)),
"time" => Ok(Func::Scalar(ScalarFunc::Time)),

View File

@@ -317,7 +317,7 @@ pub fn translate_expr(
});
Ok(target_register)
}
ScalarFunc::Substring => {
ScalarFunc::Substr | ScalarFunc::Substring => {
let args = if let Some(args) = args {
if !(args.len() == 2 || args.len() == 3) {
crate::bail_parse_error!(

View File

@@ -1313,7 +1313,7 @@ impl Program {
}
state.pc += 1;
}
Func::Scalar(ScalarFunc::Substring) => {
Func::Scalar(ScalarFunc::Substr) | Func::Scalar(ScalarFunc::Substring) => {
let start_reg = *start_reg;
let str_value = &state.registers[start_reg];
let start_value = &state.registers[start_reg + 1];

View File

@@ -255,6 +255,22 @@ do_execsql_test max-null {
select max(null,null)
} {}
do_execsql_test substr-3-args {
SELECT substr('limbo', 1, 3);
} {lim}
do_execsql_test substr-3-args-exceed-length {
SELECT substr('limbo', 1, 10);
} {limbo}
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 substring-3-args {
SELECT substring('limbo', 1, 3);
} {lim}