[tarantool-patches] [PATCH 5/6] sql: introduce extended range for INTEGER type

Nikita Pettik korablev at tarantool.org
Fri Jun 7 18:37:45 MSK 2019


This patch allows to operate on integer values in range [2^63, 2^64 - 1]
It means that:
 - One can use literals from 9223372036854775808 to 18446744073709551615
 - One can pass values from mentioned range to bindings
 - One can insert and select values from mentioned range

Support of built-in functions and operators has been introduced in
previous patches.

Closes #3810
Part of #4015
---
 src/box/bind.c                             |  13 +-
 src/box/bind.h                             |   1 +
 src/box/errcode.h                          |   2 +-
 src/box/execute.c                          |   2 +-
 src/box/lua/execute.c                      |   9 +-
 src/box/lua/lua_sql.c                      |   2 +-
 src/box/sql/build.c                        |   4 +-
 src/box/sql/expr.c                         |   7 +-
 src/box/sql/pragma.c                       |   2 +-
 src/box/sql/sqlInt.h                       |   6 +
 src/box/sql/util.c                         |   2 -
 src/box/sql/vdbe.c                         |   2 +-
 src/box/sql/vdbe.h                         |   3 +-
 src/box/sql/vdbeapi.c                      |  23 +-
 src/box/sql/vdbeaux.c                      |  14 +-
 test/sql-tap/func.test.lua                 |   2 +-
 test/sql-tap/hexlit.test.lua               |   2 +-
 test/sql-tap/sql-errors.test.lua           |   4 +-
 test/sql/bind.result                       |  46 ++-
 test/sql/bind.test.lua                     |   4 +
 test/sql/gh-2347-max-int-literals.result   |  39 ---
 test/sql/gh-2347-max-int-literals.test.lua |  11 -
 test/sql/integer-overflow.result           |  62 +++-
 test/sql/integer-overflow.test.lua         |   7 +
 test/sql/iproto.result                     |   6 +-
 test/sql/types.result                      | 503 +++++++++++++++++++++++++++++
 test/sql/types.test.lua                    |  98 ++++++
 27 files changed, 761 insertions(+), 115 deletions(-)
 delete mode 100644 test/sql/gh-2347-max-int-literals.result
 delete mode 100644 test/sql/gh-2347-max-int-literals.test.lua

