Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v2 0/3] sql: fix NUMBER type
@ 2019-12-30 13:01 imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE imeevma
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: imeevma @ 2019-12-30 13:01 UTC (permalink / raw)
  To: korablev; +Cc: tarantool-patches

This patch-set makes number to be union of UNSIGNED, INTEGER and
DOUBLE numeric types. Also it fixes couple of small bugs of DOUBLE
type.

https://github.com/tarantool/tarantool/issues/4233
https://github.com/tarantool/tarantool/tree/imeevma/gh-4233-fix-number-field-type-in-sql

Mergen Imeev (3):
  sql: allow conversion of numeric binary values to DOUBLE
  sql: fix typeof() for double values
  sql: make NUMBER to be union of SQL numeric types

 src/box/sql/func.c                   |   2 +-
 src/box/sql/vdbe.c                   |  15 +---
 src/box/sql/vdbeInt.h                |   1 -
 src/box/sql/vdbemem.c                |  46 ++-----------
 test/sql-tap/cast.test.lua           |  44 ++++++------
 test/sql-tap/check.test.lua          |   4 +-
 test/sql-tap/e_select1.test.lua      |   2 +-
 test/sql-tap/func.test.lua           |   4 +-
 test/sql-tap/numcast.test.lua        | 128 ++++++++++++++++++++++++++++++++++-
 test/sql-tap/select3.test.lua        |   8 +--
 test/sql-tap/sort.test.lua           |  12 ++--
 test/sql-tap/tkt-80e031a00f.test.lua |   8 +--
 test/sql-tap/tkt-91e2e8ba6f.test.lua |  12 ++--
 test/sql/integer-overflow.result     |   2 +-
 test/sql/types.result                |   9 ++-
 test/sql/types.test.lua              |   9 +++
 16 files changed, 198 insertions(+), 108 deletions(-)

-- 
2.7.4

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

* [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE
  2019-12-30 13:01 [Tarantool-patches] [PATCH v2 0/3] sql: fix NUMBER type imeevma
@ 2019-12-30 13:01 ` imeevma
  2019-12-30 13:17   ` Nikita Pettik
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 2/3] sql: fix typeof() for double values imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 3/3] sql: make NUMBER to be union of SQL numeric types imeevma
  2 siblings, 1 reply; 6+ messages in thread
From: imeevma @ 2019-12-30 13:01 UTC (permalink / raw)
  To: korablev; +Cc: tarantool-patches

This patch allows to convert binary values consisting of numeric
literals to numbers.

Follow-uo #3812
---
 src/box/sql/vdbemem.c                |  2 +-
 test/sql-tap/numcast.test.lua        | 25 ++++++++++++++++++++++++-
 test/sql-tap/tkt-80e031a00f.test.lua |  8 ++++----
 test/sql/types.result                |  7 +++++--
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index df3f0d8..3c5e5fc 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -516,7 +516,7 @@ sqlVdbeRealValue(Mem * pMem, double *v)
 	} else if ((pMem->flags & MEM_UInt) != 0) {
 		*v = (double)pMem->u.u;
 		return 0;
-	} else if (pMem->flags & MEM_Str) {
+	} else if ((pMem->flags & (MEM_Blob | MEM_Str)) != 0) {
 		if (sqlAtoF(pMem->z, v, pMem->n))
 			return 0;
 	}
diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
index 07117d0..a45daef 100755
--- a/test/sql-tap/numcast.test.lua
+++ b/test/sql-tap/numcast.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(20)
+test:plan(22)
 
 --!./tcltestrunner.lua
 -- 2013 March 20
@@ -147,4 +147,27 @@ test:do_catchsql_test(
         1,"Tuple field 1 type does not match one required by operation: expected integer"
     })
 
+--
+-- Allow to convert binary values consisting of numeric literals
+-- to numbers.
+--
+test:do_execsql_test(
+    "cast-3.1",
+    [[
+        CREATE TABLE td (i DOUBLE PRIMARY KEY);
+        INSERT INTO td VALUES(X'3132332E35');
+        INSERT INTO td VALUES(X'31323334');
+        SELECT * FROM td;
+    ]], {
+        123.5, 1234
+    })
+
+test:do_execsql_test(
+    "cast-3.2",
+    [[
+        SELECT CAST(X'39' AS DOUBLE), CAST(X'39' AS DOUBLE) / 10;
+    ]], {
+        9, 0.9
+    })
+
 test:finish_test()
diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
index a0e6539..01f4265 100755
--- a/test/sql-tap/tkt-80e031a00f.test.lua
+++ b/test/sql-tap/tkt-80e031a00f.test.lua
@@ -380,23 +380,23 @@ test:do_execsql_test(
         -- </tkt-80e031a00f.30>
     })
 
