From 27d9af2bf4fef801a642466c591bda3c91a5e7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Fri, 16 Aug 2024 08:26:42 +0900 Subject: [PATCH] Add support for substr scalar function --- COMPAT.md | 4 ++-- core/function.rs | 3 +++ core/translate/expr.rs | 2 +- core/vdbe/mod.rs | 2 +- testing/scalar-functions.test | 16 ++++++++++++++++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/COMPAT.md b/COMPAT.md index 1e0def3aa..acc23976c 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 d6cc28947..09aa5b148 100644 --- a/core/function.rs +++ b/core/function.rs @@ -53,6 +53,7 @@ pub enum ScalarFunc { Length, Min, Max, + Substr, Substring, Date, Time, @@ -75,6 +76,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(), @@ -114,6 +116,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 882f64c3b..1ea4fe9ec 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -302,7 +302,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 0bb64a0de..0a557b927 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -1307,7 +1307,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 41eed2fcc..31160f01c 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -239,6 +239,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}