[Tarantool-patches] [PATCH v2 09/10] sql: check built-in functions argument types
imeevma at tarantool.org
imeevma at tarantool.org
Fri Aug 14 18:05:11 MSK 2020
This patch creates a uniform way to check the argument types of SQL
built-in functions. Prior to this patch, argument types were checked
inside functions. They are now checked in the ApplyType opcode.
Closes #4159
---
src/box/sql/expr.c | 4 +
src/box/sql/select.c | 26 +
src/box/sql/sqlInt.h | 14 +
test/sql-tap/cse.test.lua | 24 +-
test/sql-tap/func.test.lua | 46 +-
test/sql-tap/orderby1.test.lua | 2 +-
test/sql-tap/position.test.lua | 16 +-
test/sql-tap/substr.test.lua | 2 +-
test/sql/boolean.result | 32 +-
test/sql/checks.result | 8 -
test/sql/checks.test.lua | 2 -
test/sql/types.result | 1535 +++++++++++++++++++++++++++++++-
test/sql/types.test.lua | 258 ++++++
13 files changed, 1828 insertions(+), 141 deletions(-)
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 99ca91bba..68b55f0e4 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -4134,6 +4134,10 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
} else {
r1 = 0;
}
+ if (func->def->language == FUNC_LANGUAGE_SQL_BUILTIN) {
+ sql_emit_func_arg_type_check(v, func, r1,
+ nFarg);
+ }
if (sql_func_flag_is_set(func, SQL_FUNC_NEEDCOLL)) {
sqlVdbeAddOp4(v, OP_CollSeq, 0, 0, 0,
(char *)coll, P4_COLLSEQ);
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index b0554a172..49f01eb0d 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -124,6 +124,31 @@ clearSelect(sql * db, Select * p, int bFree)
}
}
+void
+sql_emit_func_arg_type_check(struct Vdbe *vdbe, struct func *func, int reg,
+ uint32_t argc)
+{
+ if (argc == 0 || func->def->param_list == NULL)
+ return;
+ assert(func->def->param_count > 0);
+ uint32_t len = (uint32_t)func->def->param_count;
+ assert(len > 0);
+ size_t size = (argc + 1) * sizeof(enum field_type);
+ enum field_type *types = sqlDbMallocZero(sql_get(), size);
+ if (argc <= len) {
+ for (uint32_t i = 0; i < argc; ++i)
+ types[i] = func->def->param_list[i];
+ } else {
+ for (uint32_t i = 0; i < len; ++i)
+ types[i] = func->def->param_list[i];
+ for (uint32_t i = len; i < argc; ++i)
+ types[i] = func->def->param_list[len - 1];
+ }
+ types[argc] = field_type_MAX;
+ sqlVdbeAddOp4(vdbe, OP_ApplyType, reg, argc, 0, (char *)types,
+ P4_DYNAMIC);
+}
+
/*
* Initialize a SelectDest structure.
*/
@@ -5420,6 +5445,7 @@ updateAccumulator(Parse * pParse, AggInfo * pAggInfo)
vdbe_insert_distinct(pParse, pF->iDistinct, pF->reg_eph,
addrNext, 1, regAgg);
}
+ sql_emit_func_arg_type_check(v, pF->func, regAgg, nArg);
if (sql_func_flag_is_set(pF->func, SQL_FUNC_NEEDCOLL)) {
struct coll *coll = NULL;
struct ExprList_item *pItem;
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 9ff1dd3ff..38fa83df0 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -3883,6 +3883,20 @@ sql_index_type_str(struct sql *db, const struct index_def *idx_def);
void
sql_emit_table_types(struct Vdbe *v, struct space_def *def, int reg);
+/**
+ * Code an OP_ApplyType opcode that try to cast implicitly types
+ * for given range of register starting from @a reg. These values
+ * then will be used as arguments of a function.
+ *
+ * @param vdbe VDBE.
+ * @param func Definition of the function.
+ * @param reg Register where types will be placed.
+ * @param argc Number of arguments.
+ */
+void
+sql_emit_func_arg_type_check(struct Vdbe *vdbe, struct func *func,
+ int reg, uint32_t argc);
+
enum field_type
sql_type_result(enum field_type lhs, enum field_type rhs);
diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua
index 341b6de01..18ddbf47c 100755
--- a/test/sql-tap/cse.test.lua
+++ b/test/sql-tap/cse.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(118)
+test:plan(116)
--!./tcltestrunner.lua
-- 2008 April 1
@@ -193,28 +193,6 @@ test:do_execsql_test(
-- </cse-1.12>
})
-
-
-test:do_execsql_test(
- "cse-1.13",
- [[
- SELECT upper(b), typeof(b), b FROM t1
- ]], {
- -- <cse-1.13>
- "11", "integer", 11, "21", "integer", 21
- -- </cse-1.13>
- })
-
-test:do_execsql_test(
- "cse-1.14",
- [[
- SELECT b, typeof(b), upper(b), typeof(b), b FROM t1
- ]], {
- -- <cse-1.14>
- 11, "integer", "11", "integer", 11, 21, "integer", "21", "integer", 21
- -- </cse-1.14>
- })
-
-- Overflow the column cache. Create queries involving more and more
-- columns until the cache overflows. Verify correct operation throughout.
--
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 3c088920f..575a21007 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(14694)
+test:plan(14693)
--!./tcltestrunner.lua
-- 2001 September 15
@@ -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
@@ -197,7 +197,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-2.9",
[[
- SELECT substr(a,1,1) FROM t2
+ SELECT substr(CAST(a AS STRING),1,1) FROM t2
]], {
-- <func-2.9>
"1", "", "3", "", "6"
@@ -207,7 +207,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-2.10",
[[
- SELECT substr(a,2,2) FROM t2
+ SELECT substr(CAST(a AS STRING),2,2) FROM t2
]], {
-- <func-2.10>
"", "", "45", "", "78"
@@ -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>
})
@@ -502,13 +502,13 @@ test:do_execsql_test(
-- </func-4.12>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"func-4.13",
[[
SELECT round(t1,2) FROM tbl1
]], {
-- <func-4.13>
- 0.0, 0.0, 0.0, 0.0, 0.0
+ 1, "Type mismatch: can not convert this to double"
-- </func-4.13>
})
@@ -760,18 +760,6 @@ test:do_execsql_test(
-- </func-5.2>
})
-test:do_execsql_test(
- "func-5.3",
- [[
- SELECT upper(a), lower(a) FROM t2
- ]], {
- -- <func-5.3>
- "1","1","","","345","345","","","67890","67890"
- -- </func-5.3>
- })
-
-
-
test:do_catchsql_test(
"func-5.5",
[[
@@ -797,7 +785,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-6.2",
[[
- SELECT coalesce(upper(a),'nil') FROM t2
+ SELECT coalesce(upper(CAST(a AS STRING)),'nil') FROM t2
]], {
-- <func-6.2>
"1","nil","345","nil","67890"
@@ -893,7 +881,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-8.5",
[[
- SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
+ SELECT sum(x) FROM (SELECT CAST('9223372036' || '854775807' AS INTEGER) AS x
UNION ALL SELECT -9223372036854775807)
]], {
-- <func-8.5>
@@ -904,7 +892,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-8.6",
[[
- SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
+ SELECT typeof(sum(x)) FROM (SELECT CAST('9223372036' || '854775807' AS INTEGER) AS x
UNION ALL SELECT -9223372036854775807)
]], {
-- <func-8.6>
@@ -915,7 +903,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-8.7",
[[
- SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
+ SELECT typeof(sum(x)) FROM (SELECT CAST('9223372036' || '854775808' AS INTEGER) AS x
UNION ALL SELECT -9223372036854775807)
]], {
-- <func-8.7>
@@ -926,7 +914,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-8.8",
[[
- SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
+ SELECT sum(x)>0.0 FROM (SELECT CAST('9223372036' || '854775808' AS INTEGER) AS x
UNION ALL SELECT -9223372036850000000)
]], {
-- <func-8.8>
@@ -985,7 +973,7 @@ test:do_execsql_test(
test:do_execsql_test(
"func-9.5",
[[
- SELECT length(randomblob(32)), length(randomblob(-5)),
+ SELECT length(randomblob(32)), length(randomblob(0)),
length(randomblob(2000))
]], {
-- <func-9.5>
@@ -2918,7 +2906,7 @@ test:do_catchsql_test(
SELECT ROUND(X'FF')
]], {
-- <func-76.1>
- 1, "Type mismatch: can not convert varbinary to numeric"
+ 1, "Type mismatch: can not convert varbinary to double"
-- </func-76.1>
})
@@ -2928,7 +2916,7 @@ test:do_catchsql_test(
SELECT RANDOMBLOB(X'FF')
]], {
-- <func-76.2>
- 1, "Type mismatch: can not convert varbinary to numeric"
+ 1, "Type mismatch: can not convert varbinary to unsigned"
-- </func-76.2>
})
@@ -2938,7 +2926,7 @@ test:do_catchsql_test(
SELECT SOUNDEX(X'FF')
]], {
-- <func-76.3>
- 1, "Type mismatch: can not convert varbinary to text"
+ 1, "Type mismatch: can not convert varbinary to string"
-- </func-76.3>
})
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-tap/position.test.lua b/test/sql-tap/position.test.lua
index e0455abc9..08fee3796 100755
--- a/test/sql-tap/position.test.lua
+++ b/test/sql-tap/position.test.lua
@@ -228,7 +228,7 @@ test:do_test(
return test:catchsql "SELECT position(34, 12345);"
end, {
-- <position-1.23>
- 1, "Inconsistent types: expected text or varbinary got unsigned"
+ 1, "Type mismatch: can not convert 34 to string"
-- </position-1.23>
})
@@ -238,7 +238,7 @@ test:do_test(
return test:catchsql "SELECT position(34, 123456.78);"
end, {
-- <position-1.24>
- 1, "Inconsistent types: expected text or varbinary got real"
+ 1, "Type mismatch: can not convert 34 to string"
-- </position-1.24>
})
@@ -248,7 +248,7 @@ test:do_test(
return test:catchsql "SELECT position(x'3334', 123456.78);"
end, {
-- <position-1.25>
- 1, "Inconsistent types: expected text or varbinary got real"
+ 1, "Type mismatch: can not convert 123456.78 to varbinary"
-- </position-1.25>
})
@@ -554,7 +554,7 @@ test:do_test(
return test:catchsql("SELECT position('x', x'78c3a4e282ac79');")
end, {
-- <position-1.54>
- 1, "Inconsistent types: expected text got varbinary"
+ 1, "Type mismatch: can not convert varbinary to string"
-- </position-1.54>
})
@@ -564,7 +564,7 @@ test:do_test(
return test:catchsql "SELECT position('y', x'78c3a4e282ac79');"
end, {
-- <position-1.55>
- 1, "Inconsistent types: expected text got varbinary"
+ 1, "Type mismatch: can not convert varbinary to string"
-- </position-1.55>
})
@@ -614,7 +614,7 @@ test:do_test(
return test:catchsql "SELECT position(x'79', 'xä€y');"
end, {
-- <position-1.57.1>
- 1, "Inconsistent types: expected varbinary got text"
+ 1, "Type mismatch: can not convert xä€y to varbinary"
-- </position-1.57.1>
})
@@ -624,7 +624,7 @@ test:do_test(
return test:catchsql "SELECT position(x'a4', 'xä€y');"
end, {
-- <position-1.57.2>
- 1, "Inconsistent types: expected varbinary got text"
+ 1, "Type mismatch: can not convert xä€y to varbinary"
-- </position-1.57.2>
})
@@ -634,7 +634,7 @@ test:do_test(
return test:catchsql "SELECT position('y', x'78c3a4e282ac79');"
end, {
-- <position-1.57.3>
- 1, "Inconsistent types: expected text got varbinary"
+ 1, "Type mismatch: can not convert varbinary to string"
-- </position-1.57.3>
})
diff --git a/test/sql-tap/substr.test.lua b/test/sql-tap/substr.test.lua
index a9e656e6d..a970f9e93 100755
--- a/test/sql-tap/substr.test.lua
+++ b/test/sql-tap/substr.test.lua
@@ -25,7 +25,7 @@ test:plan(93)
--
test:execsql [[
CREATE TABLE t1(id integer primary key --autoincrement
- , t text, b SCALAR)
+ , t text, b VARBINARY)
]]
local function substr_test(id, string, i1, i2, result)
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index 51ec5820b..b525e908c 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -276,29 +276,17 @@ 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;
| ---
- | - metadata:
- | - name: COLUMN_1
- | type: string
- | rows:
- | - ['false']
- | - ['true']
- | - [null]
- | - [null]
+ | - null
+ | - 'Type mismatch: can not convert FALSE to string'
| ...
SELECT upper(a) FROM t0;
| ---
- | - metadata:
- | - name: COLUMN_1
- | type: string
- | rows:
- | - ['FALSE']
- | - ['TRUE']
- | - [null]
- | - [null]
+ | - null
+ | - 'Type mismatch: can not convert FALSE to string'
| ...
SELECT quote(a) FROM t0;
| ---
@@ -314,14 +302,8 @@ SELECT quote(a) FROM t0;
-- gh-4462: LENGTH didn't take BOOLEAN arguments.
SELECT length(a) FROM t0;
| ---
- | - metadata:
- | - name: COLUMN_1
- | type: integer
- | rows:
- | - [5]
- | - [4]
- | - [null]
- | - [null]
+ | - null
+ | - 'Type mismatch: can not convert FALSE to string'
| ...
SELECT typeof(a) FROM t0;
| ---
diff --git a/test/sql/checks.result b/test/sql/checks.result
index 7b18e5d6b..3c942fb23 100644
--- a/test/sql/checks.result
+++ b/test/sql/checks.result
@@ -519,14 +519,6 @@ s:insert({1, 'string'})
---
- error: 'Check constraint failed ''complex2'': typeof(coalesce(z,0))==''integer'''
...
-s:insert({1, {map=true}})
----
-- error: 'Check constraint failed ''complex2'': typeof(coalesce(z,0))==''integer'''
-...
-s:insert({1, {'a', 'r','r','a','y'}})
----
-- error: 'Check constraint failed ''complex2'': typeof(coalesce(z,0))==''integer'''
-...
s:insert({1, 3.14})
---
- error: 'Check constraint failed ''complex2'': typeof(coalesce(z,0))==''integer'''
diff --git a/test/sql/checks.test.lua b/test/sql/checks.test.lua
index 301f8ea69..b55abe955 100644
--- a/test/sql/checks.test.lua
+++ b/test/sql/checks.test.lua
@@ -173,8 +173,6 @@ s:format({{name='X', type='integer'}, {name='Z', type='any'}})
_ = s:create_index('pk', {parts = {1, 'integer'}})
_ = box.space._ck_constraint:insert({s.id, 'complex2', false, 'SQL', 'typeof(coalesce(z,0))==\'integer\'', true})
s:insert({1, 'string'})
-s:insert({1, {map=true}})
-s:insert({1, {'a', 'r','r','a','y'}})
s:insert({1, 3.14})
s:insert({1, 666})
s:drop()
diff --git a/test/sql/types.result b/test/sql/types.result
index 2498f3a48..bd503c700 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -215,25 +215,22 @@ box.execute("INSERT INTO t1 VALUES (randomblob(5));")
box.execute("SELECT * FROM t1 WHERE s LIKE 'blob';")
---
- null
-- 'Inconsistent types: expected text got varbinary'
+- 'Type mismatch: can not convert varbinary to string'
...
box.execute("SELECT * FROM t1 WHERE 'blob' LIKE s;")
---
- null
-- 'Inconsistent types: expected text got varbinary'
+- 'Type mismatch: can not convert varbinary to string'
...
box.execute("SELECT * FROM t1 WHERE 'blob' LIKE x'0000';")
---
- null
-- 'Inconsistent types: expected text got varbinary'
+- 'Type mismatch: can not convert varbinary to string'
...
box.execute("SELECT s LIKE NULL FROM t1;")
---
-- metadata:
- - name: COLUMN_1
- type: boolean
- rows:
- - [null]
+- null
+- 'Type mismatch: can not convert varbinary to string'
...
box.execute("DELETE FROM t1;")
---
@@ -246,20 +243,17 @@ box.execute("INSERT INTO t1 VALUES (1);")
box.execute("SELECT * FROM t1 WHERE s LIKE 'int';")
---
- null
-- 'Inconsistent types: expected text got unsigned'
+- 'Type mismatch: can not convert 1 to string'
...
box.execute("SELECT * FROM t1 WHERE 'int' LIKE 4;")
---
- null
-- 'Inconsistent types: expected text got unsigned'
+- 'Type mismatch: can not convert 4 to string'
...
box.execute("SELECT NULL LIKE s FROM t1;")
---
-- metadata:
- - name: COLUMN_1
- type: boolean
- rows:
- - [null]
+- null
+- 'Type mismatch: can not convert 1 to string'
...
box.space.T1:drop()
---
@@ -830,19 +824,13 @@ box.execute("DELETE FROM t WHERE i < 18446744073709551613;")
...
box.execute("SELECT lower(i) FROM t;")
---
-- metadata:
- - name: COLUMN_1
- type: string
- rows:
- - ['18446744073709551613']
+- null
+- 'Type mismatch: can not convert 18446744073709551613 to string'
...
box.execute("SELECT upper(i) FROM t;")
---
-- metadata:
- - name: COLUMN_1
- type: string
- rows:
- - ['18446744073709551613']
+- null
+- 'Type mismatch: can not convert 18446744073709551613 to string'
...
box.execute("SELECT abs(i) FROM t;")
---
@@ -1312,17 +1300,17 @@ box.execute("SELECT group_concat(v) FROM t;")
box.execute("SELECT lower(v) FROM t;")
---
- null
-- 'Inconsistent types: expected text got varbinary'
+- 'Type mismatch: can not convert varbinary to string'
...
box.execute("SELECT upper(v) FROM t;")
---
- null
-- 'Inconsistent types: expected text got varbinary'
+- 'Type mismatch: can not convert varbinary to string'
...
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;")
---
@@ -1879,25 +1867,13 @@ box.execute("SELECT group_concat(d) FROM t;")
...
box.execute("SELECT lower(d) FROM t;")
---
-- metadata:
- - name: COLUMN_1
- type: string
- rows:
- - ['10.0']
- - ['-2.0']
- - ['3.3']
- - ['1.8e+19']
+- null
+- 'Type mismatch: can not convert 10.0 to string'
...
box.execute("SELECT upper(d) FROM t;")
---
-- metadata:
- - name: COLUMN_1
- type: string
- rows:
- - ['10.0']
- - ['-2.0']
- - ['3.3']
- - ['1.8E+19']
+- null
+- 'Type mismatch: can not convert 10.0 to string'
...
box.execute("SELECT abs(d) FROM t;")
---
@@ -2807,3 +2783,1474 @@ box.execute([[SELECT typeof(length('abc'));]])
rows:
- ['integer']
...
+-- Make sure the function argument types are checked.
+box.execute([[SELECT abs(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1]
+...
+box.execute([[SELECT abs(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1]
+...
+box.execute([[SELECT abs(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT abs(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to number'
+...
+box.execute([[SELECT abs('a');]])
+---
+- null
+- 'Type mismatch: can not convert a to number'
+...
+box.execute([[SELECT abs(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to number'
+...
+box.execute([[SELECT char(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to unsigned'
+...
+box.execute([[SELECT char(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ["\x01"]
+...
+box.execute([[SELECT char(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ["\x01"]
+...
+box.execute([[SELECT char(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to unsigned'
+...
+box.execute([[SELECT char('a');]])
+---
+- null
+- 'Type mismatch: can not convert a to unsigned'
+...
+box.execute([[SELECT char(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to unsigned'
+...
+box.execute([[SELECT character_length(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT character_length(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT character_length(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT character_length(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT character_length('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT character_length(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT char_length(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT char_length(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT char_length(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT char_length(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT char_length('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT char_length(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT coalesce(-1, -1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT coalesce(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT coalesce(1.5, 1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT coalesce(true, true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT coalesce('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT coalesce(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT greatest(-1, -1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT greatest(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT greatest(1.5, 1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT greatest(true, true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT greatest('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT greatest(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT hex(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['2D31']
+...
+box.execute([[SELECT hex(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['31']
+...
+box.execute([[SELECT hex(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['312E35']
+...
+box.execute([[SELECT hex(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['54525545']
+...
+box.execute([[SELECT hex('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['61']
+...
+box.execute([[SELECT hex(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['33']
+...
+box.execute([[SELECT ifnull(-1, -1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT ifnull(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT ifnull(1.5, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT ifnull(true, true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT ifnull('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT ifnull(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT least(-1, -1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT least(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT least(1.5, 1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT least(true, true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT least('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT least(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT length(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT length(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT length(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT length(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT length('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT length(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT likelihood(-1, -1);]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likelihood(1, 1);]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likelihood(1.5, 1.5);]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likelihood(true, true);]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likelihood('a', 'a');]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likelihood(X'33', X'33');]])
+---
+- null
+- Illegal parameters, second argument to likelihood() must be a constant between 0.0
+ and 1.0
+...
+box.execute([[SELECT likely(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [-1]
+...
+box.execute([[SELECT likely(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT likely(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: double
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT likely(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: boolean
+ rows:
+ - [true]
+...
+box.execute([[SELECT likely('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT likely(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - ['3']
+...
+box.execute([[SELECT lower(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT lower(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT lower(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT lower(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT lower('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT lower(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT nullif(-1, -1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT nullif(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT nullif(1.5, 1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT nullif(true, true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT nullif('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT nullif(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [null]
+...
+box.execute([[SELECT position(-1, -1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT position(1, 1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT position(1.5, 1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT position(true, true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT position('a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT position(X'33', X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT printf(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['-1']
+...
+box.execute([[SELECT printf(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['1']
+...
+box.execute([[SELECT printf(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['1.5']
+...
+box.execute([[SELECT printf(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['TRUE']
+...
+box.execute([[SELECT printf('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT printf(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['3']
+...
+box.execute([[SELECT quote(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - [-1]
+...
+box.execute([[SELECT quote(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - [1]
+...
+box.execute([[SELECT quote(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['1.5']
+...
+box.execute([[SELECT quote(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['TRUE']
+...
+box.execute([[SELECT quote('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['''a''']
+...
+box.execute([[SELECT quote(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['X''33''']
+...
+box.execute([[SELECT randomblob(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to unsigned'
+...
+box.execute([[SELECT randomblob(0);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - [null]
+...
+box.execute([[SELECT randomblob(0.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - [null]
+...
+box.execute([[SELECT randomblob(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to unsigned'
+...
+box.execute([[SELECT randomblob('a');]])
+---
+- null
+- 'Type mismatch: can not convert a to unsigned'
+...
+box.execute([[SELECT randomblob(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to unsigned'
+...
+box.execute([[SELECT replace(-1, -1, -1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT replace(1, 1, 1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT replace(1.5, 1.5, 1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT replace(true, true, true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT replace('a', 'a', 'a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT replace(X'33', X'33', X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT round(-1, -1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to unsigned'
+...
+box.execute([[SELECT round(1, 1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: double
+ rows:
+ - [1]
+...
+box.execute([[SELECT round(1.5, 1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: double
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT round(true, true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to double'
+...
+box.execute([[SELECT round('a', 'a');]])
+---
+- null
+- 'Type mismatch: can not convert a to double'
+...
+box.execute([[SELECT round(X'33', X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to double'
+...
+box.execute([[SELECT soundex(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT soundex(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT soundex(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT soundex(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT soundex('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['A000']
+...
+box.execute([[SELECT soundex(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT substr(-1, -1, -1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT substr(1, 1, 1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT substr(1.5, 1.5, 1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT substr(true, true, true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT substr('a', 'a', 'a');]])
+---
+- null
+- 'Type mismatch: can not convert a to integer'
+...
+box.execute([[SELECT substr(X'33', X'33', X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to integer'
+...
+box.execute([[SELECT typeof(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['integer']
+...
+box.execute([[SELECT typeof(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['integer']
+...
+box.execute([[SELECT typeof(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['double']
+...
+box.execute([[SELECT typeof(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['boolean']
+...
+box.execute([[SELECT typeof('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['string']
+...
+box.execute([[SELECT typeof(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['varbinary']
+...
+box.execute([[SELECT unicode(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT unicode(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT unicode(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT unicode(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT unicode('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - [97]
+...
+box.execute([[SELECT unicode(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT unlikely(-1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [-1]
+...
+box.execute([[SELECT unlikely(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT unlikely(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: double
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT unlikely(true);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: boolean
+ rows:
+ - [true]
+...
+box.execute([[SELECT unlikely('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT unlikely(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - ['3']
+...
+box.execute([[SELECT upper(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT upper(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT upper(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT upper(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT upper('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['A']
+...
+box.execute([[SELECT upper(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[SELECT zeroblob(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to unsigned'
+...
+box.execute([[SELECT zeroblob(1);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - ["\0"]
+...
+box.execute([[SELECT zeroblob(1.5);]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: varbinary
+ rows:
+ - ["\0"]
+...
+box.execute([[SELECT zeroblob(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to unsigned'
+...
+box.execute([[SELECT zeroblob('a');]])
+---
+- null
+- 'Type mismatch: can not convert a to unsigned'
+...
+box.execute([[SELECT zeroblob(X'33');]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to unsigned'
+...
+box.execute([[SELECT trim(-1);]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT trim(1);]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT trim(1.5);]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT trim(true);]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT trim('a');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT trim(X'33');]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['3']
+...
+box.execute([[SELECT -1 like -1;]])
+---
+- null
+- 'Type mismatch: can not convert -1 to string'
+...
+box.execute([[SELECT 1 like 1;]])
+---
+- null
+- 'Type mismatch: can not convert 1 to string'
+...
+box.execute([[SELECT 1.5 like 1.5;]])
+---
+- null
+- 'Type mismatch: can not convert 1.5 to string'
+...
+box.execute([[SELECT true like true;]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to string'
+...
+box.execute([[SELECT 'a' like 'a';]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: boolean
+ rows:
+ - [true]
+...
+box.execute([[SELECT X'33' like X'33';]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to string'
+...
+box.execute([[CREATE TABLE t (i INTEGER PRIMARY KEY, u UNSIGNED, d DOUBLE, b BOOLEAN, s STRING, v VARBINARY);]])
+---
+- row_count: 1
+...
+box.execute([[INSERT INTO t VALUES (-1, 1, 1.5, true, 'a', X'33');]])
+---
+- row_count: 1
+...
+box.execute([[SELECT avg(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [-1]
+...
+box.execute([[SELECT avg(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1]
+...
+box.execute([[SELECT avg(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT avg(b) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to number'
+...
+box.execute([[SELECT avg(s) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert a to number'
+...
+box.execute([[SELECT avg(v) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to number'
+...
+box.execute([[SELECT count(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT count(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT count(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT count(b) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT count(s) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT count(v) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT group_concat(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['-1']
+...
+box.execute([[SELECT group_concat(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['1']
+...
+box.execute([[SELECT group_concat(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['1.5']
+...
+box.execute([[SELECT group_concat(b) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['TRUE']
+...
+box.execute([[SELECT group_concat(s) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['a']
+...
+box.execute([[SELECT group_concat(v) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: string
+ rows:
+ - ['3']
+...
+box.execute([[SELECT max(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT max(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT max(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT max(b) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT max(s) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT max(v) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT min(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [-1]
+...
+box.execute([[SELECT min(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1]
+...
+box.execute([[SELECT min(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT min(b) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - [true]
+...
+box.execute([[SELECT min(s) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['a']
+...
+box.execute([[SELECT min(v) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT sum(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [-1]
+...
+box.execute([[SELECT sum(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1]
+...
+box.execute([[SELECT sum(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT sum(b) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to number'
+...
+box.execute([[SELECT sum(s) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert a to number'
+...
+box.execute([[SELECT sum(v) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to number'
+...
+box.execute([[SELECT total(i) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [-1]
+...
+box.execute([[SELECT total(u) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1]
+...
+box.execute([[SELECT total(d) FROM t;]])
+---
+- metadata:
+ - name: COLUMN_1
+ type: number
+ rows:
+ - [1.5]
+...
+box.execute([[SELECT total(b) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert TRUE to number'
+...
+box.execute([[SELECT total(s) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert a to number'
+...
+box.execute([[SELECT total(v) FROM t;]])
+---
+- null
+- 'Type mismatch: can not convert varbinary to number'
+...
+box.execute([[DROP TABLE t;]])
+---
+- row_count: 1
+...
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index fff0057bd..61483e7e9 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -629,3 +629,261 @@ box.execute([[DROP TABLE ts;]])
-- instead of values of type UNSIGNED.
--
box.execute([[SELECT typeof(length('abc'));]])
+
+-- Make sure the function argument types are checked.
+box.execute([[SELECT abs(-1);]])
+box.execute([[SELECT abs(1);]])
+box.execute([[SELECT abs(1.5);]])
+box.execute([[SELECT abs(true);]])
+box.execute([[SELECT abs('a');]])
+box.execute([[SELECT abs(X'33');]])
+
+box.execute([[SELECT char(-1);]])
+box.execute([[SELECT char(1);]])
+box.execute([[SELECT char(1.5);]])
+box.execute([[SELECT char(true);]])
+box.execute([[SELECT char('a');]])
+box.execute([[SELECT char(X'33');]])
+
+box.execute([[SELECT character_length(-1);]])
+box.execute([[SELECT character_length(1);]])
+box.execute([[SELECT character_length(1.5);]])
+box.execute([[SELECT character_length(true);]])
+box.execute([[SELECT character_length('a');]])
+box.execute([[SELECT character_length(X'33');]])
+
+box.execute([[SELECT char_length(-1);]])
+box.execute([[SELECT char_length(1);]])
+box.execute([[SELECT char_length(1.5);]])
+box.execute([[SELECT char_length(true);]])
+box.execute([[SELECT char_length('a');]])
+box.execute([[SELECT char_length(X'33');]])
+
+box.execute([[SELECT coalesce(-1, -1);]])
+box.execute([[SELECT coalesce(1, 1);]])
+box.execute([[SELECT coalesce(1.5, 1.5);]])
+box.execute([[SELECT coalesce(true, true);]])
+box.execute([[SELECT coalesce('a', 'a');]])
+box.execute([[SELECT coalesce(X'33', X'33');]])
+
+box.execute([[SELECT greatest(-1, -1);]])
+box.execute([[SELECT greatest(1, 1);]])
+box.execute([[SELECT greatest(1.5, 1.5);]])
+box.execute([[SELECT greatest(true, true);]])
+box.execute([[SELECT greatest('a', 'a');]])
+box.execute([[SELECT greatest(X'33', X'33');]])
+
+box.execute([[SELECT hex(-1);]])
+box.execute([[SELECT hex(1);]])
+box.execute([[SELECT hex(1.5);]])
+box.execute([[SELECT hex(true);]])
+box.execute([[SELECT hex('a');]])
+box.execute([[SELECT hex(X'33');]])
+
+box.execute([[SELECT ifnull(-1, -1);]])
+box.execute([[SELECT ifnull(1, 1);]])
+box.execute([[SELECT ifnull(1.5, 1);]])
+box.execute([[SELECT ifnull(true, true);]])
+box.execute([[SELECT ifnull('a', 'a');]])
+box.execute([[SELECT ifnull(X'33', X'33');]])
+
+box.execute([[SELECT least(-1, -1);]])
+box.execute([[SELECT least(1, 1);]])
+box.execute([[SELECT least(1.5, 1.5);]])
+box.execute([[SELECT least(true, true);]])
+box.execute([[SELECT least('a', 'a');]])
+box.execute([[SELECT least(X'33', X'33');]])
+
+box.execute([[SELECT length(-1);]])
+box.execute([[SELECT length(1);]])
+box.execute([[SELECT length(1.5);]])
+box.execute([[SELECT length(true);]])
+box.execute([[SELECT length('a');]])
+box.execute([[SELECT length(X'33');]])
+
+box.execute([[SELECT likelihood(-1, -1);]])
+box.execute([[SELECT likelihood(1, 1);]])
+box.execute([[SELECT likelihood(1.5, 1.5);]])
+box.execute([[SELECT likelihood(true, true);]])
+box.execute([[SELECT likelihood('a', 'a');]])
+box.execute([[SELECT likelihood(X'33', X'33');]])
+
+box.execute([[SELECT likely(-1);]])
+box.execute([[SELECT likely(1);]])
+box.execute([[SELECT likely(1.5);]])
+box.execute([[SELECT likely(true);]])
+box.execute([[SELECT likely('a');]])
+box.execute([[SELECT likely(X'33');]])
+
+box.execute([[SELECT lower(-1);]])
+box.execute([[SELECT lower(1);]])
+box.execute([[SELECT lower(1.5);]])
+box.execute([[SELECT lower(true);]])
+box.execute([[SELECT lower('a');]])
+box.execute([[SELECT lower(X'33');]])
+
+box.execute([[SELECT nullif(-1, -1);]])
+box.execute([[SELECT nullif(1, 1);]])
+box.execute([[SELECT nullif(1.5, 1.5);]])
+box.execute([[SELECT nullif(true, true);]])
+box.execute([[SELECT nullif('a', 'a');]])
+box.execute([[SELECT nullif(X'33', X'33');]])
+
+box.execute([[SELECT position(-1, -1);]])
+box.execute([[SELECT position(1, 1);]])
+box.execute([[SELECT position(1.5, 1.5);]])
+box.execute([[SELECT position(true, true);]])
+box.execute([[SELECT position('a', 'a');]])
+box.execute([[SELECT position(X'33', X'33');]])
+
+box.execute([[SELECT printf(-1);]])
+box.execute([[SELECT printf(1);]])
+box.execute([[SELECT printf(1.5);]])
+box.execute([[SELECT printf(true);]])
+box.execute([[SELECT printf('a');]])
+box.execute([[SELECT printf(X'33');]])
+
+box.execute([[SELECT quote(-1);]])
+box.execute([[SELECT quote(1);]])
+box.execute([[SELECT quote(1.5);]])
+box.execute([[SELECT quote(true);]])
+box.execute([[SELECT quote('a');]])
+box.execute([[SELECT quote(X'33');]])
+
+box.execute([[SELECT randomblob(-1);]])
+box.execute([[SELECT randomblob(0);]])
+box.execute([[SELECT randomblob(0.5);]])
+box.execute([[SELECT randomblob(true);]])
+box.execute([[SELECT randomblob('a');]])
+box.execute([[SELECT randomblob(X'33');]])
+
+box.execute([[SELECT replace(-1, -1, -1);]])
+box.execute([[SELECT replace(1, 1, 1);]])
+box.execute([[SELECT replace(1.5, 1.5, 1.5);]])
+box.execute([[SELECT replace(true, true, true);]])
+box.execute([[SELECT replace('a', 'a', 'a');]])
+box.execute([[SELECT replace(X'33', X'33', X'33');]])
+
+box.execute([[SELECT round(-1, -1);]])
+box.execute([[SELECT round(1, 1);]])
+box.execute([[SELECT round(1.5, 1.5);]])
+box.execute([[SELECT round(true, true);]])
+box.execute([[SELECT round('a', 'a');]])
+box.execute([[SELECT round(X'33', X'33');]])
+
+box.execute([[SELECT soundex(-1);]])
+box.execute([[SELECT soundex(1);]])
+box.execute([[SELECT soundex(1.5);]])
+box.execute([[SELECT soundex(true);]])
+box.execute([[SELECT soundex('a');]])
+box.execute([[SELECT soundex(X'33');]])
+
+box.execute([[SELECT substr(-1, -1, -1);]])
+box.execute([[SELECT substr(1, 1, 1);]])
+box.execute([[SELECT substr(1.5, 1.5, 1.5);]])
+box.execute([[SELECT substr(true, true, true);]])
+box.execute([[SELECT substr('a', 'a', 'a');]])
+box.execute([[SELECT substr(X'33', X'33', X'33');]])
+
+box.execute([[SELECT typeof(-1);]])
+box.execute([[SELECT typeof(1);]])
+box.execute([[SELECT typeof(1.5);]])
+box.execute([[SELECT typeof(true);]])
+box.execute([[SELECT typeof('a');]])
+box.execute([[SELECT typeof(X'33');]])
+
+box.execute([[SELECT unicode(-1);]])
+box.execute([[SELECT unicode(1);]])
+box.execute([[SELECT unicode(1.5);]])
+box.execute([[SELECT unicode(true);]])
+box.execute([[SELECT unicode('a');]])
+box.execute([[SELECT unicode(X'33');]])
+
+box.execute([[SELECT unlikely(-1);]])
+box.execute([[SELECT unlikely(1);]])
+box.execute([[SELECT unlikely(1.5);]])
+box.execute([[SELECT unlikely(true);]])
+box.execute([[SELECT unlikely('a');]])
+box.execute([[SELECT unlikely(X'33');]])
+
+box.execute([[SELECT upper(-1);]])
+box.execute([[SELECT upper(1);]])
+box.execute([[SELECT upper(1.5);]])
+box.execute([[SELECT upper(true);]])
+box.execute([[SELECT upper('a');]])
+box.execute([[SELECT upper(X'33');]])
+
+box.execute([[SELECT zeroblob(-1);]])
+box.execute([[SELECT zeroblob(1);]])
+box.execute([[SELECT zeroblob(1.5);]])
+box.execute([[SELECT zeroblob(true);]])
+box.execute([[SELECT zeroblob('a');]])
+box.execute([[SELECT zeroblob(X'33');]])
+
+box.execute([[SELECT trim(-1);]])
+box.execute([[SELECT trim(1);]])
+box.execute([[SELECT trim(1.5);]])
+box.execute([[SELECT trim(true);]])
+box.execute([[SELECT trim('a');]])
+box.execute([[SELECT trim(X'33');]])
+
+box.execute([[SELECT -1 like -1;]])
+box.execute([[SELECT 1 like 1;]])
+box.execute([[SELECT 1.5 like 1.5;]])
+box.execute([[SELECT true like true;]])
+box.execute([[SELECT 'a' like 'a';]])
+box.execute([[SELECT X'33' like X'33';]])
+
+box.execute([[CREATE TABLE t (i INTEGER PRIMARY KEY, u UNSIGNED, d DOUBLE, b BOOLEAN, s STRING, v VARBINARY);]])
+box.execute([[INSERT INTO t VALUES (-1, 1, 1.5, true, 'a', X'33');]])
+
+box.execute([[SELECT avg(i) FROM t;]])
+box.execute([[SELECT avg(u) FROM t;]])
+box.execute([[SELECT avg(d) FROM t;]])
+box.execute([[SELECT avg(b) FROM t;]])
+box.execute([[SELECT avg(s) FROM t;]])
+box.execute([[SELECT avg(v) FROM t;]])
+
+box.execute([[SELECT count(i) FROM t;]])
+box.execute([[SELECT count(u) FROM t;]])
+box.execute([[SELECT count(d) FROM t;]])
+box.execute([[SELECT count(b) FROM t;]])
+box.execute([[SELECT count(s) FROM t;]])
+box.execute([[SELECT count(v) FROM t;]])
+
+box.execute([[SELECT group_concat(i) FROM t;]])
+box.execute([[SELECT group_concat(u) FROM t;]])
+box.execute([[SELECT group_concat(d) FROM t;]])
+box.execute([[SELECT group_concat(b) FROM t;]])
+box.execute([[SELECT group_concat(s) FROM t;]])
+box.execute([[SELECT group_concat(v) FROM t;]])
+
+box.execute([[SELECT max(i) FROM t;]])
+box.execute([[SELECT max(u) FROM t;]])
+box.execute([[SELECT max(d) FROM t;]])
+box.execute([[SELECT max(b) FROM t;]])
+box.execute([[SELECT max(s) FROM t;]])
+box.execute([[SELECT max(v) FROM t;]])
+
+box.execute([[SELECT min(i) FROM t;]])
+box.execute([[SELECT min(u) FROM t;]])
+box.execute([[SELECT min(d) FROM t;]])
+box.execute([[SELECT min(b) FROM t;]])
+box.execute([[SELECT min(s) FROM t;]])
+box.execute([[SELECT min(v) FROM t;]])
+
+box.execute([[SELECT sum(i) FROM t;]])
+box.execute([[SELECT sum(u) FROM t;]])
+box.execute([[SELECT sum(d) FROM t;]])
+box.execute([[SELECT sum(b) FROM t;]])
+box.execute([[SELECT sum(s) FROM t;]])
+box.execute([[SELECT sum(v) FROM t;]])
+
+box.execute([[SELECT total(i) FROM t;]])
+box.execute([[SELECT total(u) FROM t;]])
+box.execute([[SELECT total(d) FROM t;]])
+box.execute([[SELECT total(b) FROM t;]])
+box.execute([[SELECT total(s) FROM t;]])
+box.execute([[SELECT total(v) FROM t;]])
+
+box.execute([[DROP TABLE t;]])
\ No newline at end of file
--
2.25.1
More information about the Tarantool-patches
mailing list