-test:do_catchsql_test(
+test:do_execsql_test(
     "tkt-80e031a00f.31",
     [[
         SELECT x'303132' IN t1
     ]], {
         -- <tkt-80e031a00f.31>
-        1, 'Type mismatch: can not convert varbinary to integer'
+        false
         -- </tkt-80e031a00f.31>
     })
 
-test:do_catchsql_test(
+test:do_execsql_test(
     "tkt-80e031a00f.32",
     [[
         SELECT x'303132' NOT IN t1
     ]], {
         -- <tkt-80e031a00f.32>
-        1, 'Type mismatch: can not convert varbinary to integer'
+        true
         -- </tkt-80e031a00f.32>
     })
 
diff --git a/test/sql/types.result b/test/sql/types.result
index 6d0aefd..8c0186d 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -1760,8 +1760,11 @@ box.execute("SELECT CAST(x'' AS DOUBLE);")
 ...
 box.execute("SELECT CAST(x'35' AS DOUBLE);")
 ---
-- null
-- 'Type mismatch: can not convert varbinary to double'
+- metadata:
+  - name: CAST(x'35' AS DOUBLE)
+    type: double
+  rows:
+  - [5]
 ...
 box.execute("SELECT CAST(CAST(x'35' AS STRING) AS DOUBLE);")
 ---
-- 
2.7.4

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

* [Tarantool-patches] [PATCH v2 2/3] sql: fix typeof() for double values
  2019-12-30 13:01 [Tarantool-patches] [PATCH v2 0/3] sql: fix NUMBER type imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE imeevma
@ 2019-12-30 13:01 ` imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 3/3] sql: make NUMBER to be union of SQL numeric types imeevma
  2 siblings, 0 replies; 6+ messages in thread
From: imeevma @ 2019-12-30 13:01 UTC (permalink / raw)
  To: korablev; +Cc: tarantool-patches

This patch corrects the result of typeof() for double values.
Previously, it gave the type "number" in the case of a
floating-point number. Now it gives "double".

Follow-up #3812
---
 src/box/sql/func.c            |  2 +-
 test/sql-tap/cast.test.lua    | 12 ++++++------
 test/sql-tap/check.test.lua   |  4 ++--
 test/sql-tap/func.test.lua    |  4 ++--
 test/sql-tap/select3.test.lua |  8 ++++----
 test/sql/types.test.lua       |  9 +++++++++
 6 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index deaae61..6e724c8 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -428,7 +428,7 @@ typeofFunc(sql_context * context, int NotUsed, sql_value ** argv)
 		z = "string";
 		break;
 	case MP_DOUBLE:
-		z = "number";
+		z = "double";
 		break;
 	case MP_BIN:
 		z = "varbinary";
diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
index 23229db..9c937a0 100755
--- a/test/sql-tap/cast.test.lua
+++ b/test/sql-tap/cast.test.lua
@@ -257,10 +257,10 @@ test:do_execsql_test(
 test:do_execsql_test(
     "cast-1.26",
     [[
-        SELECT typeof(CAST(123 AS NUMBER))
+        SELECT typeof(CAST(123 AS DOUBLE))
     ]], {
         -- <cast-1.26>
-        "number"
+        "double"
         -- </cast-1.26>
     })
 
@@ -320,7 +320,7 @@ test:do_execsql_test(
         SELECT typeof(123.456)
     ]], {
         -- <cast-1.32>
-        "number"
+        "double"
         -- </cast-1.32>
     })
 
@@ -357,10 +357,10 @@ test:do_execsql_test(
 test:do_execsql_test(
     "cast-1.36",
     [[
-        SELECT typeof(CAST(123.456 AS NUMBER))
+        SELECT typeof(CAST(123.456 AS DOUBLE))
     ]], {
         -- <cast-1.36>
-        "number"
+        "double"
         -- </cast-1.36>
     })
 
@@ -380,7 +380,7 @@ test:do_execsql_test(
         SELECT typeof(CAST(123.456 AS SCALAR))
     ]], {
         -- <cast-1.38>
-        "number"
+        "double"
         -- </cast-1.38>
     })
 
diff --git a/test/sql-tap/check.test.lua b/test/sql-tap/check.test.lua
index 21ededa..3dc28cf 100755
--- a/test/sql-tap/check.test.lua
+++ b/test/sql-tap/check.test.lua
@@ -29,7 +29,7 @@ test:do_execsql_test(
     [[
         CREATE TABLE t1(
           x INTEGER CHECK( x<5 ),
-          y NUMBER CHECK( y>x ),
+          y DOUBLE CHECK( y>x ),
           z  INT primary key
         );
     ]], {
@@ -207,7 +207,7 @@ test:do_execsql_test(
         CREATE TABLE t2(
           id  INT primary key,
           x SCALAR CONSTRAINT one CHECK( typeof(coalesce(x,0))=='integer'),
-          y NUMBER CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='number' ),
+          y DOUBLE CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='double' ),
           z SCALAR CONSTRAINT three CHECK( typeof(coalesce(z,''))=='string' )
         );
     ]], {
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index bd1941b..3c08892 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -518,7 +518,7 @@ test:do_execsql_test(
         SELECT typeof(round(5.1,1));
     ]], {
         -- <func-4.14>
-        "number"
+        "double"
         -- </func-4.14>
     })
 
@@ -528,7 +528,7 @@ test:do_execsql_test(
         SELECT typeof(round(5.1));
     ]], {
         -- <func-4.15>
-        "number"
+        "double"
         -- </func-4.15>
     })
 
diff --git a/test/sql-tap/select3.test.lua b/test/sql-tap/select3.test.lua
index 92e7f8e..0b0b9cc 100755
--- a/test/sql-tap/select3.test.lua
+++ b/test/sql-tap/select3.test.lua
@@ -376,9 +376,9 @@ test:do_execsql_test("select3-7.2", [[
 test:do_execsql_test("select3-8.1", [[
   DROP TABLE IF EXISTS A;
   CREATE TABLE A (
-    A1 NUMBER,
+    A1 DOUBLE,
     A2 TEXT,
-    A3 NUMBER,
+    A3 DOUBLE,
     id int primary key
   );
   INSERT INTO A VALUES(39136,'ABC',1201900000, 1);
@@ -386,7 +386,7 @@ test:do_execsql_test("select3-8.1", [[
   SELECT typeof(sum(a3)) FROM a;
 ]], {
   -- <select3-8.1>
-  "number"
+  "double"
   -- </select3-8.1>
 })
 
@@ -394,7 +394,7 @@ test:do_execsql_test("select3-8.2", [[
   SELECT typeof(sum(a3)) FROM a GROUP BY a1;
 ]], {
   -- <select3-8.2>
-  "number"
+  "double"
   -- </select3-8.2>
 })
 
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index 24bfa42..59d6709 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -465,3 +465,12 @@ box.execute("CREATE TABLE t4 (i INT PRIMARY KEY, d DOUBLE DEFAULT 1.2345);")
 box.execute("INSERT INTO t4(i) VALUES (1);")
 box.execute("SELECT * FROM t4;")
 box.execute("DROP TABLE t4;")
+
+-- Make sure the typeof() function works correctly with DOUBLE.
+box.execute("SELECT typeof(1.0);")
+box.execute("SELECT typeof(CAST(2 AS DOUBLE));")
+box.execute("SELECT typeof(3e3);")
+
+box.execute("CREATE TABLE t5 (d DOUBLE PRIMARY KEY);")
+box.execute("INSERT INTO t5 VALUES (4), (5.5), (6e6);")
+box.execute("SELECT TYPEOF(d) FROM t5;")
-- 
2.7.4

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

* [Tarantool-patches] [PATCH v2 3/3] sql: make NUMBER to be union of SQL numeric types
  2019-12-30 13:01 [Tarantool-patches] [PATCH v2 0/3] sql: fix NUMBER type imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE imeevma
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 2/3] sql: fix typeof() for double values imeevma
@ 2019-12-30 13:01 ` imeevma
  2 siblings, 0 replies; 6+ messages in thread
From: imeevma @ 2019-12-30 13:01 UTC (permalink / raw)
  To: korablev; +Cc: tarantool-patches

Hi! Thank you for review. My answers and new patch below.

On 11/8/19 5:09 PM, Nikita Pettik wrote:
> On 07 Nov 15:13, imeevma@tarantool.org wrote:
>> This patch makes number to be union of UNSIGNED, INTEGER and
>> DOUBLE numeric types. The first two types represented by Tarantool
>> UNSIGNED and INTEGER types.
>
> Nit: integer's range includes unsigned's one.
>
Still, I think that it is worth to mention UNSIGNED here.

>> Currently there is not DOUBLE type in Tarantool.
>
> TBO from commit message it's not clear what does you patch change.
> Please, elaborate it. What is more, your patch modifies user-visible
> behaviour, so I think doc-bot request is required.
>
>> Closes #4233
>> Closes #4463
>
> Please, split patch into two ones: each fixes corresponding problem.
>
I do not think this is possible, since both problems have been
fixed by replacing sqlVdbeMemRealify() with sqlVdbeMemNumerify().

>> ---
>> https://github.com/tarantool/tarantool/issues/4233
>> https://github.com/tarantool/tarantool/tree/imeevma/gh-4233-fix-number-field-type-in-sql
>>
>>  src/box/sql/vdbe.c                   |  15 +----
>>  src/box/sql/vdbeInt.h                |   1 -
>>  src/box/sql/vdbemem.c                |  57 ++-----------------
>>  test/sql-tap/cast.test.lua           |  32 +++++------
>>  test/sql-tap/e_select1.test.lua      |   2 +-
>>  test/sql-tap/numcast.test.lua        | 104 ++++++++++++++++++++++++++++++++++-
>>  test/sql-tap/select3.test.lua        |   2 +-
>>  test/sql-tap/sort.test.lua           |  12 ++--
>>  test/sql-tap/tkt-91e2e8ba6f.test.lua |  12 ++--
>>  test/sql/integer-overflow.result     |   2 +-
>>  test/sql/types.result                |   2 +-
>>  11 files changed, 140 insertions(+), 101 deletions(-)
>
> What I really dislike about this patch is the fact that it eliminates
> ability to convert value to floating point representation. As far as I
> remember you told that you was working on introducing floating point
> field type in NoSQL Tarantool. And after making floating point type
> available in SQL part of code you deleted should be resurrected.
> I suggest firstly introduce floating point type in NoSQL, then make it
> available in SQL and finally rename CAST(source TO NUMBER) -> source TO FLOAT
>
Fixed by adding DOUBLE type, I think.

>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index 03c63d8..2ceee1a 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> @@ -1586,7 +1586,6 @@ case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
>>  case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
>>  case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
>>  case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
>> -	char bIntint;   /* Started out as two integer operands */
>>  	u32 flags;      /* Combined MEM_* flags from both inputs */
>>  	u16 type1;      /* Numeric type of left operand */
>>  	u16 type2;      /* Numeric type of right operand */
>> @@ -1609,7 +1608,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
>>  		bool is_lhs_neg = pIn1->flags & MEM_Int;
>>  		bool is_rhs_neg = pIn2->flags & MEM_Int;
>>  		bool is_res_neg;
>> -		bIntint = 1;
>>  		switch( pOp->opcode) {
>>  		case OP_Add: {
>>  			if (sql_add_int(iA, is_lhs_neg, iB, is_rhs_neg,
>> @@ -1649,7 +1647,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
>>  		}
>>  		mem_set_int(pOut, iB, is_res_neg);
>>  	} else {
>> -		bIntint = 0;
>>  		if (sqlVdbeRealValue(pIn1, &rA) != 0) {
>>  			diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>>  				 sql_value_to_diag_str(pIn1), "numeric");
>> @@ -1660,6 +1657,7 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
>>  				 sql_value_to_diag_str(pIn2), "numeric");
>>  			goto abort_due_to_error;
>>  		}
>> +		assert(((type1 | type2) & MEM_Real) != 0);
>>  		switch( pOp->opcode) {
>>  		case OP_Add:         rB += rA;       break;
>>  		case OP_Subtract:    rB -= rA;       break;
>> @@ -1685,9 +1683,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
>>  		}
>>  		pOut->u.r = rB;
>>  		MemSetTypeFlag(pOut, MEM_Real);
>> -		if (((type1|type2)&MEM_Real)==0 && !bIntint) {
>> -			mem_apply_integer_type(pOut);
>> -		}
>>  	}
>
> Seems like this change of OP_Remainder is barely related to patch..
>
This change applies to all operations. Since I deleted the only
place where bIntint was used, I also deleted the bIntint variable.


New patch:

From ff11be5e9245cc3168ec9f45a8926b9b3deb8d34 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Sat, 26 Oct 2019 17:27:53 +0300
Subject: [PATCH] sql: make NUMBER to be union of SQL numeric types

This patch makes number to be union of UNSIGNED, INTEGER and
DOUBLE numeric types.

Closes #4233
Closes #4463

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index ca99e8e..dab01b7 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1593,7 +1593,6 @@ case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
 case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
 case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
 case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
-	char bIntint;   /* Started out as two integer operands */
 	u32 flags;      /* Combined MEM_* flags from both inputs */
 	u16 type1;      /* Numeric type of left operand */
 	u16 type2;      /* Numeric type of right operand */
@@ -1616,7 +1615,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
 		bool is_lhs_neg = pIn1->flags & MEM_Int;
 		bool is_rhs_neg = pIn2->flags & MEM_Int;
 		bool is_res_neg;
-		bIntint = 1;
 		switch( pOp->opcode) {
 		case OP_Add: {
 			if (sql_add_int(iA, is_lhs_neg, iB, is_rhs_neg,
@@ -1656,7 +1654,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
 		}
 		mem_set_int(pOut, iB, is_res_neg);
 	} else {
-		bIntint = 0;
 		if (sqlVdbeRealValue(pIn1, &rA) != 0) {
 			diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
 				 sql_value_to_diag_str(pIn1), "numeric");
@@ -1667,6 +1664,7 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
 				 sql_value_to_diag_str(pIn2), "numeric");
 			goto abort_due_to_error;
 		}
+		assert(((type1 | type2) & MEM_Real) != 0);
 		switch( pOp->opcode) {
 		case OP_Add:         rB += rA;       break;
 		case OP_Subtract:    rB -= rA;       break;
@@ -1692,9 +1690,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
 		}
 		pOut->u.r = rB;
 		MemSetTypeFlag(pOut, MEM_Real);
-		if (((type1|type2)&MEM_Real)==0 && !bIntint) {
-			mem_apply_integer_type(pOut);
-		}
 	}
 	break;
 
@@ -2753,14 +2748,6 @@ case OP_Column: {
 	    default_val_mem != NULL) {
 		sqlVdbeMemShallowCopy(pDest, default_val_mem, MEM_Static);
 	}
-	if ((pDest->flags & (MEM_Int | MEM_UInt)) != 0) {
-		if (field_type == FIELD_TYPE_NUMBER) {
-			if ((pDest->flags & MEM_Int) != 0)
-				sqlVdbeMemSetDouble(pDest, pDest->u.i);
-			else
-				sqlVdbeMemSetDouble(pDest, pDest->u.u);
-		}
-	}
 	pDest->field_type = field_type;
 op_column_out:
 	REGISTER_TRACE(p, pOp->p3, pDest);
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 1393f3f..361860f 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -531,7 +531,6 @@ int sqlVdbeRealValue(Mem *, double *);
 int
 mem_value_bool(const struct Mem *mem, bool *b);
 
-int mem_apply_integer_type(Mem *);
 int sqlVdbeMemRealify(Mem *);
 int sqlVdbeMemNumerify(Mem *);
 int sqlVdbeMemCast(Mem *, enum field_type type);
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 3c5e5fc..84937da 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -534,23 +534,6 @@ mem_value_bool(const struct Mem *mem, bool *b)
 }
 
 /*
- * The MEM structure is already a MEM_Real.  Try to also make it a
- * MEM_Int if we can.
- */
-int
-mem_apply_integer_type(Mem *pMem)
-{
-	int rc;
-	i64 ix;
-	assert(pMem->flags & MEM_Real);
-	assert(EIGHT_BYTE_ALIGNMENT(pMem));
-
-	if ((rc = doubleToInt64(pMem->u.r, (int64_t *) &ix)) == 0)
-		mem_set_int(pMem, ix, pMem->u.r <= -1);
-	return rc;
-}
-
-/*
  * Convert pMem to type integer.  Invalidate any prior representations.
  */
 int
@@ -608,18 +591,16 @@ int
 sqlVdbeMemNumerify(Mem * pMem)
 {
 	if ((pMem->flags & (MEM_Int | MEM_UInt | MEM_Real | MEM_Null)) == 0) {
-		assert((pMem->flags & (MEM_Blob | MEM_Str)) != 0);
+		if ((pMem->flags & (MEM_Blob | MEM_Str)) == 0)
+			return -1;
 		bool is_neg;
 		int64_t i;
 		if (sql_atoi64(pMem->z, &i, &is_neg, pMem->n) == 0) {
 			mem_set_int(pMem, i, is_neg);
 		} else {
-			double v;
-			if (sqlVdbeRealValue(pMem, &v))
+			if (sqlAtoF(pMem->z, &pMem->u.r, pMem->n) == 0)
 				return -1;
-			pMem->u.r = v;
 			MemSetTypeFlag(pMem, MEM_Real);
-			mem_apply_integer_type(pMem);
 		}
 	}
 	assert((pMem->flags & (MEM_Int | MEM_UInt | MEM_Real | MEM_Null)) != 0);
@@ -676,22 +657,6 @@ sqlVdbeMemCast(Mem * pMem, enum field_type type)
 	assert(type < field_type_MAX);
 	if (pMem->flags & MEM_Null)
 		return 0;
-	if ((pMem->flags & MEM_Blob) != 0 && type == FIELD_TYPE_NUMBER) {
-		bool is_neg;
-		if (sql_atoi64(pMem->z,  (int64_t *) &pMem->u.i, &is_neg,
-			       pMem->n) == 0) {
-			MemSetTypeFlag(pMem, MEM_Real);
-			if (is_neg)
-				pMem->u.r = pMem->u.i;
-			else
-				pMem->u.r = pMem->u.u;
-			return 0;
-		}
-		if (sqlAtoF(pMem->z, &pMem->u.r, pMem->n) == 0)
-			return -1;
-		MemSetTypeFlag(pMem, MEM_Real);
-		return 0;
-	}
 	switch (type) {
 	case FIELD_TYPE_SCALAR:
 		return 0;
@@ -742,8 +707,9 @@ sqlVdbeMemCast(Mem * pMem, enum field_type type)
 			return -1;
 		return 0;
 	case FIELD_TYPE_DOUBLE:
-	case FIELD_TYPE_NUMBER:
 		return sqlVdbeMemRealify(pMem);
+	case FIELD_TYPE_NUMBER:
+		return sqlVdbeMemNumerify(pMem);
 	case FIELD_TYPE_VARBINARY:
 		if ((pMem->flags & MEM_Blob) != 0)
 			return 0;
diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
index 9c937a0..9bff909 100755
--- a/test/sql-tap/cast.test.lua
+++ b/test/sql-tap/cast.test.lua
@@ -628,14 +628,14 @@ test:do_execsql_test(
         SELECT CAST(9223372036854774800 AS NUMBER)
     ]], {
         -- <cast-3.2>
-        9223372036854774784
+        9223372036854774800LL
         -- </cast-3.2>
     })
 
 test:do_execsql_test(
     "cast-3.3",
     "SELECT CAST(9223372036854774800 AS NUMBER)",
-    {9.22337203685477e+18})
+    {9223372036854774800LL})
 
 test:do_execsql_test(
     "cast-3.4",
@@ -643,7 +643,7 @@ test:do_execsql_test(
         SELECT CAST(CAST(9223372036854774800 AS NUMBER) AS integer)
     ]], {
         -- <cast-3.4>
-        9223372036854774784LL
+        9223372036854774800LL
         -- </cast-3.4>
     })
 
