* [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