diff --git a/src/box/bind.c b/src/box/bind.c
index f15915377..9e952857f 100644
--- a/src/box/bind.c
+++ b/src/box/bind.c
@@ -69,13 +69,8 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet)
 	switch (type) {
 	case MP_UINT: {
 		uint64_t n = mp_decode_uint(packet);
-		if (n > INT64_MAX) {
-			diag_set(ClientError, ER_SQL_BIND_VALUE,
-				 sql_bind_name(bind), "INTEGER");
-			return -1;
-		}
-		bind->i64 = (int64_t) n;
-		bind->bytes = sizeof(bind->i64);
+		bind->u64 = n;
+		bind->bytes = sizeof(bind->u64);
 		break;
 	}
 	case MP_INT:
@@ -173,9 +168,11 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p,
 	}
 	switch (p->type) {
 	case MP_INT:
-	case MP_UINT:
 		rc = sql_bind_int64(stmt, pos, p->i64);
 		break;
+	case MP_UINT:
+		rc = sql_bind_uint64(stmt, pos, p->u64);
+		break;
 	case MP_BOOL:
 		rc = sql_bind_boolean(stmt, pos, p->b);
 		break;
diff --git a/src/box/bind.h b/src/box/bind.h
index d9823431e..568c558f3 100644
--- a/src/box/bind.h
+++ b/src/box/bind.h
@@ -64,6 +64,7 @@ struct sql_bind {
 		bool b;
 		double d;
 		int64_t i64;
+		uint64_t u64;
 		/** For string or blob. */
 		const char *s;
 	};
diff --git a/src/box/errcode.h b/src/box/errcode.h
index f4aba2f54..417029adb 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -242,7 +242,7 @@ struct errcode_record {
 	/*187 */_(ER_SQL_ANALYZE_ARGUMENT,	"ANALYZE statement argument %s is not a base table") \
 	/*188 */_(ER_SQL_COLUMN_COUNT_MAX,	"Failed to create space '%s': space column count %d exceeds the limit (%d)") \
 	/*189 */_(ER_HEX_LITERAL_MAX,		"Hex literal %s%s length %d exceeds the supported limit (%d)") \
-	/*190 */_(ER_INT_LITERAL_MAX,		"Integer literal %s exceeds the supported range %lld - %lld") \
+	/*190 */_(ER_INT_LITERAL_MAX,		"Integer literal %s exceeds the supported range %lld - %llu") \
 	/*191 */_(ER_SQL_PARSER_LIMIT,		"%s %d exceeds the limit (%d)") \
 	/*192 */_(ER_INDEX_DEF_UNSUPPORTED,	"%s are prohibited in an index definition") \
 	/*193 */_(ER_CK_DEF_UNSUPPORTED,	"%s are prohibited in a CHECK constraint definition") \
diff --git a/src/box/execute.c b/src/box/execute.c
index f5aead391..2e76724a6 100644
--- a/src/box/execute.c
+++ b/src/box/execute.c
@@ -146,7 +146,7 @@ sql_column_to_messagepack(struct sql_stmt *stmt, int i,
 		break;
 	}
 	case MP_UINT: {
-		uint64_t n = sql_column_int64(stmt, i);
+		uint64_t n = sql_column_uint64(stmt, i);
 		size = mp_sizeof_uint(n);
 		char *pos = (char *) region_alloc(region, size);
 		if (pos == NULL)
diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
index 239aba47b..eb6516096 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -140,12 +140,9 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i)
 		return -1;
 	switch (field.type) {
 	case MP_UINT:
-		if ((uint64_t) field.ival > INT64_MAX) {
-			diag_set(ClientError, ER_SQL_BIND_VALUE,
-				 sql_bind_name(bind), "INTEGER");
-			return -1;
-		}
-		FALLTHROUGH;
+		bind->u64 = field.ival;
+		bind->bytes = sizeof(bind->u64);
+		break;
 	case MP_INT:
 		bind->i64 = field.ival;
 		bind->bytes = sizeof(bind->i64);
diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
index 59ea260bf..89e72e6d2 100644
--- a/src/box/lua/lua_sql.c
+++ b/src/box/lua/lua_sql.c
@@ -61,7 +61,7 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
 			luaL_pushint64(L, sql_value_int64(param));
 			break;
 		case MP_UINT:
-			luaL_pushuint64(L, sql_value_int64(param));
+			luaL_pushuint64(L, sql_value_uint64(param));
 			break;
 		case MP_DOUBLE:
 			lua_pushnumber(L, sql_value_double(param));
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index e2353d8cc..75d6579ca 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -918,10 +918,10 @@ emitNewSysSequenceRecord(Parse *pParse, int reg_seq_id, const char *seq_name)
 
 	/* 5. Minimum  */
 	sqlVdbeAddOp4Dup8(v, OP_Int64, 0, first_col + 5, 0,
-			      (unsigned char*)&min_usigned_long_long, P4_INT64);
+			      (unsigned char*)&min_usigned_long_long, P4_UINT64);
 	/* 6. Maximum  */
 	sqlVdbeAddOp4Dup8(v, OP_Int64, 0, first_col + 6, 0,
-			      (unsigned char*)&max_usigned_long_long, P4_INT64);
+			      (unsigned char*)&max_usigned_long_long, P4_UINT64);
 	/* 7. Start  */
 	sqlVdbeAddOp2(v, OP_Integer, 1, first_col + 7);
 
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 158631416..4da297a5f 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -1203,7 +1203,7 @@ sqlExprAssignVarNumber(Parse * pParse, Expr * pExpr, u32 n)
 			testcase(i == 1);
 			testcase(i == SQL_BIND_PARAMETER_MAX - 1);
 			testcase(i == SQL_BIND_PARAMETER_MAX);
-			if (i < 1) {
+			if (is_neg || i < 1) {
 				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
 					 "Index of binding slots must start "\
 					 "from 1");
@@ -3367,12 +3367,13 @@ expr_code_int(struct Parse *parse, struct Expr *expr, bool is_neg,
 		if (rc != 0) {
 int_overflow:
 			diag_set(ClientError, ER_INT_LITERAL_MAX, z, INT64_MIN,
-				 INT64_MAX);
+				 UINT64_MAX);
 			parse->is_aborted = true;
 			return;
 		}
 	}
-	sqlVdbeAddOp4Dup8(v, OP_Int64, 0, mem, 0, (u8 *)&value, P4_INT64);
+	sqlVdbeAddOp4Dup8(v, OP_Int64, 0, mem, 0, (u8 *) &value,
+			  is_neg ? P4_INT64 : P4_UINT64);
 }
 
 /*
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 53524b617..18b8f351b 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -134,7 +134,7 @@ static void
 returnSingleInt(Vdbe * v, i64 value)
 {
 	sqlVdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8 *)&value,
-			      P4_INT64);
+			  value < 0 ? P4_INT64 : P4_UINT64);
 	sqlVdbeAddOp2(v, OP_ResultRow, 1, 1);
 }
 
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 4697e3003..89b7356d8 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -594,6 +594,9 @@ sql_column_boolean(struct sql_stmt *stmt, int column);
 sql_int64
 sql_column_int64(sql_stmt *, int iCol);
 
+uint64_t
+sql_column_uint64(struct sql_stmt *stmt, int column);
+
 const unsigned char *
 sql_column_text(sql_stmt *,
 		    int iCol);
@@ -908,6 +911,9 @@ sql_bind_int(sql_stmt *, int, int);
 int
 sql_bind_int64(sql_stmt *, int, sql_int64);
 
+int
+sql_bind_uint64(struct sql_stmt *stmt, int i, uint64_t value);
+
 int
 sql_bind_null(sql_stmt *, int);
 
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index ee6a83ad5..3af2d6d1f 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -611,8 +611,6 @@ sql_atoi64(const char *z, int64_t *val, bool *is_neg, int length)
 		*val = strtoll(z, &end, 10);
 	} else {
 		uint64_t u_val = strtoull(z, &end, 10);
-		if (u_val > INT64_MAX)
-			return -1;
 		*val = u_val;
 	}
 	/* No digits were found, e.g. an empty string. */
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 9c28b9131..dae9f903d 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1108,7 +1108,7 @@ case OP_Bool: {         /* out2 */
 case OP_Int64: {           /* out2 */
 	pOut = out2Prerelease(p, pOp);
 	assert(pOp->p4.pI64!=0);
-	mem_set_int(pOut, *pOp->p4.pI64, *pOp->p4.pI64 < 0);
+	mem_set_int(pOut, *pOp->p4.pI64, pOp->p4type == P4_INT64);
 	break;
 }
 
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index f9bb96f09..b37daa897 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -70,7 +70,7 @@ struct VdbeOp {
 		int i;		/* Integer value if p4type==P4_INT32 */
 		void *p;	/* Generic pointer */
 		char *z;	/* Pointer to data for string (char array) types */
-		i64 *pI64;	/* Used when p4type is P4_INT64 */
+		i64 *pI64;	/* Used when p4type is P4_INT64/UINT64 */
 		double *pReal;	/* Used when p4type is P4_REAL */
 		FuncDef *pFunc;	/* Used when p4type is P4_FUNCDEF */
 		sql_context *pCtx;	/* Used when p4type is P4_FUNCCTX */
@@ -127,6 +127,7 @@ struct SubProgram {
 #define P4_TRANSIENT  0		/* P4 is a pointer to a transient string */
 #define P4_REAL     (-9)	/* P4 is a 64-bit floating point value */
 #define P4_INT64    (-10)	/* P4 is a 64-bit signed integer */
+#define P4_UINT64   (-8)	/* P4 is a 64-bit signed integer */
 #define P4_INT32    (-11)	/* P4 is a 32-bit signed integer */
 #define P4_INTARRAY (-12)	/* P4 is a vector of 32-bit integers */
 #define P4_SUBPROGRAM  (-13)	/* P4 is a pointer to a SubProgram structure */
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 752efeecb..751aead70 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -1027,6 +1027,14 @@ sql_column_int64(sql_stmt * pStmt, int i)
 	return val;
 }
 
+uint64_t
+sql_column_uint64(sql_stmt * pStmt, int i)
+{
+	sql_int64 val = sql_value_uint64(columnMem(pStmt, i));
+	columnMallocFailure(pStmt);
+	return val;
+}
+
 const unsigned char *
 sql_column_text(sql_stmt * pStmt, int i)
 {
@@ -1387,9 +1395,22 @@ sql_bind_int64(sql_stmt * pStmt, int i, sql_int64 iValue)
 	int rc;
 	Vdbe *p = (Vdbe *) pStmt;
 	rc = vdbeUnbind(p, i);
+	assert(iValue < 0);
 	if (rc == SQL_OK) {
 		rc = sql_bind_type(p, i, "INTEGER");
-		mem_set_int(&p->aVar[i - 1], iValue, iValue < 0);
+		mem_set_int(&p->aVar[i - 1], iValue, true);
+	}
+	return rc;
+}
+
+int
+sql_bind_uint64(struct sql_stmt *stmt, int i, uint64_t value)
+{
+	struct Vdbe *p = (struct Vdbe *) stmt;
+	int rc = vdbeUnbind(p, i);
+	if (rc == SQL_OK) {
+		rc = sql_bind_type(p, i, "UNSIGNED");
+		mem_set_int(&p->aVar[i - 1], value, false);
 	}
 	return rc;
 }
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 5a71e1801..7ca2d89d8 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -386,8 +386,8 @@ sqlVdbeAddOp4(Vdbe * p,	/* Add the opcode to this VM */
 }
 
 /*
- * Add an opcode that includes the p4 value with a P4_INT64 or
- * P4_REAL type.
+ * Add an opcode that includes the p4 value with a P4_INT64/UINT64
+ * or P4_REAL type.
  */
 int
 sqlVdbeAddOp4Dup8(Vdbe * p,	/* Add the opcode to this VM */
@@ -863,6 +863,7 @@ freeP4(sql * db, int p4type, void *p4)
 		}
 	case P4_REAL:
 	case P4_INT64:
+	case P4_UINT64:
 	case P4_DYNAMIC:
 	case P4_INTARRAY:{
 			sqlDbFree(db, p4);
@@ -1355,6 +1356,10 @@ displayP4(Op * pOp, char *zTemp, int nTemp)
 			sqlXPrintf(&x, "%lld", *pOp->p4.pI64);
 			break;
 		}
+	case P4_UINT64: {
+		sqlXPrintf(&x, "%llu", (uint64_t)*pOp->p4.pI64);
+			break;
+	}
 	case P4_INT32:{
 			sqlXPrintf(&x, "%d", pOp->p4.i);
 			break;
@@ -3735,11 +3740,6 @@ vdbe_decode_msgpack_into_mem(const char *buf, struct Mem *mem, uint32_t *len)
 	}
 	case MP_UINT: {
 		uint64_t v = mp_decode_uint(&buf);
-		if (v > INT64_MAX) {
-			diag_set(ClientError, ER_SQL_EXECUTE,
-				 "integer is overflowed");
-			return -1;
-		}
 		mem->u.u = v;
 		mem->flags = MEM_UInt;
 		break;
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 9cf9c2f67..217b137a4 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -919,7 +919,7 @@ test:do_execsql_test(
                             UNION ALL SELECT -9223372036854775807)
     ]], {
         -- <func-8.7>
-        "number"
+        "unsigned"
         -- </func-8.7>
     })
 
