Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v1 1/1] sql: bit-wise operations now accepts only UNSIGNED
@ 2021-07-29 23:05 Mergen Imeev via Tarantool-patches
  0 siblings, 0 replies; 13+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-07-29 23:05 UTC (permalink / raw)
  To: tsafin; +Cc: tarantool-patches

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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* [Tarantool-patches] [PATCH v1 1/1] sql: bit-wise operations now accepts only UNSIGNED
@ 2021-08-04  8:26 Mergen Imeev via Tarantool-patches
  2021-08-04 14:05 ` Kirill Yukhin via Tarantool-patches
  2021-08-05  9:57 ` Kirill Yukhin via Tarantool-patches
  0 siblings, 2 replies; 13+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-04  8:26 UTC (permalink / raw)
  To: kyukhin; +Cc: tarantool-patches

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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* [Tarantool-patches] [PATCH v1 1/1] sql: bit-wise operations now accepts only UNSIGNED
@ 2021-08-02 17:09 Mergen Imeev via Tarantool-patches
  0 siblings, 0 replies; 13+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-02 17:09 UTC (permalink / raw)
  To: imun; +Cc: tarantool-patches

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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* [Tarantool-patches] [PATCH v1 1/1] sql: bit-wise operations now accepts only UNSIGNED
@ 2021-07-23  9:55 Mergen Imeev via Tarantool-patches
  2021-07-26 21:12 ` Vladislav Shpilevoy via Tarantool-patches
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-07-23  9:55 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

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


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-08-05 13:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-29 23:05 [Tarantool-patches] [PATCH v1 1/1] sql: bit-wise operations now accepts only UNSIGNED Mergen Imeev via Tarantool-patches
  -- strict thread matches above, loose matches on Subject: below --
2021-08-04  8:26 Mergen Imeev via Tarantool-patches
2021-08-04 14:05 ` Kirill Yukhin via Tarantool-patches
2021-08-04 15:15   ` Vitaliia Ioffe via Tarantool-patches
2021-08-05  9:57 ` Kirill Yukhin via Tarantool-patches
2021-08-05 13:28   ` Safin Timur via Tarantool-patches
2021-08-02 17:09 Mergen Imeev via Tarantool-patches
2021-07-23  9:55 Mergen Imeev via Tarantool-patches
2021-07-26 21:12 ` Vladislav Shpilevoy via Tarantool-patches
2021-07-27  9:02   ` Mergen Imeev via Tarantool-patches
2021-07-26 21:54 ` Vladislav Shpilevoy via Tarantool-patches
2021-07-27  9:10   ` Mergen Imeev via Tarantool-patches
2021-07-29 20:49 ` Vladislav Shpilevoy via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox