From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 07192430412 for ; Fri, 14 Aug 2020 18:05:12 +0300 (MSK) From: imeevma@tarantool.org Date: Fri, 14 Aug 2020 18:05:11 +0300 Message-Id: <30b965327d52f04ef5adc433593b73dc3c7ce676.1597417321.git.imeevma@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH v2 09/10] sql: check built-in functions argument types List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: v.shpilevoy@tarantool.org, tsafin@tarantool.org Cc: tarantool-patches@dev.tarantool.org 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( -- }) - - -test:do_execsql_test( - "cse-1.13", - [[ - SELECT upper(b), typeof(b), b FROM t1 - ]], { - -- - "11", "integer", 11, "21", "integer", 21 - -- - }) - -test:do_execsql_test( - "cse-1.14", - [[ - SELECT b, typeof(b), upper(b), typeof(b), b FROM t1 - ]], { - -- - 11, "integer", "11", "integer", 11, 21, "integer", "21", "integer", 21 - -- - }) - -- 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 ]], { -- 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 ]], { -- "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 ]], { -- "", "", "45", "", "78" @@ -412,13 +412,13 @@ test:do_execsql_test( -- }) -test:do_execsql_test( +test:do_catchsql_test( "func-4.4.2", [[ SELECT abs(t1) FROM tbl1 ]], { -- - 0.0, 0.0, 0.0, 0.0, 0.0 + 1, "Type mismatch: can not convert this to number" -- }) @@ -502,13 +502,13 @@ test:do_execsql_test( -- }) -test:do_execsql_test( +test:do_catchsql_test( "func-4.13", [[ SELECT round(t1,2) FROM tbl1 ]], { -- - 0.0, 0.0, 0.0, 0.0, 0.0 + 1, "Type mismatch: can not convert this to double" -- }) @@ -760,18 +760,6 @@ test:do_execsql_test( -- }) -test:do_execsql_test( - "func-5.3", - [[ - SELECT upper(a), lower(a) FROM t2 - ]], { - -- - "1","1","","","345","345","","","67890","67890" - -- - }) - - - 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 ]], { -- "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) ]], { -- @@ -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) ]], { -- @@ -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) ]], { -- @@ -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) ]], { -- @@ -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)) ]], { -- @@ -2918,7 +2906,7 @@ test:do_catchsql_test( SELECT ROUND(X'FF') ]], { -- - 1, "Type mismatch: can not convert varbinary to numeric" + 1, "Type mismatch: can not convert varbinary to double" -- }) @@ -2928,7 +2916,7 @@ test:do_catchsql_test( SELECT RANDOMBLOB(X'FF') ]], { -- - 1, "Type mismatch: can not convert varbinary to numeric" + 1, "Type mismatch: can not convert varbinary to unsigned" -- }) @@ -2938,7 +2926,7 @@ test:do_catchsql_test( SELECT SOUNDEX(X'FF') ]], { -- - 1, "Type mismatch: can not convert varbinary to text" + 1, "Type mismatch: can not convert varbinary to string" -- }) 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, { -- - 1, "Inconsistent types: expected text or varbinary got unsigned" + 1, "Type mismatch: can not convert 34 to string" -- }) @@ -238,7 +238,7 @@ test:do_test( return test:catchsql "SELECT position(34, 123456.78);" end, { -- - 1, "Inconsistent types: expected text or varbinary got real" + 1, "Type mismatch: can not convert 34 to string" -- }) @@ -248,7 +248,7 @@ test:do_test( return test:catchsql "SELECT position(x'3334', 123456.78);" end, { -- - 1, "Inconsistent types: expected text or varbinary got real" + 1, "Type mismatch: can not convert 123456.78 to varbinary" -- }) @@ -554,7 +554,7 @@ test:do_test( return test:catchsql("SELECT position('x', x'78c3a4e282ac79');") end, { -- - 1, "Inconsistent types: expected text got varbinary" + 1, "Type mismatch: can not convert varbinary to string" -- }) @@ -564,7 +564,7 @@ test:do_test( return test:catchsql "SELECT position('y', x'78c3a4e282ac79');" end, { -- - 1, "Inconsistent types: expected text got varbinary" + 1, "Type mismatch: can not convert varbinary to string" -- }) @@ -614,7 +614,7 @@ test:do_test( return test:catchsql "SELECT position(x'79', 'xä€y');" end, { -- - 1, "Inconsistent types: expected varbinary got text" + 1, "Type mismatch: can not convert xä€y to varbinary" -- }) @@ -624,7 +624,7 @@ test:do_test( return test:catchsql "SELECT position(x'a4', 'xä€y');" end, { -- - 1, "Inconsistent types: expected varbinary got text" + 1, "Type mismatch: can not convert xä€y to varbinary" -- }) @@ -634,7 +634,7 @@ test:do_test( return test:catchsql "SELECT position('y', x'78c3a4e282ac79');" end, { -- - 1, "Inconsistent types: expected text got varbinary" + 1, "Type mismatch: can not convert varbinary to string" -- }) 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