diff --git a/test/sql-tap/hexlit.test.lua b/test/sql-tap/hexlit.test.lua
index 288d823d9..220aa9117 100755
--- a/test/sql-tap/hexlit.test.lua
+++ b/test/sql-tap/hexlit.test.lua
@@ -91,7 +91,7 @@ hexlit1(160, "0X1000000000000000", 1152921504606846976LL)
 hexlit1(161, "0x2000000000000000", 2305843009213693952LL)
 hexlit1(162, "0X4000000000000000", 4611686018427387904LL)
 hexlit1(163, "0x8000000000000000", -9223372036854775808LL)
-hexlit1(164, "0XFFFFFFFFFFFFFFFF", -1)
+hexlit1(164, "0XFFFFFFFFFFFFFFFF", 18446744073709551615LL)
 for n = 1, 0x10 -1, 1 do
     hexlit1("200."..n..".1", "0X"..string.format("%03X",n), n)
     hexlit1("200."..n..".2", "0x"..string.format("%03X",n), n)
diff --git a/test/sql-tap/sql-errors.test.lua b/test/sql-tap/sql-errors.test.lua
index 9357c406b..4201899fd 100755
--- a/test/sql-tap/sql-errors.test.lua
+++ b/test/sql-tap/sql-errors.test.lua
@@ -139,10 +139,10 @@ test:do_catchsql_test(
 test:do_catchsql_test(
 	"sql-errors-1.13",
 	[[
-		SELECT 9223372036854775808;
+		SELECT 18446744073709551616;
 	]], {
 		-- <sql-errors-1.13>
-		1,"Integer literal 9223372036854775808 exceeds the supported range -9223372036854775808 - 9223372036854775807"
+		1,"Integer literal 18446744073709551616 exceeds the supported range -9223372036854775808 - 18446744073709551615"
 		-- </sql-errors-1.13>
 	})
 
diff --git a/test/sql/bind.result b/test/sql/bind.result
index 076bf8319..209daff85 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -72,11 +72,11 @@ execute('SELECT ?, ?, ?', {1, 2, 3})
 ---
 - metadata:
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   rows:
   - [1, 2, 3]
 ...
@@ -102,11 +102,11 @@ execute('SELECT ?, :value1, @value2', parameters)
 ---
 - metadata:
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: :value1
-    type: INTEGER
+    type: UNSIGNED
   - name: '@value2'
-    type: INTEGER
+    type: UNSIGNED
   rows:
   - [10, 11, 12]
 ...
@@ -144,21 +144,21 @@ execute('SELECT :value3, ?, :value1, ?, ?, @value2, ?, :value3', parameters)
 ---
 - metadata:
   - name: :value3
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: :value1
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
-    type: INTEGER
+    type: UNSIGNED
   - name: '@value2'
-    type: INTEGER
+    type: UNSIGNED
   - name: '?'
     type: boolean
   - name: :value3
-    type: INTEGER
+    type: UNSIGNED
   rows:
   - [1, 2, 3, 4, 5, 6, null, 1]
 ...
@@ -187,9 +187,9 @@ execute('SELECT ? AS kek, ? AS kek2', {1, 2})
 ---
 - metadata:
   - name: KEK
-    type: INTEGER
+    type: UNSIGNED
   - name: KEK2
-    type: INTEGER
+    type: UNSIGNED
   rows:
   - [1, 2]
 ...
@@ -236,7 +236,11 @@ execute(sql, parameters)
 -- suitable method in its bind API.
 execute('SELECT ? AS big_uint', {0xefffffffffffffff})
 ---
-- error: Bind value for parameter 1 is out of range for type INTEGER
+- metadata:
+  - name: BIG_UINT
+    type: UNSIGNED
+  rows:
+  - [17293822569102704640]
 ...
 -- Bind incorrect parameters.
 ok, err = pcall(execute, 'SELECT ?', { {1, 2, 3} })
@@ -275,6 +279,16 @@ execute('SELECT :value', parameters)
 ---
 - error: Bind value type MAP for parameter ':value' is not supported
 ...
+-- gh-3810: bind values of integer in range up to 2^64 - 1.
+--
+execute('SELECT ? ', {18446744073709551615ULL})
+---
+- metadata:
+  - name: '?'
+    type: UNSIGNED
+  rows:
+  - [18446744073709551615]
+...
 test_run:cmd("setopt delimiter ';'")
 ---
 - true
diff --git a/test/sql/bind.test.lua b/test/sql/bind.test.lua
index 229207d3a..ea71e7fe7 100644
--- a/test/sql/bind.test.lua
+++ b/test/sql/bind.test.lua
@@ -89,6 +89,10 @@ parameters[1] = {}
 parameters[1][':value'] = {kek = 300}
 execute('SELECT :value', parameters)
 
+-- gh-3810: bind values of integer in range up to 2^64 - 1.
+--
+execute('SELECT ? ', {18446744073709551615ULL})
+
 test_run:cmd("setopt delimiter ';'")
 if remote then
 	cn:close()
diff --git a/test/sql/gh-2347-max-int-literals.result b/test/sql/gh-2347-max-int-literals.result
deleted file mode 100644
index e6c4d9992..000000000
--- a/test/sql/gh-2347-max-int-literals.result
+++ /dev/null
@@ -1,39 +0,0 @@
-test_run = require('test_run').new()
----
-...
-engine = test_run:get_cfg('engine')
----
-...
-box.execute('pragma sql_default_engine=\''..engine..'\'')
----
-- row_count: 0
-...
-box.cfg{}
----
-...
-box.execute("select (9223372036854775807)")
----
-- metadata:
-  - name: (9223372036854775807)
-    type: integer
-  rows:
-  - [9223372036854775807]
-...
-box.execute("select (-9223372036854775808)")
----
-- metadata:
-  - name: (-9223372036854775808)
-    type: integer
-  rows:
-  - [-9223372036854775808]
-...
-box.execute("select (9223372036854775808)")
----
-- error: Integer literal 9223372036854775808 exceeds the supported range -9223372036854775808
-    - 9223372036854775807
-...
-box.execute("select (-9223372036854775809)")
----
-- error: Integer literal -9223372036854775809 exceeds the supported range -9223372036854775808
-    - 9223372036854775807
-...
diff --git a/test/sql/gh-2347-max-int-literals.test.lua b/test/sql/gh-2347-max-int-literals.test.lua
deleted file mode 100644
index 8331f0333..000000000
--- a/test/sql/gh-2347-max-int-literals.test.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-test_run = require('test_run').new()
-engine = test_run:get_cfg('engine')
-box.execute('pragma sql_default_engine=\''..engine..'\'')
-
-box.cfg{}
-
-box.execute("select (9223372036854775807)")
-box.execute("select (-9223372036854775808)")
-
-box.execute("select (9223372036854775808)")
-box.execute("select (-9223372036854775809)")
diff --git a/test/sql/integer-overflow.result b/test/sql/integer-overflow.result
index 40962ac5c..915914eac 100644
--- a/test/sql/integer-overflow.result
+++ b/test/sql/integer-overflow.result
@@ -40,28 +40,67 @@ box.execute('SELECT (9223372036854775807 + 9223372036854775807 + 2);')
 ---
 - error: 'Failed to execute SQL statement: integer is overflowed'
 ...
+box.execute('SELECT 18446744073709551615 * 2;')
+---
+- error: 'Failed to execute SQL statement: integer is overflowed'
+...
+box.execute('SELECT (-9223372036854775807 * (-2));')
+---
+- metadata:
+  - name: (-9223372036854775807 * (-2))
+    type: integer
+  rows:
+  - [18446744073709551614]
+...
 -- Literals are checked right after parsing.
 --
 box.execute('SELECT 9223372036854775808;')
 ---
-- error: Integer literal 9223372036854775808 exceeds the supported range -9223372036854775808
-    - 9223372036854775807
+- metadata:
+  - name: '9223372036854775808'
+    type: integer
+  rows:
+  - [9223372036854775808]
 ...
 box.execute('SELECT -9223372036854775809;')
 ---
 - error: Integer literal -9223372036854775809 exceeds the supported range -9223372036854775808
-    - 9223372036854775807
+    - 18446744073709551615
 ...
 box.execute('SELECT 9223372036854775808 - 1;')
 ---
-- error: Integer literal 9223372036854775808 exceeds the supported range -9223372036854775808
-    - 9223372036854775807
+- metadata:
+  - name: 9223372036854775808 - 1
+    type: integer
+  rows:
+  - [9223372036854775807]
+...
+box.execute('SELECT 18446744073709551615;')
+---
+- metadata:
+  - name: '18446744073709551615'
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+box.execute('SELECT 18446744073709551616;')
+---
+- error: Integer literal 18446744073709551616 exceeds the supported range -9223372036854775808
+    - 18446744073709551615
 ...
 -- Test that CAST may also leads to overflow.
 --
 box.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);')
 ---
