[Tarantool-patches] [PATCH v6 03/22] sql: check args of abs()
imeevma at tarantool.org
imeevma at tarantool.org
Thu Jul 16 17:45:47 MSK 2020
After this patch, the argument types of the abs() function will be
checked properly.
Part of #4159
---
src/box/sql/func.c | 52 ++++++++++-------------------------
test/sql-tap/func.test.lua | 4 +--
test/sql-tap/func5.test.lua | 55 ++++++++++++++++++++++++++++++++++++-
test/sql/boolean.result | 2 +-
test/sql/types.result | 2 +-
5 files changed, 73 insertions(+), 42 deletions(-)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 511061b50..329554731 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -504,44 +504,22 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
{
assert(argc == 1);
UNUSED_PARAMETER(argc);
- switch (sql_value_type(argv[0])) {
- case MP_UINT: {
- sql_result_uint(context, sql_value_uint64(argv[0]));
- break;
- }
- case MP_INT: {
+ enum mp_type mp_type = sql_value_type(argv[0]);
+ if (mp_type == MP_NIL)
+ return sql_result_null(context);
+ if (mp_type == MP_UINT)
+ return sql_result_uint(context, sql_value_uint64(argv[0]));
+ if (mp_type == MP_INT) {
int64_t value = sql_value_int64(argv[0]);
assert(value < 0);
- sql_result_uint(context, -value);
- break;
- }
- case MP_NIL:{
- /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
- sql_result_null(context);
- break;
- }
- case MP_BOOL:
- case MP_BIN:
- case MP_ARRAY:
- case MP_MAP: {
- diag_set(ClientError, ER_INCONSISTENT_TYPES, "number",
- mem_type_to_str(argv[0]));
- context->is_aborted = true;
- return;
- }
- default:{
- /* Because sql_value_double() returns 0.0 if the argument is not
- * something that can be converted into a number, we have:
- * IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
- * that cannot be converted to a numeric value.
- */
- double rVal = sql_value_double(argv[0]);
- if (rVal < 0)
- rVal = -rVal;
- sql_result_double(context, rVal);
- break;
- }
- }
+ return sql_result_uint(context, -value);
+ }
+ assert(mp_type == MP_DOUBLE);
+ double value = sql_value_double(argv[0]);
+ if (value < 0)
+ value = -value;
+ sql_result_double(context, value);
+ return;
}
/**
@@ -2242,7 +2220,7 @@ static struct {
} sql_builtins[] = {
{.name = "ABS",
.param_count = 1,
- .first_arg = FIELD_TYPE_ANY,
+ .first_arg = FIELD_TYPE_NUMBER,
.args = FIELD_TYPE_ANY,
.is_blob_like_str = false,
.returns = FIELD_TYPE_NUMBER,
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 3c088920f..422c8ce58 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -412,13 +412,13 @@ test:do_execsql_test(
-- </func-4.4.1>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"func-4.4.2",
[[
SELECT abs(t1) FROM tbl1
]], {
-- <func-4.4.2>
- 0.0, 0.0, 0.0, 0.0, 0.0
+ 1, "Type mismatch: can not convert this to number"
-- </func-4.4.2>
})
diff --git a/test/sql-tap/func5.test.lua b/test/sql-tap/func5.test.lua
index 8329e1735..d6d5d4df6 100755
--- a/test/sql-tap/func5.test.lua
+++ b/test/sql-tap/func5.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(22)
+test:plan(29)
--!./tcltestrunner.lua
-- 2010 August 27
@@ -293,4 +293,57 @@ test:do_catchsql_test(
box.func.COUNTER1:drop()
box.func.COUNTER2:drop()
+--
+-- gh-4159: Make sure function argument types are validated
+-- correctly.
+--
+test:do_execsql_test(
+ "func-5-6.1.1", [[
+ SELECT abs(NULL);
+ ]],{
+ ""
+ })
+
+test:do_execsql_test(
+ "func-5-6.1.2", [[
+ SELECT abs(123);
+ ]], {
+ 123
+ })
+
+test:do_execsql_test(
+ "func-5-6.1.3", [[
+ SELECT abs(-123);
+ ]], {
+ 123
+ })
+
+test:do_execsql_test(
+ "func-5-6.1.4", [[
+ SELECT abs(-5.5);
+ ]], {
+ 5.5
+ })
+
+test:do_catchsql_test(
+ "func-5-6.1.5", [[
+ SELECT abs('-123');
+ ]], {
+ 1, "Type mismatch: can not convert -123 to number"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.1.6", [[
+ SELECT abs(false);
+ ]], {
+ 1, "Type mismatch: can not convert FALSE to number"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.1.7", [[
+ SELECT abs(X'3334');
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to number"
+ })
+
test:finish_test()
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index 112e41a12..c470ebd40 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -276,7 +276,7 @@ SELECT is_boolean('true');
SELECT abs(a) FROM t0;
| ---
| - null
- | - 'Inconsistent types: expected number got boolean'
+ | - 'Type mismatch: can not convert FALSE to number'
| ...
SELECT lower(a) FROM t0;
| ---
diff --git a/test/sql/types.result b/test/sql/types.result
index 438ac44ab..9cb0818e6 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -1326,7 +1326,7 @@ box.execute("SELECT upper(v) FROM t;")
box.execute("SELECT abs(v) FROM t;")
---
- null
-- 'Inconsistent types: expected number got varbinary'
+- 'Type mismatch: can not convert varbinary to number'
...
box.execute("SELECT typeof(v) FROM t;")
---
--
2.25.1
More information about the Tarantool-patches
mailing list