[Tarantool-patches] [PATCH v1 03/10] sql: check number of arguments during parsing
imeevma at tarantool.org
imeevma at tarantool.org
Fri Aug 13 06:17:10 MSK 2021
Prior to this patch, the number of arguments for functions with a
variable number of arguments was checked at runtime. After this patch,
it will be checked during parsing. For functions with a constant number
of arguments, it is always checked during parsing.
Part of #6105
---
src/box/sql/func.c | 23 +++--
test/sql-tap/built-in-functions.test.lua | 119 +++++++++++++++++++++++
test/sql-tap/engine.cfg | 3 +
test/sql-tap/func.test.lua | 8 +-
test/sql-tap/func2.test.lua | 18 ++--
test/sql-tap/func5.test.lua | 6 +-
test/sql-tap/select1.test.lua | 2 +-
test/sql-tap/uuid.test.lua | 2 +-
test/sql/collation.result | 2 +-
9 files changed, 158 insertions(+), 25 deletions(-)
create mode 100755 test/sql-tap/built-in-functions.test.lua
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 7d53b1646..27e38ec16 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -2104,14 +2104,25 @@ find_built_in_func(struct Expr *expr, struct sql_func_dictionary *dict)
{
const char *name = expr->u.zToken;
int n = expr->x.pList != NULL ? expr->x.pList->nExpr : 0;
- struct func *func = &dict->functions[0]->base;
- assert(func->def->exports.sql);
- int param_count = func->def->param_count;
- if (param_count != -1 && param_count != n) {
- diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, name,
- tt_sprintf("%d", func->def->param_count), n);
+ int argc_min = dict->argc_min;
+ int argc_max = dict->argc_max;
+ if (n < argc_min || n > argc_max) {
+ const char *str;
+ if (argc_min == argc_max)
+ str = tt_sprintf("%d", argc_min);
+ else if (argc_max == SQL_MAX_FUNCTION_ARG && n < argc_min)
+ str = tt_sprintf("at least %d", argc_min);
+ else
+ str = tt_sprintf("from %d to %d", argc_min, argc_max);
+ diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, name, str, n);
return NULL;
}
+ struct func *func = NULL;
+ for (uint32_t i = 0; i < dict->count; ++i) {
+ func = &dict->functions[i]->base;
+ if (func->def->param_count == n)
+ break;
+ }
return func;
}
diff --git a/test/sql-tap/built-in-functions.test.lua b/test/sql-tap/built-in-functions.test.lua
new file mode 100755
index 000000000..c704e71a6
--- /dev/null
+++ b/test/sql-tap/built-in-functions.test.lua
@@ -0,0 +1,119 @@
+#!/usr/bin/env tarantool
+local test = require("sqltester")
+test:plan(10)
+
+--
+-- Make sure that number of arguments check is checked properly for SQL built-in
+-- functions with variable number of arguments.
+--
+test:do_catchsql_test(
+ "builtins-1.1",
+ [[
+ SELECT COUNT(1, 2);
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to COUNT(): ]]..
+ [[expected from 0 to 1, got 2]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.2",
+ [[
+ SELECT GREATEST();
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to GREATEST(): ]]..
+ [[expected at least 2, got 0]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.3",
+ [[
+ SELECT GROUP_CONCAT();
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to GROUP_CONCAT(): ]]..
+ [[expected from 1 to 2, got 0]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.4",
+ [[
+ SELECT GROUP_CONCAT(1, 2, 3);
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to GROUP_CONCAT(): ]]..
+ [[expected from 1 to 2, got 3]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.5",
+ [[
+ SELECT LEAST();
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to LEAST(): ]]..
+ [[expected at least 2, got 0]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.6",
+ [[
+ SELECT ROUND();
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to ROUND(): ]]..
+ [[expected from 1 to 2, got 0]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.7",
+ [[
+ SELECT ROUND(1, 2, 3);
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to ROUND(): ]]..
+ [[expected from 1 to 2, got 3]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.8",
+ [[
+ SELECT SUBSTR('1');
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to SUBSTR(): ]]..
+ [[expected from 2 to 3, got 1]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.9",
+ [[
+ SELECT SUBSTR('1', '2', '3', '4');
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to SUBSTR(): ]]..
+ [[expected from 2 to 3, got 4]]
+ }
+)
+
+test:do_catchsql_test(
+ "builtins-1.10",
+ [[
+ SELECT UUID(1, 2);
+ ]],
+ {
+ 1, [[Wrong number of arguments is passed to UUID(): ]]..
+ [[expected from 0 to 1, got 2]]
+ }
+)
+
+test:finish_test()
diff --git a/test/sql-tap/engine.cfg b/test/sql-tap/engine.cfg
index 820c72b00..7d7d281dd 100644
--- a/test/sql-tap/engine.cfg
+++ b/test/sql-tap/engine.cfg
@@ -26,6 +26,9 @@
"metatypes.test.lua": {
"memtx": {"engine": "memtx"}
},
+ "built-in-functions.test.lua": {
+ "memtx": {"engine": "memtx"}
+ },
"gh-4077-iproto-execute-no-bind.test.lua": {},
"*": {
"memtx": {"engine": "memtx"},
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 4cc722d1e..637d67a30 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -427,7 +427,7 @@ test:do_catchsql_test(
SELECT round(a,b,c) FROM t1
]], {
-- <func-4.5>
- 1, "Wrong number of arguments is passed to ROUND(): expected 1 or 2, got 3"
+ 1, "Wrong number of arguments is passed to ROUND(): expected from 1 to 2, got 3"
-- </func-4.5>
})
@@ -487,7 +487,7 @@ test:do_catchsql_test(
SELECT round() FROM t1 ORDER BY a
]], {
-- <func-4.11>
- 1, "Wrong number of arguments is passed to ROUND(): expected 1 or 2, got 0"
+ 1, "Wrong number of arguments is passed to ROUND(): expected from 1 to 2, got 0"
-- </func-4.11>
})
@@ -2553,7 +2553,7 @@ test:do_catchsql_test(
SELECT coalesce()
]], {
-- <func-27.1>
- 1, "Wrong number of arguments is passed to COALESCE(): expected at least two, got 0"
+ 1, "Wrong number of arguments is passed to COALESCE(): expected at least 2, got 0"
-- </func-27.1>
})
@@ -2563,7 +2563,7 @@ test:do_catchsql_test(
SELECT coalesce(1)
]], {
-- <func-27.2>
- 1, "Wrong number of arguments is passed to COALESCE(): expected at least two, got 1"
+ 1, "Wrong number of arguments is passed to COALESCE(): expected at least 2, got 1"
-- </func-27.2>
})
diff --git a/test/sql-tap/func2.test.lua b/test/sql-tap/func2.test.lua
index 95b8a1f5f..792f020f1 100755
--- a/test/sql-tap/func2.test.lua
+++ b/test/sql-tap/func2.test.lua
@@ -50,7 +50,7 @@ test:do_catchsql_test(
SELECT SUBSTR()
]], {
-- <func2-1.2.1>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 0"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 0"
-- </func2-1.2.1>
})
@@ -60,7 +60,7 @@ test:do_catchsql_test(
SELECT SUBSTR('Supercalifragilisticexpialidocious')
]], {
-- <func2-1.2.2>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 1"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 1"
-- </func2-1.2.2>
})
@@ -70,7 +70,7 @@ test:do_catchsql_test(
SELECT SUBSTR('Supercalifragilisticexpialidocious', 1,1,1)
]], {
-- <func2-1.2.3>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 4"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 4"
-- </func2-1.2.3>
})
@@ -673,7 +673,7 @@ if ("ሴ" ~= "u1234")
SELECT SUBSTR()
]], {
-- <func2-2.1.2>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 0"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 0"
-- </func2-2.1.2>
})
@@ -683,7 +683,7 @@ if ("ሴ" ~= "u1234")
SELECT SUBSTR('hiሴho')
]], {
-- <func2-2.1.3>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 1"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 1"
-- </func2-2.1.3>
})
@@ -693,7 +693,7 @@ if ("ሴ" ~= "u1234")
SELECT SUBSTR('hiሴho', 1,1,1)
]], {
-- <func2-2.1.4>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 4"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 4"
-- </func2-2.1.4>
})
@@ -1038,7 +1038,7 @@ test:do_catchsql_test(
SELECT SUBSTR()
]], {
-- <func2-3.1.2>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 0"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 0"
-- </func2-3.1.2>
})
@@ -1048,7 +1048,7 @@ test:do_catchsql_test(
SELECT SUBSTR(x'1234')
]], {
-- <func2-3.1.3>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 1"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 1"
-- </func2-3.1.3>
})
@@ -1058,7 +1058,7 @@ test:do_catchsql_test(
SELECT SUBSTR(x'1234', 1,1,1)
]], {
-- <func2-3.1.4>
- 1, "Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 4"
+ 1, "Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 4"
-- </func2-3.1.4>
})
diff --git a/test/sql-tap/func5.test.lua b/test/sql-tap/func5.test.lua
index 44755b1f7..253c59967 100755
--- a/test/sql-tap/func5.test.lua
+++ b/test/sql-tap/func5.test.lua
@@ -276,19 +276,19 @@ test:do_catchsql_test(
"func-5-5.1",
[[
SELECT LEAST(false);
- ]], { 1, "Wrong number of arguments is passed to LEAST(): expected at least two, got 1" } )
+ ]], { 1, "Wrong number of arguments is passed to LEAST(): expected at least 2, got 1" } )
test:do_catchsql_test(
"func-5-5.2",
[[
SELECT GREATEST('abc');
- ]], { 1, "Wrong number of arguments is passed to GREATEST(): expected at least two, got 1" } )
+ ]], { 1, "Wrong number of arguments is passed to GREATEST(): expected at least 2, got 1" } )
test:do_catchsql_test(
"func-5-5.3",
[[
SELECT LEAST();
- ]], { 1, "Wrong number of arguments is passed to LEAST(): expected at least two, got 0" } )
+ ]], { 1, "Wrong number of arguments is passed to LEAST(): expected at least 2, got 0" } )
-- Make sure that ifnull() returns type of corresponding (i.e. first
-- non-null) argument.
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index dbc6e193d..ba12470f3 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -250,7 +250,7 @@ test:do_catchsql_test(
SELECT count(f1,f2) FROM test1
]], {
-- <select1-2.1>
- 1, "Wrong number of arguments is passed to COUNT(): expected 0 or 1, got 2"
+ 1, "Wrong number of arguments is passed to COUNT(): expected from 0 to 1, got 2"
-- </select1-2.1>
})
diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua
index 57e638046..92691773d 100755
--- a/test/sql-tap/uuid.test.lua
+++ b/test/sql-tap/uuid.test.lua
@@ -1290,7 +1290,7 @@ test:do_catchsql_test(
[[
SELECT uuid(4, 5);
]], {
- 1, "Wrong number of arguments is passed to UUID(): expected one or zero, got 2"
+ 1, "Wrong number of arguments is passed to UUID(): expected from 0 to 1, got 2"
})
-- Make sure the uuid() function generates a new UUID each time when called.
diff --git a/test/sql/collation.result b/test/sql/collation.result
index 1fcc212d8..8444cc7ab 100644
--- a/test/sql/collation.result
+++ b/test/sql/collation.result
@@ -298,7 +298,7 @@ box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = c COLLATE \"unicode\";
box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = substr();")
---
- null
-- 'Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 0'
+- 'Wrong number of arguments is passed to SUBSTR(): expected from 2 to 3, got 0'
...
-- Compound queries perform implicit comparisons between values.
-- Hence, rules for collations compatibilities are the same.
--
2.25.1
More information about the Tarantool-patches
mailing list