-- error: 'Type mismatch: can not convert 9223372036854775808 to integer'
+- metadata:
+  - name: CAST('9223372036854775808' AS INTEGER)
+    type: integer
+  rows:
+  - [9223372036854775808]
+...
+box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
+---
+- error: 'Type mismatch: can not convert 18446744073709551616 to integer'
 ...
 -- Due to inexact represantation of large integers in terms of
 -- floating point numbers, numerics with value < INT64_MAX
@@ -85,9 +124,18 @@ box.space.T:insert({9223372036854775809})
 ---
 - [9223372036854775808]
 ...
+box.space.T:insert({18446744073709551615ULL})
+---
+- [18446744073709551615]
+...
 box.execute('SELECT * FROM t;')
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- metadata:
+  - name: ID
+    type: integer
+  rows:
+  - [9223372036854775808]
+  - [18446744073709551615]
 ...
 box.space.T:drop()
 ---
diff --git a/test/sql/integer-overflow.test.lua b/test/sql/integer-overflow.test.lua
index 7727f368c..246465da0 100644
--- a/test/sql/integer-overflow.test.lua
+++ b/test/sql/integer-overflow.test.lua
@@ -11,15 +11,21 @@ box.execute('SELECT (-9223372036854775808 / -1);')
 box.execute('SELECT (-9223372036854775808 - 1);')
 box.execute('SELECT (9223372036854775807 + 1);')
 box.execute('SELECT (9223372036854775807 + 9223372036854775807 + 2);')
