[Tarantool-patches] [PATCH v6 06/22] sql: check args of length()
imeevma at tarantool.org
imeevma at tarantool.org
Thu Jul 16 17:45:52 MSK 2020
After this patch, the argument types of the length(), char_length() and
character_length() functions will be checked properly.
Part of #4159
---
src/box/sql/func.c | 48 ++++-------
test/sql-tap/func.test.lua | 2 +-
test/sql-tap/func5.test.lua | 149 ++++++++++++++++++++++++++++++++-
test/sql-tap/orderby1.test.lua | 2 +-
test/sql/boolean.result | 10 +--
5 files changed, 170 insertions(+), 41 deletions(-)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 2d0aea801..a22ba38e2 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -467,30 +467,18 @@ lengthFunc(sql_context * context, int argc, sql_value ** argv)
assert(argc == 1);
UNUSED_PARAMETER(argc);
- switch (sql_value_type(argv[0])) {
- case MP_BIN:
- case MP_ARRAY:
- case MP_MAP:
- case MP_INT:
- case MP_UINT:
- case MP_BOOL:
- case MP_DOUBLE:{
- sql_result_uint(context, sql_value_bytes(argv[0]));
- break;
- }
- case MP_STR:{
- const unsigned char *z = sql_value_text(argv[0]);
- if (z == 0)
- return;
- len = sql_utf8_char_count(z, sql_value_bytes(argv[0]));
- sql_result_uint(context, len);
- break;
- }
- default:{
- sql_result_null(context);
- break;
- }
- }
+ enum mp_type mp_type = sql_value_type(argv[0]);
+ if (mp_type == MP_NIL)
+ return sql_result_null(context);
+ if (mp_type == MP_BIN)
+ return sql_result_uint(context, sql_value_bytes(argv[0]));
+ assert(mp_type == MP_STR);
+ const unsigned char *z = sql_value_text(argv[0]);
+ if (z == NULL)
+ return;
+ len = sql_utf8_char_count(z, sql_value_bytes(argv[0]));
+ sql_result_uint(context, len);
+ return;
}
/*
@@ -2278,9 +2266,9 @@ static struct {
}, {
.name = "CHARACTER_LENGTH",
.param_count = 1,
- .first_arg = FIELD_TYPE_ANY,
+ .first_arg = FIELD_TYPE_STRING,
.args = FIELD_TYPE_ANY,
- .is_blob_like_str = false,
+ .is_blob_like_str = true,
.returns = FIELD_TYPE_INTEGER,
.aggregate = FUNC_AGGREGATE_NONE,
.is_deterministic = true,
@@ -2291,9 +2279,9 @@ static struct {
}, {
.name = "CHAR_LENGTH",
.param_count = 1,
- .first_arg = FIELD_TYPE_ANY,
+ .first_arg = FIELD_TYPE_STRING,
.args = FIELD_TYPE_ANY,
- .is_blob_like_str = false,
+ .is_blob_like_str = true,
.returns = FIELD_TYPE_INTEGER,
.aggregate = FUNC_AGGREGATE_NONE,
.is_deterministic = true,
@@ -2551,9 +2539,9 @@ static struct {
}, {
.name = "LENGTH",
.param_count = 1,
- .first_arg = FIELD_TYPE_ANY,
+ .first_arg = FIELD_TYPE_STRING,
.args = FIELD_TYPE_ANY,
- .is_blob_like_str = false,
+ .is_blob_like_str = true,
.returns = FIELD_TYPE_INTEGER,
.aggregate = FUNC_AGGREGATE_NONE,
.is_deterministic = true,
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index ffee8f1c5..69d175e16 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -95,7 +95,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-1.4",
[[
- SELECT coalesce(length(a),-1) FROM t2
+ SELECT coalesce(length(CAST(a AS STRING)),-1) FROM t2
]], {
-- <func-1.4>
1, -1, 3, -1, 5
diff --git a/test/sql-tap/func5.test.lua b/test/sql-tap/func5.test.lua
index 6e65b98ac..0398d8a9d 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(57)
+test:plan(78)
--!./tcltestrunner.lua
-- 2010 August 27
@@ -542,4 +542,151 @@ test:do_catchsql_test(
1, "Type mismatch: can not convert varbinary to unsigned"
})
+test:do_execsql_test(
+ "func-5-6.6.1", [[
+ SELECT length(NULL);
+ ]],{
+ ""
+ })
+
+test:do_catchsql_test(
+ "func-5-6.6.2", [[
+ SELECT length(123);
+ ]], {
+ 1, "Type mismatch: can not convert 123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.6.3", [[
+ SELECT length(-123);
+ ]], {
+ 1, "Type mismatch: can not convert -123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.6.4", [[
+ SELECT length(-5.5);
+ ]], {
+ 1, "Type mismatch: can not convert -5.5 to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.6.5", [[
+ SELECT length('-123');
+ ]], {
+ 4
+ })
+
+test:do_catchsql_test(
+ "func-5-6.6.6", [[
+ SELECT length(false);
+ ]], {
+ 1, "Type mismatch: can not convert FALSE to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.6.7", [[
+ SELECT length(X'3334');
+ ]], {
+ 2
+ })
+
+test:do_execsql_test(
+ "func-5-6.7.1", [[
+ SELECT char_length(NULL);
+ ]],{
+ ""
+ })
+
+test:do_catchsql_test(
+ "func-5-6.7.2", [[
+ SELECT char_length(123);
+ ]], {
+ 1, "Type mismatch: can not convert 123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.7.3", [[
+ SELECT char_length(-123);
+ ]], {
+ 1, "Type mismatch: can not convert -123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.7.4", [[
+ SELECT char_length(-5.5);
+ ]], {
+ 1, "Type mismatch: can not convert -5.5 to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.7.5", [[
+ SELECT char_length('-123');
+ ]], {
+ 4
+ })
+
+test:do_catchsql_test(
+ "func-5-6.7.6", [[
+ SELECT char_length(false);
+ ]], {
+ 1, "Type mismatch: can not convert FALSE to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.7.7", [[
+ SELECT char_length(X'3334');
+ ]], {
+ 2
+ })
+
+test:do_execsql_test(
+ "func-5-6.8.1", [[
+ SELECT character_length(NULL);
+ ]],{
+ ""
+ })
+
+test:do_catchsql_test(
+ "func-5-6.8.2", [[
+ SELECT character_length(123);
+ ]], {
+ 1, "Type mismatch: can not convert 123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.8.3", [[
+ SELECT character_length(-123);
+ ]], {
+ 1, "Type mismatch: can not convert -123 to string"
+ })
+
+test:do_catchsql_test(
+ "func-5-6.8.4", [[
+ SELECT character_length(-5.5);
+ ]], {
+ 1, "Type mismatch: can not convert -5.5 to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.8.5", [[
+ SELECT character_length('-123');
+ ]], {
+ 4
+ })
+
+test:do_catchsql_test(
+ "func-5-6.8.6", [[
+ SELECT character_length(false);
+ ]], {
+ 1, "Type mismatch: can not convert FALSE to string"
+ })
+
+test:do_execsql_test(
+ "func-5-6.8.7", [[
+ SELECT character_length(X'3334');
+ ]], {
+ 2
+ })
+
test:finish_test()
diff --git a/test/sql-tap/orderby1.test.lua b/test/sql-tap/orderby1.test.lua
index 51e8d301f..95a8de487 100755
--- a/test/sql-tap/orderby1.test.lua
+++ b/test/sql-tap/orderby1.test.lua
@@ -735,7 +735,7 @@ test:do_execsql_test(
SELECT (
SELECT 'hardware' FROM (
SELECT 'software' ORDER BY 'firmware' ASC, 'sportswear' DESC
- ) GROUP BY 1 HAVING length(b) <> 0
+ ) GROUP BY 1 HAVING length(CAST(b AS STRING)) <> 0
)
FROM abc;
]], {
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index c470ebd40..39098b1f4 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -314,14 +314,8 @@ SELECT quote(a) FROM t0;
-- gh-4462: LENGTH didn't take BOOLEAN arguments.
SELECT length(a) FROM t0;
| ---
- | - metadata:
- | - name: length(a)
- | type: integer
- | rows:
- | - [5]
- | - [4]
- | - [null]
- | - [null]
+ | - null
+ | - 'Type mismatch: can not convert FALSE to string'
| ...
SELECT typeof(a) FROM t0;
| ---
--
2.25.1
More information about the Tarantool-patches
mailing list