@@ -663,14 +663,14 @@ test:do_execsql_test(
         SELECT CAST(-9223372036854774800 AS NUMBER)
     ]], {
         -- <cast-3.6>
-        -9223372036854774784
+        -9223372036854774800LL
         -- </cast-3.6>
     })
 
 test:do_execsql_test(
     "cast-3.7",
     "SELECT CAST(-9223372036854774800 AS NUMBER)",
-    {-9.22337203685477e+18})
+    {-9223372036854774800LL})
 
 test:do_execsql_test(
     "cast-3.8",
@@ -678,7 +678,7 @@ test:do_execsql_test(
         SELECT CAST(CAST(-9223372036854774800 AS NUMBER) AS integer)
     ]], {
         -- <cast-3.8>
-        -9223372036854774784LL
+        -9223372036854774800LL
         -- </cast-3.8>
     })
 
@@ -695,7 +695,7 @@ test:do_execsql_test(
 test:do_execsql_test(
     "cast-3.12",
     [[
-        SELECT CAST('9223372036854774800' AS NUMBER)
+        SELECT CAST('9223372036854774800.' AS NUMBER)
     ]], {
         -- <cast-3.12>
         9223372036854774784
@@ -705,12 +705,12 @@ test:do_execsql_test(
 test:do_execsql_test(
     "cast-3.13",
     "SELECT CAST(9223372036854774800 AS NUMBER)",
-    {9.22337203685477e+18})
+    {9223372036854774800LL})
 
 test:do_execsql_test(
     "cast-3.14",
     [[
-        SELECT CAST(CAST('9223372036854774800' AS NUMBER) AS integer)
+        SELECT CAST(CAST('9223372036854774800.' AS NUMBER) AS integer)
     ]], {
         -- <cast-3.14>
         9223372036854774784LL
@@ -732,7 +732,7 @@ test:do_execsql_test(
 test:do_execsql_test(
     "cast-3.16",
     [[
-        SELECT CAST('-9223372036854774800' AS NUMBER)
+        SELECT CAST('-9223372036854774800.' AS NUMBER)
     ]], {
         -- <cast-3.16>
         -9223372036854774784
@@ -741,13 +741,13 @@ test:do_execsql_test(
 
 test:do_execsql_test(
     "cast-3.17",
-    "SELECT CAST('-9223372036854774800' AS NUMBER)",
+    "SELECT CAST('-9223372036854774800.' AS NUMBER)",
     {-9.22337203685477e+18})
 
 test:do_execsql_test(
     "cast-3.18",
     [[
-        SELECT CAST(CAST('-9223372036854774800' AS NUMBER) AS integer)
+        SELECT CAST(CAST('-9223372036854774800.' AS NUMBER) AS integer)
     ]], {
         -- <cast-3.18>
         -9223372036854774784LL
@@ -770,7 +770,7 @@ if true then --test:execsql("PRAGMA encoding")[1][1]=="UTF-8" then
     test:do_execsql_test(
         "cast-3.22",
         [[
-            SELECT CAST(x'39323233333732303336383534373734383030' AS NUMBER)
+            SELECT CAST(x'393232333337323033363835343737343830302E' AS NUMBER)
         ]], {
             -- <cast-3.22>
             9223372036854774784
@@ -778,7 +778,7 @@ if true then --test:execsql("PRAGMA encoding")[1][1]=="UTF-8" then
         })
     test:do_execsql_test(
         "cast-3.23",
-        "SELECT CAST(x'39323233333732303336383534373734383030' AS NUMBER)",
+        "SELECT CAST(x'393232333337323033363835343737343830302E' AS NUMBER)",
         {9.22337203685477e+18})
 
     test:do_execsql_test(
@@ -788,7 +788,7 @@ if true then --test:execsql("PRAGMA encoding")[1][1]=="UTF-8" then
                         AS integer)
         ]], {
             -- <cast-3.24>
-            9223372036854774784LL
+            9223372036854774800LL
             -- </cast-3.24>
         })
 end
@@ -796,7 +796,7 @@ end
 test:do_execsql_test(
     "case-3.25",
     [[
-        SELECT CAST(x'3138343436373434303733373039353531363135' AS NUMBER);
+        SELECT CAST(x'31383434363734343037333730393535313631352E' AS NUMBER);
     ]], { 1.844674407371e+19 } )
 
 test:do_execsql_test(
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index 48d8c22..c1818dd 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -760,7 +760,7 @@ test:do_execsql_test(
         INSERT INTO z1 VALUES(6, 63, '0', -26);
 
         INSERT INTO z2 VALUES(1, NULL, 21);
-        INSERT INTO z2 VALUES(2, 36, 6);
+        INSERT INTO z2 VALUES(2, 36.0, 6.0);
 
         INSERT INTO z3 VALUES(1, 123.21, 123.12);
         INSERT INTO z3 VALUES(2, 49.17, -67);
diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
index a45daef..e704dc4 100755
--- a/test/sql-tap/numcast.test.lua
+++ b/test/sql-tap/numcast.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(22)
+test:plan(33)
 
 --!./tcltestrunner.lua
 -- 2013 March 20
@@ -170,4 +170,107 @@ test:do_execsql_test(
         9, 0.9
     })
 
+--
+-- gh-4233: Make sure that NUMBER can contain UNSIGNED, INTEGER
+-- and DOUBLE and is not automatically converted to DOUBLE.
+--
+test:do_execsql_test(
+    "numcast-2.1",
+    [[
+        CREATE TABLE t1 (id INT PRIMARY KEY, n NUMBER);
+        INSERT INTO t1 VALUES (1, 9223372036854775807);
+        INSERT INTO t1 VALUES (2, -9223372036854775807);
+        INSERT INTO t1 VALUES (3, 9223372036854775807.1);
+        SELECT n, n/100 FROM t1;
+    ]], {
+        9223372036854775807ULL, 92233720368547758ULL,
+        -9223372036854775807LL, -92233720368547758LL,
+        9223372036854775808, 92233720368547758.08
+    })
+
+test:do_execsql_test(
+    "numcast-2.2",
+    [[
+        CREATE TABLE t2(a NUMBER primary key);
+        INSERT INTO t2 VALUES(-56);
+        INSERT INTO t2 VALUES(44.0);
+        INSERT INTO t2 VALUES(46);
+        INSERT INTO t2 VALUES(56.0);
+        SELECT (a + 25) / 50 FROM t2;
+    ]], {
+        0,1.38,1,1.62
+    })
+
+test:do_execsql_test(
+    "numcast-2.3",
+    [[
+        SELECT CAST(x'3131313131313131313131313131313131313131' AS NUMBER);
+    ]], {
+        11111111111111111111ULL
+    })
+
+test:do_execsql_test(
+    "numcast-2.4",
+    [[
+        SELECT CAST(x'31313131313131313131313131313131313131312E' AS NUMBER);
+    ]], {
+        11111111111111110656
+    })
+
+test:do_execsql_test(
+    "numcast-2.5",
+    [[
+        SELECT CAST('11111111111111111111' AS NUMBER);
+    ]], {
+        11111111111111111111ULL
+    })
+
+test:do_execsql_test(
+    "numcast-2.6",
+    [[
+        SELECT CAST('101' AS NUMBER) / 10, CAST('101.' AS NUMBER) / 10;
+    ]], {
+        10, 10.1
+    })
+
+test:do_execsql_test(
+    "numcast-2.7",
+    [[
+        SELECT CAST('101     ' AS NUMBER) / 10, CAST('      101' AS NUMBER) / 10;
+    ]], {
+        10, 10
+    })
+
+test:do_execsql_test(
+    "numcast-2.8",
+    [[
+        SELECT (1 + 0) / 3, (1 + 0.) / 3, (1 + 0) / 3.;
+    ]], {
+        0, 0.33333333333333, 0.33333333333333
+    })
+
+test:do_execsql_test(
+    "numcast-2.9",
+    [[
+        SELECT (1 - 0) / 3, (1 - 0.) / 3, (1 - 0) / 3.;
+    ]], {
+        0, 0.33333333333333, 0.33333333333333
+    })
+
+test:do_execsql_test(
+    "numcast-2.10",
+    [[
+        SELECT (1 * 1) / 3, (1 * 1.) / 3, (1 * 1) / 3.;
+    ]], {
+        0, 0.33333333333333, 0.33333333333333
+    })
+
+test:do_execsql_test(
+    "numcast-2.11",
+    [[
+        SELECT (1 / 1) / 3, (1 / 1.) / 3, (1 / 1) / 3.;
+    ]], {
+        0, 0.33333333333333, 0.33333333333333
+    })
+
 test:finish_test()
diff --git a/test/sql-tap/sort.test.lua b/test/sql-tap/sort.test.lua
index e156414..36074d6 100755
--- a/test/sql-tap/sort.test.lua
+++ b/test/sql-tap/sort.test.lua
@@ -243,7 +243,7 @@ test:do_execsql_test(
         SELECT v FROM t1 ORDER BY v;
     ]], {
         -- <sort-2.1.1>
-        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4221.0", "x0.0013442", "x1.6", "x11.0"
+        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4221.0", "x0.0013442", "x1.6", "x11"
         -- </sort-2.1.1>
     })
 
@@ -253,7 +253,7 @@ test:do_execsql_test(
         SELECT v FROM t1 ORDER BY substr(v,2,999);
     ]], {
         -- <sort-2.1.2>
-        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4221.0", "x0.0013442", "x1.6", "x11.0"
+        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4221.0", "x0.0013442", "x1.6", "x11"
         -- </sort-2.1.2>
     })
 
@@ -263,7 +263,7 @@ test:do_execsql_test(
         SELECT v FROM t1 ORDER BY substr(v,2,999) DESC;
     ]], {
         -- <sort-2.1.4>
-        "x11.0", "x1.6", "x0.0013442", "x-4221.0", "x-3.141592653", "x-2b", "x-2.15", "x-123.0"
+        "x11", "x1.6", "x0.0013442", "x-4221.0", "x-3.141592653", "x-2b", "x-2.15", "x-123.0"
         -- </sort-2.1.4>
     })
 
@@ -381,7 +381,7 @@ test:do_execsql_test(
         SELECT v FROM t1 ORDER BY 1;
     ]], {
         -- <sort-4.6>
-        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4.0e9", "x-4221.0", "x0.0013442", "x01234567890123456789", "x1.6", "x11.0", "x2.7", "x5.0e10"
+        "x-123.0", "x-2.15", "x-2b", "x-3.141592653", "x-4.0e9", "x-4221.0", "x0.0013442", "x01234567890123456789", "x1.6", "x11", "x2.7", "x5.0e10"
         -- </sort-4.6>
     })
 
@@ -391,7 +391,7 @@ test:do_execsql_test(
         SELECT v FROM t1 ORDER BY 1 DESC;
     ]], {
         -- <sort-4.7>
-        "x5.0e10", "x2.7", "x11.0", "x1.6", "x01234567890123456789", "x0.0013442", "x-4221.0", "x-4.0e9", "x-3.141592653", "x-2b", "x-2.15", "x-123.0"
+        "x5.0e10", "x2.7", "x11", "x1.6", "x01234567890123456789", "x0.0013442", "x-4221.0", "x-4.0e9", "x-3.141592653", "x-2b", "x-2.15", "x-123.0"
         -- </sort-4.7>
     })
 