+box.execute('SELECT 18446744073709551615 * 2;')
+box.execute('SELECT (-9223372036854775807 * (-2));')
 
 -- Literals are checked right after parsing.
 --
 box.execute('SELECT 9223372036854775808;')
 box.execute('SELECT -9223372036854775809;')
 box.execute('SELECT 9223372036854775808 - 1;')
+box.execute('SELECT 18446744073709551615;')
+box.execute('SELECT 18446744073709551616;')
+
 -- Test that CAST may also leads to overflow.
 --
 box.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);')
+box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
 -- Due to inexact represantation of large integers in terms of
 -- floating point numbers, numerics with value < INT64_MAX
 -- have INT64_MAX + 1 value in integer representation:
@@ -33,5 +39,6 @@ box.execute('SELECT CAST(9223372036854775807.0 AS INTEGER);')
 --
 box.execute('CREATE TABLE t (id INT PRIMARY KEY);')
 box.space.T:insert({9223372036854775809})
+box.space.T:insert({18446744073709551615ULL})
 box.execute('SELECT * FROM t;')
 box.space.T:drop()
diff --git a/test/sql/iproto.result b/test/sql/iproto.result
index e734872b2..10f42d936 100644
--- a/test/sql/iproto.result
+++ b/test/sql/iproto.result
@@ -368,11 +368,11 @@ cn:execute('select $2, $1, $3', parameters)
 ---
 - metadata:
   - name: $2
-    type: INTEGER
+    type: UNSIGNED
   - name: $1
-    type: INTEGER
+    type: UNSIGNED
   - name: $3
-    type: INTEGER
+    type: UNSIGNED
   rows:
   - [22, 11, 33]
 ...
