From 93dc653dc57a58702c4e8e8af9a52d3fd4fd58e6 Mon Sep 17 00:00:00 2001 From: Arseniy Volynets <a.volynets@picodata.io> Date: Mon, 2 Sep 2024 14:35:55 +0300 Subject: [PATCH] feat: export lower/upper string functions --- doc/sql/query.ebnf | 7 +++++ .../test_app/test/integration/api_test.lua | 28 +++++++++++++++++++ sbroad-core/src/executor/engine.rs | 2 ++ .../src/frontend/sql/ir/tests/funcs.rs | 21 ++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 sbroad-core/src/frontend/sql/ir/tests/funcs.rs diff --git a/doc/sql/query.ebnf b/doc/sql/query.ebnf index 3e50438819..6b25a24b1c 100644 --- a/doc/sql/query.ebnf +++ b/doc/sql/query.ebnf @@ -29,6 +29,10 @@ expression ::= ('NOT'* ( | to_char | to_date | trim + | substr + | lower + | upper + | '(' expression ')' | 'NOT'? 'EXISTS' '(' dql ')' | '(' dql ')' | '(' expression (',' expression)* ')' @@ -56,6 +60,9 @@ trim ::= 'TRIM' '(' ((('LEADING' | 'TRAILING' | 'BOTH')? removal_chars | ('LEADING' | 'TRAILING' | 'BOTH')) 'FROM')? string ')' substr ::= 'SUBSTR' '(' string ',' from (',' count)? ')' +lower ::= 'LOWER' '(' string ')' +upper ::= 'UPPER' '(' string ')' +substr ::= 'SUBSTR' '(' string ',' from (',' count)? ')' values ::= 'VALUES' ('(' (expression(',' expression)*) ')') (',' ('(' (expression(',' expression)*) ')'))* diff --git a/sbroad-cartridge/test_app/test/integration/api_test.lua b/sbroad-cartridge/test_app/test/integration/api_test.lua index 5985e48780..8af0c9dc7a 100644 --- a/sbroad-cartridge/test_app/test/integration/api_test.lua +++ b/sbroad-cartridge/test_app/test/integration/api_test.lua @@ -698,6 +698,34 @@ g.test_union_operator_works = function () }) end +g.test_lower_upper = function () + local api = cluster:server("api-1").net_box + + local meta = { + {name = "a", type = "string"}, + {name = "b", type = "string"}, + } + local r, err = api:call("sbroad.execute", { [[ + select lower("COLUMN_1") as a, upper("COLUMN_1") as b from (values ('Aba')) + ]] }) + + t.assert_equals(err, nil) + t.assert_equals(r.metadata, meta) + t.assert_equals(r.rows, { + {'aba', 'ABA'} + }) + + r, err = api:call("sbroad.execute", { [[ + select upper(lower("COLUMN_1")) as a, lower(upper("COLUMN_1")) as b from (values ('Aba')) + ]] }) + + t.assert_equals(err, nil) + t.assert_equals(r.metadata, meta) + t.assert_equals(r.rows, { + {'ABA', 'aba'} + }) +end + g.test_like_works = function () local api = cluster:server("api-1").net_box diff --git a/sbroad-core/src/executor/engine.rs b/sbroad-core/src/executor/engine.rs index 778b4c8a5d..ce4d80b41f 100644 --- a/sbroad-core/src/executor/engine.rs +++ b/sbroad-core/src/executor/engine.rs @@ -80,6 +80,8 @@ pub fn get_builtin_functions() -> &'static [Function] { Function::new_stable("to_date".into(), Type::Datetime, false), Function::new_stable("to_char".into(), Type::String, false), Function::new_stable("substr".into(), Type::String, true), + Function::new_stable("lower".into(), Type::String, true), + Function::new_stable("upper".into(), Type::String, true), ] }) } diff --git a/sbroad-core/src/frontend/sql/ir/tests/funcs.rs b/sbroad-core/src/frontend/sql/ir/tests/funcs.rs new file mode 100644 index 0000000000..ab865bf4c1 --- /dev/null +++ b/sbroad-core/src/frontend/sql/ir/tests/funcs.rs @@ -0,0 +1,21 @@ +use crate::ir::transformation::helpers::sql_to_optimized_ir; +use pretty_assertions::assert_eq; + +#[test] +fn lower_upper() { + let input = r#"select upper(lower('a' || 'B')), upper(a) from t1"#; + + let plan = sql_to_optimized_ir(input, vec![]); + println!("{}", plan.as_explain().unwrap()); + + let expected_explain = String::from( + r#"projection (upper((lower((ROW('a'::string) || ROW('B'::string)))::string))::string -> "col_1", upper(("t1"."a"::string))::string -> "col_2") + scan "t1" +execution options: +sql_vdbe_max_steps = 45000 +vtable_max_rows = 5000 +"#, + ); + + assert_eq!(expected_explain, plan.as_explain().unwrap()); +} -- GitLab