@@ -401,7 +401,7 @@ test:do_execsql_test(
         SELECT substr(v,2,99) FROM t1 ORDER BY 1;
     ]], {
         -- <sort-4.8>
-    "-123.0","-2.15","-2b","-3.141592653","-4.0e9","-4221.0","0.0013442","01234567890123456789","1.6","11.0","2.7","5.0e10"
+    "-123.0","-2.15","-2b","-3.141592653","-4.0e9","-4221.0","0.0013442","01234567890123456789","1.6","11","2.7","5.0e10"
         -- </sort-4.8>
     })
 
diff --git a/test/sql-tap/tkt-91e2e8ba6f.test.lua b/test/sql-tap/tkt-91e2e8ba6f.test.lua
index 7622f75..b12b6e0 100755
--- a/test/sql-tap/tkt-91e2e8ba6f.test.lua
+++ b/test/sql-tap/tkt-91e2e8ba6f.test.lua
@@ -35,7 +35,7 @@ test:do_execsql_test(
         SELECT x/10, y/10 FROM t1;
     ]], {
         -- <1.2>
-        1, 1.1
+        1, 1
         -- </1.2>
     })
 
@@ -45,7 +45,7 @@ test:do_execsql_test(
         SELECT x/10, y/10 FROM (SELECT * FROM t1);
     ]], {
         -- <1.3>
-        1, 1.1
+        1, 1
         -- </1.3>
     })
 