diff --git a/test/sql/types.result b/test/sql/types.result
index 4670fd38a..e12515345 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -963,3 +963,506 @@ box.execute('SELECT ?', {true})
   rows:
   - [true]
 ...
+-- gh-3810: range of integer is extended up to 2^64 - 1.
+--
+box.execute("SELECT 18446744073709551615 > 18446744073709551614;")
+---
+- metadata:
+  - name: 18446744073709551615 > 18446744073709551614
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT 18446744073709551615 = 18446744073709551615;")
+---
+- metadata:
+  - name: 18446744073709551615 = 18446744073709551615
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT 18446744073709551615 > -9223372036854775808;")
+---
+- metadata:
+  - name: 18446744073709551615 > -9223372036854775808
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT -1 < 18446744073709551615;")
+---
+- metadata:
+  - name: -1 < 18446744073709551615
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT 18446744073709551610 - 18446744073709551615;")
+---
+- metadata:
+  - name: 18446744073709551610 - 18446744073709551615
+    type: integer
+  rows:
+  - [-5]
+...
+box.execute("SELECT 18446744073709551615 = null;")
+---
+- metadata:
+  - name: 18446744073709551615 = null
+    type: boolean
+  rows:
+  - [null]
+...
+box.execute("SELECT 18446744073709551615 = 18446744073709551615.0;")
+---
+- metadata:
+  - name: 18446744073709551615 = 18446744073709551615.0
+    type: boolean
+  rows:
+  - [false]
+...
+box.execute("SELECT 18446744073709551615.0 > 18446744073709551615")
+---
+- metadata:
+  - name: 18446744073709551615.0 > 18446744073709551615
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT 18446744073709551615 IN ('18446744073709551615', 18446744073709551615.0)")
+---
+- metadata:
+  - name: 18446744073709551615 IN ('18446744073709551615', 18446744073709551615.0)
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT 1 LIMIT 18446744073709551615;")
+---
+- metadata:
+  - name: '1'
+    type: integer
+  rows:
+  - [1]
+...
+box.execute("SELECT 1 LIMIT 1 OFFSET 18446744073709551615;")
+---
+- metadata:
+  - name: '1'
+    type: integer
+  rows: []
+...
+box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
+---
+- error: 'Type mismatch: can not convert 18446744073709551616 to integer'
+...
+box.execute("SELECT CAST('18446744073' || '709551615' AS INTEGER);")
+---
+- metadata:
+  - name: CAST('18446744073' || '709551615' AS INTEGER)
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+box.execute("SELECT 18446744073709551610 + 5;")
+---
+- metadata:
+  - name: 18446744073709551610 + 5
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+box.execute("SELECT 18446744073709551615 * 1;")
+---
+- metadata:
+  - name: 18446744073709551615 * 1
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+box.execute("SELECT 1 / 18446744073709551615;")
+---
+- metadata:
+  - name: 1 / 18446744073709551615
+    type: integer
+  rows:
+  - [0]
+...
+box.execute("SELECT 18446744073709551615 / 18446744073709551615;")
+---
+- metadata:
+  - name: 18446744073709551615 / 18446744073709551615
+    type: integer
+  rows:
+  - [1]
+...
+box.execute("SELECT 18446744073709551615 / -9223372036854775808;")
+---
+- metadata:
+  - name: 18446744073709551615 / -9223372036854775808
+    type: integer
+  rows:
+  - [-1]
+...
+box.execute("SELECT 0 - 18446744073709551610;")
+---
+- error: 'Failed to execute SQL statement: integer is overflowed'
+...
+box.execute("CREATE TABLE t (id INT PRIMARY KEY, i INT);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (2, 18446744073709551614);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (3, 18446744073709551613)")
+---
+- row_count: 1
+...
+box.execute("SELECT i FROM t;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551615]
+  - [18446744073709551614]
+  - [18446744073709551613]
+...
+box.execute("SELECT i FROM t WHERE i = 18446744073709551615;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+box.execute("SELECT i FROM t WHERE i BETWEEN 18446744073709551613 AND 18446744073709551615;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551615]
+  - [18446744073709551614]
+  - [18446744073709551613]
+...
+box.execute("SELECT i FROM t ORDER BY i;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551613]
+  - [18446744073709551614]
+  - [18446744073709551615]
+...
+box.execute("SELECT i FROM t ORDER BY -i;")
+---
+- error: 'Failed to execute SQL statement: integer is overflowed'
+...
+box.execute("SELECT i FROM t ORDER BY i LIMIT 1;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551613]
+...
+-- Test that built-in functions are capable of handling unsigneds.
+--
+box.execute("DELETE FROM t WHERE i > 18446744073709551613;")
+---
+- row_count: 2
+...
+box.execute("INSERT INTO t VALUES (1, 1);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (2, -1);")
+---
+- row_count: 1
+...
+box.execute("SELECT sum(i) FROM t;")
+---
+- metadata:
+  - name: sum(i)
+    type: number
+  rows:
+  - [18446744073709551613]
+...
+box.execute("SELECT avg(i) FROM t;")
+---
+- metadata:
+  - name: avg(i)
+    type: number
+  rows:
+  - [6148914691236516864]
+...
+box.execute("SELECT total(i) FROM t;")
+---
+- metadata:
+  - name: total(i)
+    type: number
+  rows:
+  - [1.844674407371e+19]
+...
+box.execute("SELECT min(i) FROM t;")
+---
+- metadata:
+  - name: min(i)
+    type: scalar
+  rows:
+  - [-1]
+...
+box.execute("SELECT max(i) FROM t;")
+---
+- metadata:
+  - name: max(i)
+    type: scalar
+  rows:
+  - [18446744073709551613]
+...
+box.execute("SELECT count(i) FROM t;")
+---
+- metadata:
+  - name: count(i)
+    type: integer
+  rows:
+  - [3]
+...
+box.execute("SELECT group_concat(i) FROM t;")
+---
+- metadata:
+  - name: group_concat(i)
+    type: string
+  rows:
+  - ['1,-1,18446744073709551613']
+...
+box.execute("DELETE FROM t WHERE i < 18446744073709551613;")
+---
+- row_count: 2
+...
+box.execute("SELECT lower(i) FROM t;")
+---
+- metadata:
+  - name: lower(i)
+    type: string
+  rows:
+  - ['18446744073709551613']
+...
+box.execute("SELECT upper(i) FROM t;")
+---
+- metadata:
+  - name: upper(i)
+    type: string
+  rows:
+  - ['18446744073709551613']
+...
+box.execute("SELECT abs(i) FROM t;")
+---
+- metadata:
+  - name: abs(i)
+    type: number
+  rows:
+  - [18446744073709551613]
+...
+box.execute("SELECT typeof(i) FROM t;")
+---
+- metadata:
+  - name: typeof(i)
+    type: string
+  rows:
+  - ['unsigned']
+...
+box.execute("SELECT quote(i) FROM t;")
+---
+- metadata:
+  - name: quote(i)
+    type: string
+  rows:
+  - [18446744073709551613]
+...
+box.execute("SELECT min(-1, i) FROM t;")
+---
+- metadata:
+  - name: min(-1, i)
+    type: scalar
+  rows:
+  - [-1]
+...
+box.execute("SELECT quote(i) FROM t;")
+---
+- metadata:
+  - name: quote(i)
+    type: string
+  rows:
+  - [18446744073709551613]
+...
+box.execute("CREATE INDEX i ON t(i);")
+---
+- row_count: 1
+...
+box.execute("SELECT i FROM t WHERE i = 18446744073709551613;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551613]
+...
+box.execute("SELECT i FROM t WHERE i >= 18446744073709551613 ORDER BY i;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551613]
+...
+box.execute("UPDATE t SET i = 18446744073709551615 WHERE i = 18446744073709551613;")
+---
+- row_count: 1
+...
+box.execute("SELECT i FROM t;")
+---
+- metadata:
+  - name: I
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
+-- Test constraints functionality.
+--
+box.execute("CREATE TABLE parent (id INT PRIMARY KEY, a INT UNIQUE);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO parent VALUES (1, 18446744073709551613);")
+---
+- row_count: 1
+...
+box.space.T:truncate()
+---
+...
+box.execute("ALTER TABLE t ADD CONSTRAINT fk1 FOREIGN KEY (i) REFERENCES parent (a);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+---
+- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+...
+box.execute("INSERT INTO parent VALUES (2, 18446744073709551615);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+---
+- row_count: 1
+...
+box.execute("ALTER TABLE t DROP CONSTRAINT fk1;")
+---
+- row_count: 1
+...
+box.space.PARENT:drop()
+---
+...
+box.space.T:drop()
+---
+...
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT CHECK (a > 18446744073709551612));")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t1 VALUES (1, 18446744073709551611);")
+---
+- error: 'Failed to execute SQL statement: CHECK constraint failed: T1'
+...
+box.execute("INSERT INTO t1 VALUES (1, -1);")
+---
+- error: 'Failed to execute SQL statement: CHECK constraint failed: T1'
+...
+box.space.T1:drop()
+---
+...
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT DEFAULT 18446744073709551615);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t1 (id) VALUES (1);")
+---
+- row_count: 1
+...
+box.space.T1:select()
+---
+- - [1, 18446744073709551615]
+...
+box.space.T1:drop()
+---
+...
+-- Test that autoincrement accepts only max 2^63 - 1 .
+--
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY AUTOINCREMENT);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t1 VALUES (18446744073709551615);")
+---
+- row_count: 1
+...
+box.execute("INSERT INTO t1 VALUES (NULL);")
+---
+- autoincrement_ids:
+  - 1
+  row_count: 1
+...
+box.space.T1:drop()
+---
+...
+-- Test CAST facilities.
+--
+box.execute("SELECT CAST(18446744073709551615 AS FLOAT);")
+---
+- metadata:
+  - name: CAST(18446744073709551615 AS FLOAT)
+    type: number
+  rows:
+  - [1.844674407371e+19]
+...
+box.execute("SELECT CAST(18446744073709551615 AS TEXT);")
+---
+- metadata:
+  - name: CAST(18446744073709551615 AS TEXT)
+    type: string
+  rows:
+  - ['18446744073709551615']
+...
+box.execute("SELECT CAST(18446744073709551615 AS SCALAR);")
+---
+- metadata:
+  - name: CAST(18446744073709551615 AS SCALAR)
+    type: scalar
+  rows:
+  - [18446744073709551615]
+...
+box.execute("SELECT CAST(18446744073709551615 AS BOOLEAN);")
+---
+- metadata:
+  - name: CAST(18446744073709551615 AS BOOLEAN)
+    type: boolean
+  rows:
+  - [true]
+...
+box.execute("SELECT CAST('18446744073709551615' AS INTEGER);")
+---
+- metadata:
+  - name: CAST('18446744073709551615' AS INTEGER)
+    type: integer
+  rows:
+  - [18446744073709551615]
+...
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index ae1a0ab72..ccdd1f3d4 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -234,3 +234,101 @@ box.execute('SELECT \'9223372036854\' + 1;')
 
 -- Fix BOOLEAN bindings.
 box.execute('SELECT ?', {true})
+
+-- gh-3810: range of integer is extended up to 2^64 - 1.
+--
+box.execute("SELECT 18446744073709551615 > 18446744073709551614;")
+box.execute("SELECT 18446744073709551615 = 18446744073709551615;")
+box.execute("SELECT 18446744073709551615 > -9223372036854775808;")
+box.execute("SELECT -1 < 18446744073709551615;")
+box.execute("SELECT 18446744073709551610 - 18446744073709551615;")
+box.execute("SELECT 18446744073709551615 = null;")
+box.execute("SELECT 18446744073709551615 = 18446744073709551615.0;")
+box.execute("SELECT 18446744073709551615.0 > 18446744073709551615")
+box.execute("SELECT 18446744073709551615 IN ('18446744073709551615', 18446744073709551615.0)")
+box.execute("SELECT 1 LIMIT 18446744073709551615;")
+box.execute("SELECT 1 LIMIT 1 OFFSET 18446744073709551615;")
+box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
+box.execute("SELECT CAST('18446744073' || '709551615' AS INTEGER);")
+box.execute("SELECT 18446744073709551610 + 5;")
+box.execute("SELECT 18446744073709551615 * 1;")
+box.execute("SELECT 1 / 18446744073709551615;")
+box.execute("SELECT 18446744073709551615 / 18446744073709551615;")
+box.execute("SELECT 18446744073709551615 / -9223372036854775808;")
+box.execute("SELECT 0 - 18446744073709551610;")
+box.execute("CREATE TABLE t (id INT PRIMARY KEY, i INT);")
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+box.execute("INSERT INTO t VALUES (2, 18446744073709551614);")
+box.execute("INSERT INTO t VALUES (3, 18446744073709551613)")
+box.execute("SELECT i FROM t;")
+box.execute("SELECT i FROM t WHERE i = 18446744073709551615;")
+box.execute("SELECT i FROM t WHERE i BETWEEN 18446744073709551613 AND 18446744073709551615;")
+box.execute("SELECT i FROM t ORDER BY i;")
+box.execute("SELECT i FROM t ORDER BY -i;")
+box.execute("SELECT i FROM t ORDER BY i LIMIT 1;")
+-- Test that built-in functions are capable of handling unsigneds.
+--
+box.execute("DELETE FROM t WHERE i > 18446744073709551613;")
+box.execute("INSERT INTO t VALUES (1, 1);")
+box.execute("INSERT INTO t VALUES (2, -1);")
+box.execute("SELECT sum(i) FROM t;")
+box.execute("SELECT avg(i) FROM t;")
+box.execute("SELECT total(i) FROM t;")
+box.execute("SELECT min(i) FROM t;")
+box.execute("SELECT max(i) FROM t;")
+box.execute("SELECT count(i) FROM t;")
+box.execute("SELECT group_concat(i) FROM t;")
+
+box.execute("DELETE FROM t WHERE i < 18446744073709551613;")
+box.execute("SELECT lower(i) FROM t;")
+box.execute("SELECT upper(i) FROM t;")
+box.execute("SELECT abs(i) FROM t;")
+box.execute("SELECT typeof(i) FROM t;")
+box.execute("SELECT quote(i) FROM t;")
+box.execute("SELECT min(-1, i) FROM t;")
+box.execute("SELECT quote(i) FROM t;")
+
+box.execute("CREATE INDEX i ON t(i);")
+box.execute("SELECT i FROM t WHERE i = 18446744073709551613;")
+box.execute("SELECT i FROM t WHERE i >= 18446744073709551613 ORDER BY i;")
+
+box.execute("UPDATE t SET i = 18446744073709551615 WHERE i = 18446744073709551613;")
+box.execute("SELECT i FROM t;")
+
+-- Test constraints functionality.
+--
+box.execute("CREATE TABLE parent (id INT PRIMARY KEY, a INT UNIQUE);")
+box.execute("INSERT INTO parent VALUES (1, 18446744073709551613);")
+box.space.T:truncate()
+box.execute("ALTER TABLE t ADD CONSTRAINT fk1 FOREIGN KEY (i) REFERENCES parent (a);")
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+box.execute("INSERT INTO parent VALUES (2, 18446744073709551615);")
+box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
+box.execute("ALTER TABLE t DROP CONSTRAINT fk1;")
+box.space.PARENT:drop()
+box.space.T:drop()
+
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT CHECK (a > 18446744073709551612));")
+box.execute("INSERT INTO t1 VALUES (1, 18446744073709551611);")
+box.execute("INSERT INTO t1 VALUES (1, -1);")
+box.space.T1:drop()
+
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT DEFAULT 18446744073709551615);")
+box.execute("INSERT INTO t1 (id) VALUES (1);")
+box.space.T1:select()
+box.space.T1:drop()
+
+-- Test that autoincrement accepts only max 2^63 - 1 .
+--
+box.execute("CREATE TABLE t1 (id INT PRIMARY KEY AUTOINCREMENT);")
+box.execute("INSERT INTO t1 VALUES (18446744073709551615);")
+box.execute("INSERT INTO t1 VALUES (NULL);")
+box.space.T1:drop()
+
+-- Test CAST facilities.
+--
+box.execute("SELECT CAST(18446744073709551615 AS FLOAT);")
+box.execute("SELECT CAST(18446744073709551615 AS TEXT);")
+box.execute("SELECT CAST(18446744073709551615 AS SCALAR);")
+box.execute("SELECT CAST(18446744073709551615 AS BOOLEAN);")
+box.execute("SELECT CAST('18446744073709551615' AS INTEGER);")
-- 
2.15.1







More information about the Tarantool-patches mailing list