diff --git a/COMPAT.md b/COMPAT.md index d36b38991..d8c97e7ac 100644 --- a/COMPAT.md +++ b/COMPAT.md @@ -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 | | diff --git a/core/function.rs b/core/function.rs index f12e22c48..578af0db2 100644 --- a/core/function.rs +++ b/core/function.rs @@ -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)), diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 390fb8a4b..53f0dfa78 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -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!( diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 0e26c2578..0a4f15746 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -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]; diff --git a/testing/scalar-functions.test b/testing/scalar-functions.test index a82d069db..71e0db837 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -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}