@@ -55,7 +55,7 @@ test:do_execsql_test(
         SELECT x/10, y/10 FROM (SELECT * FROM t1 LIMIT 5 OFFSET 0);
     ]], {
         -- <1.4>
-        1, 1.1
+        1, 1
         -- </1.4>
     })
 
@@ -65,7 +65,7 @@ test:do_execsql_test(
         SELECT x/10, y/10 FROM (SELECT * FROM t1 LIMIT 5 OFFSET 0) LIMIT 5 OFFSET 0;
     ]], {
         -- <1.5>
-        1, 1.1
+        1, 1
         -- </1.5>
     })
 
@@ -77,7 +77,7 @@ test:do_execsql_test(
         LIMIT 5 OFFSET 0;
     ]], {
         -- <1.6>
-        1, 1.1
+        1, 1
         -- </1.6>
     })
 
@@ -92,7 +92,7 @@ test:do_execsql_test(
         SELECT a.x/10, a.y/10 FROM v1 AS a, t1 AS b WHERE a.x = b.x LIMIT 5 OFFSET 0;
     ]], {
         -- <1.7>
-        1, 1.1
+        1, 1
         -- </1.7>
     })
 
diff --git a/test/sql/integer-overflow.result b/test/sql/integer-overflow.result
index d6223ff..8d4048c 100644
--- a/test/sql/integer-overflow.result
+++ b/test/sql/integer-overflow.result
@@ -171,7 +171,7 @@ box.execute("SELECT * FROM t;")
   - name: A
     type: number
   rows:
-  - [1, 1.844674407371e+19]
+  - [1, 18446744073709551615]
   - [2, -1]
 ...
 box.space.T:drop()
diff --git a/test/sql/types.result b/test/sql/types.result
index 8c0186d..c55fea5 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -1023,7 +1023,7 @@ box.execute("SELECT CAST(18446744073709551615 AS NUMBER);")
   - name: CAST(18446744073709551615 AS NUMBER)
     type: number
   rows:
-  - [1.844674407371e+19]
+  - [18446744073709551615]
 ...
 box.execute("SELECT CAST(18446744073709551615 AS TEXT);")
 ---

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

* Re: [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE
  2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE imeevma
@ 2019-12-30 13:17   ` Nikita Pettik
  2019-12-31  8:16     ` Mergen Imeev
  0 siblings, 1 reply; 6+ messages in thread
From: Nikita Pettik @ 2019-12-30 13:17 UTC (permalink / raw)
  To: imeevma; +Cc: tarantool-patches

On 30 Dec 16:01, imeevma@tarantool.org wrote:
> This patch allows to convert binary values consisting of numeric
> literals to numbers.

What is the justification for this change? I see no reason to allow
implicitly casting blobs to floating points.

> Follow-uo #3812

-> up

> ---
>  src/box/sql/vdbemem.c                |  2 +-
>  test/sql-tap/numcast.test.lua        | 25 ++++++++++++++++++++++++-
>  test/sql-tap/tkt-80e031a00f.test.lua |  8 ++++----
>  test/sql/types.result                |  7 +++++--
>  4 files changed, 34 insertions(+), 8 deletions(-)
> 
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index df3f0d8..3c5e5fc 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -516,7 +516,7 @@ sqlVdbeRealValue(Mem * pMem, double *v)
>  	} else if ((pMem->flags & MEM_UInt) != 0) {
>  		*v = (double)pMem->u.u;
>  		return 0;
> -	} else if (pMem->flags & MEM_Str) {
> +	} else if ((pMem->flags & (MEM_Blob | MEM_Str)) != 0) {
>  		if (sqlAtoF(pMem->z, v, pMem->n))
>  			return 0;
>  	}
> diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
> index 07117d0..a45daef 100755
> --- a/test/sql-tap/numcast.test.lua
> +++ b/test/sql-tap/numcast.test.lua
> @@ -1,6 +1,6 @@
>  #!/usr/bin/env tarantool
>  test = require("sqltester")
> -test:plan(20)
> +test:plan(22)
>  
>  --!./tcltestrunner.lua
>  -- 2013 March 20
> @@ -147,4 +147,27 @@ test:do_catchsql_test(
>          1,"Tuple field 1 type does not match one required by operation: expected integer"
>      })
>  
> +--
> +-- Allow to convert binary values consisting of numeric literals
> +-- to numbers.
> +--
> +test:do_execsql_test(
> +    "cast-3.1",
> +    [[
> +        CREATE TABLE td (i DOUBLE PRIMARY KEY);
> +        INSERT INTO td VALUES(X'3132332E35');
> +        INSERT INTO td VALUES(X'31323334');
> +        SELECT * FROM td;
> +    ]], {
> +        123.5, 1234
> +    })
> +
> +test:do_execsql_test(
> +    "cast-3.2",
> +    [[
> +        SELECT CAST(X'39' AS DOUBLE), CAST(X'39' AS DOUBLE) / 10;
> +    ]], {
> +        9, 0.9
> +    })
> +
>  test:finish_test()
> diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
> index a0e6539..01f4265 100755
> --- a/test/sql-tap/tkt-80e031a00f.test.lua
> +++ b/test/sql-tap/tkt-80e031a00f.test.lua
> @@ -380,23 +380,23 @@ test:do_execsql_test(
>          -- </tkt-80e031a00f.30>
>      })
>  
> -test:do_catchsql_test(
> +test:do_execsql_test(
>      "tkt-80e031a00f.31",
>      [[
>          SELECT x'303132' IN t1
>      ]], {
>          -- <tkt-80e031a00f.31>
> -        1, 'Type mismatch: can not convert varbinary to integer'
> +        false
>          -- </tkt-80e031a00f.31>
>      })
>  
> -test:do_catchsql_test(
> +test:do_execsql_test(
>      "tkt-80e031a00f.32",
>      [[
>          SELECT x'303132' NOT IN t1
>      ]], {
>          -- <tkt-80e031a00f.32>
> -        1, 'Type mismatch: can not convert varbinary to integer'
> +        true
>          -- </tkt-80e031a00f.32>
>      })
>  
> diff --git a/test/sql/types.result b/test/sql/types.result
> index 6d0aefd..8c0186d 100644
> --- a/test/sql/types.result
> +++ b/test/sql/types.result
> @@ -1760,8 +1760,11 @@ box.execute("SELECT CAST(x'' AS DOUBLE);")
>  ...
>  box.execute("SELECT CAST(x'35' AS DOUBLE);")
>  ---
> -- null
> -- 'Type mismatch: can not convert varbinary to double'
> +- metadata:
> +  - name: CAST(x'35' AS DOUBLE)
> +    type: double
> +  rows:
> +  - [5]
>  ...
>  box.execute("SELECT CAST(CAST(x'35' AS STRING) AS DOUBLE);")
>  ---
> -- 
> 2.7.4
> 

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

* Re: [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE
  2019-12-30 13:17   ` Nikita Pettik
@ 2019-12-31  8:16     ` Mergen Imeev
  0 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev @ 2019-12-31  8:16 UTC (permalink / raw)
  To: Nikita Pettik; +Cc: tarantool-patches

Hi! Thank you for review. You are right, I dropped this
commit. All implicit/explicit casts will be fixed in the
other issues (such as #3809, 4230 and so on).

On Mon, Dec 30, 2019 at 03:17:49PM +0200, Nikita Pettik wrote:
> On 30 Dec 16:01, imeevma@tarantool.org wrote:
> > This patch allows to convert binary values consisting of numeric
> > literals to numbers.
> 
> What is the justification for this change? I see no reason to allow
> implicitly casting blobs to floating points.
> 
> > Follow-uo #3812
> 
> -> up
> 
> > ---
> >  src/box/sql/vdbemem.c                |  2 +-
> >  test/sql-tap/numcast.test.lua        | 25 ++++++++++++++++++++++++-
> >  test/sql-tap/tkt-80e031a00f.test.lua |  8 ++++----
> >  test/sql/types.result                |  7 +++++--
> >  4 files changed, 34 insertions(+), 8 deletions(-)
> > 
> > diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> > index df3f0d8..3c5e5fc 100644
> > --- a/src/box/sql/vdbemem.c
> > +++ b/src/box/sql/vdbemem.c
> > @@ -516,7 +516,7 @@ sqlVdbeRealValue(Mem * pMem, double *v)
> >  	} else if ((pMem->flags & MEM_UInt) != 0) {
> >  		*v = (double)pMem->u.u;
> >  		return 0;
> > -	} else if (pMem->flags & MEM_Str) {
> > +	} else if ((pMem->flags & (MEM_Blob | MEM_Str)) != 0) {
> >  		if (sqlAtoF(pMem->z, v, pMem->n))
> >  			return 0;
> >  	}
> > diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
> > index 07117d0..a45daef 100755
> > --- a/test/sql-tap/numcast.test.lua
> > +++ b/test/sql-tap/numcast.test.lua
> > @@ -1,6 +1,6 @@
> >  #!/usr/bin/env tarantool
> >  test = require("sqltester")
> > -test:plan(20)
> > +test:plan(22)
> >  
> >  --!./tcltestrunner.lua
> >  -- 2013 March 20
> > @@ -147,4 +147,27 @@ test:do_catchsql_test(
> >          1,"Tuple field 1 type does not match one required by operation: expected integer"
> >      })
> >  
> > +--
> > +-- Allow to convert binary values consisting of numeric literals
> > +-- to numbers.
> > +--
> > +test:do_execsql_test(
> > +    "cast-3.1",
> > +    [[
> > +        CREATE TABLE td (i DOUBLE PRIMARY KEY);
> > +        INSERT INTO td VALUES(X'3132332E35');
> > +        INSERT INTO td VALUES(X'31323334');
> > +        SELECT * FROM td;
> > +    ]], {
> > +        123.5, 1234
> > +    })
> > +
> > +test:do_execsql_test(
> > +    "cast-3.2",
> > +    [[
> > +        SELECT CAST(X'39' AS DOUBLE), CAST(X'39' AS DOUBLE) / 10;
> > +    ]], {
> > +        9, 0.9
> > +    })
> > +
> >  test:finish_test()
> > diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
> > index a0e6539..01f4265 100755
> > --- a/test/sql-tap/tkt-80e031a00f.test.lua
> > +++ b/test/sql-tap/tkt-80e031a00f.test.lua
> > @@ -380,23 +380,23 @@ test:do_execsql_test(
> >          -- </tkt-80e031a00f.30>
> >      })
> >  
> > -test:do_catchsql_test(
> > +test:do_execsql_test(
> >      "tkt-80e031a00f.31",
> >      [[
> >          SELECT x'303132' IN t1
> >      ]], {
> >          -- <tkt-80e031a00f.31>
> > -        1, 'Type mismatch: can not convert varbinary to integer'
> > +        false
> >          -- </tkt-80e031a00f.31>
> >      })
> >  
> > -test:do_catchsql_test(
> > +test:do_execsql_test(
> >      "tkt-80e031a00f.32",
> >      [[
> >          SELECT x'303132' NOT IN t1
> >      ]], {
> >          -- <tkt-80e031a00f.32>
> > -        1, 'Type mismatch: can not convert varbinary to integer'
> > +        true
> >          -- </tkt-80e031a00f.32>
> >      })
> >  
> > diff --git a/test/sql/types.result b/test/sql/types.result
> > index 6d0aefd..8c0186d 100644
> > --- a/test/sql/types.result
> > +++ b/test/sql/types.result
> > @@ -1760,8 +1760,11 @@ box.execute("SELECT CAST(x'' AS DOUBLE);")
> >  ...
> >  box.execute("SELECT CAST(x'35' AS DOUBLE);")
> >  ---
> > -- null
> > -- 'Type mismatch: can not convert varbinary to double'
> > +- metadata:
> > +  - name: CAST(x'35' AS DOUBLE)
> > +    type: double
> > +  rows:
> > +  - [5]
> >  ...
> >  box.execute("SELECT CAST(CAST(x'35' AS STRING) AS DOUBLE);")
> >  ---
> > -- 
> > 2.7.4
> > 

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

end of thread, other threads:[~2019-12-31  8:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-30 13:01 [Tarantool-patches] [PATCH v2 0/3] sql: fix NUMBER type imeevma
2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 1/3] sql: allow conversion of numeric binary values to DOUBLE imeevma
2019-12-30 13:17   ` Nikita Pettik
2019-12-31  8:16     ` Mergen Imeev
2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 2/3] sql: fix typeof() for double values imeevma
2019-12-30 13:01 ` [Tarantool-patches] [PATCH v2 3/3] sql: make NUMBER to be union of SQL numeric types imeevma

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