From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, "n.pettik" <korablev@tarantool.org> Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Subject: [tarantool-patches] Re: [PATCH v1 1/1] sql: invalid integer type in arithmetic operations Date: Thu, 25 Apr 2019 10:32:33 +0300 [thread overview] Message-ID: <590688a0-5a0d-8c2c-5db5-66be40956be0@tarantool.org> (raw) In-Reply-To: <7C38D671-BF76-4B11-A15D-5BDC6E2358B8@tarantool.org> > -> if resulting value of arithmetic operations is integers, > then make sure its type also integer (not number). Updated. > Execution flaw hits this branch if both operands are numeric. > We consider only _INTEGER, _NUMBER and _UNSIGNED be > numeric types. If we hit this assertion, then both operands should > be _UNSIGNED (if I’m not mistaken, condition should be logical > AND not OR). > > Surely, we still can create space and set format with unsigned types > from Lua, so strictly speaking UNSIGNED is allowed even now. > But we can’t set UNSIGNED as a type of column in SQL, and we don’t > set this type in meta. So in some sense it is not allowed. > Mb it is worth fixing comment. Or return _UNSIGNED instead > of _NUMBER in this case. I guess there will be no severe consequences. Let's remove this comment and return _UNSIGNED. > The rest is OK. ================================================ Tarantool SQL used to return 'number' type in request metadata for arithmetic operations even when only 'integer's were used. This also fixes query planner optimisation bug: SELECT a FROM t1 WHERE a+0 IN (SELECT a FROM t1); used to open a new ephemeral table with OpenTEphemeral when it is not required (introduced by 2b22b913). Closes #4103 --- src/box/sql/expr.c | 11 +++++++++-- test/sql-tap/in3.test.lua | 2 +- test/sql-tap/tkt-80e031a00f.test.lua | 8 ++++---- test/sql/gh-3199-no-mem-leaks.result | 24 ++++++++++++------------ test/sql/types.result | 28 ++++++++++++++++++++++++++++ test/sql/types.test.lua | 8 ++++++++ 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index b3613d3ea..ba7eea59d 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -342,8 +342,15 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_explicit_coll, uint32_t *coll_id, enum field_type sql_type_result(enum field_type lhs, enum field_type rhs) { - if (sql_type_is_numeric(lhs) || sql_type_is_numeric(rhs)) - return FIELD_TYPE_NUMBER; + if (sql_type_is_numeric(lhs) || sql_type_is_numeric(rhs)) { + if (lhs == FIELD_TYPE_NUMBER || rhs == FIELD_TYPE_NUMBER) + return FIELD_TYPE_NUMBER; + if (lhs == FIELD_TYPE_INTEGER || rhs == FIELD_TYPE_INTEGER) + return FIELD_TYPE_INTEGER; + assert(lhs == FIELD_TYPE_UNSIGNED || + rhs == FIELD_TYPE_UNSIGNED); + return FIELD_TYPE_UNSIGNED; + } return FIELD_TYPE_SCALAR; } diff --git a/test/sql-tap/in3.test.lua b/test/sql-tap/in3.test.lua index a5e31f8a7..1ca6a6446 100755 --- a/test/sql-tap/in3.test.lua +++ b/test/sql-tap/in3.test.lua @@ -92,7 +92,7 @@ test:do_test( return exec_neph(" SELECT a FROM t1 WHERE a+0 IN (SELECT a FROM t1); ") end, { -- <in3-1.5> - 1, 1, 3, 5 + 0, 1, 3, 5 -- </in3-1.5> }) diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua index 7fd348632..3edea11ac 100755 --- a/test/sql-tap/tkt-80e031a00f.test.lua +++ b/test/sql-tap/tkt-80e031a00f.test.lua @@ -346,7 +346,7 @@ test:do_catchsql_test( SELECT 'hello' IN t1 ]], { -- <tkt-80e031a00f.27> - 1, 'Type mismatch: can not convert hello to number' + 1, 'Type mismatch: can not convert hello to integer' -- </tkt-80e031a00f.27> }) @@ -356,7 +356,7 @@ test:do_catchsql_test( SELECT 'hello' NOT IN t1 ]], { -- <tkt-80e031a00f.28> - 1, 'Type mismatch: can not convert hello to number' + 1, 'Type mismatch: can not convert hello to integer' -- </tkt-80e031a00f.28> }) @@ -386,7 +386,7 @@ test:do_catchsql_test( SELECT x'303132' IN t1 ]], { -- <tkt-80e031a00f.31> - 1, 'Type mismatch: can not convert 012 to number' + 1, 'Type mismatch: can not convert 012 to integer' -- </tkt-80e031a00f.31> }) @@ -396,7 +396,7 @@ test:do_catchsql_test( SELECT x'303132' NOT IN t1 ]], { -- <tkt-80e031a00f.32> - 1, 'Type mismatch: can not convert 012 to number' + 1, 'Type mismatch: can not convert 012 to integer' -- </tkt-80e031a00f.32> }) diff --git a/test/sql/gh-3199-no-mem-leaks.result b/test/sql/gh-3199-no-mem-leaks.result index 22be46a82..e7ba1d29c 100644 --- a/test/sql/gh-3199-no-mem-leaks.result +++ b/test/sql/gh-3199-no-mem-leaks.result @@ -31,7 +31,7 @@ box.execute('SELECT x, y, x + y FROM test ORDER BY y') - name: Y type: integer - name: x + y - type: number + type: integer rows: - [1, 1, 2] - [2, 2, 4] @@ -48,7 +48,7 @@ box.execute('SELECT x, y, x + y FROM test ORDER BY y') - name: Y type: integer - name: x + y - type: number + type: integer rows: - [1, 1, 2] - [2, 2, 4] @@ -61,7 +61,7 @@ box.execute('SELECT x, y, x + y FROM test ORDER BY y') - name: Y type: integer - name: x + y - type: number + type: integer rows: - [1, 1, 2] - [2, 2, 4] @@ -74,7 +74,7 @@ box.execute('SELECT x, y, x + y FROM test ORDER BY y') - name: Y type: integer - name: x + y - type: number + type: integer rows: - [1, 1, 2] - [2, 2, 4] @@ -87,7 +87,7 @@ box.execute('SELECT x, y, x + y FROM test ORDER BY y') - name: Y type: integer - name: x + y - type: number + type: integer rows: - [1, 1, 2] - [2, 2, 4] @@ -114,7 +114,7 @@ box.execute('SELECT a, id + 2, b FROM test2 WHERE b < id * 2 ORDER BY a ') - name: A type: string - name: id + 2 - type: number + type: integer - name: B type: integer rows: @@ -133,7 +133,7 @@ box.execute('SELECT a, id + 2 * b, a FROM test2 WHERE b < id * 2 ORDER BY a ') - name: A type: string - name: id + 2 * b - type: number + type: integer - name: A type: string rows: @@ -148,7 +148,7 @@ box.execute('SELECT a, id + 2 * b, a FROM test2 WHERE b < id * 2 ORDER BY a ') - name: A type: string - name: id + 2 * b - type: number + type: integer - name: A type: string rows: @@ -163,7 +163,7 @@ box.execute('SELECT a, id + 2 * b, a FROM test2 WHERE b < id * 2 ORDER BY a ') - name: A type: string - name: id + 2 * b - type: number + type: integer - name: A type: string rows: @@ -182,7 +182,7 @@ box.execute('SELECT x, y + 3 * b, b FROM test2, test WHERE b = x') - name: X type: integer - name: y + 3 * b - type: number + type: integer - name: B type: integer rows: @@ -195,7 +195,7 @@ box.execute('SELECT x, y + 3 * b, b FROM test2, test WHERE b = x') - name: X type: integer - name: y + 3 * b - type: number + type: integer - name: B type: integer rows: @@ -208,7 +208,7 @@ box.execute('SELECT x, y + 3 * b, b FROM test2, test WHERE b = x') - name: X type: integer - name: y + 3 * b - type: number + type: integer - name: B type: integer rows: diff --git a/test/sql/types.result b/test/sql/types.result index de17bbb78..8f442dc7d 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -860,3 +860,31 @@ box.space.T:drop() box.space.T1:drop() --- ... +-- +-- gh-4103: If resulting value of arithmetic operations is +-- integers, then make sure its type also integer (not number). +-- +box.execute('SELECT 1 + 1;') +--- +- metadata: + - name: 1 + 1 + type: integer + rows: + - [2] +... +box.execute('SELECT 1 + 1.1;') +--- +- metadata: + - name: 1 + 1.1 + type: number + rows: + - [2.1] +... +box.execute('SELECT \'9223372036854\' + 1;') +--- +- metadata: + - name: '''9223372036854'' + 1' + type: integer + rows: + - [9223372036855] +... diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua index 461635978..48c9bde10 100644 --- a/test/sql/types.test.lua +++ b/test/sql/types.test.lua @@ -205,3 +205,11 @@ box.execute("SELECT s FROM t1 WHERE s IN (true, 1, 'abcd')") box.space.T:drop() box.space.T1:drop() + +-- +-- gh-4103: If resulting value of arithmetic operations is +-- integers, then make sure its type also integer (not number). +-- +box.execute('SELECT 1 + 1;') +box.execute('SELECT 1 + 1.1;') +box.execute('SELECT \'9223372036854\' + 1;') -- 2.21.0
next prev parent reply other threads:[~2019-04-25 7:32 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-24 15:36 [tarantool-patches] " Kirill Shcherbatov 2019-04-24 19:43 ` [tarantool-patches] " n.pettik 2019-04-25 7:32 ` Kirill Shcherbatov [this message] 2019-04-24 19:56 ` Vladislav Shpilevoy 2019-04-24 23:03 ` n.pettik 2019-04-25 10:49 ` Konstantin Osipov 2019-04-25 10:52 ` Konstantin Osipov 2019-04-25 11:07 ` Kirill Shcherbatov 2019-04-25 11:15 ` Konstantin Osipov 2019-04-25 11:21 ` Kirill Shcherbatov 2019-04-25 10:37 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=590688a0-5a0d-8c2c-5db5-66be40956be0@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='[tarantool-patches] Re: [PATCH v1 1/1] sql: invalid integer type in arithmetic operations' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox