After this patch, bitwise operations will only accept UNSIGNED and positive INTEGER values as operands. The result of the bitwise operand will be UNSIGNED. Part of #4470 Closes #5364 --- https://github.com/tarantool/tarantool/issues/4470 https://github.com/tarantool/tarantool/issues/5364 https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations .../gh-5364-define-bit-wise-operations-rules | 4 + src/box/sql/mem.c | 131 +++++----- src/box/sql/vdbe.c | 8 +- test/sql-tap/cse.test.lua | 9 +- .../gh-5364-define-bit-wise-rules.test.lua | 237 ++++++++++++++++++ test/sql-tap/suite.ini | 1 + test/sql-tap/uuid.test.lua | 10 +- test/sql/boolean.result | 204 +++++++-------- test/sql/types.result | 4 +- 9 files changed, 423 insertions(+), 185 deletions(-) create mode 100644 changelogs/unreleased/gh-5364-define-bit-wise-operations-rules create mode 100755 test/sql-tap/gh-5364-define-bit-wise-rules.test.lua diff --git a/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules new file mode 100644 index 000000000..fe428d395 --- /dev/null +++ b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules @@ -0,0 +1,4 @@ +## feature/sql + +* Bitwise operations can now only accept UNSIGNED and positive INTEGER + values (gh-5364). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 50063f490..776ce8f04 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -1786,51 +1786,47 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result) return 0; } -static int -bitwise_prepare(const struct Mem *left, const struct Mem *right, - int64_t *a, int64_t *b) +int +mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) { - bool unused; - if (mem_get_int(left, a, &unused) != 0) { - diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), - "integer"); - return -1; + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; + return 0; } - if (mem_get_int(right, b, &unused) != 0) { + if (right->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), - "integer"); + "unsigned"); return -1; } - return 0; -} - -int -mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) -{ - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) - return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); return -1; - result->u.i = a & b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + mem_set_uint(result, left->u.u & right->u.u); return 0; } int mem_bit_or(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - result->u.i = a | b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, left->u.u | right->u.u); return 0; } @@ -1838,22 +1834,22 @@ int mem_shift_left(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = a >= 0 ? 0 : -1; - else if (b < 0) - result->u.i = a >> -b; - else if (b > 64) - result->u.i = 0; - else - result->u.i = a << b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u << right->u.u); return 0; } @@ -1861,42 +1857,39 @@ int mem_shift_right(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = 0; - else if (b < 0) - result->u.i = a << -b; - else if (b > 64) - result->u.i = a >= 0 ? 0 : -1; - else - result->u.i = a >> b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u >> right->u.u); return 0; } int mem_bit_not(const struct Mem *mem, struct Mem *result) { - mem_clear(result); - result->field_type = FIELD_TYPE_INTEGER; - if (mem->type == MEM_TYPE_NULL) + if (mem_is_null(mem)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t i; - bool unused; - if (mem_get_int(mem, &i, &unused) != 0) { + } + if (mem->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(mem), - "integer"); + "unsigned"); return -1; } - result->u.i = ~i; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + mem_set_uint(result, ~mem->u.u); return 0; } diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 9e763ed85..6f6b2aab9 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1354,7 +1354,7 @@ case OP_BitAnd: { /* same as TK_BITAND, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_and(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1371,7 +1371,7 @@ case OP_BitOr: { /* same as TK_BITOR, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_or(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1389,7 +1389,7 @@ case OP_ShiftLeft: { /* same as TK_LSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_left(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1407,7 +1407,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_right(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua index e09f955a0..b0e5ccddf 100755 --- a/test/sql-tap/cse.test.lua +++ b/test/sql-tap/cse.test.lua @@ -35,7 +35,8 @@ test:do_test( ]] end, { -- <cse-1.1> - 11, -11, -12, false, true, 0, 22, 121, 1, 11, 21, -21, -22, false, true, 0, 42, 441, 1, 21 + 11, -11, 18446744073709551604ULL, false, true, 0, 22, 121, 1, 11, + 21, -21, 18446744073709551594ULL, false, true, 0, 42, 441, 1, 21 -- </cse-1.1> }) @@ -135,7 +136,8 @@ test:do_execsql_test( SELECT a, -a, ~a, NOT CAST(a AS BOOLEAN), NOT NOT CAST(a AS BOOLEAN), a-a, a+a, a*a, a/a, a FROM t1 ]], { -- <cse-1.7> - 1, -1 ,-2, false, true, 0, 2, 1, 1, 1, 2, -2, -3, false, true, 0, 4, 4, 1, 2 + 1, -1, 18446744073709551614ULL, false, true, 0, 2, 1, 1, 1, + 2, -2, 18446744073709551613ULL, false, true, 0, 4, 4, 1, 2 -- </cse-1.7> }) @@ -155,7 +157,8 @@ test:do_execsql_test( SELECT NOT CAST(b AS BOOLEAN), ~b, NOT NOT CAST(b AS BOOLEAN), b FROM t1 ]], { -- <cse-1.9> - false, -12, true, 11, false, -22, true, 21 + false, 18446744073709551604ULL, true, 11, + false, 18446744073709551594ULL, true, 21 -- </cse-1.9> }) diff --git a/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua new file mode 100755 index 000000000..37bf62487 --- /dev/null +++ b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua @@ -0,0 +1,237 @@ +#!/usr/bin/env tarantool +local test = require("sqltester") +test:plan(28) + +-- +-- Make sure that bit-wise operations can only accept UNSIGNED and posivite +-- INTEGER values. +-- +test:do_execsql_test( + "gh-5364-1.1", + [[ + SELECT 9 >> 2; + ]], { + 2 + }) + +test:do_catchsql_test( + "gh-5364-1.2", + [[ + SELECT 9 >> -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.3", + [[ + SELECT 9 >> 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.4", + [[ + SELECT 9 >> '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.5", + [[ + SELECT 9 >> x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.6", + [[ + SELECT 9 >> true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.7", + [[ + SELECT 9 >> CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-2.1", + [[ + SELECT 9 << 2; + ]], { + 36 + }) + +test:do_catchsql_test( + "gh-5364-2.2", + [[ + SELECT 9 << -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.3", + [[ + SELECT 9 << 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.4", + [[ + SELECT 9 << '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.5", + [[ + SELECT 9 << x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.6", + [[ + SELECT 9 << true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.7", + [[ + SELECT 9 << CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-3.1", + [[ + SELECT 9 & 2; + ]], { + 0 + }) + +test:do_catchsql_test( + "gh-5364-3.2", + [[ + SELECT 9 & -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.3", + [[ + SELECT 9 & 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.4", + [[ + SELECT 9 & '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.5", + [[ + SELECT 9 & x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.6", + [[ + SELECT 9 & true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.7", + [[ + SELECT 9 & CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-4.1", + [[ + SELECT 9 | 2; + ]], { + 11 + }) + +test:do_catchsql_test( + "gh-5364-4.2", + [[ + SELECT 9 | -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.3", + [[ + SELECT 9 | 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.4", + [[ + SELECT 9 | '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.5", + [[ + SELECT 9 | x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.6", + [[ + SELECT 9 | true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.7", + [[ + SELECT 9 | CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:finish_test() diff --git a/test/sql-tap/suite.ini b/test/sql-tap/suite.ini index 615bd07fa..90880b3e6 100644 --- a/test/sql-tap/suite.ini +++ b/test/sql-tap/suite.ini @@ -20,6 +20,7 @@ disabled = selectA.test.lua ; analyzeD.test.lua ; analyzeE.test.lua ; analyzeF.test.lua ; + randexpr1.test.lua ; gh-3350-skip-scan.test.lua ; debug_mode_only.test.lua ; gh-3694 diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua index 70683a4fd..3e0c6eef5 100755 --- a/test/sql-tap/uuid.test.lua +++ b/test/sql-tap/uuid.test.lua @@ -1020,7 +1020,7 @@ test:do_catchsql_test( [[ SELECT ~u FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1028,7 +1028,7 @@ test:do_catchsql_test( [[ SELECT u >> 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1036,7 +1036,7 @@ test:do_catchsql_test( [[ SELECT u << 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1044,7 +1044,7 @@ test:do_catchsql_test( [[ SELECT u | 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1052,7 +1052,7 @@ test:do_catchsql_test( [[ SELECT u & 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) -- Check that logical operations work with UUIDs as intended. diff --git a/test/sql/boolean.result b/test/sql/boolean.result index 5594d92cb..1565e5cda 100644 --- a/test/sql/boolean.result +++ b/test/sql/boolean.result @@ -1366,194 +1366,194 @@ SELECT a, a1, a % a1 FROM t, t6; SELECT ~true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT ~false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true & false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false & true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true | false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false | true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true << false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false << true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a & true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a & false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a | true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a | false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a << true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a << false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a >> true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a >> false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a & a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a | a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a << a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a >> a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... -- Check concatenate. @@ -3047,325 +3047,325 @@ SELECT a2, b, b % a2 FROM t6, t7; SELECT true & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 & a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 | a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 << a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 >> a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, a2 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 & a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 | a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 << a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 >> a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, true & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b & true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b & false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b | true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b | false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b << true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b << false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b >> true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b >> false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b & a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b | a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b << a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b >> a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, b, a2 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b & a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b | a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b << a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b >> a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true > 2; diff --git a/test/sql/types.result b/test/sql/types.result index a0b8668be..98d9c5241 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -1512,7 +1512,7 @@ box.execute('SELECT typeof(a & b) FROM t1;') - name: COLUMN_1 type: string rows: - - ['integer'] + - ['unsigned'] ... box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') --- @@ -1524,7 +1524,7 @@ box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') - name: COLUMN_3 type: string rows: - - ['integer', 'integer', 'integer'] + - ['integer', 'integer', 'unsigned'] ... box.execute("SELECT typeof(CAST(0 AS UNSIGNED));") --- -- 2.25.1
Thanks for the patch! Is it said anywhere publicly that our unsigneds has 64 bits? Does the standard say anything about bit-size?
Thanks for the patch! On the branch I see 2 commits on top of the master. Did you send the first commit anywhere? This one - "sql: clear MEM only if necessary". I am not sure it is needed or even better than it was before, because it adds a branch.
Hi! Thank you fot he review! My answers below. On Mon, Jul 26, 2021 at 11:12:25PM +0200, Vladislav Shpilevoy wrote: > Thanks for the patch! > > Is it said anywhere publicly that our unsigneds has 64 bits? I couldn't find anything about 64-bit. The only description I found was about range: https://www.tarantool.io/en/doc/latest/book/box/data_model/#field-type-details > Does the standard say anything about bit-size? I believe not, at least I wasn't able to find anything.
Thank you for the review! My answer below.
On Mon, Jul 26, 2021 at 11:54:46PM +0200, Vladislav Shpilevoy wrote:
> Thanks for the patch!
>
> On the branch I see 2 commits on top of the master. Did you
> send the first commit anywhere? This one - "sql: clear MEM
> only if necessary". I am not sure it is needed or even better
> than it was before, because it adds a branch.
I rebased this patch to current master and removed "sql: clear MEM ..." commit.
That commit was to make simpler usage of mem_set_*() functions. However, later
I understood that it is completely wrong, and even it was right it is not better
than it is now.
Hi! Thanks for the patch! LGTM.
After this patch, bitwise operations will only accept UNSIGNED and positive INTEGER values as operands. The result of the bitwise operand will be UNSIGNED. Part of #4470 Closes #5364 --- https://github.com/tarantool/tarantool/issues/5364 https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations .../gh-5364-define-bit-wise-operations-rules | 4 + src/box/sql/mem.c | 131 +++++----- src/box/sql/vdbe.c | 8 +- test/sql-tap/cse.test.lua | 9 +- .../gh-5364-define-bit-wise-rules.test.lua | 237 ++++++++++++++++++ test/sql-tap/suite.ini | 1 + test/sql-tap/uuid.test.lua | 10 +- test/sql/boolean.result | 204 +++++++-------- test/sql/types.result | 4 +- 9 files changed, 423 insertions(+), 185 deletions(-) create mode 100644 changelogs/unreleased/gh-5364-define-bit-wise-operations-rules create mode 100755 test/sql-tap/gh-5364-define-bit-wise-rules.test.lua diff --git a/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules new file mode 100644 index 000000000..fe428d395 --- /dev/null +++ b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules @@ -0,0 +1,4 @@ +## feature/sql + +* Bitwise operations can now only accept UNSIGNED and positive INTEGER + values (gh-5364). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index e4ce233e0..1676d3fc4 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -1771,51 +1771,47 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result) return 0; } -static int -bitwise_prepare(const struct Mem *left, const struct Mem *right, - int64_t *a, int64_t *b) +int +mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) { - bool unused; - if (mem_get_int(left, a, &unused) != 0) { - diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), - "integer"); - return -1; + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; + return 0; } - if (mem_get_int(right, b, &unused) != 0) { + if (right->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), - "integer"); + "unsigned"); return -1; } - return 0; -} - -int -mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) -{ - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) - return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); return -1; - result->u.i = a & b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + mem_set_uint(result, left->u.u & right->u.u); return 0; } int mem_bit_or(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - result->u.i = a | b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, left->u.u | right->u.u); return 0; } @@ -1823,22 +1819,22 @@ int mem_shift_left(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = a >= 0 ? 0 : -1; - else if (b < 0) - result->u.i = a >> -b; - else if (b > 64) - result->u.i = 0; - else - result->u.i = a << b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u << right->u.u); return 0; } @@ -1846,42 +1842,39 @@ int mem_shift_right(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = 0; - else if (b < 0) - result->u.i = a << -b; - else if (b > 64) - result->u.i = a >= 0 ? 0 : -1; - else - result->u.i = a >> b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u >> right->u.u); return 0; } int mem_bit_not(const struct Mem *mem, struct Mem *result) { - mem_clear(result); - result->field_type = FIELD_TYPE_INTEGER; - if (mem->type == MEM_TYPE_NULL) + if (mem_is_null(mem)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t i; - bool unused; - if (mem_get_int(mem, &i, &unused) != 0) { + } + if (mem->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(mem), - "integer"); + "unsigned"); return -1; } - result->u.i = ~i; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + mem_set_uint(result, ~mem->u.u); return 0; } diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 9e763ed85..6f6b2aab9 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1354,7 +1354,7 @@ case OP_BitAnd: { /* same as TK_BITAND, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_and(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1371,7 +1371,7 @@ case OP_BitOr: { /* same as TK_BITOR, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_or(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1389,7 +1389,7 @@ case OP_ShiftLeft: { /* same as TK_LSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_left(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1407,7 +1407,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_right(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua index e09f955a0..b0e5ccddf 100755 --- a/test/sql-tap/cse.test.lua +++ b/test/sql-tap/cse.test.lua @@ -35,7 +35,8 @@ test:do_test( ]] end, { -- <cse-1.1> - 11, -11, -12, false, true, 0, 22, 121, 1, 11, 21, -21, -22, false, true, 0, 42, 441, 1, 21 + 11, -11, 18446744073709551604ULL, false, true, 0, 22, 121, 1, 11, + 21, -21, 18446744073709551594ULL, false, true, 0, 42, 441, 1, 21 -- </cse-1.1> }) @@ -135,7 +136,8 @@ test:do_execsql_test( SELECT a, -a, ~a, NOT CAST(a AS BOOLEAN), NOT NOT CAST(a AS BOOLEAN), a-a, a+a, a*a, a/a, a FROM t1 ]], { -- <cse-1.7> - 1, -1 ,-2, false, true, 0, 2, 1, 1, 1, 2, -2, -3, false, true, 0, 4, 4, 1, 2 + 1, -1, 18446744073709551614ULL, false, true, 0, 2, 1, 1, 1, + 2, -2, 18446744073709551613ULL, false, true, 0, 4, 4, 1, 2 -- </cse-1.7> }) @@ -155,7 +157,8 @@ test:do_execsql_test( SELECT NOT CAST(b AS BOOLEAN), ~b, NOT NOT CAST(b AS BOOLEAN), b FROM t1 ]], { -- <cse-1.9> - false, -12, true, 11, false, -22, true, 21 + false, 18446744073709551604ULL, true, 11, + false, 18446744073709551594ULL, true, 21 -- </cse-1.9> }) diff --git a/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua new file mode 100755 index 000000000..37bf62487 --- /dev/null +++ b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua @@ -0,0 +1,237 @@ +#!/usr/bin/env tarantool +local test = require("sqltester") +test:plan(28) + +-- +-- Make sure that bit-wise operations can only accept UNSIGNED and posivite +-- INTEGER values. +-- +test:do_execsql_test( + "gh-5364-1.1", + [[ + SELECT 9 >> 2; + ]], { + 2 + }) + +test:do_catchsql_test( + "gh-5364-1.2", + [[ + SELECT 9 >> -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.3", + [[ + SELECT 9 >> 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.4", + [[ + SELECT 9 >> '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.5", + [[ + SELECT 9 >> x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.6", + [[ + SELECT 9 >> true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.7", + [[ + SELECT 9 >> CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-2.1", + [[ + SELECT 9 << 2; + ]], { + 36 + }) + +test:do_catchsql_test( + "gh-5364-2.2", + [[ + SELECT 9 << -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.3", + [[ + SELECT 9 << 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.4", + [[ + SELECT 9 << '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.5", + [[ + SELECT 9 << x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.6", + [[ + SELECT 9 << true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.7", + [[ + SELECT 9 << CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-3.1", + [[ + SELECT 9 & 2; + ]], { + 0 + }) + +test:do_catchsql_test( + "gh-5364-3.2", + [[ + SELECT 9 & -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.3", + [[ + SELECT 9 & 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.4", + [[ + SELECT 9 & '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.5", + [[ + SELECT 9 & x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.6", + [[ + SELECT 9 & true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.7", + [[ + SELECT 9 & CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-4.1", + [[ + SELECT 9 | 2; + ]], { + 11 + }) + +test:do_catchsql_test( + "gh-5364-4.2", + [[ + SELECT 9 | -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.3", + [[ + SELECT 9 | 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.4", + [[ + SELECT 9 | '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.5", + [[ + SELECT 9 | x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.6", + [[ + SELECT 9 | true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.7", + [[ + SELECT 9 | CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:finish_test() diff --git a/test/sql-tap/suite.ini b/test/sql-tap/suite.ini index 615bd07fa..90880b3e6 100644 --- a/test/sql-tap/suite.ini +++ b/test/sql-tap/suite.ini @@ -20,6 +20,7 @@ disabled = selectA.test.lua ; analyzeD.test.lua ; analyzeE.test.lua ; analyzeF.test.lua ; + randexpr1.test.lua ; gh-3350-skip-scan.test.lua ; debug_mode_only.test.lua ; gh-3694 diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua index 70683a4fd..3e0c6eef5 100755 --- a/test/sql-tap/uuid.test.lua +++ b/test/sql-tap/uuid.test.lua @@ -1020,7 +1020,7 @@ test:do_catchsql_test( [[ SELECT ~u FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1028,7 +1028,7 @@ test:do_catchsql_test( [[ SELECT u >> 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1036,7 +1036,7 @@ test:do_catchsql_test( [[ SELECT u << 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1044,7 +1044,7 @@ test:do_catchsql_test( [[ SELECT u | 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1052,7 +1052,7 @@ test:do_catchsql_test( [[ SELECT u & 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) -- Check that logical operations work with UUIDs as intended. diff --git a/test/sql/boolean.result b/test/sql/boolean.result index 5594d92cb..1565e5cda 100644 --- a/test/sql/boolean.result +++ b/test/sql/boolean.result @@ -1366,194 +1366,194 @@ SELECT a, a1, a % a1 FROM t, t6; SELECT ~true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT ~false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true & false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false & true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true | false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false | true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true << false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false << true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a & true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a & false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a | true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a | false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a << true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a << false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a >> true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a >> false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a & a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a | a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a << a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a >> a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... -- Check concatenate. @@ -3047,325 +3047,325 @@ SELECT a2, b, b % a2 FROM t6, t7; SELECT true & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 & a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 | a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 << a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 >> a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, a2 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 & a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 | a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 << a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 >> a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, true & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b & true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b & false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b | true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b | false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b << true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b << false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b >> true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b >> false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b & a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b | a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b << a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b >> a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, b, a2 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b & a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b | a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b << a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b >> a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true > 2; diff --git a/test/sql/types.result b/test/sql/types.result index c1e1a8ef1..a10d73acd 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -1509,7 +1509,7 @@ box.execute('SELECT typeof(a & b) FROM t1;') - name: COLUMN_1 type: string rows: - - ['integer'] + - ['unsigned'] ... box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') --- @@ -1521,7 +1521,7 @@ box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') - name: COLUMN_3 type: string rows: - - ['integer', 'integer', 'integer'] + - ['integer', 'integer', 'unsigned'] ... box.execute("SELECT typeof(CAST(0 AS UNSIGNED));") --- -- 2.25.1
After this patch, bitwise operations will only accept UNSIGNED and positive INTEGER values as operands. The result of the bitwise operand will be UNSIGNED. Part of #4470 Closes #5364 --- https://github.com/tarantool/tarantool/issues/5364 https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations .../gh-5364-define-bit-wise-operations-rules | 4 + src/box/sql/mem.c | 131 +++++----- src/box/sql/vdbe.c | 8 +- test/sql-tap/cse.test.lua | 9 +- .../gh-5364-define-bit-wise-rules.test.lua | 237 ++++++++++++++++++ test/sql-tap/suite.ini | 1 + test/sql-tap/uuid.test.lua | 10 +- test/sql/boolean.result | 204 +++++++-------- test/sql/types.result | 4 +- 9 files changed, 423 insertions(+), 185 deletions(-) create mode 100644 changelogs/unreleased/gh-5364-define-bit-wise-operations-rules create mode 100755 test/sql-tap/gh-5364-define-bit-wise-rules.test.lua diff --git a/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules new file mode 100644 index 000000000..fe428d395 --- /dev/null +++ b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules @@ -0,0 +1,4 @@ +## feature/sql + +* Bitwise operations can now only accept UNSIGNED and positive INTEGER + values (gh-5364). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index e4ce233e0..1676d3fc4 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -1771,51 +1771,47 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result) return 0; } -static int -bitwise_prepare(const struct Mem *left, const struct Mem *right, - int64_t *a, int64_t *b) +int +mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) { - bool unused; - if (mem_get_int(left, a, &unused) != 0) { - diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), - "integer"); - return -1; + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; + return 0; } - if (mem_get_int(right, b, &unused) != 0) { + if (right->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), - "integer"); + "unsigned"); return -1; } - return 0; -} - -int -mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) -{ - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) - return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); return -1; - result->u.i = a & b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + mem_set_uint(result, left->u.u & right->u.u); return 0; } int mem_bit_or(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - result->u.i = a | b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, left->u.u | right->u.u); return 0; } @@ -1823,22 +1819,22 @@ int mem_shift_left(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = a >= 0 ? 0 : -1; - else if (b < 0) - result->u.i = a >> -b; - else if (b > 64) - result->u.i = 0; - else - result->u.i = a << b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u << right->u.u); return 0; } @@ -1846,42 +1842,39 @@ int mem_shift_right(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = 0; - else if (b < 0) - result->u.i = a << -b; - else if (b > 64) - result->u.i = a >= 0 ? 0 : -1; - else - result->u.i = a >> b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u >> right->u.u); return 0; } int mem_bit_not(const struct Mem *mem, struct Mem *result) { - mem_clear(result); - result->field_type = FIELD_TYPE_INTEGER; - if (mem->type == MEM_TYPE_NULL) + if (mem_is_null(mem)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t i; - bool unused; - if (mem_get_int(mem, &i, &unused) != 0) { + } + if (mem->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(mem), - "integer"); + "unsigned"); return -1; } - result->u.i = ~i; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + mem_set_uint(result, ~mem->u.u); return 0; } diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 9e763ed85..6f6b2aab9 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1354,7 +1354,7 @@ case OP_BitAnd: { /* same as TK_BITAND, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_and(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1371,7 +1371,7 @@ case OP_BitOr: { /* same as TK_BITOR, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_or(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1389,7 +1389,7 @@ case OP_ShiftLeft: { /* same as TK_LSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_left(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1407,7 +1407,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_right(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua index e09f955a0..b0e5ccddf 100755 --- a/test/sql-tap/cse.test.lua +++ b/test/sql-tap/cse.test.lua @@ -35,7 +35,8 @@ test:do_test( ]] end, { -- <cse-1.1> - 11, -11, -12, false, true, 0, 22, 121, 1, 11, 21, -21, -22, false, true, 0, 42, 441, 1, 21 + 11, -11, 18446744073709551604ULL, false, true, 0, 22, 121, 1, 11, + 21, -21, 18446744073709551594ULL, false, true, 0, 42, 441, 1, 21 -- </cse-1.1> }) @@ -135,7 +136,8 @@ test:do_execsql_test( SELECT a, -a, ~a, NOT CAST(a AS BOOLEAN), NOT NOT CAST(a AS BOOLEAN), a-a, a+a, a*a, a/a, a FROM t1 ]], { -- <cse-1.7> - 1, -1 ,-2, false, true, 0, 2, 1, 1, 1, 2, -2, -3, false, true, 0, 4, 4, 1, 2 + 1, -1, 18446744073709551614ULL, false, true, 0, 2, 1, 1, 1, + 2, -2, 18446744073709551613ULL, false, true, 0, 4, 4, 1, 2 -- </cse-1.7> }) @@ -155,7 +157,8 @@ test:do_execsql_test( SELECT NOT CAST(b AS BOOLEAN), ~b, NOT NOT CAST(b AS BOOLEAN), b FROM t1 ]], { -- <cse-1.9> - false, -12, true, 11, false, -22, true, 21 + false, 18446744073709551604ULL, true, 11, + false, 18446744073709551594ULL, true, 21 -- </cse-1.9> }) diff --git a/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua new file mode 100755 index 000000000..37bf62487 --- /dev/null +++ b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua @@ -0,0 +1,237 @@ +#!/usr/bin/env tarantool +local test = require("sqltester") +test:plan(28) + +-- +-- Make sure that bit-wise operations can only accept UNSIGNED and posivite +-- INTEGER values. +-- +test:do_execsql_test( + "gh-5364-1.1", + [[ + SELECT 9 >> 2; + ]], { + 2 + }) + +test:do_catchsql_test( + "gh-5364-1.2", + [[ + SELECT 9 >> -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.3", + [[ + SELECT 9 >> 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.4", + [[ + SELECT 9 >> '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.5", + [[ + SELECT 9 >> x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.6", + [[ + SELECT 9 >> true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.7", + [[ + SELECT 9 >> CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-2.1", + [[ + SELECT 9 << 2; + ]], { + 36 + }) + +test:do_catchsql_test( + "gh-5364-2.2", + [[ + SELECT 9 << -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.3", + [[ + SELECT 9 << 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.4", + [[ + SELECT 9 << '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.5", + [[ + SELECT 9 << x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.6", + [[ + SELECT 9 << true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.7", + [[ + SELECT 9 << CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-3.1", + [[ + SELECT 9 & 2; + ]], { + 0 + }) + +test:do_catchsql_test( + "gh-5364-3.2", + [[ + SELECT 9 & -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.3", + [[ + SELECT 9 & 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.4", + [[ + SELECT 9 & '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.5", + [[ + SELECT 9 & x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.6", + [[ + SELECT 9 & true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.7", + [[ + SELECT 9 & CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-4.1", + [[ + SELECT 9 | 2; + ]], { + 11 + }) + +test:do_catchsql_test( + "gh-5364-4.2", + [[ + SELECT 9 | -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.3", + [[ + SELECT 9 | 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.4", + [[ + SELECT 9 | '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.5", + [[ + SELECT 9 | x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.6", + [[ + SELECT 9 | true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.7", + [[ + SELECT 9 | CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:finish_test() diff --git a/test/sql-tap/suite.ini b/test/sql-tap/suite.ini index 615bd07fa..90880b3e6 100644 --- a/test/sql-tap/suite.ini +++ b/test/sql-tap/suite.ini @@ -20,6 +20,7 @@ disabled = selectA.test.lua ; analyzeD.test.lua ; analyzeE.test.lua ; analyzeF.test.lua ; + randexpr1.test.lua ; gh-3350-skip-scan.test.lua ; debug_mode_only.test.lua ; gh-3694 diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua index 70683a4fd..3e0c6eef5 100755 --- a/test/sql-tap/uuid.test.lua +++ b/test/sql-tap/uuid.test.lua @@ -1020,7 +1020,7 @@ test:do_catchsql_test( [[ SELECT ~u FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1028,7 +1028,7 @@ test:do_catchsql_test( [[ SELECT u >> 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1036,7 +1036,7 @@ test:do_catchsql_test( [[ SELECT u << 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1044,7 +1044,7 @@ test:do_catchsql_test( [[ SELECT u | 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1052,7 +1052,7 @@ test:do_catchsql_test( [[ SELECT u & 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) -- Check that logical operations work with UUIDs as intended. diff --git a/test/sql/boolean.result b/test/sql/boolean.result index 5594d92cb..1565e5cda 100644 --- a/test/sql/boolean.result +++ b/test/sql/boolean.result @@ -1366,194 +1366,194 @@ SELECT a, a1, a % a1 FROM t, t6; SELECT ~true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT ~false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true & false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false & true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true | false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false | true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true << false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false << true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a & true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a & false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a | true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a | false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a << true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a << false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a >> true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a >> false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a & a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a | a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a << a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a >> a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... -- Check concatenate. @@ -3047,325 +3047,325 @@ SELECT a2, b, b % a2 FROM t6, t7; SELECT true & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 & a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 | a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 << a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 >> a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, a2 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 & a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 | a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 << a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 >> a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, true & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b & true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b & false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b | true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b | false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b << true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b << false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b >> true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b >> false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b & a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b | a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b << a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b >> a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, b, a2 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b & a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b | a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b << a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b >> a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true > 2; diff --git a/test/sql/types.result b/test/sql/types.result index c1e1a8ef1..a10d73acd 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -1509,7 +1509,7 @@ box.execute('SELECT typeof(a & b) FROM t1;') - name: COLUMN_1 type: string rows: - - ['integer'] + - ['unsigned'] ... box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') --- @@ -1521,7 +1521,7 @@ box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') - name: COLUMN_3 type: string rows: - - ['integer', 'integer', 'integer'] + - ['integer', 'integer', 'unsigned'] ... box.execute("SELECT typeof(CAST(0 AS UNSIGNED));") --- -- 2.25.1
After this patch, bitwise operations will only accept UNSIGNED and positive INTEGER values as operands. The result of the bitwise operand will be UNSIGNED. Part of #4470 Closes #5364 --- https://github.com/tarantool/tarantool/issues/5364 https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations .../gh-5364-define-bit-wise-operations-rules | 4 + src/box/sql/mem.c | 131 +++++----- src/box/sql/vdbe.c | 8 +- test/sql-tap/cse.test.lua | 9 +- .../gh-5364-define-bit-wise-rules.test.lua | 237 ++++++++++++++++++ test/sql-tap/suite.ini | 1 + test/sql-tap/uuid.test.lua | 10 +- test/sql/boolean.result | 204 +++++++-------- test/sql/types.result | 4 +- 9 files changed, 423 insertions(+), 185 deletions(-) create mode 100644 changelogs/unreleased/gh-5364-define-bit-wise-operations-rules create mode 100755 test/sql-tap/gh-5364-define-bit-wise-rules.test.lua diff --git a/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules new file mode 100644 index 000000000..fe428d395 --- /dev/null +++ b/changelogs/unreleased/gh-5364-define-bit-wise-operations-rules @@ -0,0 +1,4 @@ +## feature/sql + +* Bitwise operations can now only accept UNSIGNED and positive INTEGER + values (gh-5364). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index e4ce233e0..1676d3fc4 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -1771,51 +1771,47 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result) return 0; } -static int -bitwise_prepare(const struct Mem *left, const struct Mem *right, - int64_t *a, int64_t *b) +int +mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) { - bool unused; - if (mem_get_int(left, a, &unused) != 0) { - diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), - "integer"); - return -1; + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; + return 0; } - if (mem_get_int(right, b, &unused) != 0) { + if (right->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), - "integer"); + "unsigned"); return -1; } - return 0; -} - -int -mem_bit_and(const struct Mem *left, const struct Mem *right, struct Mem *result) -{ - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) - return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); return -1; - result->u.i = a & b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + mem_set_uint(result, left->u.u & right->u.u); return 0; } int mem_bit_or(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - result->u.i = a | b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, left->u.u | right->u.u); return 0; } @@ -1823,22 +1819,22 @@ int mem_shift_left(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = a >= 0 ? 0 : -1; - else if (b < 0) - result->u.i = a >> -b; - else if (b > 64) - result->u.i = 0; - else - result->u.i = a << b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u << right->u.u); return 0; } @@ -1846,42 +1842,39 @@ int mem_shift_right(const struct Mem *left, const struct Mem *right, struct Mem *result) { - if (try_return_null(left, right, result, FIELD_TYPE_INTEGER)) + if (mem_is_any_null(left, right)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t a; - int64_t b; - if (bitwise_prepare(left, right, &a, &b) != 0) + } + if (right->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right), + "unsigned"); return -1; - if (b <= -64) - result->u.i = 0; - else if (b < 0) - result->u.i = a << -b; - else if (b > 64) - result->u.i = a >= 0 ? 0 : -1; - else - result->u.i = a >> b; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + } + if (left->type != MEM_TYPE_UINT) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left), + "unsigned"); + return -1; + } + mem_set_uint(result, right->u.u >= 64 ? 0 : left->u.u >> right->u.u); return 0; } int mem_bit_not(const struct Mem *mem, struct Mem *result) { - mem_clear(result); - result->field_type = FIELD_TYPE_INTEGER; - if (mem->type == MEM_TYPE_NULL) + if (mem_is_null(mem)) { + mem_set_null(result); + result->field_type = FIELD_TYPE_UNSIGNED; return 0; - int64_t i; - bool unused; - if (mem_get_int(mem, &i, &unused) != 0) { + } + if (mem->type != MEM_TYPE_UINT) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(mem), - "integer"); + "unsigned"); return -1; } - result->u.i = ~i; - result->type = result->u.i < 0 ? MEM_TYPE_INT : MEM_TYPE_UINT; - assert(result->flags == 0); + mem_set_uint(result, ~mem->u.u); return 0; } diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 9e763ed85..6f6b2aab9 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1354,7 +1354,7 @@ case OP_BitAnd: { /* same as TK_BITAND, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_and(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1371,7 +1371,7 @@ case OP_BitOr: { /* same as TK_BITOR, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_bit_or(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1389,7 +1389,7 @@ case OP_ShiftLeft: { /* same as TK_LSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_left(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } @@ -1407,7 +1407,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ pOut = &aMem[pOp->p3]; if (mem_shift_right(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - assert(pOut->field_type == FIELD_TYPE_INTEGER); + assert(pOut->field_type == FIELD_TYPE_UNSIGNED); break; } diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua index e09f955a0..b0e5ccddf 100755 --- a/test/sql-tap/cse.test.lua +++ b/test/sql-tap/cse.test.lua @@ -35,7 +35,8 @@ test:do_test( ]] end, { -- <cse-1.1> - 11, -11, -12, false, true, 0, 22, 121, 1, 11, 21, -21, -22, false, true, 0, 42, 441, 1, 21 + 11, -11, 18446744073709551604ULL, false, true, 0, 22, 121, 1, 11, + 21, -21, 18446744073709551594ULL, false, true, 0, 42, 441, 1, 21 -- </cse-1.1> }) @@ -135,7 +136,8 @@ test:do_execsql_test( SELECT a, -a, ~a, NOT CAST(a AS BOOLEAN), NOT NOT CAST(a AS BOOLEAN), a-a, a+a, a*a, a/a, a FROM t1 ]], { -- <cse-1.7> - 1, -1 ,-2, false, true, 0, 2, 1, 1, 1, 2, -2, -3, false, true, 0, 4, 4, 1, 2 + 1, -1, 18446744073709551614ULL, false, true, 0, 2, 1, 1, 1, + 2, -2, 18446744073709551613ULL, false, true, 0, 4, 4, 1, 2 -- </cse-1.7> }) @@ -155,7 +157,8 @@ test:do_execsql_test( SELECT NOT CAST(b AS BOOLEAN), ~b, NOT NOT CAST(b AS BOOLEAN), b FROM t1 ]], { -- <cse-1.9> - false, -12, true, 11, false, -22, true, 21 + false, 18446744073709551604ULL, true, 11, + false, 18446744073709551594ULL, true, 21 -- </cse-1.9> }) diff --git a/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua new file mode 100755 index 000000000..37bf62487 --- /dev/null +++ b/test/sql-tap/gh-5364-define-bit-wise-rules.test.lua @@ -0,0 +1,237 @@ +#!/usr/bin/env tarantool +local test = require("sqltester") +test:plan(28) + +-- +-- Make sure that bit-wise operations can only accept UNSIGNED and posivite +-- INTEGER values. +-- +test:do_execsql_test( + "gh-5364-1.1", + [[ + SELECT 9 >> 2; + ]], { + 2 + }) + +test:do_catchsql_test( + "gh-5364-1.2", + [[ + SELECT 9 >> -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.3", + [[ + SELECT 9 >> 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.4", + [[ + SELECT 9 >> '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.5", + [[ + SELECT 9 >> x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.6", + [[ + SELECT 9 >> true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-1.7", + [[ + SELECT 9 >> CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-2.1", + [[ + SELECT 9 << 2; + ]], { + 36 + }) + +test:do_catchsql_test( + "gh-5364-2.2", + [[ + SELECT 9 << -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.3", + [[ + SELECT 9 << 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.4", + [[ + SELECT 9 << '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.5", + [[ + SELECT 9 << x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.6", + [[ + SELECT 9 << true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-2.7", + [[ + SELECT 9 << CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-3.1", + [[ + SELECT 9 & 2; + ]], { + 0 + }) + +test:do_catchsql_test( + "gh-5364-3.2", + [[ + SELECT 9 & -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.3", + [[ + SELECT 9 & 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.4", + [[ + SELECT 9 & '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.5", + [[ + SELECT 9 & x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.6", + [[ + SELECT 9 & true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-3.7", + [[ + SELECT 9 & CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:do_execsql_test( + "gh-5364-4.1", + [[ + SELECT 9 | 2; + ]], { + 11 + }) + +test:do_catchsql_test( + "gh-5364-4.2", + [[ + SELECT 9 | -2; + ]], { + 1, "Type mismatch: can not convert integer(-2) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.3", + [[ + SELECT 9 | 2.0; + ]], { + 1, "Type mismatch: can not convert double(2.0) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.4", + [[ + SELECT 9 | '2'; + ]], { + 1, "Type mismatch: can not convert string('2') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.5", + [[ + SELECT 9 | x'32'; + ]], { + 1, "Type mismatch: can not convert varbinary(x'32') to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.6", + [[ + SELECT 9 | true; + ]], { + 1, "Type mismatch: can not convert boolean(TRUE) to unsigned" + }) + +test:do_catchsql_test( + "gh-5364-4.7", + [[ + SELECT 9 | CAST('11111111-1111-1111-1111-111111111111' AS UUID); + ]], { + 1, "Type mismatch: can not convert ".. + "uuid('11111111-1111-1111-1111-111111111111') to unsigned" + }) + +test:finish_test() diff --git a/test/sql-tap/suite.ini b/test/sql-tap/suite.ini index 615bd07fa..90880b3e6 100644 --- a/test/sql-tap/suite.ini +++ b/test/sql-tap/suite.ini @@ -20,6 +20,7 @@ disabled = selectA.test.lua ; analyzeD.test.lua ; analyzeE.test.lua ; analyzeF.test.lua ; + randexpr1.test.lua ; gh-3350-skip-scan.test.lua ; debug_mode_only.test.lua ; gh-3694 diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua index 70683a4fd..3e0c6eef5 100755 --- a/test/sql-tap/uuid.test.lua +++ b/test/sql-tap/uuid.test.lua @@ -1020,7 +1020,7 @@ test:do_catchsql_test( [[ SELECT ~u FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1028,7 +1028,7 @@ test:do_catchsql_test( [[ SELECT u >> 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1036,7 +1036,7 @@ test:do_catchsql_test( [[ SELECT u << 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1044,7 +1044,7 @@ test:do_catchsql_test( [[ SELECT u | 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) test:do_catchsql_test( @@ -1052,7 +1052,7 @@ test:do_catchsql_test( [[ SELECT u & 1 FROM t2; ]], { - 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to integer" + 1, "Type mismatch: can not convert uuid('11111111-1111-1111-1111-111111111111') to unsigned" }) -- Check that logical operations work with UUIDs as intended. diff --git a/test/sql/boolean.result b/test/sql/boolean.result index 5594d92cb..1565e5cda 100644 --- a/test/sql/boolean.result +++ b/test/sql/boolean.result @@ -1366,194 +1366,194 @@ SELECT a, a1, a % a1 FROM t, t6; SELECT ~true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT ~false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true & false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false & true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true | false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false | true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true << false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false << true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT false >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false & a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false | a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false << a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, true >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, false >> a FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a & true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a & false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a | true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a | false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a << true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a << false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a >> true FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a, a >> false FROM t; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a & a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a | a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a << a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a, a1, a >> a1 FROM t, t6; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... -- Check concatenate. @@ -3047,325 +3047,325 @@ SELECT a2, b, b % a2 FROM t6, t7; SELECT true & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false & 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false | 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false << 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT true >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT false >> 2; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 & true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 & false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 | true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 | false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 << true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 << false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT 2 >> true; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT 2 >> false; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, a1 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 & a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 | a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 << a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, 2 >> a1 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, a2 & 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 | 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 << 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, a2 >> 2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 & a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 | a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 << a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, 2 >> a2 FROM t6 | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, true & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false & b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false | b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false << b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, true >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, false >> b FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b & true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b & false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b | true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b | false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b << true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b << false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT b, b >> true FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT b, b >> false FROM t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, a1 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b & a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b | a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b << a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a1, b, b >> a1 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(FALSE) to integer' + | - 'Type mismatch: can not convert boolean(FALSE) to unsigned' | ... SELECT a2, b, a2 & b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 | b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 << b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, a2 >> b FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b & a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b | a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b << a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT a2, b, b >> a2 FROM t6, t7; | --- | - null - | - 'Type mismatch: can not convert boolean(TRUE) to integer' + | - 'Type mismatch: can not convert boolean(TRUE) to unsigned' | ... SELECT true > 2; diff --git a/test/sql/types.result b/test/sql/types.result index c1e1a8ef1..a10d73acd 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -1509,7 +1509,7 @@ box.execute('SELECT typeof(a & b) FROM t1;') - name: COLUMN_1 type: string rows: - - ['integer'] + - ['unsigned'] ... box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') --- @@ -1521,7 +1521,7 @@ box.execute('SELECT typeof(a), typeof(b), typeof(a & b) FROM t1') - name: COLUMN_3 type: string rows: - - ['integer', 'integer', 'integer'] + - ['integer', 'integer', 'unsigned'] ... box.execute("SELECT typeof(CAST(0 AS UNSIGNED));") --- -- 2.25.1
Hello,
On 04 авг 11:26, imeevma@tarantool.org wrote:
> After this patch, bitwise operations will only accept UNSIGNED and
> positive INTEGER values as operands. The result of the bitwise operand
> will be UNSIGNED.
>
> Part of #4470
> Closes #5364
The patch LGTM.
--
Regards, Kirill Yukhin
[-- Attachment #1: Type: text/plain, Size: 497 bytes --] Hi all, QA LGTM -- Vitaliia Ioffe >Среда, 4 августа 2021, 17:05 +03:00 от Kirill Yukhin via Tarantool-patches <tarantool-patches@dev.tarantool.org>: > >Hello, > >On 04 авг 11:26, imeevma@tarantool.org wrote: >> After this patch, bitwise operations will only accept UNSIGNED and >> positive INTEGER values as operands. The result of the bitwise operand >> will be UNSIGNED. >> >> Part of #4470 >> Closes #5364 >The patch LGTM. > >-- >Regards, Kirill Yukhin [-- Attachment #2: Type: text/html, Size: 1082 bytes --]
Hello,
On 04 авг 11:26, imeevma@tarantool.org wrote:
> After this patch, bitwise operations will only accept UNSIGNED and
> positive INTEGER values as operands. The result of the bitwise operand
> will be UNSIGNED.
>
> Part of #4470
> Closes #5364
> ---
> https://github.com/tarantool/tarantool/issues/5364
> https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations
I've checked your patch into 2.7, 2.8 and master.
--
Regards, Kirill Yukhin
This patch, if unmodified, breaks 2.7, and 2.8 due to failing test
test/sql-tap/gh-5364-define-bit-wise-rules.test.lua
Could you or Mergen please remome UUID subtests (2.7, 3.7, 4.7) which
are incompatible (due to missing UUID) with 2.7 and 2.8 code base?
Thanks,
Timur
On 05.08.2021 12:57, Kirill Yukhin via Tarantool-patches wrote:
> Hello,
>
> On 04 авг 11:26, imeevma@tarantool.org wrote:
>> After this patch, bitwise operations will only accept UNSIGNED and
>> positive INTEGER values as operands. The result of the bitwise operand
>> will be UNSIGNED.
>>
>> Part of #4470
>> Closes #5364
>> ---
>> https://github.com/tarantool/tarantool/issues/5364
>> https://github.com/tarantool/tarantool/tree/imeevma/gh-5364-fix-bitwise-operations
>
> I've checked your patch into 2.7, 2.8 and master.
>
> --
> Regards, Kirill Yukhin
>