* [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast
@ 2020-06-25 15:17 imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double() imeevma
` (7 more replies)
0 siblings, 8 replies; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
This patch-set removes implicit cast between string and numbers
for assignment and for comparison.
https://github.com/tarantool/tarantool/issues/3809
https://github.com/tarantool/tarantool/issues/4230
https://github.com/tarantool/tarantool/tree/imeevma/gh-3809-disallow-imlicit-cast-from-string-to-nums
@ChangeLog
- [Breaking change] Removed implicit cast from string to numbers
and vice versa for assignment and comparison.
v2:
- Added a commit that changes the type mismatch error
description.
v3:
- Introduction of mem_set_double() was moved to another commit.
- Implicit cast rules for assigning were changed.
Mergen Imeev (8):
sql: introduce mem_set_double()
sql: change implicit cast for assignment
sql: remove mem_apply_type() from OP_MakeRecord
sql: replace ApplyType by CheckType for IN operator
sql: remove mem_apply_type() from OP_MustBeInt
sql: remove implicit cast for comparison
sql: remove unused functions
sql: show value and its type in type mismatch error
src/box/sql/analyze.c | 7 +-
src/box/sql/delete.c | 8 +-
src/box/sql/expr.c | 53 +-
src/box/sql/fk_constraint.c | 9 +-
src/box/sql/func.c | 8 +-
src/box/sql/insert.c | 16 +-
src/box/sql/select.c | 25 +-
src/box/sql/sqlInt.h | 34 +-
src/box/sql/update.c | 14 +-
src/box/sql/vdbe.c | 322 ++--
src/box/sql/vdbeInt.h | 5 +-
src/box/sql/vdbeapi.c | 31 +-
src/box/sql/vdbemem.c | 38 +-
src/box/sql/wherecode.c | 211 +--
test/sql-tap/autoinc.test.lua | 6 +-
test/sql-tap/cast.test.lua | 16 +-
test/sql-tap/default.test.lua | 6 +-
test/sql-tap/e_select1.test.lua | 27 +-
.../gh-3809-implicit-cast-assignment.test.lua | 653 ++++++++
.../gh-4230-del-impl-cast-str-to-num.test.lua | 281 ++++
...-4766-wrong-cast-from-blob-to-int.test.lua | 9 +-
test/sql-tap/identifier_case.test.lua | 6 +-
test/sql-tap/in1.test.lua | 4 +-
test/sql-tap/in3.test.lua | 18 +-
test/sql-tap/in4.test.lua | 100 +-
test/sql-tap/index1.test.lua | 28 +-
test/sql-tap/insert3.test.lua | 12 +-
test/sql-tap/intpkey.test.lua | 133 +-
test/sql-tap/join.test.lua | 8 +-
test/sql-tap/limit.test.lua | 2 +-
test/sql-tap/minmax2.test.lua | 6 +-
test/sql-tap/misc1.test.lua | 66 +-
test/sql-tap/numcast.test.lua | 8 +-
test/sql-tap/select1.test.lua | 18 +-
test/sql-tap/select4.test.lua | 12 +-
test/sql-tap/select5.test.lua | 2 +-
test/sql-tap/select7.test.lua | 4 +-
test/sql-tap/sort.test.lua | 8 +-
test/sql-tap/subquery.test.lua | 73 +-
test/sql-tap/tkt-3998683a16.test.lua | 26 +-
test/sql-tap/tkt-54844eea3f.test.lua | 8 +-
test/sql-tap/tkt-7bbfb7d442.test.lua | 4 +-
test/sql-tap/tkt-80e031a00f.test.lua | 4 +-
test/sql-tap/tkt-9a8b09f8e6.test.lua | 528 ------
test/sql-tap/tkt-f973c7ac31.test.lua | 18 +-
test/sql-tap/tkt-fc7bd6358f.test.lua | 111 --
test/sql-tap/tkt1444.test.lua | 4 +-
test/sql-tap/tkt3493.test.lua | 46 +-
test/sql-tap/tkt3841.test.lua | 12 +-
test/sql-tap/transitive1.test.lua | 16 +-
test/sql-tap/triggerA.test.lua | 4 +-
test/sql-tap/unique.test.lua | 8 +-
test/sql-tap/view.test.lua | 2 +-
test/sql-tap/where2.test.lua | 183 +-
test/sql-tap/where5.test.lua | 22 +-
test/sql-tap/whereB.test.lua | 908 ----------
test/sql-tap/whereC.test.lua | 8 +-
test/sql/boolean.result | 1484 ++++++++---------
test/sql/integer-overflow.result | 4 +-
test/sql/persistency.result | 2 +-
test/sql/types.result | 67 +-
test/sql/types.test.lua | 1 -
62 files changed, 2231 insertions(+), 3526 deletions(-)
create mode 100755 test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
create mode 100755 test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
delete mode 100755 test/sql-tap/tkt-9a8b09f8e6.test.lua
delete mode 100755 test/sql-tap/tkt-fc7bd6358f.test.lua
delete mode 100755 test/sql-tap/whereB.test.lua
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double()
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-28 13:31 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment imeevma
` (6 subsequent siblings)
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
The mem_set_double () function is used to properly set MEM as
containing DOUBLE value.
---
src/box/sql/func.c | 8 ++++----
src/box/sql/vdbe.c | 9 +++------
src/box/sql/vdbeInt.h | 5 ++++-
src/box/sql/vdbeapi.c | 4 ++--
src/box/sql/vdbemem.c | 25 ++++++++++---------------
5 files changed, 23 insertions(+), 28 deletions(-)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 4715ffabb..1856fe343 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -267,10 +267,10 @@ port_lua_get_vdbemem(struct port *base, uint32_t *size)
mem_set_bool(&val[i], field.bval);
break;
case MP_FLOAT:
- sqlVdbeMemSetDouble(&val[i], field.fval);
+ mem_set_double(&val[i], field.fval);
break;
case MP_DOUBLE:
- sqlVdbeMemSetDouble(&val[i], field.dval);
+ mem_set_double(&val[i], field.dval);
break;
case MP_INT:
mem_set_i64(&val[i], field.ival);
@@ -338,10 +338,10 @@ port_c_get_vdbemem(struct port *base, uint32_t *size)
mem_set_bool(&val[i], mp_decode_bool(&data));
break;
case MP_FLOAT:
- sqlVdbeMemSetDouble(&val[i], mp_decode_float(&data));
+ mem_set_double(&val[i], mp_decode_float(&data));
break;
case MP_DOUBLE:
- sqlVdbeMemSetDouble(&val[i], mp_decode_double(&data));
+ mem_set_double(&val[i], mp_decode_double(&data));
break;
case MP_INT:
mem_set_i64(&val[i], mp_decode_int(&data));
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 6b769805c..950f72ddd 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -271,8 +271,7 @@ mem_apply_numeric_type(struct Mem *record)
double float_value;
if (sqlAtoF(record->z, &float_value, record->n) == 0)
return -1;
- record->u.r = float_value;
- MemSetTypeFlag(record, MEM_Real);
+ mem_set_double(record, float_value);
return 0;
}
@@ -1198,9 +1197,8 @@ case OP_Int64: { /* out2 */
*/
case OP_Real: { /* same as TK_FLOAT, out2 */
pOut = vdbe_prepare_null_out(p, pOp->p2);
- pOut->flags = MEM_Real;
assert(!sqlIsNaN(*pOp->p4.pReal));
- pOut->u.r = *pOp->p4.pReal;
+ mem_set_double(pOut, *pOp->p4.pReal);
break;
}
@@ -1673,8 +1671,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if (sqlIsNaN(rB)) {
goto arithmetic_result_is_null;
}
- pOut->u.r = rB;
- MemSetTypeFlag(pOut, MEM_Real);
+ mem_set_double(pOut, rB);
}
break;
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 2c50b6768..a3ecd13af 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -517,7 +517,10 @@ mem_set_u64(struct Mem *mem, uint64_t value);
void
mem_set_int(struct Mem *mem, int64_t value, bool is_neg);
-void sqlVdbeMemSetDouble(Mem *, double);
+/** Set double value and MEM_Real flag. */
+void
+mem_set_double(struct Mem *mem, double value);
+
void sqlVdbeMemInit(Mem *, sql *, u32);
void sqlVdbeMemSetNull(Mem *);
void sqlVdbeMemSetZeroBlob(Mem *, int);
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 6e307e97f..4e103a653 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -330,7 +330,7 @@ sql_result_blob64(sql_context * pCtx,
void
sql_result_double(sql_context * pCtx, double rVal)
{
- sqlVdbeMemSetDouble(pCtx->pOut, rVal);
+ mem_set_double(pCtx->pOut, rVal);
}
void
@@ -1021,7 +1021,7 @@ sql_bind_double(sql_stmt * pStmt, int i, double rValue)
if (vdbeUnbind(p, i) != 0)
return -1;
int rc = sql_bind_type(p, i, "numeric");
- sqlVdbeMemSetDouble(&p->aVar[i - 1], rValue);
+ mem_set_double(&p->aVar[i - 1], rValue);
return rc;
}
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 8dad2db9a..a721afc83 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -561,9 +561,7 @@ sqlVdbeMemRealify(Mem * pMem)
double v;
if (sqlVdbeRealValue(pMem, &v))
return -1;
-
- pMem->u.r = v;
- MemSetTypeFlag(pMem, MEM_Real);
+ mem_set_double(pMem, v);
return 0;
}
@@ -583,9 +581,10 @@ vdbe_mem_numerify(struct Mem *mem)
if (sql_atoi64(mem->z, &i, &is_neg, mem->n) == 0) {
mem_set_int(mem, i, is_neg);
} else {
- if (sqlAtoF(mem->z, &mem->u.r, mem->n) == 0)
+ double d;
+ if (sqlAtoF(mem->z, &d, mem->n) == 0)
return -1;
- MemSetTypeFlag(mem, MEM_Real);
+ mem_set_double(mem, d);
}
return 0;
}
@@ -839,18 +838,14 @@ mem_set_int(struct Mem *mem, int64_t value, bool is_neg)
}
}
-/*
- * Delete any previous value and set the value stored in *pMem to val,
- * manifest type REAL.
- */
void
-sqlVdbeMemSetDouble(Mem * pMem, double val)
+mem_set_double(struct Mem *mem, double value)
{
- sqlVdbeMemSetNull(pMem);
- if (!sqlIsNaN(val)) {
- pMem->u.r = val;
- pMem->flags = MEM_Real;
- }
+ sqlVdbeMemSetNull(mem);
+ if (sqlIsNaN(value))
+ return;
+ mem->u.r = value;
+ MemSetTypeFlag(mem, MEM_Real);
}
/*
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double() imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-30 11:50 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 3/8] sql: remove mem_apply_type() from OP_MakeRecord imeevma
` (5 subsequent siblings)
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
Hi! Thank you for review. My answers and new patch below. I
haven't included diffs since there were quite a few changes.
I have included answers to review questions in the next three
patches here.
On 22.06.2020 11:23, Nikita Pettik wrote:
> On 17 Jun 15:36, imeevma@tarantool.org wrote:
>> This patch removes implicit cast for assignment, however,
>> it is allowed to implicitly cast DOUBLE to INTEGER and
>> vice versa.
>>
>> Closes #3809
>> ---
>>
>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index 6b769805c..ae2622c9e 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> @@ -418,6 +418,113 @@ sql_value_apply_type(
>> mem_apply_type((Mem *) pVal, type);
>> }
>>
>> +/**
>> + * Check that mem_type of the mem is compatible with given type.
>> + * In the case of numeric values, this function tries to convert
>> + * the mem to the specified type and returns -1 if this is not
>> + * possible.
>> + *
>> + * @param mem The value to check.
>> + * @param type The type to check.
>> + */
>> +static int
>> +mem_check_types(struct Mem *mem, enum field_type type)
>
> I'd rename it to mem_icast_to_type() or mem_impl_cast_to_type()
> or smth like that.
>
I divided into 2 functions: mem_check_type (), which checks, and
mem_convert_numeric(), which converts.
>> +{
>> + if ((mem->flags & MEM_Null) != 0)
>> + return 0;
>> + assert(type < field_type_MAX);
>> + uint32_t flags = mem->flags;
>> + switch (type) {
>
> Instead of such long switch-cases could we organize it in one table
> containing valid conversions? I mean sort of field_mp_type_is_compatible()
> To provide not only check but execution mechanism you can fill
> table with pointers to functions implementing particular casts.
>
Fixed, I think.
>> + case FIELD_TYPE_INTEGER:
>> + if ((flags & (MEM_Int | MEM_UInt)) != 0)
>> + return 0;
>> + if ((flags & MEM_Real) == 0)
>> + return -1;
>> + double d = mem->u.r;
>> + if (d >= (double)UINT64_MAX || d < (double)INT64_MIN)
>> + return -1;
>> + if (d < (double)INT64_MAX) {
>> + int64_t i = (int64_t) d;
>> + if (i == d) {
>> + mem_set_int(mem, i, i <= -1);
>> + return 0;
>> + }
>> + return -1;
>> + }
>> + uint64_t u = (uint64_t) d;
>> + if (u == d) {
>> + mem_set_u64(mem, u);
>> + return 0;
>> + }
>> + return -1;
>> + case FIELD_TYPE_SCALAR:
>> + /* Can't cast MAP and ARRAY to scalar types. */
>
> Except for map and arrays we alread have decimal. IS this function
> able to handle it?
>
We do not have a MEM type corresponding to MP_EXT, so we cannot
get MP_EXT in this function.
>> + if ((flags & MEM_Subtype) == 0 ||
>> + mem->subtype != SQL_SUBTYPE_MSGPACK)
>> + return 0;
>> + assert(mp_typeof(*mem->z) == MP_MAP ||
>> + mp_typeof(*mem->z) == MP_ARRAY);
>> + return -1;
>> @@ -2776,6 +2883,31 @@ case OP_ApplyType: {
>> break;
>> }
>>
>> +/* Opcode: CheckType P1 P2 * P4 *
>
> ApplyType was quite suitable name, meanwhile CheckType is a bit confusing
> since in fact it doesn't only check but cast (apply, coerce or whatever)
> mem to given type.
>
I replaced by ImplicitCast for now.
>> + * Synopsis: type(r[P1@P2])
>> + *
>> + * Check that types of P2 registers starting from register
>> + * P1 are compatible with given with given field types in P4.
>> + */
>> +case OP_CheckType: {
>> + enum field_type *types = pOp->p4.types;
>> + assert(types != NULL);
>> + assert(types[pOp->p2] == field_type_MAX);
>> + pIn1 = &aMem[pOp->p1];
>> + enum field_type type;
>> + while((type = *(types++)) != field_type_MAX) {
>> + assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
>> + assert(memIsValid(pIn1));
>> + if (mem_check_types(pIn1, type) != 0) {
>> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>> + mem_type_to_str(pIn1), field_type_strs[type]);
>> + goto abort_due_to_error;
>> + }
>> + pIn1++;
>> + }
>> + break;
>> +}
>> +
>> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
>> index 8dad2db9a..9e8586ffc 100644
>> --- a/src/box/sql/vdbemem.c
>> +++ b/src/box/sql/vdbemem.c
>> @@ -839,6 +839,13 @@ mem_set_int(struct Mem *mem, int64_t value, bool is_neg)
>> }
>> }
>>
>> +void
>> +mem_set_double(struct Mem *mem, double value)
>> +{
>
> I see inconsistency with other setters: they provide auxiliary
> clean-up in case mem has one of Agg/Dyn/Frame flags. Please
> investigate whether it is really required and if it is so add
> it to current one (or remove from other setters).
>
Fixed in previous commit. In fact, I found that such a function
already exists, so I renamed it and refactored it a bit.
>> + mem->u.r = value;
>> + MemSetTypeFlag(mem, MEM_Real);
>> +}
>> +
>> diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
>> index 37e65e541..ec8dfeab1 100755
>> --- a/test/sql-tap/autoinc.test.lua
>> +++ b/test/sql-tap/autoinc.test.lua
>> @@ -618,7 +618,7 @@ test:do_catchsql_test(
>> INSERT INTO t2 VALUES('asd');
>> ]], {
>> -- <autoinc-10.2>
>> - 1, "Type mismatch: can not convert asd to integer"
>> + 1, "Type mismatch: can not convert text to integer"
>
> Having an opportunity to see which particular value can't be
> converted is quite helpful. Let's leave it.
>
Fixed. Fully fixed in the last commit of the set.
>> @@ -694,7 +694,7 @@ test:do_test(
>> INSERT INTO t3928(b) VALUES('after-int-' || CAST(new.b AS TEXT));
>> END;
>> DELETE FROM t3928 WHERE a!=1;
>> - UPDATE t3928 SET b=456 WHERE a=1;
>> + UPDATE t3928 SET b='456' WHERE a=1;
>> SELECT * FROM t3928 ORDER BY a;
>> ]])
>> end, {
>> diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
>> new file mode 100755
>> index 000000000..de72cf3a4
>> --- /dev/null
>> +++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
>
> It's not regression issue, so you can a) remove gh- prefix;
> b) amalgamate it with another test (e.g. sql/types.test.lua).
> It's up to you tho.
>
>> @@ -0,0 +1,649 @@
>> +#!/usr/bin/env tarantool
>> +test = require("sqltester")
>> +test:plan(77)
>> +
>> +--
>> +-- Make sure there are no implicit casts during assignment,
>> +-- except for the implicit cast between numeric values.
>> +--
>
> Why do you still avoid .sql test format?
>
As far as I know, the TAP format is preferable.
>> +test:execsql([[
>> + CREATE TABLE ti (a INT PRIMARY KEY AUTOINCREMENT, i INTEGER);
>> + CREATE TABLE td (a INT PRIMARY KEY AUTOINCREMENT, d DOUBLE);
>> + CREATE TABLE tb (a INT PRIMARY KEY AUTOINCREMENT, b BOOLEAN);
>> + CREATE TABLE tt (a INT PRIMARY KEY AUTOINCREMENT, t TEXT);
>> + CREATE TABLE tv (a INT PRIMARY KEY AUTOINCREMENT, v VARBINARY);
>> + CREATE TABLE ts (a INT PRIMARY KEY AUTOINCREMENT, s SCALAR);
>> +]])
>> +
>> +test:do_catchsql_test(
>> + "gh-3809-1",
>> + [[
>> + INSERT INTO ti(i) VALUES (11)
>> + ]], {
>> + 0
>> + })
>> +
>> +test:do_catchsql_test(
>> + "gh-3809-2",
>> + [[
>> + INSERT INTO ti(i) VALUES (22.2)
>> + ]], {
>> + 1, "Type mismatch: can not convert real to integer"
>> + })
>> +
>> +test:do_catchsql_test(
>> + "gh-3809-3",
>> + [[
>> + INSERT INTO ti(i) VALUES (33.0)
>
> Should this be valid? Could you please ask Peter to clarify this question?
>
It should, new rules I described in doc request.
>> +test:execsql([[
>> + DELETE FROM ti;
>> + DELETE FROM td;
>> + DELETE FROM tb;
>> + DELETE FROM tt;
>> + DELETE FROM tv;
>> + DELETE FROM ts;
>> + INSERT INTO ti(a) VALUES(1);
>> + INSERT INTO td(a) VALUES(1);
>> + INSERT INTO tb(a) VALUES(1);
>> + INSERT INTO tt(a) VALUES(1);
>> + INSERT INTO tv(a) VALUES(1);
>> + INSERT INTO ts(a) VALUES(1);
>> +]])
>
> Strange turn..Could you please supply each batch of tests with
> brief description?
>
Added a comment here.
>> +test:do_execsql_test(
>> + "gh-3809-39",
>> + [[
>> + SELECT * FROM ti, td, tb, tt, tv, ts;
>> + ]], {
>> + 1, "", 1, "", 1, "", 1, "", 1, "", 1, ""
>> + })
>> diff --git a/test/sql-tap/index1.test.lua b/test/sql-tap/index1.test.lua
>> index e173e685c..ce66b7c1e 100755
>> --- a/test/sql-tap/index1.test.lua
>> +++ b/test/sql-tap/index1.test.lua
>> @@ -593,25 +593,17 @@ test:do_test(
>> -- </index-11.1>
>> })
>> end
>> --- integrity_check index-11.2
>> --- Numeric strings should compare as if they were numbers. So even if the
>> --- strings are not character-by-character the same, if they represent the
>> --- same number they should compare equal to one another. Verify that this
>> --- is true in indices.
>> ---
>> --- Updated for sql v3: sql will now store these values as numbers
>> --- (because the affinity of column a is NUMERIC) so the quirky
>> --- representations are not retained. i.e. '+1.0' becomes '1'.
>> +
>> test:do_execsql_test(
>> "index-12.1",
>> [[
>> CREATE TABLE t4(id INT primary key, a NUMBER,b INT );
>> - INSERT INTO t4 VALUES(1, '0.0',1);
>> - INSERT INTO t4 VALUES(2, '0.00',2);
>> - INSERT INTO t4 VALUES(4, '-1.0',4);
>> - INSERT INTO t4 VALUES(5, '+1.0',5);
>> - INSERT INTO t4 VALUES(6, '0',6);
>> - INSERT INTO t4 VALUES(7, '00000',7);
>> + INSERT INTO t4 VALUES(1, 0.0, 1);
>> + INSERT INTO t4 VALUES(2, 0.00, 2);
>> + INSERT INTO t4 VALUES(4, -1.0, 4);
>> + INSERT INTO t4 VALUES(5, +1.0, 5);
>> + INSERT INTO t4 VALUES(6, 0, 6);
>> + INSERT INTO t4 VALUES(7, 00000, 7);
>> SELECT a FROM t4 ORDER BY b;
>
> Does this test make any sense now?
>
Removed these tests.
>> ]], {
>> -- <index-12.1>
>> @@ -692,7 +684,7 @@ test:do_execsql_test(
>> c TEXT,
>> UNIQUE(a,c)
>> );
>> - INSERT INTO t5 VALUES(1,2,3);
>> + INSERT INTO t5 VALUES(1,2,'3');
>> SELECT * FROM t5;
>> ]], {
>> -- <index-13.1>
>> diff --git a/test/sql-tap/intpkey.test.lua b/test/sql-tap/intpkey.test.lua
>> index b6b186632..0db18ba91 100755
>> --- a/test/sql-tap/intpkey.test.lua
>> +++ b/test/sql-tap/intpkey.test.lua
>> @@ -770,11 +770,6 @@ test:do_execsql_test(
>> -- </intpkey-11.1>
>> })
>>
>> --- integrity_check intpkey-12.1
>> --- Try to use a string that looks like a floating point number as
>> --- an integer primary key. This should actually work when the floating
>> --- point value can be rounded to an integer without loss of data.
>> ---
>
> Ditto
>
Removed these tests.
>> test:do_execsql_test(
>> "intpkey-13.1",
>> [[
>> @@ -788,7 +783,7 @@ test:do_execsql_test(
>> test:do_execsql_test(
>> "intpkey-13.2",
>> [[
>> - INSERT INTO t1 VALUES('1',2,3);
>> + INSERT INTO t1 VALUES(1,'2','3');
>> SELECT * FROM t1 WHERE a=1;
>> ]], {
>> -- <intpkey-13.2>
>> --- a/test/sql-tap/whereB.test.lua
>> +++ b/test/sql-tap/whereB.test.lua
>> @@ -112,24 +112,16 @@ test:do_execsql_test(
>> -- </whereB-1.102>
>> })
>>
>> --- For this set of tests:
>> ---
>> --- * t1.y holds a text value with affinity TEXT
>> --- * t2.b holds an integer value with affinity NONE
>> ---
>> --- These values are not equal and because neither affinity is NUMERIC
>> --- no type conversion occurs.
>> ---
>
> Ditto
>
Removed these tests.
>> test:do_execsql_test(
>> "whereB-2.1",
>> [[
>> DROP TABLE t1;
>> DROP TABLE t2;
>>
>> - CREATE TABLE t1(x INT primary key, y TEXT); -- affinity of t1.y is TEXT
>> - INSERT INTO t1 VALUES(1,99);
>> + CREATE TABLE t1(x INT primary key, y TEXT);
>> + INSERT INTO t1 VALUES(1,'99');
>>
>> - CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
>> + CREATE TABLE t2(a INT primary key, b SCALAR);
>> CREATE INDEX t2b ON t2(b);
>> INSERT INTO t2 VALUES(2, 99);
>>
On 22.06.2020 11:48, Nikita Pettik wrote:
> On 17 Jun 15:36, imeevma@tarantool.org wrote:
>> This patch removes type changing from OP_MakeRecord.
>
> Please reflect user-visible changes in commit message.
>
Fixed.
>> Part of #4230
>> ---
>> src/box/sql/analyze.c | 7 +------
>> src/box/sql/delete.c | 8 ++------
>> src/box/sql/expr.c | 8 +-------
>> src/box/sql/fk_constraint.c | 9 ++-------
>> src/box/sql/select.c | 25 ++++++-------------------
>> src/box/sql/update.c | 14 +++-----------
>> src/box/sql/vdbe.c | 19 +------------------
>> test/sql-tap/in3.test.lua | 4 ++--
>> 8 files changed, 18 insertions(+), 76 deletions(-)
>>
>> diff --git a/test/sql-tap/in3.test.lua b/test/sql-tap/in3.test.lua
>> index e29db9d93..f7681640e 100755
>> --- a/test/sql-tap/in3.test.lua
>> +++ b/test/sql-tap/in3.test.lua
>> @@ -354,7 +354,7 @@ test:do_test(
>> return exec_neph(" SELECT y IN (SELECT a FROM t1) FROM t2 ")
>> end, {
>> -- <in3-3.5>
>> - 1, true
>> + 1, false
>> -- </in3-3.5>
>> })
>>
>> @@ -378,7 +378,7 @@ test:do_test(
>> return exec_neph(" SELECT y IN (SELECT c FROM t1) FROM t2 ")
>> end, {
>> -- <in3-3.7>
>> - 1, true
>> + 1, false
>> -- </in3-3.7>
>> })
>>
>> --
>> 2.25.1
>>
On 22.06.2020 12:32, Nikita Pettik wrote:
> On 17 Jun 15:36, imeevma@tarantool.org wrote:
>> This patch removes implicit cast from STRING to numeric
>> and vice versa of left operand of IN operator.
>>
>> Part of #4230
>> Part of #4692
>> ---
>> src/box/sql/expr.c | 2 +-
>> test/sql-tap/in3.test.lua | 14 +-----
>> test/sql-tap/subquery.test.lua | 69 +---------------------------
>> test/sql-tap/tkt-80e031a00f.test.lua | 4 +-
>> test/sql/boolean.result | 12 ++---
>> 5 files changed, 11 insertions(+), 90 deletions(-)
>>
>> diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
>> index a0e6539e0..c883937ca 100755
>> --- a/test/sql-tap/tkt-80e031a00f.test.lua
>> +++ b/test/sql-tap/tkt-80e031a00f.test.lua
>> @@ -346,7 +346,7 @@ test:do_catchsql_test(
>> SELECT 'hello' IN t1
>> ]], {
>> -- <tkt-80e031a00f.27>
>> - 1, 'Type mismatch: can not convert hello to integer'
>> + 1, 'Type mismatch: can not convert text to integer'
>> -- </tkt-80e031a00f.27>
>> })
>>
>> @@ -356,7 +356,7 @@ test:do_catchsql_test(
>> SELECT 'hello' NOT IN t1
>> ]], {
>> -- <tkt-80e031a00f.28>
>> - 1, 'Type mismatch: can not convert hello to integer'
>> + 1, 'Type mismatch: can not convert text to integer'
>> -- </tkt-80e031a00f.28>
>> })
>
> Again, old format of error message containing value which
> can't be converted seems more suitable to me. Mb it is worth
> combining them putting in error message both type and value:
>
> ... convert 'hello' (type : text) to integer
>
Fixed in the last patch of the set.
> Otherwise LGTM
>
>> diff --git a/test/sql/boolean.result b/test/sql/boolean.result
>> index e88183854..c74713c34 100644
>> --- a/test/sql/boolean.result
>> +++ b/test/sql/boolean.result
>> @@ -3877,12 +3877,12 @@ SELECT false IN (0, 1, 2, 3);
>> SELECT true IN (SELECT b FROM t7);
>> | ---
>> | - null
>> - | - 'Type mismatch: can not convert TRUE to integer'
>> + | - 'Type mismatch: can not convert boolean to integer'
>> | ...
On 22.06.2020 13:07, Nikita Pettik wrote:
> On 17 Jun 15:36, imeevma@tarantool.org wrote:
>> This patch replaces mem_apply_type() with mem_check_types() in
>> OP_MustBeInt, which allows to remove implicit cast in some places,
>> for example, in the IN statement.
>>
>> Part of #4230
>> ---
>> src/box/sql/vdbe.c | 2 +-
>> test/sql-tap/e_select1.test.lua | 17 +-
>> test/sql-tap/in4.test.lua | 97 +--
>> test/sql-tap/join.test.lua | 1 -
>> test/sql-tap/limit.test.lua | 2 +-
>> test/sql-tap/tkt-9a8b09f8e6.test.lua | 24 +-
>> test/sql-tap/tkt-fc7bd6358f.test.lua | 111 ----
>> test/sql-tap/transitive1.test.lua | 4 +-
>> test/sql-tap/whereB.test.lua | 900 ---------------------------
>> test/sql-tap/whereC.test.lua | 8 +-
>> 10 files changed, 19 insertions(+), 1147 deletions(-)
>> delete mode 100755 test/sql-tap/tkt-fc7bd6358f.test.lua
>> delete mode 100755 test/sql-tap/whereB.test.lua
>>
>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index eb5c89e9d..77b758833 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> @@ -2096,7 +2096,7 @@ case OP_AddImm: { /* in1 */
>> case OP_MustBeInt: { /* jump, in1 */
>> pIn1 = &aMem[pOp->p1];
>> if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
>> - mem_apply_type(pIn1, FIELD_TYPE_INTEGER);
>> + mem_check_types(pIn1, FIELD_TYPE_INTEGER);
>> if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
>> if (pOp->p2==0) {
>> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>
> Have the code coverage changed after these patches?
> I'm wondering since a lot of tests are removed now (I believe
> due to redundancy, so in perfect case coverage may even increase).
>
The coverage of src/box/sql/* has not changed according to
coverall.io:
https://coveralls.io/builds/31683427
>> index 7673426f4..578620fca 100755
>> --- a/test/sql-tap/e_select1.test.lua
>> +++ b/test/sql-tap/e_select1.test.lua
>> @@ -1,6 +1,6 @@
>> #!/usr/bin/env tarantool
>> test = require("sqltester")
>> -test:plan(510)
>> +test:plan(509)
>>
New patch:
commit 21d7145c1929bc4606c56e9a566477f248637ed1
Author: Mergen Imeev <imeevma@gmail.com>
Date: Wed May 27 13:49:11 2020 +0300
sql: change implicit cast for assignment
This patch changes implicit cast for assignment.
Closes #3809
@TarantoolBot document
Title: change implicit cast for comparison
After this patch, these rules will apply during the implicit cast:
| | STRING | BINARY | BOOLEAN | INTEGER | UNSIGNED | DOUBLE |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
| STRING | A | N | N | N | N | N |
| BINARY | N | A | N | N | N | N |
| BOOLEAN | N | N | A | N | N | N |
| INTEGER | N | N | N | A | S | Aa |
| UNSIGNED | N | N | N | A | A | Aa |
| DOUBLE | N | N | N | Sa | Sa | A |
In this table, the types of the assigned value are on the left,
and the types that should be after the assignment are at the top.
'A' - the assignment will be completed.
'N' - the assignment won't be completed.
'S' - the appointment may be unsuccessful.
'a' - after assignment, the resulting value may be approximated.
Rules for numeric values are these:
1) Loss of significant digits (overflow) is an error.
2) Loss of insignificant digits is not an error.
Example:
```
tarantool> box.execute([[CREATE TABLE t1(i INT PRIMARY KEY);]])
tarantool> box.execute([[INSERT INTO t1 VALUES ('1');]])
---
- null
- 'Type mismatch: can not convert 1 to integer'
...
tarantool> box.execute('INSERT INTO t1 VALUES (1.2345);')
tarantool> box.execute('SELECT * FROM t1;')
---
- metadata:
- name: I
type: integer
rows:
- [1]
...
tarantool> box.execute([[CREATE TABLE t2(t text PRIMARY KEY);]])
tarantool> box.execute([[INSERT INTO t2 VALUES (1);]])
---
- null
- 'Type mismatch: can not convert 1 to string'
...
```
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 588e142d2..8a89f9904 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -69,7 +69,7 @@ sql_emit_table_types(struct Vdbe *v, struct space_def *def, int reg)
for (uint32_t i = 0; i < field_count; ++i)
colls_type[i] = def->fields[i].type;
colls_type[field_count] = field_type_MAX;
- sqlVdbeAddOp4(v, OP_ApplyType, reg, field_count, 0,
+ sqlVdbeAddOp4(v, OP_ImplicitCast, reg, field_count, 0,
(char *)colls_type, P4_DYNAMIC);
}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 37283e506..f1d0345f9 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
enum mp_type
sql_value_type(sql_value *);
+/*
+ * Return the MP_type of the value of the MEM.
+ *
+ * @param mem MEM with the correct MEM_type.
+ * @retval MP_type of the value.
+ */
+enum mp_type
+sql_value_mp_type(struct Mem *mem);
+
static inline bool
sql_value_is_null(sql_value *value)
{
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 950f72ddd..009d577d2 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -417,6 +417,143 @@ sql_value_apply_type(
mem_apply_type((Mem *) pVal, type);
}
+/**
+ * Check that MEM_type of the mem is compatible with given type.
+ *
+ * @param mem The MEM that contains the value to check.
+ * @param type The type to check.
+ * @retval 0 if the MEM_type of the value and the given type are
+ * compatible, -1 otherwise.
+ */
+static int
+mem_check_type(struct Mem *mem, enum field_type type)
+{
+ enum mp_type mp_type = sql_value_mp_type(mem);
+ assert(mp_type < MP_EXT);
+ if (field_mp_plain_type_is_compatible(type, mp_type, true))
+ return 0;
+ return -1;
+}
+
+/**
+ * Convert the numeric value contained in MEM to double. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_double(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
+ return -1;
+ if ((mem->flags & MEM_Int) != 0) {
+ int64_t i = mem->u.i;
+ double d = (double)i;
+ if (!is_precise || i == (int64_t)d)
+ mem_set_double(mem, d);
+ else
+ return -1;
+ } else {
+ uint64_t u = mem->u.u;
+ double d = (double)u;
+ if (!is_precise || u == (uint64_t)d)
+ mem_set_double(mem, d);
+ else
+ return -1;
+ }
+ mem->field_type = FIELD_TYPE_DOUBLE;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to unsigned. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_unsigned(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & MEM_Real) == 0)
+ return -1;
+ double d = mem->u.r;
+ if (d < 0.0 || d >= (double)UINT64_MAX)
+ return -1;
+ uint64_t u = (uint64_t)d;
+ if (!is_precise || d == (double)u)
+ mem_set_u64(mem, (uint64_t) d);
+ else
+ return -1;
+ mem->field_type = FIELD_TYPE_UNSIGNED;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to integer. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_integer(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & MEM_Real) == 0)
+ return -1;
+ double d = mem->u.r;
+ if (d >= (double)UINT64_MAX || d < (double)INT64_MIN)
+ return -1;
+ if (d < (double)INT64_MAX) {
+ int64_t i = (int64_t)d;
+ if (!is_precise || d == (double)i)
+ mem_set_i64(mem, (int64_t) d);
+ else
+ return -1;
+ } else {
+ uint64_t u = (uint64_t)d;
+ if (!is_precise || d == (double)u)
+ mem_set_u64(mem, (uint64_t) d);
+ else
+ return -1;
+ }
+ mem->field_type = FIELD_TYPE_INTEGER;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to another numeric
+ * type. If the is_precise flag is set, the conversion will
+ * succeed only if it is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param type The type to convert to.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_numeric(struct Mem *mem, enum field_type type, bool is_precise)
+{
+ if (!sql_type_is_numeric(type) ||
+ (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
+ return -1;
+ if (type == FIELD_TYPE_NUMBER)
+ return 0;
+ if (type == FIELD_TYPE_DOUBLE)
+ return mem_convert_to_double(mem, is_precise);
+ if (type == FIELD_TYPE_UNSIGNED)
+ return mem_convert_to_unsigned(mem, is_precise);
+ assert(type == FIELD_TYPE_INTEGER);
+ return mem_convert_to_integer(mem, is_precise);
+}
+
/*
* pMem currently only holds a string type (or maybe a BLOB that we can
* interpret as a string if we want to). Compute its corresponding
@@ -2773,6 +2910,36 @@ case OP_ApplyType: {
break;
}
+/* Opcode: CheckType P1 P2 * P4 *
+ * Synopsis: type(r[P1@P2])
+ *
+ * Check that types of P2 registers starting from register
+ * P1 are compatible with given with given field types in P4.
+ * If the MEM_type of the value and the given type are
+ * incompatible, but both are numeric, this opcode attempts to
+ * convert the value to the type.
+ */
+case OP_ImplicitCast: {
+ enum field_type *types = pOp->p4.types;
+ assert(types != NULL);
+ assert(types[pOp->p2] == field_type_MAX);
+ pIn1 = &aMem[pOp->p1];
+ enum field_type type;
+ while((type = *(types++)) != field_type_MAX) {
+ assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
+ assert(memIsValid(pIn1));
+ if (mem_check_type(pIn1, type) != 0 &&
+ mem_convert_numeric(pIn1, type, false) != 0) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1),
+ field_type_strs[type]);
+ goto abort_due_to_error;
+ }
+ pIn1++;
+ }
+ break;
+}
+
/* Opcode: MakeRecord P1 P2 P3 P4 P5
* Synopsis: r[P3]=mkrec(r[P1@P2])
*
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 4e103a653..087c661ec 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -225,6 +225,33 @@ sql_value_type(sql_value *pVal)
}
}
+enum mp_type
+sql_value_mp_type(struct Mem *mem)
+{
+ switch (mem->flags & MEM_PURE_TYPE_MASK) {
+ case MEM_Int:
+ return MP_INT;
+ case MEM_UInt:
+ return MP_UINT;
+ case MEM_Real:
+ return MP_DOUBLE;
+ case MEM_Str:
+ return MP_STR;
+ case MEM_Blob:
+ if ((mem->flags & MEM_Subtype) == 0 ||
+ mem->subtype != SQL_SUBTYPE_MSGPACK)
+ return MP_BIN;
+ assert(mp_typeof(*mem->z) == MP_MAP ||
+ mp_typeof(*mem->z) == MP_ARRAY);
+ return mp_typeof(*mem->z);
+ case MEM_Bool:
+ return MP_BOOL;
+ case MEM_Null:
+ return MP_NIL;
+ default: unreachable();
+ }
+}
+
/* Make a copy of an sql_value object
*/
sql_value *
diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
index 37e65e541..07442b60a 100755
--- a/test/sql-tap/autoinc.test.lua
+++ b/test/sql-tap/autoinc.test.lua
@@ -694,7 +694,7 @@ test:do_test(
INSERT INTO t3928(b) VALUES('after-int-' || CAST(new.b AS TEXT));
END;
DELETE FROM t3928 WHERE a!=1;
- UPDATE t3928 SET b=456 WHERE a=1;
+ UPDATE t3928 SET b='456' WHERE a=1;
SELECT * FROM t3928 ORDER BY a;
]])
end, {
diff --git a/test/sql-tap/default.test.lua b/test/sql-tap/default.test.lua
index d3e35c71c..f1def2b10 100755
--- a/test/sql-tap/default.test.lua
+++ b/test/sql-tap/default.test.lua
@@ -109,16 +109,12 @@ test:do_execsql_test(
f VARCHAR(15), --COLLATE RTRIM,
g INTEGER DEFAULT( 3600*12 )
);
- INSERT INTO t3 VALUES(null, 5, 'row1', 5.25, 8.67, 321, 432);
+ INSERT INTO t3 VALUES(null, 5, 'row1', 5.25, 8.67, '321', 432);
SELECT a, typeof(a), b, typeof(b), c, typeof(c),
d, typeof(d), e, typeof(e), f, typeof(f),
g, typeof(g) FROM t3;
]], {
-- <default-3.1>
- -- TODO: In original test "321" is not a string, its a value.
- -- In current situation I don't know what to do, need Kirill's
- -- advice.
- -- Bulat
1, "integer", 5, "integer", "row1", "string", 5.25, "number", 8.67, "number", "321", "string", 432, "integer"
-- </default-3.1>
})
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index 1d3b964b9..7673426f4 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -753,11 +753,11 @@ test:do_execsql_test(
CREATE TABLE z3(id INT primary key, a NUMBER, b NUMBER);
INSERT INTO z1 VALUES(1, 51.65, -59.58, 'belfries');
- INSERT INTO z1 VALUES(2, -5, NULL, 75);
+ INSERT INTO z1 VALUES(2, -5, NULL, '75');
INSERT INTO z1 VALUES(3, -2.2, -23.18, 'suiters');
INSERT INTO z1 VALUES(4, NULL, 67, 'quartets');
INSERT INTO z1 VALUES(5, -1.04, -32.3, 'aspen');
- INSERT INTO z1 VALUES(6, 63, '0', -26);
+ INSERT INTO z1 VALUES(6, 63, 0, '-26');
INSERT INTO z2 VALUES(1, NULL, 21);
INSERT INTO z2 VALUES(2, 36.0, 6.0);
@@ -1457,13 +1457,13 @@ test:do_execsql_test(
CREATE TABLE q2(id INT primary key, d TEXT, e NUMBER);
CREATE TABLE q3(id INT primary key, f TEXT, g INT);
- INSERT INTO q1 VALUES(1, 16, -87.66, NULL);
+ INSERT INTO q1 VALUES(1, '16', -87.66, NULL);
INSERT INTO q1 VALUES(2, 'legible', 94, -42.47);
INSERT INTO q1 VALUES(3, 'beauty', 36, NULL);
INSERT INTO q2 VALUES(1, 'legible', 1);
INSERT INTO q2 VALUES(2, 'beauty', 2);
- INSERT INTO q2 VALUES(3, -65, 4);
+ INSERT INTO q2 VALUES(3, '-65', 4);
INSERT INTO q2 VALUES(4, 'emanating', -16.56);
INSERT INTO q3 VALUES(1, 'beauty', 2);
@@ -1603,7 +1603,7 @@ test:do_execsql_test(
CREATE TABLE w2(a INT PRIMARY KEY, b TEXT);
INSERT INTO w1 VALUES('1', 4.1);
- INSERT INTO w2 VALUES(1, 4.1);
+ INSERT INTO w2 VALUES(1, '4.1');
]], {
-- <e_select-7.10.0>
diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
new file mode 100755
index 000000000..a1809b3cb
--- /dev/null
+++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
@@ -0,0 +1,653 @@
+#!/usr/bin/env tarantool
+test = require("sqltester")
+test:plan(77)
+
+--
+-- Make sure there are no implicit casts during assignment,
+-- except for the implicit cast between numeric values.
+--
+test:execsql([[
+ CREATE TABLE ti (a INT PRIMARY KEY AUTOINCREMENT, i INTEGER);
+ CREATE TABLE td (a INT PRIMARY KEY AUTOINCREMENT, d DOUBLE);
+ CREATE TABLE tb (a INT PRIMARY KEY AUTOINCREMENT, b BOOLEAN);
+ CREATE TABLE tt (a INT PRIMARY KEY AUTOINCREMENT, t TEXT);
+ CREATE TABLE tv (a INT PRIMARY KEY AUTOINCREMENT, v VARBINARY);
+ CREATE TABLE ts (a INT PRIMARY KEY AUTOINCREMENT, s SCALAR);
+]])
+
+test:do_catchsql_test(
+ "gh-3809-1",
+ [[
+ INSERT INTO ti(i) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-2",
+ [[
+ INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
+ ]], {
+ 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-3",
+ [[
+ INSERT INTO ti(i) VALUES (33.0)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-4",
+ [[
+ INSERT INTO ti(i) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-5",
+ [[
+ INSERT INTO ti(i) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-6",
+ [[
+ INSERT INTO ti(i) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to integer"
+ })
+
+test:do_execsql_test(
+ "gh-3809-7",
+ [[
+ SELECT * FROM ti;
+ ]], {
+ 1, 11, 2, 33
+ })
+
+test:do_catchsql_test(
+ "gh-3809-8",
+ [[
+ INSERT INTO td(d) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-9",
+ [[
+ INSERT INTO td(d) VALUES (100000000000000001);
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-10",
+ [[
+ INSERT INTO td(d) VALUES (22.2)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-11",
+ [[
+ INSERT INTO td(d) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-12",
+ [[
+ INSERT INTO td(d) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-13",
+ [[
+ INSERT INTO td(d) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to double"
+ })
+
+test:do_execsql_test(
+ "gh-3809-14",
+ [[
+ SELECT * FROM td;
+ ]], {
+ 1, 11, 2, 100000000000000000, 3, 22.2
+ })
+
+test:do_catchsql_test(
+ "gh-3809-15",
+ [[
+ INSERT INTO tb(b) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-16",
+ [[
+ INSERT INTO tb(b) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-17",
+ [[
+ INSERT INTO tb(b) VALUES (true)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-18",
+ [[
+ INSERT INTO tb(b) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-19",
+ [[
+ INSERT INTO tb(b) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to boolean"
+ })
+
+test:do_execsql_test(
+ "gh-3809-20",
+ [[
+ SELECT * FROM tb;
+ ]], {
+ 1, true
+ })
+
+test:do_catchsql_test(
+ "gh-3809-21",
+ [[
+ INSERT INTO tt(t) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-22",
+ [[
+ INSERT INTO tt(t) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-23",
+ [[
+ INSERT INTO tt(t) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-24",
+ [[
+ INSERT INTO tt(t) VALUES ('33')
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-25",
+ [[
+ INSERT INTO tt(t) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to string"
+ })
+
+test:do_execsql_test(
+ "gh-3809-26",
+ [[
+ SELECT * FROM tt;
+ ]], {
+ 1, "33"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-27",
+ [[
+ INSERT INTO tv(v) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-28",
+ [[
+ INSERT INTO tv(v) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-29",
+ [[
+ INSERT INTO tv(v) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-30",
+ [[
+ INSERT INTO tv(v) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-31",
+ [[
+ INSERT INTO tv(v) VALUES (X'3434')
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-32",
+ [[
+ SELECT * FROM tv;
+ ]], {
+ 1, "44"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-33",
+ [[
+ INSERT INTO ts(s) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-34",
+ [[
+ INSERT INTO ts(s) VALUES (22.2)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-35",
+ [[
+ INSERT INTO ts(s) VALUES (true)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-36",
+ [[
+ INSERT INTO ts(s) VALUES ('33')
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-37",
+ [[
+ INSERT INTO ts(s) VALUES (X'3434')
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-38",
+ [[
+ SELECT * FROM ts;
+ ]], {
+ 1, 11, 2, 22.2, 3, true, 4, "33", 5, "44"
+ })
+
+--
+-- This test suite verifies that ASSIGNMENT is working correctly
+-- during an UPDATE.
+--
+test:execsql([[
+ DELETE FROM ti;
+ DELETE FROM td;
+ DELETE FROM tb;
+ DELETE FROM tt;
+ DELETE FROM tv;
+ DELETE FROM ts;
+ INSERT INTO ti(a) VALUES(1);
+ INSERT INTO td(a) VALUES(1);
+ INSERT INTO tb(a) VALUES(1);
+ INSERT INTO tt(a) VALUES(1);
+ INSERT INTO tv(a) VALUES(1);
+ INSERT INTO ts(a) VALUES(1);
+]])
+
+test:do_execsql_test(
+ "gh-3809-39",
+ [[
+ SELECT * FROM ti, td, tb, tt, tv, ts;
+ ]], {
+ 1, "", 1, "", 1, "", 1, "", 1, "", 1, ""
+ })
+
+test:do_catchsql_test(
+ "gh-3809-40",
+ [[
+ UPDATE ti SET i = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-41",
+ [[
+ UPDATE ti SET i = 100000000000000000000000000000000.1 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-42",
+ [[
+ UPDATE ti SET i = 33.0 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-43",
+ [[
+ UPDATE ti SET i = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-44",
+ [[
+ UPDATE ti SET i = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-45",
+ [[
+ UPDATE ti SET i = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to integer"
+ })
+
+test:do_execsql_test(
+ "gh-3809-46",
+ [[
+ SELECT * FROM ti;
+ ]], {
+ 1, 33
+ })
+
+test:do_catchsql_test(
+ "gh-3809-47",
+ [[
+ UPDATE td SET d = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-48",
+ [[
+ UPDATE td SET d = 100000000000000001 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-49",
+ [[
+ UPDATE td SET d = 22.2 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-50",
+ [[
+ UPDATE td SET d = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-51",
+ [[
+ UPDATE td SET d = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-52",
+ [[
+ UPDATE td SET d = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to double"
+ })
+
+test:do_execsql_test(
+ "gh-3809-53",
+ [[
+ SELECT * FROM td;
+ ]], {
+ 1, 22.2
+ })
+
+test:do_catchsql_test(
+ "gh-3809-54",
+ [[
+ UPDATE tb SET b = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-55",
+ [[
+ UPDATE tb SET b = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-56",
+ [[
+ UPDATE tb SET b = true WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-57",
+ [[
+ UPDATE tb SET b = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-58",
+ [[
+ UPDATE tb SET b = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to boolean"
+ })
+
+test:do_execsql_test(
+ "gh-3809-59",
+ [[
+ SELECT * FROM tb;
+ ]], {
+ 1, true
+ })
+
+test:do_catchsql_test(
+ "gh-3809-60",
+ [[
+ UPDATE tt SET t = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-61",
+ [[
+ UPDATE tt SET t = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-62",
+ [[
+ UPDATE tt SET t = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-63",
+ [[
+ UPDATE tt SET t = '33' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-64",
+ [[
+ UPDATE tt SET t = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to string"
+ })
+
+test:do_execsql_test(
+ "gh-3809-65",
+ [[
+ SELECT * FROM tt;
+ ]], {
+ 1, "33"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-66",
+ [[
+ UPDATE tv SET v = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-67",
+ [[
+ UPDATE tv SET v = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-68",
+ [[
+ UPDATE tv SET v = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-69",
+ [[
+ UPDATE tv SET v = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-70",
+ [[
+ UPDATE tv SET v = X'3434' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-71",
+ [[
+ SELECT * FROM tv;
+ ]], {
+ 1, "44"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-72",
+ [[
+ UPDATE ts SET s = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-73",
+ [[
+ UPDATE ts SET s = 22.2 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-74",
+ [[
+ UPDATE ts SET s = true WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-75",
+ [[
+ UPDATE ts SET s = '33' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-76",
+ [[
+ UPDATE ts SET s = X'3434' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-77",
+ [[
+ SELECT * FROM ts;
+ ]], {
+ 1, "44"
+ })
+
+test:finish_test()
diff --git a/test/sql-tap/index1.test.lua b/test/sql-tap/index1.test.lua
index e173e685c..ce66b7c1e 100755
--- a/test/sql-tap/index1.test.lua
+++ b/test/sql-tap/index1.test.lua
@@ -593,25 +593,17 @@ test:do_test(
-- </index-11.1>
})
end
--- integrity_check index-11.2
--- Numeric strings should compare as if they were numbers. So even if the
--- strings are not character-by-character the same, if they represent the
--- same number they should compare equal to one another. Verify that this
--- is true in indices.
---
--- Updated for sql v3: sql will now store these values as numbers
--- (because the affinity of column a is NUMERIC) so the quirky
--- representations are not retained. i.e. '+1.0' becomes '1'.
+
test:do_execsql_test(
"index-12.1",
[[
CREATE TABLE t4(id INT primary key, a NUMBER,b INT );
- INSERT INTO t4 VALUES(1, '0.0',1);
- INSERT INTO t4 VALUES(2, '0.00',2);
- INSERT INTO t4 VALUES(4, '-1.0',4);
- INSERT INTO t4 VALUES(5, '+1.0',5);
- INSERT INTO t4 VALUES(6, '0',6);
- INSERT INTO t4 VALUES(7, '00000',7);
+ INSERT INTO t4 VALUES(1, 0.0, 1);
+ INSERT INTO t4 VALUES(2, 0.00, 2);
+ INSERT INTO t4 VALUES(4, -1.0, 4);
+ INSERT INTO t4 VALUES(5, +1.0, 5);
+ INSERT INTO t4 VALUES(6, 0, 6);
+ INSERT INTO t4 VALUES(7, 00000, 7);
SELECT a FROM t4 ORDER BY b;
]], {
-- <index-12.1>
@@ -692,7 +684,7 @@ test:do_execsql_test(
c TEXT,
UNIQUE(a,c)
);
- INSERT INTO t5 VALUES(1,2,3);
+ INSERT INTO t5 VALUES(1,2,'3');
SELECT * FROM t5;
]], {
-- <index-13.1>
diff --git a/test/sql-tap/insert3.test.lua b/test/sql-tap/insert3.test.lua
index 43bb06630..b92bc508e 100755
--- a/test/sql-tap/insert3.test.lua
+++ b/test/sql-tap/insert3.test.lua
@@ -60,7 +60,7 @@ test:do_execsql_test(
CREATE TABLE log2(rowid INTEGER PRIMARY KEY AUTOINCREMENT, x TEXT UNIQUE,y INT );
CREATE TRIGGER r2 BEFORE INSERT ON t1 FOR EACH ROW BEGIN
UPDATE log2 SET y=y+1 WHERE x=new.b;
- INSERT OR IGNORE INTO log2(x, y) VALUES(new.b,1);
+ INSERT OR IGNORE INTO log2(x, y) VALUES(CAST(new.b AS STRING),1);
END;
INSERT INTO t1(a, b) VALUES('hi', 453);
SELECT x,y FROM log ORDER BY x;
@@ -129,8 +129,8 @@ test:do_execsql_test(
INSERT INTO t2dup(a,b,c) VALUES(new.a,new.b,new.c);
END;
INSERT INTO t2(a) VALUES(123);
- INSERT INTO t2(b) VALUES(234);
- INSERT INTO t2(c) VALUES(345);
+ INSERT INTO t2(b) VALUES('234');
+ INSERT INTO t2(c) VALUES('345');
SELECT * FROM t2dup;
]], {
-- <insert3-2.1>
@@ -143,8 +143,8 @@ test:do_execsql_test(
[[
DELETE FROM t2dup;
INSERT INTO t2(a) SELECT 1 FROM t1 LIMIT 1;
- INSERT INTO t2(b) SELECT 987 FROM t1 LIMIT 1;
- INSERT INTO t2(c) SELECT 876 FROM t1 LIMIT 1;
+ INSERT INTO t2(b) SELECT '987' FROM t1 LIMIT 1;
+ INSERT INTO t2(c) SELECT '876' FROM t1 LIMIT 1;
SELECT * FROM t2dup;
]], {
-- <insert3-2.2>
diff --git a/test/sql-tap/intpkey.test.lua b/test/sql-tap/intpkey.test.lua
index b6b186632..684a24114 100755
--- a/test/sql-tap/intpkey.test.lua
+++ b/test/sql-tap/intpkey.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(40)
+test:plan(31)
--!./tcltestrunner.lua
-- 2001 September 15
@@ -770,142 +770,13 @@ test:do_execsql_test(
-- </intpkey-11.1>
})
--- integrity_check intpkey-12.1
--- Try to use a string that looks like a floating point number as
--- an integer primary key. This should actually work when the floating
--- point value can be rounded to an integer without loss of data.
---
-test:do_execsql_test(
- "intpkey-13.1",
- [[
- SELECT * FROM t1 WHERE a=1;
- ]], {
- -- <intpkey-13.1>
-
- -- </intpkey-13.1>
- })
-
-test:do_execsql_test(
- "intpkey-13.2",
- [[
- INSERT INTO t1 VALUES('1',2,3);
- SELECT * FROM t1 WHERE a=1;
- ]], {
- -- <intpkey-13.2>
- 1, "2", "3"
- -- </intpkey-13.2>
- })
-
--- MUST_WORK_TEST
-if (0 > 0) then
- -- Tarantool: issue submitted #2315
- test:do_catchsql_test(
- "intpkey-13.3",
- [[
- INSERT INTO t1 VALUES('1.5',3,4);
- ]], {
- -- <intpkey-13.3>
- 1, "datatype mismatch"
- -- </intpkey-13.3>
- })
-
- test:do_catchsql_test(
- "intpkey-13.4",
- [[
- INSERT INTO t1 VALUES(x'123456',3,4);
- ]], {
- -- <intpkey-13.4>
- 1, "datatype mismatch"
- -- </intpkey-13.4>
- })
-
-
-
-end
-test:do_catchsql_test(
- "intpkey-13.5",
- [[
- INSERT INTO t1 VALUES('+1234567890',3,4);
- ]], {
- -- <intpkey-13.5>
- 0
- -- </intpkey-13.5>
- })
-
--- Compare an INTEGER PRIMARY KEY against a TEXT expression. The INTEGER
--- affinity should be applied to the text value before the comparison
--- takes place.
---
-test:do_execsql_test(
- "intpkey-14.1",
- [[
- CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT);
- INSERT INTO t3 VALUES(1, 1, 'one');
- INSERT INTO t3 VALUES(2, 2, '2');
- INSERT INTO t3 VALUES(3, 3, 3);
- ]], {
- -- <intpkey-14.1>
-
- -- </intpkey-14.1>
- })
-
-test:do_execsql_test(
- "intpkey-14.2",
- [[
- SELECT * FROM t3 WHERE a>2;
- ]], {
- -- <intpkey-14.2>
- 3, 3, "3"
- -- </intpkey-14.2>
- })
-
-test:do_execsql_test(
- "intpkey-14.3",
- [[
- SELECT * FROM t3 WHERE a>'2';
- ]], {
- -- <intpkey-14.3>
- 3, 3, "3"
- -- </intpkey-14.3>
- })
-
-test:do_execsql_test(
- "intpkey-14.4",
- [[
- SELECT * FROM t3 WHERE a<'2';
- ]], {
- -- <intpkey-14.4>
- 1, 1, "one"
- -- </intpkey-14.4>
- })
-
-test:do_execsql_test(
- "intpkey-14.5",
- [[
- SELECT * FROM t3 WHERE a<c;
- ]], {
- -- <intpkey-14.5>
- 1, 1, "one"
- -- </intpkey-14.5>
- })
-
-test:do_execsql_test(
- "intpkey-14.6",
- [[
- SELECT * FROM t3 WHERE a=c;
- ]], {
- -- <intpkey-14.6>
- 2, 2, "2", 3, 3, "3"
- -- </intpkey-14.6>
- })
-
-- Check for proper handling of primary keys greater than 2^31.
-- Ticket #1188
--
test:do_execsql_test(
"intpkey-15.1",
[[
- INSERT INTO t1 VALUES(2147483647, 'big-1', 123);
+ INSERT INTO t1 VALUES(2147483647, 'big-1', '123');
SELECT * FROM t1 WHERE a>2147483648;
]], {
-- <intpkey-15.1>
diff --git a/test/sql-tap/minmax2.test.lua b/test/sql-tap/minmax2.test.lua
index 0e0f0d08e..707d1c4da 100755
--- a/test/sql-tap/minmax2.test.lua
+++ b/test/sql-tap/minmax2.test.lua
@@ -441,9 +441,9 @@ test:do_execsql_test(
"minmax2-8.2",
[[
CREATE TABLE t5(a INTEGER PRIMARY KEY);
- INSERT INTO t5 VALUES('1234');
- INSERT INTO t5 VALUES('234');
- INSERT INTO t5 VALUES('34');
+ INSERT INTO t5 VALUES(1234);
+ INSERT INTO t5 VALUES(234);
+ INSERT INTO t5 VALUES(34);
SELECT min(a), max(a) FROM t5;
]], {
-- <minmax2-8.2>
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index 32f38cc97..e0fe50bbe 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -34,9 +34,9 @@ test:do_test(
end
cmd = cmd .. ")"
test:execsql(cmd)
- cmd = "INSERT INTO manycol VALUES(1, 0"
+ cmd = "INSERT INTO manycol VALUES(1, '0'"
for i = 1, 99, 1 do
- cmd = cmd .. ","..i..""
+ cmd = cmd .. ",'"..i.."'"
end
cmd = cmd .. ")"
test:execsql(cmd)
@@ -61,9 +61,9 @@ test:do_test(
"misc1-1.3.1",
function()
for j = 100, 1000, 100 do
- local cmd = string.format("INSERT INTO manycol VALUES(%s, %s", j, j)
+ local cmd = string.format("INSERT INTO manycol VALUES(%s, '%s'", j, j)
for i = 1, 99, 1 do
- cmd = cmd .. ","..(i + j)..""
+ cmd = cmd .. ",'"..(i + j).."'"
end
cmd = cmd .. ")"
test:execsql(cmd)
@@ -178,12 +178,12 @@ test:do_test(
test:execsql([[
CREATE TABLE agger(one text primary key, two text, three text, four text);
START TRANSACTION;
- INSERT INTO agger VALUES(1, 'one', 'hello', 'yes');
- INSERT INTO agger VALUES(2, 'two', 'howdy', 'no');
- INSERT INTO agger VALUES(3, 'thr', 'howareya', 'yes');
- INSERT INTO agger VALUES(4, 'two', 'lothere', 'yes');
- INSERT INTO agger VALUES(5, 'one', 'atcha', 'yes');
- INSERT INTO agger VALUES(6, 'two', 'hello', 'no');
+ INSERT INTO agger VALUES('1', 'one', 'hello', 'yes');
+ INSERT INTO agger VALUES('2', 'two', 'howdy', 'no');
+ INSERT INTO agger VALUES('3', 'thr', 'howareya', 'yes');
+ INSERT INTO agger VALUES('4', 'two', 'lothere', 'yes');
+ INSERT INTO agger VALUES('5', 'one', 'atcha', 'yes');
+ INSERT INTO agger VALUES('6', 'two', 'hello', 'no');
COMMIT
]])
return test:execsql("SELECT count(*) FROM agger")
@@ -531,7 +531,7 @@ test:do_test(
"misc1-10.7",
function()
where = string.gsub(where, "x0=0", "x0=100")
- return test:catchsql("UPDATE manycol SET x1=x1+1 "..where.."")
+ return test:catchsql("UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where.."")
end, {
-- <misc1-10.7>
0
@@ -553,7 +553,7 @@ test:do_execsql_test(
-- } {0 {}}
test:do_execsql_test(
"misc1-10.9",
- "UPDATE manycol SET x1=x1+1 "..where
+ "UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where
--"UPDATE manycol SET x1=x1+1 $::where AND rowid>0"
, {})
@@ -665,7 +665,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-12.6",
[[
- INSERT OR IGNORE INTO t6 VALUES('y',0);
+ INSERT OR IGNORE INTO t6 VALUES('y','0');
SELECT * FROM t6;
]], {
-- <misc1-12.6>
@@ -679,10 +679,10 @@ test:do_execsql_test(
"misc1-12.7",
[[
CREATE TABLE t7(x INTEGER, y TEXT, z INT primary key);
- INSERT INTO t7 VALUES(0,0,1);
- INSERT INTO t7 VALUES(0.0,0,2);
- INSERT INTO t7 VALUES(0,0.0,3);
- INSERT INTO t7 VALUES(0.0,0.0,4);
+ INSERT INTO t7 VALUES(0,'0',1);
+ INSERT INTO t7 VALUES(0.0,'0',2);
+ INSERT INTO t7 VALUES(0,'0.0',3);
+ INSERT INTO t7 VALUES(0.0,'0.0',4);
SELECT DISTINCT x, y FROM t7 ORDER BY z;
]], {
-- <misc1-12.7>
diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
index eeac5353a..3161e48fa 100755
--- a/test/sql-tap/numcast.test.lua
+++ b/test/sql-tap/numcast.test.lua
@@ -135,16 +135,16 @@ test:do_catchsql_test(
INSERT INTO t VALUES(20000000000000000000.01);
SELECT * FROM t;
]], {
- 1,"Tuple field 1 type does not match one required by operation: expected integer"
+ 1,"Type mismatch: can not convert 2.0e+19 to integer"
})
-test:do_catchsql_test(
+test:do_execsql_test(
"cast-2.9",
[[
INSERT INTO t VALUES(2.1);
SELECT * FROM t;
]], {
- 1,"Tuple field 1 type does not match one required by operation: expected integer"
+ 2, 9223372036854775808ULL, 18000000000000000000ULL
})
--
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index fbebfab37..9a969bf3c 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -231,7 +231,7 @@ string.format([[
CREATE TABLE t3(id INT, a TEXT, b TEXT, PRIMARY KEY(id));
INSERT INTO t3 VALUES(1, 'abc',NULL);
INSERT INTO t3 VALUES(2, NULL,'xyz');
- INSERT INTO t3 SELECT f1, * FROM test1;
+ INSERT INTO t3 SELECT f1, CAST(f1 AS STRING), CAST(f2 AS STRING) FROM test1;
DROP TABLE IF EXISTS t4;
CREATE TABLE t4(id INT, a INT , b TEXT , PRIMARY KEY(id));
INSERT INTO t4 VALUES(1, NULL,'%s');
@@ -1671,8 +1671,8 @@ test:do_execsql_test(
[[
DELETE FROM t3;
DELETE FROM t4;
- INSERT INTO t3 VALUES(0,1,2);
- INSERT INTO t4 VALUES(0,3,4);
+ INSERT INTO t3 VALUES(0,'1','2');
+ INSERT INTO t4 VALUES(0,3,'4');
SELECT * FROM t3, t4;
]], {
-- <select1-11.1>
@@ -1878,7 +1878,7 @@ test:do_execsql_test(
"select1-12.4",
[[
DELETE FROM t3;
- INSERT INTO t3 VALUES(0,1,2);
+ INSERT INTO t3 VALUES(0,'1','2');
]], {
-- <select1-12.4>
diff --git a/test/sql-tap/select4.test.lua b/test/sql-tap/select4.test.lua
index 23cf1bf1b..f7a320438 100755
--- a/test/sql-tap/select4.test.lua
+++ b/test/sql-tap/select4.test.lua
@@ -761,12 +761,12 @@ test:do_test(
test:execsql [[
CREATE TABLE t3(a text primary key, b NUMBER, c text);
START TRANSACTION;
- INSERT INTO t3 VALUES(1, 1.1, '1.1');
- INSERT INTO t3 VALUES(2, 1.10, '1.10');
- INSERT INTO t3 VALUES(3, 1.10, '1.1');
- INSERT INTO t3 VALUES(4, 1.1, '1.10');
- INSERT INTO t3 VALUES(5, 1.2, '1.2');
- INSERT INTO t3 VALUES(6, 1.3, '1.3');
+ INSERT INTO t3 VALUES('1', 1.1, '1.1');
+ INSERT INTO t3 VALUES('2', 1.10, '1.10');
+ INSERT INTO t3 VALUES('3', 1.10, '1.1');
+ INSERT INTO t3 VALUES('4', 1.1, '1.10');
+ INSERT INTO t3 VALUES('5', 1.2, '1.2');
+ INSERT INTO t3 VALUES('6', 1.3, '1.3');
COMMIT;
]]
return test:execsql [[
diff --git a/test/sql-tap/select7.test.lua b/test/sql-tap/select7.test.lua
index fec5d7a41..e1e43c557 100755
--- a/test/sql-tap/select7.test.lua
+++ b/test/sql-tap/select7.test.lua
@@ -255,7 +255,7 @@ test:do_execsql_test(
[[
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a TEXT primary key, b INT);
- INSERT INTO t5 VALUES(123, 456);
+ INSERT INTO t5 VALUES('123', 456);
SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
]], {
-- <select7-7.7>
diff --git a/test/sql-tap/sort.test.lua b/test/sql-tap/sort.test.lua
index 36074d6ef..18bfd443d 100755
--- a/test/sql-tap/sort.test.lua
+++ b/test/sql-tap/sort.test.lua
@@ -505,10 +505,10 @@ test:do_execsql_test(
a INTEGER PRIMARY KEY,
b VARCHAR(30)
);
- INSERT INTO t4 VALUES(1,1);
- INSERT INTO t4 VALUES(2,2);
- INSERT INTO t4 VALUES(11,11);
- INSERT INTO t4 VALUES(12,12);
+ INSERT INTO t4 VALUES(1,'1');
+ INSERT INTO t4 VALUES(2,'2');
+ INSERT INTO t4 VALUES(11,'11');
+ INSERT INTO t4 VALUES(12,'12');
SELECT a FROM t4 ORDER BY 1;
]], {
-- <sort-7.1>
diff --git a/test/sql-tap/tkt-3998683a16.test.lua b/test/sql-tap/tkt-3998683a16.test.lua
index 885dcf5cd..9bc310358 100755
--- a/test/sql-tap/tkt-3998683a16.test.lua
+++ b/test/sql-tap/tkt-3998683a16.test.lua
@@ -26,29 +26,17 @@ test:do_test(
function()
return test:execsql [[
CREATE TABLE t1(x INT primary key, y NUMBER);
- INSERT INTO t1 VALUES(1, '1.0');
- INSERT INTO t1 VALUES(2, '.125');
- INSERT INTO t1 VALUES(3, '123.');
- INSERT INTO t1 VALUES(4, '123.e+2');
- INSERT INTO t1 VALUES(5, '.125e+3');
- INSERT INTO t1 VALUES(6, '123e4');
- INSERT INTO t1 VALUES(11, ' 1.0');
- INSERT INTO t1 VALUES(12, ' .125');
- INSERT INTO t1 VALUES(13, ' 123.');
- INSERT INTO t1 VALUES(14, ' 123.e+2');
- INSERT INTO t1 VALUES(15, ' .125e+3');
- INSERT INTO t1 VALUES(16, ' 123e4');
- INSERT INTO t1 VALUES(21, '1.0 ');
- INSERT INTO t1 VALUES(22, '.125 ');
- INSERT INTO t1 VALUES(23, '123. ');
- INSERT INTO t1 VALUES(24, '123.e+2 ');
- INSERT INTO t1 VALUES(25, '.125e+3 ');
- INSERT INTO t1 VALUES(26, '123e4 ');
+ INSERT INTO t1 VALUES(1, 1.0);
+ INSERT INTO t1 VALUES(2, .125);
+ INSERT INTO t1 VALUES(3, 123.);
+ INSERT INTO t1 VALUES(4, 123.e+2);
+ INSERT INTO t1 VALUES(5, .125e+3);
+ INSERT INTO t1 VALUES(6, 123e4);
SELECT x FROM t1 WHERE typeof(y)=='number' ORDER BY x;
]]
end, {
-- <tkt-3998683a16.1>
- 1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26
+ 1, 2, 3, 4, 5, 6
-- </tkt-3998683a16.1>
})
diff --git a/test/sql-tap/tkt-54844eea3f.test.lua b/test/sql-tap/tkt-54844eea3f.test.lua
index d6cd56e52..89d0d1218 100755
--- a/test/sql-tap/tkt-54844eea3f.test.lua
+++ b/test/sql-tap/tkt-54844eea3f.test.lua
@@ -62,10 +62,10 @@ test:do_execsql_test(
"1.2",
[[
CREATE TABLE t4(id INT primary key, a TEXT, b TEXT, c TEXT);
- INSERT INTO t4 VALUES(1, 'a', 1, 'one');
- INSERT INTO t4 VALUES(2, 'a', 2, 'two');
- INSERT INTO t4 VALUES(3, 'b', 1, 'three');
- INSERT INTO t4 VALUES(4, 'b', 2, 'four');
+ INSERT INTO t4 VALUES(1, 'a', '1', 'one');
+ INSERT INTO t4 VALUES(2, 'a', '2', 'two');
+ INSERT INTO t4 VALUES(3, 'b', '1', 'three');
+ INSERT INTO t4 VALUES(4, 'b', '2', 'four');
SELECT (
SELECT c FROM (
SELECT a,b,c FROM t4 WHERE a=output.a ORDER BY b LIMIT 10 OFFSET 1
diff --git a/test/sql-tap/tkt-7bbfb7d442.test.lua b/test/sql-tap/tkt-7bbfb7d442.test.lua
index 535303771..bfddcd920 100755
--- a/test/sql-tap/tkt-7bbfb7d442.test.lua
+++ b/test/sql-tap/tkt-7bbfb7d442.test.lua
@@ -109,13 +109,13 @@ if (1 > 0)
T1.Variant AS Variant,
T1.ControlDate AS ControlDate,
1 AS ControlState,
- COALESCE(T2.DeliveredQty,0) AS DeliveredQty
+ CAST(COALESCE(T2.DeliveredQty,0) AS STRING) AS DeliveredQty
FROM (
SELECT
NEW.InventoryControlId AS InventoryControlId,
II.SKU AS SKU,
II.Variant AS Variant,
- COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS ControlDate
+ CAST(COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS STRING) AS ControlDate
FROM
InventoryItem II
LEFT JOIN
diff --git a/test/sql-tap/tkt1444.test.lua b/test/sql-tap/tkt1444.test.lua
index 82a5ded25..fb148bc5f 100755
--- a/test/sql-tap/tkt1444.test.lua
+++ b/test/sql-tap/tkt1444.test.lua
@@ -30,8 +30,8 @@ test:do_execsql_test(
[[
CREATE TABLE DemoTable (id INT primary key, x INTEGER, TextKey TEXT, DKey NUMBER);
CREATE INDEX DemoTableIdx ON DemoTable (TextKey);
- INSERT INTO DemoTable VALUES(1, 9,8,7);
- INSERT INTO DemoTable VALUES(2, 1,2,3);
+ INSERT INTO DemoTable VALUES(1, 9,'8',7);
+ INSERT INTO DemoTable VALUES(2, 1,'2',3);
CREATE VIEW DemoView AS SELECT x, TextKey, DKey FROM DemoTable ORDER BY TextKey;
SELECT x,TextKey,DKey FROM DemoTable UNION ALL SELECT * FROM DemoView ORDER BY 1;
]], {
diff --git a/test/sql-tap/tkt3493.test.lua b/test/sql-tap/tkt3493.test.lua
index 7ceec4702..de77e61e9 100755
--- a/test/sql-tap/tkt3493.test.lua
+++ b/test/sql-tap/tkt3493.test.lua
@@ -29,8 +29,8 @@ test:do_execsql_test(
START TRANSACTION;
INSERT INTO A VALUES(1,'123');
INSERT INTO A VALUES(2,'456');
- INSERT INTO B VALUES(1,1);
- INSERT INTO B VALUES(2,2);
+ INSERT INTO B VALUES(1,'1');
+ INSERT INTO B VALUES(2,'2');
INSERT INTO A_B VALUES(1,1);
INSERT INTO A_B VALUES(2,2);
COMMIT;
@@ -116,7 +116,7 @@ test:do_execsql_test(
"tkt3493-2.1",
[[
CREATE TABLE t1(a TEXT PRIMARY KEY, b INT);
- INSERT INTO t1 VALUES(123, 456);
+ INSERT INTO t1 VALUES('123', 456);
]], {
-- <tkt3493-2.1>
diff --git a/test/sql-tap/tkt3841.test.lua b/test/sql-tap/tkt3841.test.lua
index 5203d0cd4..56668f6a3 100755
--- a/test/sql-tap/tkt3841.test.lua
+++ b/test/sql-tap/tkt3841.test.lua
@@ -31,12 +31,12 @@ test:do_execsql_test(
INSERT INTO table2 VALUES ('a', 'alist');
INSERT INTO table2 VALUES ('b', 'blist');
- INSERT INTO list VALUES ('a', 1);
- INSERT INTO list VALUES ('a', 2);
- INSERT INTO list VALUES ('a', 3);
- INSERT INTO list VALUES ('b', 4);
- INSERT INTO list VALUES ('b', 5);
- INSERT INTO list VALUES ('b', 6);
+ INSERT INTO list VALUES ('a', '1');
+ INSERT INTO list VALUES ('a', '2');
+ INSERT INTO list VALUES ('a', '3');
+ INSERT INTO list VALUES ('b', '4');
+ INSERT INTO list VALUES ('b', '5');
+ INSERT INTO list VALUES ('b', '6');
SELECT
table2.x,
diff --git a/test/sql-tap/triggerA.test.lua b/test/sql-tap/triggerA.test.lua
index fac51ca14..fc8ecfe17 100755
--- a/test/sql-tap/triggerA.test.lua
+++ b/test/sql-tap/triggerA.test.lua
@@ -283,7 +283,7 @@ test:do_test(
CREATE TABLE result2(id INTEGER PRIMARY KEY, a TEXT,b INT);
CREATE TRIGGER r5d INSTEAD OF DELETE ON v5 FOR EACH ROW BEGIN
INSERT INTO result2(id, a,b) VALUES((SELECT coalesce(max(id),0) + 1 FROM result2),
- old.x, old.b);
+ CAST(old.x AS STRING), old.b);
END;
DELETE FROM v5 WHERE x=5;
SELECT a, b FROM result2;
@@ -301,7 +301,7 @@ test:do_test(
DELETE FROM result4;
CREATE TRIGGER r5u INSTEAD OF UPDATE ON v5 FOR EACH ROW BEGIN
INSERT INTO result4(id, a,b,c,d) VALUES((SELECT coalesce(max(id),0) + 1 FROM result4),
- old.x, old.b, new.x, new.b);
+ CAST(old.x AS STRING), old.b, CAST(new.x AS STRING), new.b);
END;
UPDATE v5 SET b = b+9900000 WHERE x BETWEEN 3 AND 5;
SELECT a,b,c,d FROM result4 ORDER BY a;
diff --git a/test/sql-tap/unique.test.lua b/test/sql-tap/unique.test.lua
index 9818f90a8..6b0a7e20d 100755
--- a/test/sql-tap/unique.test.lua
+++ b/test/sql-tap/unique.test.lua
@@ -52,7 +52,7 @@ test:do_catchsql_test(
test:do_catchsql_test(
"unique-1.2",
[[
- INSERT INTO t1(a,b,c) VALUES(1,2,3)
+ INSERT INTO t1(a,b,c) VALUES(1,2,'3')
]], {
-- <unique-1.2>
0
@@ -62,7 +62,7 @@ test:do_catchsql_test(
test:do_catchsql_test(
"unique-1.3",
[[
- INSERT INTO t1(a,b,c) VALUES(1,3,4)
+ INSERT INTO t1(a,b,c) VALUES(1,3,'4')
]], {
-- <unique-1.3>
1, "Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
@@ -83,7 +83,7 @@ test:do_execsql_test(
test:do_catchsql_test(
"unique-1.5",
[[
- INSERT INTO t1(a,b,c) VALUES(3,2,4)
+ INSERT INTO t1(a,b,c) VALUES(3,2,'4')
]], {
-- <unique-1.5>
1, "Duplicate key exists in unique index 'unique_unnamed_T1_2' in space 'T1'"
@@ -104,7 +104,7 @@ test:do_execsql_test(
test:do_catchsql_test(
"unique-1.7",
[[
- INSERT INTO t1(a,b,c) VALUES(3,4,5)
+ INSERT INTO t1(a,b,c) VALUES(3,4,'5')
]], {
-- <unique-1.7>
0
diff --git a/test/sql-tap/view.test.lua b/test/sql-tap/view.test.lua
index e553b91c7..ab14c5edb 100755
--- a/test/sql-tap/view.test.lua
+++ b/test/sql-tap/view.test.lua
@@ -757,7 +757,7 @@ test:do_execsql_test(
"view-10.1",
[=[
CREATE TABLE t3("9" integer primary key, "4" text);
- INSERT INTO t3 VALUES(1,2);
+ INSERT INTO t3 VALUES(1,'2');
CREATE VIEW v_t3_a AS SELECT a."9" FROM t3 AS a;
CREATE VIEW v_t3_b AS SELECT "4" FROM t3;
SELECT * FROM v_t3_a;
diff --git a/test/sql-tap/where5.test.lua b/test/sql-tap/where5.test.lua
index 749201564..3aefcaca5 100755
--- a/test/sql-tap/where5.test.lua
+++ b/test/sql-tap/where5.test.lua
@@ -27,11 +27,11 @@ test:do_test("where5-1.0", function()
CREATE TABLE t1(x TEXT primary key);
CREATE TABLE t2(x integer primary key);
CREATE TABLE t3(x integer PRIMARY KEY);
- INSERT INTO t1 VALUES(-1);
- INSERT INTO t1 VALUES(0);
- INSERT INTO t1 VALUES(1);
- INSERT INTO t2 SELECT * FROM t1;
- INSERT INTO t3 SELECT * FROM t1;
+ INSERT INTO t1 VALUES('-1');
+ INSERT INTO t1 VALUES('0');
+ INSERT INTO t1 VALUES('1');
+ INSERT INTO t2 SELECT CAST(x AS INTEGER) FROM t1;
+ INSERT INTO t3 SELECT CAST(x AS INTEGER) FROM t1;
]]
return test:execsql [[
SELECT * FROM t1 WHERE x<0
diff --git a/test/sql-tap/whereB.test.lua b/test/sql-tap/whereB.test.lua
index d98645fdc..fe5e28c70 100755
--- a/test/sql-tap/whereB.test.lua
+++ b/test/sql-tap/whereB.test.lua
@@ -112,24 +112,16 @@ test:do_execsql_test(
-- </whereB-1.102>
})
--- For this set of tests:
---
--- * t1.y holds a text value with affinity TEXT
--- * t2.b holds an integer value with affinity NONE
---
--- These values are not equal and because neither affinity is NUMERIC
--- no type conversion occurs.
---
test:do_execsql_test(
"whereB-2.1",
[[
DROP TABLE t1;
DROP TABLE t2;
- CREATE TABLE t1(x INT primary key, y TEXT); -- affinity of t1.y is TEXT
- INSERT INTO t1 VALUES(1,99);
+ CREATE TABLE t1(x INT primary key, y TEXT);
+ INSERT INTO t1 VALUES(1,'99');
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
+ CREATE TABLE t2(a INT primary key, b SCALAR);
CREATE INDEX t2b ON t2(b);
INSERT INTO t2 VALUES(2, 99);
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 3/8] sql: remove mem_apply_type() from OP_MakeRecord
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double() imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator imeevma
` (4 subsequent siblings)
7 siblings, 0 replies; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
This patch removes the type change from OP_MakeRecord. This allows
us to remove unnecessary implicit casts. So far, this only affects
the IN operator.
Part of #4230
---
src/box/sql/analyze.c | 7 +------
src/box/sql/delete.c | 8 ++------
src/box/sql/expr.c | 8 +-------
src/box/sql/fk_constraint.c | 9 ++-------
src/box/sql/select.c | 25 ++++++-------------------
src/box/sql/update.c | 14 +++-----------
src/box/sql/vdbe.c | 19 +------------------
test/sql-tap/in3.test.lua | 4 ++--
8 files changed, 18 insertions(+), 76 deletions(-)
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index f74f9b358..23fbb15de 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -965,12 +965,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space)
sqlVdbeAddOp2(v, OP_Next, idx_cursor, next_row_addr);
/* Add the entry to the stat1 table. */
callStatGet(v, stat4_reg, STAT_GET_STAT1, stat1_reg);
- enum field_type types[4] = { FIELD_TYPE_STRING,
- FIELD_TYPE_STRING,
- FIELD_TYPE_STRING,
- field_type_MAX };
- sqlVdbeAddOp4(v, OP_MakeRecord, tab_name_reg, 4, tmp_reg,
- (char *)types, sizeof(types));
+ sqlVdbeAddOp3(v, OP_MakeRecord, tab_name_reg, 4, tmp_reg);
sqlVdbeAddOp4(v, OP_IdxInsert, tmp_reg, 0, 0,
(char *)stat1, P4_SPACEPTR);
/* Add the entries to the stat4 table. */
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 68abd1f58..0b6f0bd62 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -328,12 +328,8 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
* key.
*/
key_len = 0;
- struct index *pk = space_index(space, 0);
- enum field_type *types = is_view ? NULL :
- sql_index_type_str(parse->db,
- pk->def);
- sqlVdbeAddOp4(v, OP_MakeRecord, reg_pk, pk_len,
- reg_key, (char *)types, P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, reg_pk, pk_len,
+ reg_key);
/* Set flag to save memory allocating one
* by malloc.
*/
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index bc2182446..019628a26 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -2859,8 +2859,6 @@ sqlCodeSubselect(Parse * pParse, /* Parsing context */
struct ExprList_item *pItem;
int r1, r2, r3;
- enum field_type lhs_type =
- sql_expr_type(pLeft);
bool unused;
struct coll *unused_coll;
if (sql_expr_coll(pParse, pExpr->pLeft, &unused,
@@ -2886,11 +2884,7 @@ sqlCodeSubselect(Parse * pParse, /* Parsing context */
jmpIfDynamic = -1;
}
r3 = sqlExprCodeTarget(pParse, pE2, r1);
- enum field_type types[2] =
- { lhs_type, field_type_MAX };
- sqlVdbeAddOp4(v, OP_MakeRecord, r3,
- 1, r2, (char *)types,
- sizeof(types));
+ sqlVdbeAddOp3(v, OP_MakeRecord, r3, 1, r2);
sql_expr_type_cache_change(pParse,
r3, 1);
sqlVdbeAddOp2(v, OP_IdxInsert, r2,
diff --git a/src/box/sql/fk_constraint.c b/src/box/sql/fk_constraint.c
index 482220a95..43471d51a 100644
--- a/src/box/sql/fk_constraint.c
+++ b/src/box/sql/fk_constraint.c
@@ -262,13 +262,8 @@ fk_constraint_lookup_parent(struct Parse *parse_context, struct space *parent,
link->child_field + 1 + reg_data,
temp_regs + i);
}
- struct index *idx = space_index(parent, referenced_idx);
- assert(idx != NULL);
- sqlVdbeAddOp4(v, OP_MakeRecord, temp_regs, field_count,
- rec_reg,
- (char *) sql_index_type_str(parse_context->db,
- idx->def),
- P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, temp_regs, field_count,
+ rec_reg);
sqlVdbeAddOp4Int(v, OP_Found, cursor, ok_label, rec_reg, 0);
sqlReleaseTempReg(parse_context, rec_reg);
sqlReleaseTempRange(parse_context, temp_regs, field_count);
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 4b069addb..1687448d4 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -1270,13 +1270,8 @@ selectInnerLoop(Parse * pParse, /* The parser context */
regOrig, nResultCol, nPrefixReg);
} else {
int r1 = sqlGetTempReg(pParse);
- enum field_type *types =
- field_type_sequence_dup(pParse,
- pDest->dest_type,
- nResultCol);
- sqlVdbeAddOp4(v, OP_MakeRecord, regResult,
- nResultCol, r1, (char *)types,
- P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, regResult,
+ nResultCol, r1);
sql_expr_type_cache_change(pParse,
regResult,
nResultCol);
@@ -1693,12 +1688,8 @@ generateSortTail(Parse * pParse, /* Parsing context */
break;
}
case SRT_Set:{
- enum field_type *types =
- field_type_sequence_dup(pParse, pDest->dest_type,
- nColumn);
- sqlVdbeAddOp4(v, OP_MakeRecord, regRow, nColumn,
- regTupleid, (char *)types,
- P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, regRow, nColumn,
+ regTupleid);
sql_expr_type_cache_change(pParse, regRow, nColumn);
sqlVdbeAddOp2(v, OP_IdxInsert, regTupleid, pDest->reg_eph);
break;
@@ -3137,12 +3128,8 @@ generateOutputSubroutine(struct Parse *parse, struct Select *p,
int r1;
testcase(in->nSdst > 1);
r1 = sqlGetTempReg(parse);
- enum field_type *types =
- field_type_sequence_dup(parse, dest->dest_type,
- in->nSdst);
- sqlVdbeAddOp4(v, OP_MakeRecord, in->iSdst,
- in->nSdst, r1, (char *)types,
- P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, in->iSdst, in->nSdst,
+ r1);
sql_expr_type_cache_change(parse, in->iSdst,
in->nSdst);
sqlVdbeAddOp2(v, OP_IdxInsert, r1, dest->reg_eph);
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 24c7cfa27..22f82390c 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -251,11 +251,7 @@ sqlUpdate(Parse * pParse, /* The parser context */
nKey = pk_part_count;
regKey = iPk;
} else {
- enum field_type *types = is_view ? NULL :
- sql_index_type_str(pParse->db,
- pPk->def);
- sqlVdbeAddOp4(v, OP_MakeRecord, iPk, pk_part_count,
- regKey, (char *) types, P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, iPk, pk_part_count, regKey);
/*
* Set flag to save memory allocating one by
* malloc.
@@ -420,12 +416,8 @@ sqlUpdate(Parse * pParse, /* The parser context */
int key_reg;
if (okOnePass) {
key_reg = sqlGetTempReg(pParse);
- enum field_type *types =
- sql_index_type_str(pParse->db,
- pPk->def);
- sqlVdbeAddOp4(v, OP_MakeRecord, iPk,
- pk_part_count, key_reg,
- (char *) types, P4_DYNAMIC);
+ sqlVdbeAddOp3(v, OP_MakeRecord, iPk,
+ pk_part_count, key_reg);
} else {
assert(nKey == 0);
key_reg = regKey;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 009d577d2..276956170 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2940,24 +2940,17 @@ case OP_ImplicitCast: {
break;
}
-/* Opcode: MakeRecord P1 P2 P3 P4 P5
+/* Opcode: MakeRecord P1 P2 P3 * P5
* Synopsis: r[P3]=mkrec(r[P1@P2])
*
* Convert P2 registers beginning with P1 into the [record format]
* use as a data record in a database table or as a key
* in an index. The OP_Column opcode can decode the record later.
*
- * P4 may be a string that is P2 characters long. The nth character of the
- * string indicates the column type that should be used for the nth
- * field of the index key.
- *
- * If P4 is NULL then all index fields have type SCALAR.
- *
* If P5 is not NULL then record under construction is intended to be inserted
* into ephemeral space. Thus, sort of memory optimization can be performed.
*/
case OP_MakeRecord: {
- Mem *pRec; /* The new record */
Mem *pData0; /* First field to be combined into the record */
Mem MAYBE_UNUSED *pLast; /* Last field of the record */
int nField; /* Number of fields in the record */
@@ -2979,7 +2972,6 @@ case OP_MakeRecord: {
* of the record to data0.
*/
nField = pOp->p1;
- enum field_type *types = pOp->p4.types;
bIsEphemeral = pOp->p5;
assert(nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1);
pData0 = &aMem[nField];
@@ -2990,15 +2982,6 @@ case OP_MakeRecord: {
assert(pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2);
pOut = vdbe_prepare_null_out(p, pOp->p3);
- /* Apply the requested types to all inputs */
- assert(pData0<=pLast);
- if (types != NULL) {
- pRec = pData0;
- do {
- mem_apply_type(pRec++, *(types++));
- } while(types[0] != field_type_MAX);
- }
-
struct region *region = &fiber()->gc;
size_t used = region_used(region);
uint32_t tuple_size;
diff --git a/test/sql-tap/in3.test.lua b/test/sql-tap/in3.test.lua
index e29db9d93..f7681640e 100755
--- a/test/sql-tap/in3.test.lua
+++ b/test/sql-tap/in3.test.lua
@@ -354,7 +354,7 @@ test:do_test(
return exec_neph(" SELECT y IN (SELECT a FROM t1) FROM t2 ")
end, {
-- <in3-3.5>
- 1, true
+ 1, false
-- </in3-3.5>
})
@@ -378,7 +378,7 @@ test:do_test(
return exec_neph(" SELECT y IN (SELECT c FROM t1) FROM t2 ")
end, {
-- <in3-3.7>
- 1, true
+ 1, false
-- </in3-3.7>
})
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
` (2 preceding siblings ...)
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 3/8] sql: remove mem_apply_type() from OP_MakeRecord imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-29 12:56 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt imeevma
` (3 subsequent siblings)
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
This patch removes implicit cast from STRING to numeric
and vice versa of left operand of IN operator.
Part of #4230
Part of #4692
---
src/box/sql/expr.c | 2 +-
test/sql-tap/in3.test.lua | 14 +------
test/sql-tap/subquery.test.lua | 69 +---------------------------------
3 files changed, 3 insertions(+), 82 deletions(-)
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 019628a26..745011d35 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -3179,7 +3179,7 @@ sqlExprCodeIN(Parse * pParse, /* Parsing and code generating context */
* true.
*/
zAff[nVector] = field_type_MAX;
- sqlVdbeAddOp4(v, OP_ApplyType, rLhs, nVector, 0, (char*)zAff,
+ sqlVdbeAddOp4(v, OP_ImplicitCast, rLhs, nVector, 0, (char*)zAff,
P4_DYNAMIC);
/*
* zAff will be freed at the end of VDBE execution, since
diff --git a/test/sql-tap/in3.test.lua b/test/sql-tap/in3.test.lua
index f7681640e..a2147b0e8 100755
--- a/test/sql-tap/in3.test.lua
+++ b/test/sql-tap/in3.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(29)
+test:plan(28)
--!./tcltestrunner.lua
-- 2007 November 29
@@ -322,18 +322,6 @@ test:do_test(
-- </in3-3.2>
})
-test:do_test(
- "in3-3.3",
- function()
- -- Logically, numeric affinity is applied to both sides before
- -- the comparison, but index can't be used.
- return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
- end, {
- -- <in3-3.3>
- 1, true
- -- </in3-3.3>
- })
-
test:do_test(
"in3-3.4",
function()
diff --git a/test/sql-tap/subquery.test.lua b/test/sql-tap/subquery.test.lua
index 15c4c8276..e0771825e 100755
--- a/test/sql-tap/subquery.test.lua
+++ b/test/sql-tap/subquery.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(73)
+test:plan(69)
--!./tcltestrunner.lua
-- 2005 January 19
@@ -335,73 +335,6 @@ test:do_execsql_test(
-- </subquery-2.4.3>
})
-test:do_execsql_test(
- "subquery-2.5.1",
- [[
- CREATE TABLE t3(a INTEGER PRIMARY KEY);
- INSERT INTO t3 VALUES(10);
-
- CREATE TABLE t4(x TEXT PRIMARY KEY);
- INSERT INTO t4 VALUES('10');
- ]], {
- -- <subquery-2.5.1>
-
- -- </subquery-2.5.1>
- })
-
-test:do_test(
- "subquery-2.5.2",
- function()
- -- In the expr "x IN (SELECT a FROM t3)" the RHS of the IN operator
- -- has text affinity and the LHS has integer affinity. The rule is
- -- that we try to convert both sides to an integer before doing the
- -- comparision. Hence, the integer value 10 in t3 will compare equal
- -- to the string value '10.0' in t4 because the t4 value will be
- -- converted into an integer.
- return test:execsql [[
- SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
- ]]
- end, {
- -- <subquery-2.5.2>
- "10"
- -- </subquery-2.5.2>
- })
-
-test:do_test(
- "subquery-2.5.3.1",
- function()
- -- The t4i index cannot be used to resolve the "x IN (...)" constraint
- -- because the constraint has integer affinity but t4i has text affinity.
- return test:execsql [[
- CREATE INDEX t4i ON t4(x);
- SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
- ]]
- end, {
- -- <subquery-2.5.3.1>
- "10"
- -- </subquery-2.5.3.1>
- })
-
--- Tarantool: no-rowid is implied for the table, so query plan contains
--- scan over t4i. Verified w/ vanilla sql. Comment this case
---do_test subquery-2.5.3.2 {
--- Verify that the t4i index was not used in the previous query
--- execsql {
--- EXPLAIN QUERY PLAN
--- SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
--- }
---} {~/t4i/}
-test:do_execsql_test(
- "subquery-2.5.4",
- [[
- DROP TABLE t3;
- DROP TABLE t4;
- ]], {
- -- <subquery-2.5.4>
-
- -- </subquery-2.5.4>
- })
-
--------------------------------------------------------------------
-- The following test cases - subquery-3.* - test tickets that
-- were raised during development of correlated subqueries.
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
` (3 preceding siblings ...)
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-29 13:29 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison imeevma
` (2 subsequent siblings)
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
This patch replaces mem_apply_type() with
mem_convert_to_integer(), since this mem_convert_to_integer()
contains the only functionality needed here from the
mem_apply_type().
---
src/box/sql/vdbe.c | 18 +-
test/sql-tap/e_select1.test.lua | 17 +-
test/sql-tap/in4.test.lua | 97 +--
test/sql-tap/join.test.lua | 1 -
test/sql-tap/limit.test.lua | 2 +-
test/sql-tap/tkt-9a8b09f8e6.test.lua | 24 +-
test/sql-tap/tkt-fc7bd6358f.test.lua | 111 ----
test/sql-tap/transitive1.test.lua | 4 +-
test/sql-tap/whereB.test.lua | 900 ---------------------------
test/sql-tap/whereC.test.lua | 8 +-
10 files changed, 25 insertions(+), 1157 deletions(-)
delete mode 100755 test/sql-tap/tkt-fc7bd6358f.test.lua
delete mode 100755 test/sql-tap/whereB.test.lua
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 276956170..a609fa985 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2122,17 +2122,13 @@ case OP_AddImm: { /* in1 */
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
- if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
- mem_apply_type(pIn1, FIELD_TYPE_INTEGER);
- if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
- if (pOp->p2==0) {
- diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- sql_value_to_diag_str(pIn1), "integer");
- goto abort_due_to_error;
- } else {
- goto jump_to_p2;
- }
- }
+ if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0 &&
+ mem_convert_to_integer(pIn1, true) != 0) {
+ if (pOp->p2 != 0)
+ goto jump_to_p2;
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1), "integer");
+ goto abort_due_to_error;
}
break;
}
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index 7673426f4..578620fca 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(510)
+test:plan(509)
--!./tcltestrunner.lua
-- 2010 July 16
@@ -2150,7 +2150,6 @@ test:do_select_tests(
{"2", "SELECT b FROM f1 ORDER BY a LIMIT 2+3 ", {"a", "b", "c", "d", "e"}},
{"3", "SELECT b FROM f1 ORDER BY a LIMIT (SELECT a FROM f1 WHERE b = 'e') ", {"a", "b", "c", "d", "e"}},
{"4", "SELECT b FROM f1 ORDER BY a LIMIT 5.0 ", {"a", "b", "c", "d", "e"}},
- {"5", "SELECT b FROM f1 ORDER BY a LIMIT '5' ", {"a", "b", "c", "d", "e"}},
})
-- EVIDENCE-OF: R-46155-47219 If the expression evaluates to a NULL value
@@ -2195,7 +2194,7 @@ test:do_select_tests(
{"1", "SELECT b FROM f1 ORDER BY a LIMIT 0 ", {}},
{"2", "SELECT b FROM f1 ORDER BY a DESC LIMIT 4 ", {"z", "y", "x", "w"}},
{"3", "SELECT b FROM f1 ORDER BY a DESC LIMIT 8 ", {"z", "y", "x", "w", "v", "u", "t", "s"}},
- {"4", "SELECT b FROM f1 ORDER BY a DESC LIMIT '12' ", {"z", y, "x", "w", "v", "u", "t", "s", "r", "q", "p", "o"}},
+ {"4", "SELECT b FROM f1 ORDER BY a DESC LIMIT 12 ", {"z", y, "x", "w", "v", "u", "t", "s", "r", "q", "p", "o"}},
})
-- EVIDENCE-OF: R-54935-19057 Or, if the SELECT statement would return
@@ -2240,10 +2239,10 @@ test:do_select_tests(
{"1", "SELECT b FROM f1 ORDER BY a LIMIT 10 OFFSET 5", {"f", "g", "h", "i", "j", "k", "l", "m", "n", "o"}},
{"2", "SELECT b FROM f1 ORDER BY a LIMIT 2+3 OFFSET 10", {"k", "l", "m", "n", "o"}},
{"3", "SELECT b FROM f1 ORDER BY a LIMIT (SELECT a FROM f1 WHERE b='j') OFFSET (SELECT a FROM f1 WHERE b='b') ", {"c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}},
- {"4", "SELECT b FROM f1 ORDER BY a LIMIT '5' OFFSET 3.0 ", {"d", "e", "f", "g", "h"}},
- {"5", "SELECT b FROM f1 ORDER BY a LIMIT '5' OFFSET 0 ", {"a", "b", "c", "d", "e"}},
+ {"4", "SELECT b FROM f1 ORDER BY a LIMIT 5 OFFSET 3.0 ", {"d", "e", "f", "g", "h"}},
+ {"5", "SELECT b FROM f1 ORDER BY a LIMIT 5 OFFSET 0 ", {"a", "b", "c", "d", "e"}},
{"6", "SELECT b FROM f1 ORDER BY a LIMIT 0 OFFSET 10 ", {}},
- {"7", "SELECT b FROM f1 ORDER BY a LIMIT 3 OFFSET '1'||'5' ", {"p", "q", "r"}},
+ {"7", "SELECT b FROM f1 ORDER BY a LIMIT 3 OFFSET CAST('1'||'5' AS INTEGER) ", {"p", "q", "r"}},
})
-- EVIDENCE-OF: R-34648-44875 Or, if the SELECT would return less than
@@ -2279,10 +2278,10 @@ test:do_select_tests(
{"1", "SELECT b FROM f1 ORDER BY a LIMIT 5, 10 ", {"f", "g", "h", "i", "j", "k", "l", "m", "n", "o"}},
{"2", "SELECT b FROM f1 ORDER BY a LIMIT 10, 2+3 ", {"k", "l", "m", "n", "o"}},
{"3", "SELECT b FROM f1 ORDER BY a LIMIT (SELECT a FROM f1 WHERE b='b'), (SELECT a FROM f1 WHERE b='j')", {"c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}},
- {"4", "SELECT b FROM f1 ORDER BY a LIMIT 3.0, '5' ", {"d", "e", "f", "g", "h"}},
- {"5", "SELECT b FROM f1 ORDER BY a LIMIT 0, '5' ", {"a", "b", "c", "d", "e"}},
+ {"4", "SELECT b FROM f1 ORDER BY a LIMIT 3.0, 5 ", {"d", "e", "f", "g", "h"}},
+ {"5", "SELECT b FROM f1 ORDER BY a LIMIT 0, 5 ", {"a", "b", "c", "d", "e"}},
{"6", "SELECT b FROM f1 ORDER BY a LIMIT 10, 0 ", {}},
- {"7", "SELECT b FROM f1 ORDER BY a LIMIT '1'||'5', 3 ", {"p", "q", "r"}},
+ {"7", "SELECT b FROM f1 ORDER BY a LIMIT CAST('1'||'5' AS INTEGER), 3 ", {"p", "q", "r"}},
{"8", "SELECT b FROM f1 ORDER BY a LIMIT 20, 10 ", {"u", "v", "w", "x", "y", "z"}},
{"9", "SELECT a FROM f1 ORDER BY a DESC LIMIT 18+4, 100 ", {4, 3, 2, 1}},
{"10", "SELECT b FROM f1 ORDER BY a LIMIT 0, 5 ", {"a", "b", "c", "d", "e"}},
diff --git a/test/sql-tap/in4.test.lua b/test/sql-tap/in4.test.lua
index 8c6917379..33947d0ab 100755
--- a/test/sql-tap/in4.test.lua
+++ b/test/sql-tap/in4.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(61)
+test:plan(52)
--!./tcltestrunner.lua
-- 2008 September 1
@@ -140,7 +140,7 @@ test:do_execsql_test(
test:do_execsql_test(
"in4-2.7",
[[
- SELECT b FROM t2 WHERE a IN ('1', '2')
+ SELECT b FROM t2 WHERE a IN (1, 2)
]], {
-- <in4-2.7>
"one", "two"
@@ -153,7 +153,6 @@ test:do_execsql_test(
SELECT b FROM t2 WHERE a IN ('', '0.0.0', '2')
]], {
-- <in4-2.8>
- "two"
-- </in4-2.8>
})
@@ -585,98 +584,6 @@ test:do_execsql_test(
-- </in4-4.6>
})
-test:do_execsql_test(
- "in4-4.11",
- [[
- CREATE TABLE t4b(a TEXT, b NUMBER, c INT PRIMARY KEY);
- INSERT INTO t4b VALUES('1.0',1,4);
- SELECT c FROM t4b WHERE a=b;
- ]], {
- -- <in4-4.11>
- 4
- -- </in4-4.11>
- })
-
-test:do_execsql_test(
- "in4-4.12",
- [[
- SELECT c FROM t4b WHERE b=a;
- ]], {
- -- <in4-4.12>
- 4
- -- </in4-4.12>
- })
-
-test:do_execsql_test(
- "in4-4.13",
- [[
- SELECT c FROM t4b WHERE +a=b;
- ]], {
- -- <in4-4.13>
- 4
- -- </in4-4.13>
- })
-
-test:do_execsql_test(
- "in4-4.14",
- [[
- SELECT c FROM t4b WHERE a=+b;
- ]], {
- -- <in4-4.14>
- 4
- -- </in4-4.14>
- })
-
-test:do_execsql_test(
- "in4-4.15",
- [[
- SELECT c FROM t4b WHERE +b=a;
- ]], {
- -- <in4-4.15>
- 4
- -- </in4-4.15>
- })
-
-test:do_execsql_test(
- "in4-4.16",
- [[
- SELECT c FROM t4b WHERE b=+a;
- ]], {
- -- <in4-4.16>
- 4
- -- </in4-4.16>
- })
-
-test:do_execsql_test(
- "in4-4.17",
- [[
- SELECT c FROM t4b WHERE a IN (b);
- ]], {
- -- <in4-4.17>
- 4
- -- </in4-4.17>
- })
-
-test:do_execsql_test(
- "in4-4.18",
- [[
- SELECT c FROM t4b WHERE b IN (a);
- ]], {
- -- <in4-4.18>
- 4
- -- </in4-4.18>
- })
-
-test:do_execsql_test(
- "in4-4.19",
- [[
- SELECT c FROM t4b WHERE +b IN (a);
- ]], {
- -- <in4-4.19>
- 4
- -- </in4-4.19>
- })
-
-- MUST_WORK_TEST
-- Tarantool: TBI: Need to support collations. Depends on #2121
-- test:do_execsql_test(
diff --git a/test/sql-tap/join.test.lua b/test/sql-tap/join.test.lua
index 840b780a3..51e0ecb79 100755
--- a/test/sql-tap/join.test.lua
+++ b/test/sql-tap/join.test.lua
@@ -1034,7 +1034,6 @@ test:do_execsql_test(
SELECT * FROM t1 NATURAL JOIN t2
]], {
-- <join-11.9>
- "one", "1", "two", "2"
-- </join-11.9>
})
diff --git a/test/sql-tap/limit.test.lua b/test/sql-tap/limit.test.lua
index 870233942..a7d1451f7 100755
--- a/test/sql-tap/limit.test.lua
+++ b/test/sql-tap/limit.test.lua
@@ -441,7 +441,7 @@ test:do_catchsql_test(
test:do_execsql_test(
"limit-6.5.2",
[[
- SELECT * FROM t6 LIMIT '12'
+ SELECT * FROM t6 LIMIT 12
]], {
-- <limit-6.5>
1, 2, 3, 4
diff --git a/test/sql-tap/tkt-9a8b09f8e6.test.lua b/test/sql-tap/tkt-9a8b09f8e6.test.lua
index cb5348ab4..ac89c7df2 100755
--- a/test/sql-tap/tkt-9a8b09f8e6.test.lua
+++ b/test/sql-tap/tkt-9a8b09f8e6.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(49)
+test:plan(47)
--!./tcltestrunner.lua
-- 2014 June 26
@@ -189,20 +189,9 @@ test:do_execsql_test(
SELECT x FROM t2 WHERE x IN ('1');
]], {
-- <3.3>
- 1
-- </3.3>
})
-test:do_execsql_test(
- 3.4,
- [[
- SELECT x FROM t2 WHERE x IN ('1');
- ]], {
- -- <3.4>
- 1
- -- </3.4>
- })
-
test:do_execsql_test(
3.5,
[[
@@ -229,20 +218,9 @@ test:do_execsql_test(
SELECT x FROM t2 WHERE '1' IN (x);
]], {
-- <3.7>
- 1
-- </3.7>
})
-test:do_execsql_test(
- 3.8,
- [[
- SELECT x FROM t2 WHERE '1' IN (x);
- ]], {
- -- <3.8>
- 1
- -- </3.8>
- })
-
test:do_execsql_test(
4.1,
[[
diff --git a/test/sql-tap/tkt-fc7bd6358f.test.lua b/test/sql-tap/tkt-fc7bd6358f.test.lua
deleted file mode 100755
index fe5d6200f..000000000
--- a/test/sql-tap/tkt-fc7bd6358f.test.lua
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env tarantool
-test = require("sqltester")
-test:plan(50)
-
---!./tcltestrunner.lua
--- 2013 March 05
---
--- The author disclaims copyright to this source code. In place of
--- a legal notice, here is a blessing:
---
--- May you do good and not evil.
--- May you find forgiveness for yourself and forgive others.
--- May you share freely, never taking more than you give.
---
--------------------------------------------------------------------------
--- This file implements regression tests for sql library. Specifically,
--- it tests that ticket [fc7bd6358f]:
---
--- The following SQL yields an incorrect result (zero rows) in all
--- versions of sql between 3.6.14 and 3.7.15.2:
---
--- CREATE TABLE t(textid TEXT);
--- INSERT INTO t VALUES('12');
--- INSERT INTO t VALUES('34');
--- CREATE TABLE i(intid INTEGER PRIMARY KEY);
--- INSERT INTO i VALUES(12);
--- INSERT INTO i VALUES(34);
---
--- SELECT t1.textid AS a, i.intid AS b, t2.textid AS c
--- FROM t t1, i, t t2
--- WHERE t1.textid = i.intid
--- AND t1.textid = t2.textid;
---
--- The correct result should be two rows, one with 12|12|12 and the other
--- with 34|34|34. With this bug, no rows are returned. Bisecting shows that
--- this bug was introduced with check-in [dd4d67a67454] on 2009-04-23.
---
--- ["set","testdir",[["file","dirname",["argv0"]]]]
--- ["source",[["testdir"],"\/tester.tcl"]]
-test:do_test(
- "tkt-fc7bd6358f.100",
- function()
- return test:execsql [[
- CREATE TABLE t(textid TEXT PRIMARY KEY);
- INSERT INTO t VALUES('12');
- INSERT INTO t VALUES('34');
- CREATE TABLE i(intid INTEGER PRIMARY KEY);
- INSERT INTO i VALUES(12);
- INSERT INTO i VALUES(34);
- ]]
- end, {
- -- <tkt-fc7bd6358f.100>
-
- -- </tkt-fc7bd6358f.100>
- })
-
--- ["unset","-nocomplain","from"]
--- ["unset","-nocomplain","where"]
--- ["unset","-nocomplain","a"]
--- ["unset","-nocomplain","b"]
-local froms = {
- "FROM t t1, i, t t2",
- "FROM i, t t1, t t2",
- "FROM t t1, t t2, i",
-}
-local wheres = {
- "WHERE t1.textid=i.intid AND t1.textid=t2.textid",
- "WHERE i.intid=t1.textid AND t1.textid=t2.textid",
- "WHERE t1.textid=i.intid AND i.intid=t2.textid",
- "WHERE t1.textid=i.intid AND t2.textid=i.intid",
- "WHERE i.intid=t1.textid AND i.intid=t2.textid",
- "WHERE i.intid=t1.textid AND t2.textid=i.intid",
- "WHERE t1.textid=t2.textid AND i.intid=t2.textid",
- "WHERE t1.textid=t2.textid AND t2.textid=i.intid",
-}
-for a, from in ipairs(froms) do
- for b, where in ipairs(wheres) do
- test:do_test(
- string.format("tkt-fc7bd6358f.110.%s.%s.1", a, b),
- function()
- return test:execsql(string.format("SELECT t1.textid, i.intid, t2.textid %s %s", from, where))
- end, {
- "12", 12, "12", "34", 34, "34"
- })
-
- test:do_test(
- string.format("tkt-fc7bd6358f.110.%s.%s.2", a, b),
- function()
- return test:execsql(string.format("SELECT t1.textid, i.intid, t2.textid %s %s", from, where))
- end, {
- "12", 12, "12", "34", 34, "34"
- })
-
- end
-end
-
-test:do_test(
- "tkt-fc7bd6358f.200",
- function()
- return test:execsql [[
- DROP TABLE t;
- DROP TABLE i;
- ]]
- end, {
- -- <tkt-fc7bd6358f.100>
-
- -- </tkt-fc7bd6358f.100>
- })
-
-test:finish_test()
-
diff --git a/test/sql-tap/transitive1.test.lua b/test/sql-tap/transitive1.test.lua
index e96056580..96895b4a7 100755
--- a/test/sql-tap/transitive1.test.lua
+++ b/test/sql-tap/transitive1.test.lua
@@ -338,7 +338,7 @@ test:do_execsql_test(
ON tvshow.idshow = episode.idshow
LEFT JOIN seasons
ON seasons.idshow = episode.idshow
- AND seasons.season = episode.c12
+ AND seasons.season = CAST(episode.c12 AS INTEGER)
JOIN path
ON files.idpath = path.idpath
LEFT JOIN bookmark
@@ -378,7 +378,7 @@ test:do_execsql_test(
FROM episodeview
JOIN tvshowview ON tvshowview.idShow = episodeview.idShow
JOIN seasons ON (seasons.idShow = tvshowview.idShow
- AND seasons.season = episodeview.c12)
+ AND seasons.season = CAST(episodeview.c12 AS INTEGER))
JOIN files ON files.idFile = episodeview.idFile
JOIN tvshowlinkpath ON tvshowlinkpath.idShow = tvshowview.idShow
JOIN path ON path.idPath = tvshowlinkpath.idPath
diff --git a/test/sql-tap/whereB.test.lua b/test/sql-tap/whereB.test.lua
deleted file mode 100755
index fe5e28c70..000000000
--- a/test/sql-tap/whereB.test.lua
+++ /dev/null
@@ -1,900 +0,0 @@
-#!/usr/bin/env tarantool
-test = require("sqltester")
-test:plan(63)
-
---!./tcltestrunner.lua
--- 2009 August 13
---
--- The author disclaims copyright to this source code. In place of
--- a legal notice, here is a blessing:
---
--- May you do good and not evil.
--- May you find forgiveness for yourself and forgive others.
--- May you share freely, never taking more than you give.
---
--------------------------------------------------------------------------
--- This file implements regression tests for sql library. The
--- focus of this file is testing WHERE clause conditions with
--- subtle affinity issues.
---
--- ["set","testdir",[["file","dirname",["argv0"]]]]
--- ["source",[["testdir"],"\/tester.tcl"]]
--- For this set of tests:
---
--- * t1.y holds an integer value with affinity NONE
--- * t2.b holds a text value with affinity TEXT
---
--- These values are not equal and because neither affinity is NUMERIC
--- no type conversion occurs.
---
-test:do_execsql_test(
- "whereB-1.1",
- [[
- CREATE TABLE t1(x INT primary key,y INT ); -- affinity of t1.y is NONE
- INSERT INTO t1 VALUES(1,99);
-
- CREATE TABLE t2(a INT primary key, b TEXT); -- affinity of t2.b is TEXT
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,'99');
-
- SELECT x, a, y=b FROM t1, t2 ORDER BY +x, +a;
- ]],
- {
- -- <whereB-1.1>
- 1, 2, true
- -- </whereB-1.1>
- })
-
-test:do_execsql_test(
- "whereB-1.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-1.2>
- 1, 2, true
- -- </whereB-1.2>
- })
-
-test:do_execsql_test(
- "whereB-1.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-1.3>
- 1, 2, true
- -- </whereB-1.3>
- })
-
-test:do_execsql_test(
- "whereB-1.4",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-1.4>
- 1, 2, true
- -- </whereB-1.4>
- })
-
-test:do_execsql_test(
- "whereB-1.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-1.100>
- 1, 2, true
- -- </whereB-1.100>
- })
-
-test:do_execsql_test(
- "whereB-1.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-1.101>
- 1, 2, true
- -- </whereB-1.101>
- })
-
-test:do_execsql_test(
- "whereB-1.102",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-1.102>
- 1, 2, true
- -- </whereB-1.102>
- })
-
-test:do_execsql_test(
- "whereB-2.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y TEXT);
- INSERT INTO t1 VALUES(1,'99');
-
- CREATE TABLE t2(a INT primary key, b SCALAR);
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2, 99);
-
- SELECT x, a, y=b FROM t1, t2 ORDER BY +x, +a;
- ]],
- {
- -- <whereB-2.1>
- 1, 2, false
- -- </whereB-2.1>
- })
-
-test:do_execsql_test(
- "whereB-2.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-2.2>
-
- -- </whereB-2.2>
- })
-
-test:do_execsql_test(
- "whereB-2.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-2.3>
-
- -- </whereB-2.3>
- })
-
-test:do_execsql_test(
- "whereB-2.4",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-2.4>
-
- -- </whereB-2.4>
- })
-
-test:do_execsql_test(
- "whereB-2.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-2.100>
-
- -- </whereB-2.100>
- })
-
-test:do_execsql_test(
- "whereB-2.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-2.101>
-
- -- </whereB-2.101>
- })
-
-test:do_execsql_test(
- "whereB-2.102",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-2.102>
-
- -- </whereB-2.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds a text value with affinity NONE
--- * t2.b holds an integer value with affinity NONE
---
--- These values are not equal and because neither affinity is NUMERIC
--- no type conversion occurs.
---
-test:do_execsql_test(
- "whereB-3.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y SCALAR); -- affinity of t1.y is NONE
- INSERT INTO t1 VALUES(1,99);
-
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,'99');
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-3.1>
- 1, 2, false
- -- </whereB-3.1>
- })
-
-test:do_execsql_test(
- "whereB-3.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-3.2>
-
- -- </whereB-3.2>
- })
-
-test:do_execsql_test(
- "whereB-3.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-3.3>
-
- -- </whereB-3.3>
- })
-
-test:do_execsql_test(
- "whereB-3.4",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-3.4>
-
- -- </whereB-3.4>
- })
-
-test:do_execsql_test(
- "whereB-3.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-3.100>
-
- -- </whereB-3.100>
- })
-
-test:do_execsql_test(
- "whereB-3.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-3.101>
-
- -- </whereB-3.101>
- })
-
-test:do_execsql_test(
- "whereB-3.102",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-3.102>
-
- -- </whereB-3.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds a text value with affinity NONE
--- * t2.b holds an integer value with affinity NUMERIC
---
--- Because t2.b has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-4.1",
- [[
- DROP TABLE IF EXISTS t1;
- DROP TABLE IF EXISTS t2;
-
- CREATE TABLE t1(x INT primary key, y SCALAR); -- affinity of t1.y is NONE
- INSERT INTO t1 VALUES(1,'99');
-
- CREATE TABLE t2(a INT primary key, b NUMBER); -- affinity of t2.b is NUMERIC
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,99);
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-4.1>
- 1, 2, true
- -- </whereB-4.1>
- })
-
-test:do_execsql_test(
- "whereB-4.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-4.2>
- 1, 2, true
- -- </whereB-4.2>
- })
-
-test:do_execsql_test(
- "whereB-4.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-4.3>
- 1, 2, true
- -- </whereB-4.3>
- })
-
-test:do_execsql_test(
- "whereB-4.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-4.4>
- 1, 2, true
- -- </whereB-4.4>
- })
-
-test:do_execsql_test(
- "whereB-4.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-4.100>
- 1, 2, true
- -- </whereB-4.100>
- })
-
-test:do_execsql_test(
- "whereB-4.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-4.101>
- 1, 2, true
- -- </whereB-4.101>
- })
-
-test:do_execsql_test(
- "whereB-4.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-4.102>
- 1, 2, true
- -- </whereB-4.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds a text value with affinity NONE
--- * t2.b holds an integer value with affinity INTEGER
---
--- Because t2.b has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-5.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y SCALAR); -- affinity of t1.y is NONE
- INSERT INTO t1 VALUES(1,'99');
-
- CREATE TABLE t2(a INT primary key, b INT); -- affinity of t2.b is INTEGER
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,99);
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-5.1>
- 1, 2, true
- -- </whereB-5.1>
- })
-
-test:do_execsql_test(
- "whereB-5.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-5.2>
- 1, 2, true
- -- </whereB-5.2>
- })
-
-test:do_execsql_test(
- "whereB-5.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-5.3>
- 1, 2, true
- -- </whereB-5.3>
- })
-
-test:do_execsql_test(
- "whereB-5.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-5.4>
- 1, 2, true
- -- </whereB-5.4>
- })
-
-test:do_execsql_test(
- "whereB-5.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-5.100>
- 1, 2, true
- -- </whereB-5.100>
- })
-
-test:do_execsql_test(
- "whereB-5.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-5.101>
- 1, 2, true
- -- </whereB-5.101>
- })
-
-test:do_execsql_test(
- "whereB-5.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-5.102>
- 1, 2, true
- -- </whereB-5.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds a text value with affinity NONE
--- * t2.b holds an integer value with affinity REAL
---
--- Because t2.b has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-6.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y SCALAR); -- affinity of t1.y is NONE
- INSERT INTO t1 VALUES(1,'99');
-
- CREATE TABLE t2(a INT primary key, b NUMBER); -- affinity of t2.b is REAL
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,99.0);
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-6.1>
- 1, 2, true
- -- </whereB-6.1>
- })
-
-test:do_execsql_test(
- "whereB-6.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-6.2>
- 1, 2, true
- -- </whereB-6.2>
- })
-
-test:do_execsql_test(
- "whereB-6.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-6.3>
- 1, 2, true
- -- </whereB-6.3>
- })
-
-test:do_execsql_test(
- "whereB-6.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-6.4>
- 1, 2, true
- -- </whereB-6.4>
- })
-
-test:do_execsql_test(
- "whereB-6.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-6.100>
- 1, 2, true
- -- </whereB-6.100>
- })
-
-test:do_execsql_test(
- "whereB-6.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-6.101>
- 1, 2, true
- -- </whereB-6.101>
- })
-
-test:do_execsql_test(
- "whereB-6.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-6.102>
- 1, 2, true
- -- </whereB-6.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds an integer value with affinity NUMERIC
--- * t2.b holds a text value with affinity NONE
---
--- Because t1.y has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-7.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y NUMBER); -- affinity of t1.y is NUMERIC
- INSERT INTO t1 VALUES(1,99);
-
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,'99');
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-7.1>
- 1, 2, true
- -- </whereB-7.1>
- })
-
-test:do_execsql_test(
- "whereB-7.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-7.2>
- 1, 2, true
- -- </whereB-7.2>
- })
-
-test:do_execsql_test(
- "whereB-7.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-7.3>
- 1, 2, true
- -- </whereB-7.3>
- })
-
-test:do_execsql_test(
- "whereB-7.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-7.4>
- 1, 2, true
- -- </whereB-7.4>
- })
-
-test:do_execsql_test(
- "whereB-7.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-7.100>
- 1, 2, true
- -- </whereB-7.100>
- })
-
-test:do_execsql_test(
- "whereB-7.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-7.101>
- 1, 2, true
- -- </whereB-7.101>
- })
-
-test:do_execsql_test(
- "whereB-7.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-7.102>
- 1, 2, true
- -- </whereB-7.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds an integer value with affinity INTEGER
--- * t2.b holds a text value with affinity NONE
---
--- Because t1.y has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-8.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y INT); -- affinity of t1.y is INTEGER
- INSERT INTO t1 VALUES(1,99);
-
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,'99');
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-8.1>
- 1, 2, true
- -- </whereB-8.1>
- })
-
-test:do_execsql_test(
- "whereB-8.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-8.2>
- 1, 2, true
- -- </whereB-8.2>
- })
-
-test:do_execsql_test(
- "whereB-8.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-8.3>
- 1, 2, true
- -- </whereB-8.3>
- })
-
-test:do_execsql_test(
- "whereB-8.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-8.4>
- 1, 2, true
- -- </whereB-8.4>
- })
-
-test:do_execsql_test(
- "whereB-8.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-8.100>
- 1, 2, true
- -- </whereB-8.100>
- })
-
-test:do_execsql_test(
- "whereB-8.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-8.101>
- 1, 2, true
- -- </whereB-8.101>
- })
-
-test:do_execsql_test(
- "whereB-8.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-8.102>
- 1, 2, true
- -- </whereB-8.102>
- })
-
--- For this set of tests:
---
--- * t1.y holds an integer value with affinity REAL
--- * t2.b holds a text value with affinity NONE
---
--- Because t1.y has a numeric affinity, type conversion should occur
--- and the two fields should be equal.
---
-test:do_execsql_test(
- "whereB-9.1",
- [[
- DROP TABLE t1;
- DROP TABLE t2;
-
- CREATE TABLE t1(x INT primary key, y NUMBER); -- affinity of t1.y is REAL
- INSERT INTO t1 VALUES(1,99.0);
-
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
- CREATE INDEX t2b ON t2(b);
- INSERT INTO t2 VALUES(2,'99');
-
- SELECT x, a, y=b FROM t1, t2;
- ]],
- {
- -- <whereB-9.1>
- 1, 2, true
- -- </whereB-9.1>
- })
-
-test:do_execsql_test(
- "whereB-9.2",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-9.2>
- 1, 2, true
- -- </whereB-9.2>
- })
-
-test:do_execsql_test(
- "whereB-9.3",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-9.3>
- 1, 2, true
- -- </whereB-9.3>
- })
-
-test:do_execsql_test(
- "whereB-9.4",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-9.4>
- 1, 2, true
- -- </whereB-9.4>
- })
-
-test:do_execsql_test(
- "whereB-9.100",
- [[
- DROP INDEX t2b ON t2;
- SELECT x, a, y=b FROM t1, t2 WHERE y=b;
- ]],
- {
- -- <whereB-9.100>
- 1, 2, true
- -- </whereB-9.100>
- })
-
-test:do_execsql_test(
- "whereB-9.101",
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE b=y;
- ]],
- {
- -- <whereB-9.101>
- 1, 2, true
- -- </whereB-9.101>
- })
-
-test:do_execsql_test(
- "whereB-9.102",
- -- In this case the unary "+" operator shouldn't
- -- affect result set of query.
- [[
- SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
- ]],
- {
- -- <whereB-9.102>
- 1, 2, true
- -- </whereB-9.102>
- })
-
-test:finish_test()
-
diff --git a/test/sql-tap/whereC.test.lua b/test/sql-tap/whereC.test.lua
index 89459dee3..58c049553 100755
--- a/test/sql-tap/whereC.test.lua
+++ b/test/sql-tap/whereC.test.lua
@@ -55,9 +55,9 @@ test:do_execsql_test(
test:test("main", function()
local data = {{"SELECT i FROM t1 WHERE a=1 AND b=2 AND i>3", {4, 5}},
-- {"SELECT i FROM t1 WHERE rowid='12'", {12}},
- {"SELECT i FROM t1 WHERE a=1 AND b='2'", {3, 4, 5}},
- {"SELECT i FROM t1 WHERE a=1 AND b='2' AND i>'3'", {4, 5}},
- {"SELECT i FROM t1 WHERE a=1 AND b='2' AND i<5", {3, 4}},
+ {"SELECT i FROM t1 WHERE a=1 AND b=2", {3, 4, 5}},
+ {"SELECT i FROM t1 WHERE a=1 AND b=2 AND i>3", {4, 5}},
+ {"SELECT i FROM t1 WHERE a=1 AND b=2 AND i<5", {3, 4}},
{"SELECT i FROM t1 WHERE a=2 AND b=2 AND i<12", {10, 11}},
{"SELECT i FROM t1 WHERE a IN(1, 2) AND b=2 AND i<11", {3, 4, 5, 10}},
{"SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 12", {10, 11, 12}},
@@ -66,7 +66,7 @@ test:test("main", function()
{"SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 12 AND 10", {}},
{"SELECT i FROM t1 WHERE a=2 AND b=2 AND i<NULL", {}},
{"SELECT i FROM t1 WHERE a=2 AND b=2 AND i>=NULL", {}},
- {"SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5", {3, 4}}}
+ {"SELECT i FROM t1 WHERE a=1 AND b=2 AND i<4.5", {3, 4}}}
-- {"SELECT i FROM t1 WHERE rowid IS '12'", {12}}}
for tn, t in ipairs(data) do
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
` (4 preceding siblings ...)
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-29 23:51 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error imeevma
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
Thank you for review! My answers and new patch below.
On 22.06.2020 15:25, Nikita Pettik wrote:
> On 17 Jun 15:36, imeevma@tarantool.org wrote:
>> @@ -2399,14 +2387,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
>> default: res2 = res>=0; break;
>> }
>>
>> - /* Undo any changes made by mem_apply_type() to the input registers. */
>> - assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
>> - pIn1->flags = flags1;
>> - pIn1->field_type = ft_p1;
>> - assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
>> - pIn3->flags = flags3;
>> - pIn3->field_type = ft_p3;
>> -
>
> Replace these assertions with relevant ones.
>
Not sure if this is necessary, since now we have much less flag
changes after removal of mem_apply_type().
>> @@ -3496,8 +3476,6 @@ case OP_SeekGT: { /* jump, in3 */
>> pIn3 = &aMem[int_field];
>> if ((pIn3->flags & MEM_Null) != 0)
>> goto skip_truncate;
>> - if ((pIn3->flags & MEM_Str) != 0)
>> - mem_apply_numeric_type(pIn3);
>> int64_t i;
>> if ((pIn3->flags & MEM_Int) == MEM_Int) {
>> i = pIn3->u.i;
>
> Could you substitute routine below with mem_check_types()
> (or whatever this function is called)?
>
Partially substituted.
>> @@ -3590,6 +3568,26 @@ skip_truncate:
>> assert(oc!=OP_SeekLT || r.default_rc==+1);
>>
>> r.aMem = &aMem[pOp->p3];
>
> Code below definitely lacks some comments.
>
Fixed.
>> + for (int i = 0; i < r.nField; ++i) {
>> + enum field_type type = r.key_def->parts[i].type;
>> + struct Mem *mem = &r.aMem[i];
>> + if ((mem->flags & MEM_Str) != 0 && sql_type_is_numeric(type)) {
>
> What if key_def contains scalar/any type?
>
It will be fine since mem_check_type() process these cases.
>> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>> + field_type_strs[type], mem_type_to_str(mem));
>> + goto abort_due_to_error;
>> + }
>> + if (mem_check_types(mem, type) == 0)
>> + continue;
>> + if ((mem->flags & MEM_Real) != 0 &&
>> + (type == FIELD_TYPE_INTEGER ||
>> + type == FIELD_TYPE_UNSIGNED)) {
>> + res = 1;
>> + goto seek_not_found;
>> + }
>> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>> + field_type_strs[type], mem_type_to_str(mem));
>> + goto abort_due_to_error;
>> + }
>> #ifdef SQL_DEBUG
>> { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
>> #endif
>> @@ -4717,6 +4715,27 @@ case OP_IdxGE: { /* jump */
>> r.default_rc = 0;
>> }
>> r.aMem = &aMem[pOp->p3];
>> + for (int i = 0; i < r.nField; ++i) {
>> + struct Mem *mem = &r.aMem[i];
>> + enum mp_type mp_type = sql_value_type(mem);
>> + enum field_type field_type = r.key_def->parts[i].type;
>> + if (field_type == FIELD_TYPE_SCALAR ||
>> + mem->field_type == FIELD_TYPE_SCALAR)
>> + continue;
>> + bool is_nullable = r.key_def->parts[i].nullable_action ==
>> + ON_CONFLICT_ACTION_NONE;
>> + if (field_mp_plain_type_is_compatible(field_type, mp_type,
>> + is_nullable))
>> + continue;
>
> Why this procedure is different from one in Seek* opcode
> handling routine? Could you put it in one function and reuse?
> Also lacks comments.
>
At Seek*, we convert numbers to use them in an iterator. This is
not so in Idx*. In addition, Seek* is used only once during a
selection from space, but Idx* can be used more than once, so we
cannot convert here.
>> + if (!sql_type_is_numeric(field_type) ||
>> + !(mp_type == MP_INT || mp_type == MP_UINT ||
>> + mp_type == MP_DOUBLE || mp_type == MP_FLOAT)) {
>> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>> + mem_type_to_str(mem),
>> + field_type_strs[field_type]);
>> + goto abort_due_to_error;
>> + }
>> + }
>> diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
>> index 6d8768865..1d7c76670 100644
>> --- a/src/box/sql/wherecode.c
>> +++ b/src/box/sql/wherecode.c
>> @@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
>> }
>> }
>>
>> -/**
>> - types[i] = FIELD_TYPE_SCALAR;
>> - }
>> - }
>> -}
>> -
>> /*
>> * Generate code for a single equality term of the WHERE clause. An equality
>> * term can be either X=expr or X IN (...). pTerm is the term to be
>> testcase(pRangeStart->wtFlags & TERM_VIRTUAL);
>> if (sqlExprIsVector(pRight) == 0) {
>> @@ -1049,94 +950,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
>> }
>> struct index_def *idx_pk = space->index[0]->def;
>> uint32_t pk_part_count = idx_pk->key_def->part_count;
>> - /*
>> - * Tarantool's iterator over integer fields doesn't
>> - * tolerate floating point values. Hence, if term
>> - * is equality comparison and value of operand is
>> - * not integer, we can skip it since it always
>> - * results in false: INT a == 0.5 -> false;
>> - * It is done using OP_MustBeInt facilities.
>> - * In case term is greater comparison (a > ?), we
>> - * should notify OP_SeekGT to process truncation of
>> - * floating point value: a > 0.5 -> a >= 1;
>> - * It is done by setting P5 flag for OP_Seek*.
>> - * It is worth mentioning that we do not need
>> - * this step when it comes for less (<) comparison
>> - * of nullable field. Key is NULL in this case:
>> - * values are ordered as NULL, ... NULL, min_value,
>> - * so to fetch min value we pass NULL to GT iterator.
>> - * The only exception is less comparison in
>> - * conjunction with ORDER BY DESC clause:
>> - * in such situation we use LE iterator and
>> - * truncated value to compare. But then
>> - * pRangeStart == NULL.
>> - * This procedure is correct for compound index:
>> - * only one comparison of less/greater type can be
>> - * used at the same time. For instance,
>> - * a < 1.5 AND b > 0.5 is handled by SeekGT using
>> - * column a and fetching column b from tuple and
>> - * OP_Le comparison.
>> - *
>> - * Note that OP_ApplyType, which is emitted before
>> - * OP_Seek** doesn't truncate floating point to
>> - * integer. That's why we need this routine.
>> - * Also, note that terms are separated by OR
>> - * predicates, so we consider term as sequence
>> - * of AND'ed predicates.
>> - */
>> - size_t addrs_sz;
>> - int *seek_addrs = region_alloc_array(&pParse->region,
>> - typeof(seek_addrs[0]), nEq,
>> - &addrs_sz);
>> - if (seek_addrs == NULL) {
>> - diag_set(OutOfMemory, addrs_sz, "region_alloc_array",
>> - "seek_addrs");
>> - pParse->is_aborted = true;
>> - return 0;
>
> Solid code removal. I won't review it, I hope you verified that all
> tests are working as desired.
>
Sure.
>> - memset(seek_addrs, 0, addrs_sz);
>> - for (int i = 0; i < nEq; i++) {
>> - enum field_type type = idx_def->key_def->parts[i].type;
>> - if (type == FIELD_TYPE_INTEGER ||
>> - type == FIELD_TYPE_UNSIGNED) {
>> - /*
>> - * OP_MustBeInt consider NULLs as
>> - * non-integer values, so firstly
>> - * check whether value is NULL or not.
>> - */
>> - seek_addrs[i] = sqlVdbeAddOp1(v, OP_IsNull,
>> - regBase);
>> - sqlVdbeAddOp2(v, OP_MustBeInt, regBase + i,
>> - addrNxt);
>> - start_types[i] = FIELD_TYPE_SCALAR;
>> - /*
>> - * We need to notify column cache
>> - * that type of value may change
>> - * so we should fetch value from
>> - * tuple again rather then copy
>> - * from register.
>> - */
>> - sql_expr_type_cache_change(pParse, regBase + i,
>> - 1);
>> - }
>> - }
>> - /* Inequality constraint comes always at the end of list. */
>> - part_count = idx_def->key_def->part_count;
>> - if (pRangeStart != NULL) {
>> - /*
>> - * nEq == 0 means that filter condition
>> - * contains only inequality.
>> - */
>> - uint32_t ineq_idx = nEq == 0 ? 0 : nEq - 1;
>> - assert(ineq_idx < part_count);
>> - enum field_type ineq_type =
>> - idx_def->key_def->parts[ineq_idx].type;
>> - if (ineq_type == FIELD_TYPE_INTEGER ||
>> - ineq_type == FIELD_TYPE_UNSIGNED)
>> - force_integer_reg = regBase + nEq;
>> - }
>> - emit_apply_type(pParse, regBase, nConstraint - bSeekPastNull,
>> - start_types);
>> if (pLoop->nSkip > 0 && nConstraint == pLoop->nSkip) {
>> /* The skip-scan logic inside the call to codeAllEqualityConstraints()
>> * above has already left the cursor sitting on the correct row,
>> --- /dev/null
>> +++ b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
>
> Same note: I'd better use .sql test format and/or amalgamate it with
> already existing test file.
>
I was said that TAP is preferred.
>> @@ -0,0 +1,281 @@
>> +#!/usr/bin/env tarantool
>> +test = require("sqltester")
>> +test:plan(32)
>> +
>> +--
>> +
>> +test:execsql([[
>> + CREATE TABLE t1(x TEXT primary key);
>> + INSERT INTO t1 VALUES('1');
>> + CREATE TABLE t2(x INTEGER primary key);
>> + INSERT INTO t2 VALUES(1);
>> + CREATE TABLE t3(x DOUBLE primary key);
>> + INSERT INTO t3 VALUES(1.0);
>
> What about table with scalar/any fields?
>
I think this is too big a problem to solve it here.
New patch:
From 64653f49b79f2888243a76c30425d762acd301db Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Thu, 25 Jun 2020 12:39:19 +0300
Subject: [PATCH] sql: remove implicit cast for comparison
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch removes implicit cast for comparison.
Closes #4230
@TarantoolBot document
Title: remove implicit cast for comparison
After this patch-set, there will be no implicit casts for
comparison. This means that the values of the field types STRING,
BOOLEAN and VARBINARY can be compared with the values of the same
field type. Any numerical value can be compared with any other
numerical value.
Example:
For comparison:
```
tarantool> box.execute([[SELECT '1' > 0;]])
---
- null
- "Type mismatch: can not convert '1' (type: text) to numeric"
...
tarantool> box.execute([[SELECT true > X'33';]])
---
- null
- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to varbinary'
...
tarantool> box.execute([[SELECT 1.23 > 123;]])
---
- metadata:
- name: 1.23 > 123
type: boolean
rows:
- [false]
...
```
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index a609fa985..f531a2241 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2283,8 +2283,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
- enum field_type ft_p1 = pIn1->field_type;
- enum field_type ft_p3 = pIn3->field_type;
if ((flags1 | flags3)&MEM_Null) {
/* One or both operands are NULL */
if (pOp->p5 & SQL_NULLEQ) {
@@ -2343,22 +2341,17 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
} else {
enum field_type type = pOp->p5 & FIELD_TYPE_MASK;
if (sql_type_is_numeric(type)) {
- if ((flags1 | flags3)&MEM_Str) {
- if ((flags1 & MEM_Str) == MEM_Str) {
- mem_apply_numeric_type(pIn1);
- testcase( flags3!=pIn3->flags); /* Possible if pIn1==pIn3 */
- flags3 = pIn3->flags;
- }
- if ((flags3 & MEM_Str) == MEM_Str) {
- if (mem_apply_numeric_type(pIn3) != 0) {
- diag_set(ClientError,
- ER_SQL_TYPE_MISMATCH,
- sql_value_to_diag_str(pIn3),
- "numeric");
- goto abort_due_to_error;
- }
-
- }
+ if ((flags1 & MEM_Str) == MEM_Str) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1),
+ "numeric");
+ goto abort_due_to_error;
+ }
+ if ((flags3 & MEM_Str) == MEM_Str) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn3),
+ "numeric");
+ goto abort_due_to_error;
}
/* Handle the common case of integer comparison here, as an
* optimization, to avoid a call to sqlMemCompare()
@@ -2391,22 +2384,17 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
} else if (type == FIELD_TYPE_STRING) {
- if ((flags1 & MEM_Str) == 0 &&
- (flags1 & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
- testcase( pIn1->flags & MEM_Int);
- testcase( pIn1->flags & MEM_Real);
- sqlVdbeMemStringify(pIn1);
- testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn));
- flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
- assert(pIn1!=pIn3);
+ if ((flags1 & MEM_Str) == 0) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ mem_type_to_str(pIn3),
+ mem_type_to_str(pIn1));
+ goto abort_due_to_error;
}
- if ((flags3 & MEM_Str) == 0 &&
- (flags3 & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
- testcase( pIn3->flags & MEM_Int);
- testcase( pIn3->flags & MEM_Real);
- sqlVdbeMemStringify(pIn3);
- testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn));
- flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
+ if ((flags3 & MEM_Str) == 0) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ mem_type_to_str(pIn1),
+ mem_type_to_str(pIn3));
+ goto abort_due_to_error;
}
}
assert(pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0);
@@ -2422,14 +2410,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
default: res2 = res>=0; break;
}
- /* Undo any changes made by mem_apply_type() to the input registers. */
- assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
- pIn1->flags = flags1;
- pIn1->field_type = ft_p1;
- assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
- pIn3->flags = flags3;
- pIn3->field_type = ft_p3;
-
if (pOp->p5 & SQL_STOREP2) {
iCompare = res;
res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */
@@ -3524,8 +3504,6 @@ case OP_SeekGT: { /* jump, in3 */
pIn3 = &aMem[int_field];
if ((pIn3->flags & MEM_Null) != 0)
goto skip_truncate;
- if ((pIn3->flags & MEM_Str) != 0)
- mem_apply_numeric_type(pIn3);
int64_t i;
if ((pIn3->flags & MEM_Int) == MEM_Int) {
i = pIn3->u.i;
@@ -3617,7 +3595,38 @@ skip_truncate:
assert(oc!=OP_SeekGE || r.default_rc==+1);
assert(oc!=OP_SeekLT || r.default_rc==+1);
+ /*
+ * Make sure that the types of all the fields in the tuple
+ * that will be used in the iterator match the field types
+ * of the space.
+ */
r.aMem = &aMem[pOp->p3];
+ for (int i = 0; i < r.nField; ++i) {
+ enum field_type type = r.key_def->parts[i].type;
+ struct Mem *mem = &r.aMem[i];
+ if (mem_check_type(mem, type) == 0 ||
+ mem_convert_numeric(mem, type, true) == 0)
+ continue;
+ /*
+ * If the number was not converted without loss,
+ * we will not find tuples using the EQ iterator.
+ */
+ if ((mem->flags & MEM_Real) != 0 &&
+ (type == FIELD_TYPE_INTEGER ||
+ type == FIELD_TYPE_UNSIGNED)) {
+ assert(eqOnly == 1);
+ res = 1;
+ goto seek_not_found;
+ }
+ if ((mem->flags & (MEM_Int | MEM_UInt)) != 0 &&
+ type == FIELD_TYPE_DOUBLE && eqOnly == 1) {
+ res = 1;
+ goto seek_not_found;
+ }
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ field_type_strs[type], mem_type_to_str(mem));
+ goto abort_due_to_error;
+ }
#ifdef SQL_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
#endif
@@ -4744,7 +4753,25 @@ case OP_IdxGE: { /* jump */
assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
r.default_rc = 0;
}
+
+ /*
+ * Make sure that the types of all the fields in the tuple
+ * that will be used in the iterator comparable with the
+ * fields of the space.
+ */
r.aMem = &aMem[pOp->p3];
+ for (int i = 0; i < r.nField; ++i) {
+ enum field_type type = r.key_def->parts[i].type;
+ struct Mem *mem = &r.aMem[i];
+ if (mem_check_type(mem, type) == 0)
+ continue;
+ if (sql_type_is_numeric(type) &&
+ (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
+ continue;
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ field_type_strs[type], mem_type_to_str(mem));
+ goto abort_due_to_error;
+ }
#ifdef SQL_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
#endif
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 6d8768865..1d7c76670 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
}
}
-/**
- * Code an OP_ApplyType opcode to apply the column type string
- * @types to the n registers starting at @base.
- *
- * As an optimization, SCALAR entries (which are no-ops) at the
- * beginning and end of @types are ignored. If all entries in
- * @types are SCALAR, then no code gets generated.
- *
- * This routine makes its own copy of @types so that the caller is
- * free to modify @types after this routine returns.
- */
-static void
-emit_apply_type(Parse *pParse, int base, int n, enum field_type *types)
-{
- Vdbe *v = pParse->pVdbe;
- if (types == NULL) {
- assert(pParse->db->mallocFailed);
- return;
- }
- assert(v != 0);
-
- /*
- * Adjust base and n to skip over SCALAR entries at the
- * beginning and end of the type sequence.
- */
- while (n > 0 && types[0] == FIELD_TYPE_SCALAR) {
- n--;
- base++;
- types++;
- }
- while (n > 1 && types[n - 1] == FIELD_TYPE_SCALAR) {
- n--;
- }
-
- if (n > 0) {
- enum field_type *types_dup = field_type_sequence_dup(pParse,
- types, n);
- sqlVdbeAddOp4(v, OP_ApplyType, base, n, 0,
- (char *) types_dup, P4_DYNAMIC);
- sql_expr_type_cache_change(pParse, base, n);
- }
-}
-
-/**
- * Expression @rhs, which is the RHS of a comparison operation, is
- * either a vector of n elements or, if n==1, a scalar expression.
- * Before the comparison operation, types @types are to be applied
- * to the @rhs values. This function modifies entries within the
- * field sequence to SCALAR if either:
- *
- * * the comparison will be performed with no type, or
- * * the type change in @types is guaranteed not to change the value.
- */
-static void
-expr_cmp_update_rhs_type(struct Expr *rhs, int n, enum field_type *types)
-{
- for (int i = 0; i < n; i++) {
- Expr *p = sqlVectorFieldSubexpr(rhs, i);
- enum field_type expr_type = sql_expr_type(p);
- if (sql_type_result(expr_type, types[i]) == FIELD_TYPE_SCALAR ||
- sql_expr_needs_no_type_change(p, types[i])) {
- types[i] = FIELD_TYPE_SCALAR;
- }
- }
-}
-
/*
* Generate code for a single equality term of the WHERE clause. An equality
* term can be either X=expr or X IN (...). pTerm is the term to be
@@ -644,8 +578,7 @@ static int
codeAllEqualityTerms(Parse * pParse, /* Parsing context */
WhereLevel * pLevel, /* Which nested loop of the FROM we are coding */
int bRev, /* Reverse the order of IN operators */
- int nExtraReg, /* Number of extra registers to allocate */
- enum field_type **res_type)
+ int nExtraReg) /* Number of extra registers to allocate */
{
u16 nEq; /* The number of == or IN constraints to code */
u16 nSkip; /* Number of left-most columns to skip */
@@ -669,9 +602,6 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
nReg = pLoop->nEq + nExtraReg;
pParse->nMem += nReg;
- enum field_type *type = sql_index_type_str(pParse->db, idx_def);
- assert(type != NULL || pParse->db->mallocFailed);
-
if (nSkip) {
int iIdxCur = pLevel->iIdxCur;
sqlVdbeAddOp1(v, (bRev ? OP_Last : OP_Rewind), iIdxCur);
@@ -714,17 +644,7 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
sqlVdbeAddOp2(v, OP_SCopy, r1, regBase + j);
}
}
- if (pTerm->eOperator & WO_IN) {
- if (pTerm->pExpr->flags & EP_xIsSelect) {
- /* No type ever needs to be (or should be) applied to a value
- * from the RHS of an "? IN (SELECT ...)" expression. The
- * sqlFindInIndex() routine has already ensured that the
- * type of the comparison has been applied to the value.
- */
- if (type != NULL)
- type[j] = FIELD_TYPE_SCALAR;
- }
- } else if ((pTerm->eOperator & WO_ISNULL) == 0) {
+ if ((pTerm->eOperator & (WO_IN | WO_ISNULL)) == 0) {
Expr *pRight = pTerm->pExpr->pRight;
if (sqlExprCanBeNull(pRight)) {
sqlVdbeAddOp2(v, OP_IsNull, regBase + j,
@@ -733,7 +653,6 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
}
}
}
- *res_type = type;
return regBase;
}
@@ -904,10 +823,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
int iIdxCur; /* The VDBE cursor for the index */
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
- /* Types for start of range constraint. */
- enum field_type *start_types;
- /* Types for end of range constraint */
- enum field_type *end_types = NULL;
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
int force_integer_reg = -1; /* If non-negative: number of
@@ -994,17 +909,7 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
* and store the values of those terms in an array of registers
* starting at regBase.
*/
- regBase =
- codeAllEqualityTerms(pParse, pLevel, bRev, nExtraReg,
- &start_types);
- if (start_types != NULL && nTop) {
- uint32_t len = 0;
- for (enum field_type *tmp = &start_types[nEq];
- *tmp != field_type_MAX; tmp++, len++);
- uint32_t sz = len * sizeof(enum field_type);
- end_types = sqlDbMallocRaw(db, sz);
- memcpy(end_types, &start_types[nEq], sz);
- }
+ regBase = codeAllEqualityTerms(pParse, pLevel, bRev, nExtraReg);
addrNxt = pLevel->addrNxt;
testcase(pRangeStart && (pRangeStart->eOperator & WO_LE) != 0);
@@ -1029,10 +934,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
VdbeCoverage(v);
}
- if (start_types) {
- expr_cmp_update_rhs_type(pRight, nBtm,
- &start_types[nEq]);
- }
nConstraint += nBtm;
testcase(pRangeStart->wtFlags & TERM_VIRTUAL);
if (sqlExprIsVector(pRight) == 0) {
@@ -1049,94 +950,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
}
struct index_def *idx_pk = space->index[0]->def;
uint32_t pk_part_count = idx_pk->key_def->part_count;
- /*
- * Tarantool's iterator over integer fields doesn't
- * tolerate floating point values. Hence, if term
- * is equality comparison and value of operand is
- * not integer, we can skip it since it always
- * results in false: INT a == 0.5 -> false;
- * It is done using OP_MustBeInt facilities.
- * In case term is greater comparison (a > ?), we
- * should notify OP_SeekGT to process truncation of
- * floating point value: a > 0.5 -> a >= 1;
- * It is done by setting P5 flag for OP_Seek*.
- * It is worth mentioning that we do not need
- * this step when it comes for less (<) comparison
- * of nullable field. Key is NULL in this case:
- * values are ordered as NULL, ... NULL, min_value,
- * so to fetch min value we pass NULL to GT iterator.
- * The only exception is less comparison in
- * conjunction with ORDER BY DESC clause:
- * in such situation we use LE iterator and
- * truncated value to compare. But then
- * pRangeStart == NULL.
- * This procedure is correct for compound index:
- * only one comparison of less/greater type can be
- * used at the same time. For instance,
- * a < 1.5 AND b > 0.5 is handled by SeekGT using
- * column a and fetching column b from tuple and
- * OP_Le comparison.
- *
- * Note that OP_ApplyType, which is emitted before
- * OP_Seek** doesn't truncate floating point to
- * integer. That's why we need this routine.
- * Also, note that terms are separated by OR
- * predicates, so we consider term as sequence
- * of AND'ed predicates.
- */
- size_t addrs_sz;
- int *seek_addrs = region_alloc_array(&pParse->region,
- typeof(seek_addrs[0]), nEq,
- &addrs_sz);
- if (seek_addrs == NULL) {
- diag_set(OutOfMemory, addrs_sz, "region_alloc_array",
- "seek_addrs");
- pParse->is_aborted = true;
- return 0;
- }
- memset(seek_addrs, 0, addrs_sz);
- for (int i = 0; i < nEq; i++) {
- enum field_type type = idx_def->key_def->parts[i].type;
- if (type == FIELD_TYPE_INTEGER ||
- type == FIELD_TYPE_UNSIGNED) {
- /*
- * OP_MustBeInt consider NULLs as
- * non-integer values, so firstly
- * check whether value is NULL or not.
- */
- seek_addrs[i] = sqlVdbeAddOp1(v, OP_IsNull,
- regBase);
- sqlVdbeAddOp2(v, OP_MustBeInt, regBase + i,
- addrNxt);
- start_types[i] = FIELD_TYPE_SCALAR;
- /*
- * We need to notify column cache
- * that type of value may change
- * so we should fetch value from
- * tuple again rather then copy
- * from register.
- */
- sql_expr_type_cache_change(pParse, regBase + i,
- 1);
- }
- }
- /* Inequality constraint comes always at the end of list. */
- part_count = idx_def->key_def->part_count;
- if (pRangeStart != NULL) {
- /*
- * nEq == 0 means that filter condition
- * contains only inequality.
- */
- uint32_t ineq_idx = nEq == 0 ? 0 : nEq - 1;
- assert(ineq_idx < part_count);
- enum field_type ineq_type =
- idx_def->key_def->parts[ineq_idx].type;
- if (ineq_type == FIELD_TYPE_INTEGER ||
- ineq_type == FIELD_TYPE_UNSIGNED)
- force_integer_reg = regBase + nEq;
- }
- emit_apply_type(pParse, regBase, nConstraint - bSeekPastNull,
- start_types);
if (pLoop->nSkip > 0 && nConstraint == pLoop->nSkip) {
/* The skip-scan logic inside the call to codeAllEqualityConstraints()
* above has already left the cursor sitting on the correct row,
@@ -1146,10 +959,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
op = aStartOp[(start_constraints << 2) +
(startEq << 1) + bRev];
assert(op != 0);
- for (uint32_t i = 0; i < nEq; ++i) {
- if (seek_addrs[i] != 0)
- sqlVdbeJumpHere(v, seek_addrs[i]);
- }
sqlVdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
nConstraint);
/* If this is Seek* opcode, and IPK is detected in the
@@ -1189,13 +998,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
addrNxt);
VdbeCoverage(v);
}
- if (end_types) {
- expr_cmp_update_rhs_type(pRight, nTop, end_types);
- emit_apply_type(pParse, regBase + nEq, nTop,
- end_types);
- } else {
- assert(pParse->db->mallocFailed);
- }
nConstraint += nTop;
testcase(pRangeEnd->wtFlags & TERM_VIRTUAL);
@@ -1209,8 +1011,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
endEq = 0;
nConstraint++;
}
- sqlDbFree(db, start_types);
- sqlDbFree(db, end_types);
/* Top of the loop body */
pLevel->p2 = sqlVdbeCurrentAddr(v);
diff --git a/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
new file mode 100755
index 000000000..b405a11b6
--- /dev/null
+++ b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
@@ -0,0 +1,281 @@
+#!/usr/bin/env tarantool
+test = require("sqltester")
+test:plan(32)
+
+--
+-- Make sure that there is no implicit cast between string and
+-- number.
+--
+test:do_catchsql_test(
+ "gh-4230-1",
+ [[
+ SELECT '1' > 0;
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-2",
+ [[
+ SELECT 0 > '1';
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+test:execsql([[
+ CREATE TABLE t (i INT PRIMARY KEY, d DOUBLE, n NUMBER, s STRING);
+ INSERT INTO t VALUES (1, 1.0, 1, '2'), (2, 2.0, 2.0, '2');
+ ]])
+
+test:do_catchsql_test(
+ "gh-4230-3",
+ [[
+ SELECT * from t where i > s;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-4",
+ [[
+ SELECT * from t WHERE s > i;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-5",
+ [[
+ SELECT * from t WHERE d > s;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-6",
+ [[
+ SELECT * from t WHERE s > d;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-7",
+ [[
+ SELECT * from t WHERE i = 1 and n > s;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-8",
+ [[
+ SELECT * from t WHERE i = 2 and s > n;
+ ]], {
+ 1, "Type mismatch: can not convert 2 to numeric"
+ })
+
+test:execsql([[
+ CREATE TABLE t1(x TEXT primary key);
+ INSERT INTO t1 VALUES('1');
+ CREATE TABLE t2(x INTEGER primary key);
+ INSERT INTO t2 VALUES(1);
+ CREATE TABLE t3(x DOUBLE primary key);
+ INSERT INTO t3 VALUES(1.0);
+]])
+
+test:do_catchsql_test(
+ "gh-4230-9",
+ [[
+ SELECT x FROM t1 WHERE x IN (1);
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+
+test:do_catchsql_test(
+ "gh-4230-10",
+ [[
+ SELECT x FROM t1 WHERE x IN (1.0);
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+test:do_execsql_test(
+ "gh-4230-11",
+ [[
+ SELECT x FROM t1 WHERE x IN ('1');
+ ]], {
+ "1"
+ })
+
+test:do_execsql_test(
+ "gh-4230-12",
+ [[
+ SELECT x FROM t1 WHERE x IN ('1.0');
+ ]], {
+ })
+
+test:do_catchsql_test(
+ "gh-4230-13",
+ [[
+ SELECT x FROM t1 WHERE 1 IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-14",
+ [[
+ SELECT x FROM t1 WHERE 1.0 IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert 1 to numeric"
+ })
+
+test:do_execsql_test(
+ "gh-4230-15",
+ [[
+ SELECT x FROM t1 WHERE '1' IN (x);
+ ]], {
+ -- <2.7>
+ "1"
+ -- </2.7>
+ })
+
+test:do_execsql_test(
+ "gh-4230-16",
+ [[
+ SELECT x FROM t1 WHERE '1.0' IN (x);
+ ]], {
+ })
+
+test:do_execsql_test(
+ "gh-4230-17",
+ [[
+ SELECT x FROM t2 WHERE x IN (1);
+ ]], {
+ 1
+ })
+
+
+test:do_execsql_test(
+ "gh-4230-18",
+ [[
+ SELECT x FROM t2 WHERE x IN (1.0);
+ ]], {
+ 1
+ })
+
+test:do_catchsql_test(
+ "gh-4230-19",
+ [[
+ SELECT x FROM t2 WHERE x IN ('1');
+ ]], {
+ 1, "Type mismatch: can not convert integer to text"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-20",
+ [[
+ SELECT x FROM t2 WHERE x IN ('1.0');
+ ]], {
+ 1, "Type mismatch: can not convert integer to text"
+ })
+
+test:do_execsql_test(
+ "gh-4230-21",
+ [[
+ SELECT x FROM t2 WHERE 1 IN (x);
+ ]], {
+ 1
+ })
+
+test:do_execsql_test(
+ "gh-4230-22",
+ [[
+ SELECT x FROM t2 WHERE 1.0 IN (x);
+ ]], {
+ 1
+ })
+
+test:do_catchsql_test(
+ "gh-4230-23",
+ [[
+ SELECT x FROM t2 WHERE '1' IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert integer to text"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-24",
+ [[
+ SELECT x FROM t2 WHERE '1.0' IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert integer to text"
+ })
+
+test:do_execsql_test(
+ "gh-4230-25",
+ [[
+ SELECT x FROM t3 WHERE x IN (1);
+ ]], {
+ 1
+ })
+
+test:do_execsql_test(
+ "gh-4230-26",
+ [[
+ SELECT x FROM t3 WHERE x IN (1.0);
+ ]], {
+ 1
+ })
+
+test:do_catchsql_test(
+ "gh-4230-27",
+ [[
+ SELECT x FROM t3 WHERE x IN ('1');
+ ]], {
+ 1, "Type mismatch: can not convert double to text"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-28",
+ [[
+ SELECT x FROM t3 WHERE x IN ('1.0');
+ ]], {
+ 1, "Type mismatch: can not convert double to text"
+ })
+
+test:do_execsql_test(
+ "gh-4230-29",
+ [[
+ SELECT x FROM t3 WHERE 1 IN (x);
+ ]], {
+ 1
+ })
+
+test:do_execsql_test(
+ "gh-4230-30",
+ [[
+ SELECT x FROM t3 WHERE 1.0 IN (x);
+ ]], {
+ 1
+ })
+
+test:do_catchsql_test(
+ "gh-4230-31",
+ [[
+ SELECT x FROM t3 WHERE '1' IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert double to text"
+ })
+
+test:do_catchsql_test(
+ "gh-4230-32",
+ [[
+ SELECT x FROM t3 WHERE '1.0' IN (x);
+ ]], {
+ 1, "Type mismatch: can not convert double to text"
+ })
+
+test:finish_test()
diff --git a/test/sql-tap/identifier_case.test.lua b/test/sql-tap/identifier_case.test.lua
index 2a00626fc..1d56ffb44 100755
--- a/test/sql-tap/identifier_case.test.lua
+++ b/test/sql-tap/identifier_case.test.lua
@@ -242,11 +242,11 @@ data = {
{ 2, [[ 'a' < 'b' collate "binary" ]], {0, {true}}},
{ 3, [[ 'a' < 'b' collate 'binary' ]], {1, [[Syntax error at line 1 near ''binary'']]}},
{ 4, [[ 'a' < 'b' collate "unicode" ]], {0, {true}}},
- { 5, [[ 5 < 'b' collate "unicode" ]], {0, {true}}},
+ { 5, [[ 5 < 'b' collate "unicode" ]], {1, "Type mismatch: can not convert b to numeric"}},
{ 6, [[ 5 < 'b' collate unicode ]], {1,"Collation 'UNICODE' does not exist"}},
- { 7, [[ 5 < 'b' collate "unicode_ci" ]], {0, {true}}},
+ { 7, [[ 5 < 'b' collate "unicode_ci" ]], {1, "Type mismatch: can not convert b to numeric"}},
{ 8, [[ 5 < 'b' collate NONE ]], {1, "Collation 'NONE' does not exist"}},
- { 9, [[ 5 < 'b' collate "none" ]], {0, {true}}},
+ { 9, [[ 5 < 'b' collate "none" ]], {1, "Type mismatch: can not convert b to numeric"}},
}
for _, row in ipairs(data) do
diff --git a/test/sql-tap/in1.test.lua b/test/sql-tap/in1.test.lua
index 570cc1779..e2f498889 100755
--- a/test/sql-tap/in1.test.lua
+++ b/test/sql-tap/in1.test.lua
@@ -637,12 +637,12 @@ test:do_test(
"in-11.2",
function()
-- The '2' should be coerced into 2 because t6.b is NUMERIC
- return test:execsql [[
+ return test:catchsql [[
SELECT * FROM t6 WHERE b IN ('2');
]]
end, {
-- <in-11.2>
- 1, 2
+ 1, "Type mismatch: can not convert 2 to numeric"
-- </in-11.2>
})
diff --git a/test/sql-tap/in4.test.lua b/test/sql-tap/in4.test.lua
index 33947d0ab..a494e846f 100755
--- a/test/sql-tap/in4.test.lua
+++ b/test/sql-tap/in4.test.lua
@@ -147,12 +147,13 @@ test:do_execsql_test(
-- </in4-2.7>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"in4-2.8",
[[
SELECT b FROM t2 WHERE a IN ('', '0.0.0', '2')
]], {
-- <in4-2.8>
+ 1, "Type mismatch: can not convert integer to text"
-- </in4-2.8>
})
diff --git a/test/sql-tap/insert3.test.lua b/test/sql-tap/insert3.test.lua
index b92bc508e..3276f0db2 100755
--- a/test/sql-tap/insert3.test.lua
+++ b/test/sql-tap/insert3.test.lua
@@ -59,7 +59,7 @@ test:do_execsql_test(
[[
CREATE TABLE log2(rowid INTEGER PRIMARY KEY AUTOINCREMENT, x TEXT UNIQUE,y INT );
CREATE TRIGGER r2 BEFORE INSERT ON t1 FOR EACH ROW BEGIN
- UPDATE log2 SET y=y+1 WHERE x=new.b;
+ UPDATE log2 SET y=y+1 WHERE x=CAST(new.b AS STRING);
INSERT OR IGNORE INTO log2(x, y) VALUES(CAST(new.b AS STRING),1);
END;
INSERT INTO t1(a, b) VALUES('hi', 453);
diff --git a/test/sql-tap/join.test.lua b/test/sql-tap/join.test.lua
index 51e0ecb79..792302ab5 100755
--- a/test/sql-tap/join.test.lua
+++ b/test/sql-tap/join.test.lua
@@ -1028,22 +1028,23 @@ test:do_test(
-- </join-11.8>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"join-11.9",
[[
SELECT * FROM t1 NATURAL JOIN t2
]], {
-- <join-11.9>
+ 1, "Type mismatch: can not convert integer to text"
-- </join-11.9>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"join-11.10",
[[
SELECT * FROM t2 NATURAL JOIN t1
]], {
-- <join-11.10>
- 1, "one", 2, "two"
+ 1, "Type mismatch: can not convert 1 to numeric"
-- </join-11.10>
})
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index e0fe50bbe..3cef617f4 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -88,7 +88,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-1.4",
[[
- SELECT x75 FROM manycol WHERE x50=350
+ SELECT x75 FROM manycol WHERE x50='350'
]], {
-- <misc1-1.4>
"375"
@@ -98,7 +98,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-1.5",
[[
- SELECT x50 FROM manycol WHERE x99=599
+ SELECT x50 FROM manycol WHERE x99='599'
]], {
-- <misc1-1.5>
"550"
@@ -109,7 +109,7 @@ test:do_test(
"misc1-1.6",
function()
test:execsql("CREATE INDEX manycol_idx1 ON manycol(x99)")
- return test:execsql("SELECT x50 FROM manycol WHERE x99=899")
+ return test:execsql("SELECT x50 FROM manycol WHERE x99='899'")
end, {
-- <misc1-1.6>
"850"
@@ -129,7 +129,7 @@ test:do_execsql_test(
test:do_test(
"misc1-1.8",
function()
- test:execsql("DELETE FROM manycol WHERE x98=1234")
+ test:execsql("DELETE FROM manycol WHERE x98='1234'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.8>
@@ -140,7 +140,7 @@ test:do_test(
test:do_test(
"misc1-1.9",
function()
- test:execsql("DELETE FROM manycol WHERE x98=998")
+ test:execsql("DELETE FROM manycol WHERE x98='998'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.9>
@@ -151,7 +151,7 @@ test:do_test(
test:do_test(
"misc1-1.10",
function()
- test:execsql("DELETE FROM manycol WHERE x99=500")
+ test:execsql("DELETE FROM manycol WHERE x99='500'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.10>
@@ -162,7 +162,7 @@ test:do_test(
test:do_test(
"misc1-1.11",
function()
- test:execsql("DELETE FROM manycol WHERE x99=599")
+ test:execsql("DELETE FROM manycol WHERE x99='599'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.11>
@@ -479,9 +479,9 @@ local where = ""
test:do_test(
"misc1-10.1",
function()
- where = "WHERE x0>=0"
+ where = "WHERE x0>='0'"
for i = 1, 99, 1 do
- where = where .. " AND x"..i.."<>0"
+ where = where .. " AND x"..i.."<>'0'"
end
return test:catchsql("SELECT count(*) FROM manycol "..where.."")
end, {
@@ -496,7 +496,7 @@ test:do_test(
test:do_test(
"misc1-10.3",
function()
- where = string.gsub(where,"x0>=0", "x0=0")
+ where = string.gsub(where,"x0>='0'", "x0='0'")
return test:catchsql("DELETE FROM manycol "..where.."")
end, {
-- <misc1-10.3>
@@ -520,7 +520,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-10.6",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.6>
"101"
@@ -530,7 +530,7 @@ test:do_execsql_test(
test:do_test(
"misc1-10.7",
function()
- where = string.gsub(where, "x0=0", "x0=100")
+ where = string.gsub(where, "x0='0'", "x0='100'")
return test:catchsql("UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where.."")
end, {
-- <misc1-10.7>
@@ -541,7 +541,7 @@ test:do_test(
test:do_execsql_test(
"misc1-10.8",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.8>
"102"
@@ -563,7 +563,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-10.10",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.10>
"103"
@@ -619,13 +619,13 @@ test:do_execsql_test(
-- </misc1-12.1>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"misc1-12.2",
[[
SELECT '0'==0.0
]], {
-- <misc1-12.2>
- true
+ 1, "Type mismatch: can not convert 0 to numeric"
-- </misc1-12.2>
})
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index 9a969bf3c..f5a9b63fe 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -1912,7 +1912,7 @@ test:do_execsql_test(
test:do_execsql_test(
"select1-12.7",
[[
- SELECT * FROM t3 WHERE a=(SELECT 1);
+ SELECT * FROM t3 WHERE a=(SELECT '1');
]], {
-- <select1-12.7>
0, "1", "2"
@@ -1922,7 +1922,7 @@ test:do_execsql_test(
test:do_execsql_test(
"select1-12.8",
[[
- SELECT * FROM t3 WHERE a=(SELECT 2);
+ SELECT * FROM t3 WHERE a=(SELECT '2');
]], {
-- <select1-12.8>
diff --git a/test/sql-tap/select7.test.lua b/test/sql-tap/select7.test.lua
index e1e43c557..0d1390fd6 100755
--- a/test/sql-tap/select7.test.lua
+++ b/test/sql-tap/select7.test.lua
@@ -256,7 +256,7 @@ test:do_execsql_test(
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a TEXT primary key, b INT);
INSERT INTO t5 VALUES('123', 456);
- SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
+ SELECT typeof(a), a FROM t5 GROUP BY a HAVING CAST(a AS INTEGER)<b;
]], {
-- <select7-7.7>
"string", "123"
diff --git a/test/sql-tap/subquery.test.lua b/test/sql-tap/subquery.test.lua
index e0771825e..bad702de9 100755
--- a/test/sql-tap/subquery.test.lua
+++ b/test/sql-tap/subquery.test.lua
@@ -284,13 +284,13 @@ test:do_execsql_test(
-- </subquery-2.3.1>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"subquery-2.3.2",
[[
SELECT a IN (10.0, 20) FROM t3;
]], {
-- <subquery-2.3.2>
- false
+ 1, "Type mismatch: can not convert text to real"
-- </subquery-2.3.2>
})
diff --git a/test/sql-tap/tkt-9a8b09f8e6.test.lua b/test/sql-tap/tkt-9a8b09f8e6.test.lua
deleted file mode 100755
index ac89c7df2..000000000
--- a/test/sql-tap/tkt-9a8b09f8e6.test.lua
+++ /dev/null
@@ -1,506 +0,0 @@
-#!/usr/bin/env tarantool
-test = require("sqltester")
-test:plan(47)
-
---!./tcltestrunner.lua
--- 2014 June 26
---
--- The author disclaims copyright to this source code. In place of
--- a legal notice, here is a blessing:
---
--- May you do good and not evil.
--- May you find forgiveness for yourself and forgive others.
--- May you share freely, never taking more than you give.
---
--------------------------------------------------------------------------
--- This file implements regression tests for sql library.
---
--- This file implements tests to verify that ticket [9a8b09f8e6] has been
--- fixed.
---
--- ["set","testdir",[["file","dirname",["argv0"]]]]
--- ["source",[["testdir"],"\/tester.tcl"]]
-testprefix = "tkt-9a8b09f8e6"
--- MUST_WORK_TEST
-if (0 > 0)
- then
-end
-test:do_execsql_test(
- 1.1,
- [[
- CREATE TABLE t1(x TEXT primary key);
- INSERT INTO t1 VALUES('1');
- ]], {
- -- <1.1>
-
- -- </1.1>
- })
-
-test:do_execsql_test(
- 1.2,
- [[
- CREATE TABLE t2(x INTEGER primary key);
- INSERT INTO t2 VALUES(1);
- ]], {
- -- <1.2>
-
- -- </1.2>
- })
-
-test:do_execsql_test(
- 1.3,
- [[
- CREATE TABLE t3(x NUMBER primary key);
- INSERT INTO t3 VALUES(1.0);
- ]], {
- -- <1.3>
-
- -- </1.3>
- })
-
-test:do_execsql_test(
- 1.4,
- [[
- CREATE TABLE t4(x NUMBER primary key);
- INSERT INTO t4 VALUES(1.11);
- ]], {
- -- <1.4>
-
- -- </1.4>
- })
-
-test:do_execsql_test(
- 1.5,
- [[
- CREATE TABLE t5(id INT primary key, x INT , y TEXT);
- INSERT INTO t5 VALUES(1, 1, 'one');
- INSERT INTO t5 VALUES(2, 1, 'two');
- INSERT INTO t5 VALUES(3, 1.0, 'three');
- INSERT INTO t5 VALUES(4, 1.0, 'four');
- ]], {
- -- <1.5>
-
- -- </1.5>
- })
-
-test:do_execsql_test(
- 2.1,
- [[
- SELECT x FROM t1 WHERE x IN (1);
- ]], {
- -- <2.1>
- "1"
- -- </2.1>
- })
-
-test:do_execsql_test(
- 2.2,
- [[
- SELECT x FROM t1 WHERE x IN (1.0);
- ]], {
- -- <2.2>
- "1"
- -- </2.2>
- })
-
-test:do_execsql_test(
- 2.3,
- [[
- SELECT x FROM t1 WHERE x IN ('1');
- ]], {
- -- <2.3>
- "1"
- -- </2.3>
- })
-
-test:do_execsql_test(
- 2.4,
- [[
- SELECT x FROM t1 WHERE x IN ('1.0');
- ]], {
- -- <2.4>
-
- -- </2.4>
- })
-
-test:do_execsql_test(
- 2.5,
- [[
- SELECT x FROM t1 WHERE 1 IN (x);
- ]], {
- -- <2.5>
- "1"
- -- </2.5>
- })
-
-test:do_execsql_test(
- 2.6,
- [[
- SELECT x FROM t1 WHERE 1.0 IN (x);
- ]], {
- -- <2.6>
- "1"
- -- </2.6>
- })
-
-test:do_execsql_test(
- 2.7,
- [[
- SELECT x FROM t1 WHERE '1' IN (x);
- ]], {
- -- <2.7>
- "1"
- -- </2.7>
- })
-
-test:do_execsql_test(
- 2.8,
- [[
- SELECT x FROM t1 WHERE '1.0' IN (x);
- ]], {
- -- <2.8>
-
- -- </2.8>
- })
-
-test:do_execsql_test(
- 3.1,
- [[
- SELECT x FROM t2 WHERE x IN (1);
- ]], {
- -- <3.1>
- 1
- -- </3.1>
- })
-
-test:do_execsql_test(
- 3.2,
- [[
- SELECT x FROM t2 WHERE x IN (1.0);
- ]], {
- -- <3.2>
- 1
- -- </3.2>
- })
-
-test:do_execsql_test(
- 3.3,
- [[
- SELECT x FROM t2 WHERE x IN ('1');
- ]], {
- -- <3.3>
- -- </3.3>
- })
-
-test:do_execsql_test(
- 3.5,
- [[
- SELECT x FROM t2 WHERE 1 IN (x);
- ]], {
- -- <3.5>
- 1
- -- </3.5>
- })
-
-test:do_execsql_test(
- 3.6,
- [[
- SELECT x FROM t2 WHERE 1.0 IN (x);
- ]], {
- -- <3.6>
- 1
- -- </3.6>
- })
-
-test:do_execsql_test(
- 3.7,
- [[
- SELECT x FROM t2 WHERE '1' IN (x);
- ]], {
- -- <3.7>
- -- </3.7>
- })
-
-test:do_execsql_test(
- 4.1,
- [[
- SELECT x FROM t3 WHERE x IN (1);
- ]], {
- -- <4.1>
- 1.0
- -- </4.1>
- })
-
-test:do_execsql_test(
- 4.2,
- [[
- SELECT x FROM t3 WHERE x IN (1.0);
- ]], {
- -- <4.2>
- 1.0
- -- </4.2>
- })
-
-test:do_execsql_test(
- 4.3,
- [[
- SELECT x FROM t3 WHERE x IN ('1');
- ]], {
- -- <4.3>
- 1.0
- -- </4.3>
- })
-
-test:do_execsql_test(
- 4.4,
- [[
- SELECT x FROM t3 WHERE x IN ('1.0');
- ]], {
- -- <4.4>
- 1.0
- -- </4.4>
- })
-
-test:do_execsql_test(
- 4.5,
- [[
- SELECT x FROM t3 WHERE 1 IN (x);
- ]], {
- -- <4.5>
- 1.0
- -- </4.5>
- })
-
-test:do_execsql_test(
- 4.6,
- [[
- SELECT x FROM t3 WHERE 1.0 IN (x);
- ]], {
- -- <4.6>
- 1.0
- -- </4.6>
- })
-
-test:do_execsql_test(
- 4.7,
- [[
- SELECT x FROM t3 WHERE '1' IN (x);
- ]], {
- -- <4.7>
- 1
- -- </4.7>
- })
-
-test:do_execsql_test(
- 4.8,
- [[
- SELECT x FROM t3 WHERE '1.0' IN (x);
- ]], {
- -- <4.8>
- 1
- -- </4.8>
- })
-
-test:do_execsql_test(
- 5.1,
- [[
- SELECT x FROM t4 WHERE x IN (1);
- ]], {
- -- <5.1>
-
- -- </5.1>
- })
-
-test:do_execsql_test(
- 5.2,
- [[
- SELECT x FROM t4 WHERE x IN (1.0);
- ]], {
- -- <5.2>
-
- -- </5.2>
- })
-
-test:do_execsql_test(
- 5.3,
- [[
- SELECT x FROM t4 WHERE x IN ('1');
- ]], {
- -- <5.3>
-
- -- </5.3>
- })
-
-test:do_execsql_test(
- 5.4,
- [[
- SELECT x FROM t4 WHERE x IN ('1.0');
- ]], {
- -- <5.4>
-
- -- </5.4>
- })
-
-test:do_execsql_test(
- 5.5,
- [[
- SELECT x FROM t4 WHERE x IN (1.11);
- ]], {
- -- <5.5>
- 1.11
- -- </5.5>
- })
-
-test:do_execsql_test(
- 5.6,
- [[
- SELECT x FROM t4 WHERE x IN ('1.11');
- ]], {
- -- <5.6>
- 1.11
- -- </5.6>
- })
-
-test:do_execsql_test(
- 5.7,
- [[
- SELECT x FROM t4 WHERE 1 IN (x);
- ]], {
- -- <5.7>
-
- -- </5.7>
- })
-
-test:do_execsql_test(
- 5.8,
- [[
- SELECT x FROM t4 WHERE 1.0 IN (x);
- ]], {
- -- <5.8>
-
- -- </5.8>
- })
-
-test:do_execsql_test(
- 5.9,
- [[
- SELECT x FROM t4 WHERE '1' IN (x);
- ]], {
- -- <5.9>
-
- -- </5.9>
- })
-
-test:do_execsql_test(
- 5.10,
- [[
- SELECT x FROM t4 WHERE '1.0' IN (x);
- ]], {
- -- <5.10>
-
- -- </5.10>
- })
-
-test:do_execsql_test(
- 5.11,
- [[
- SELECT x FROM t4 WHERE 1.11 IN (x);
- ]], {
- -- <5.11>
- 1.11
- -- </5.11>
- })
-
-test:do_execsql_test(
- 5.12,
- [[
- SELECT x FROM t4 WHERE '1.11' IN (x);
- ]], {
- -- <5.12>
- 1.11
- -- </5.12>
- })
-
-test:do_execsql_test(
- 6.1,
- [[
- SELECT x, y FROM t5 WHERE x IN (1);
- ]], {
- -- <6.1>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.1>
- })
-
-test:do_execsql_test(
- 6.2,
- [[
- SELECT x, y FROM t5 WHERE x IN (1.0);
- ]], {
- -- <6.2>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.2>
- })
-
-test:do_execsql_test(
- 6.3,
- [[
- SELECT x, y FROM t5 WHERE x IN ('1');
- ]], {
- -- <6.3>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.3>
- })
-
-test:do_execsql_test(
- 6.4,
- [[
- SELECT x, y FROM t5 WHERE x IN ('1.0');
- ]], {
- -- <6.4>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.4>
- })
-
-test:do_execsql_test(
- 6.5,
- [[
- SELECT x, y FROM t5 WHERE 1 IN (x);
- ]], {
- -- <6.5>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.5>
- })
-
-test:do_execsql_test(
- 6.6,
- [[
- SELECT x, y FROM t5 WHERE 1.0 IN (x);
- ]], {
- -- <6.6>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.6>
- })
-
-test:do_execsql_test(
- 6.7,
- [[
- SELECT x, y FROM t5 WHERE '1' IN (x);
- ]], {
- -- <6.7>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.7>
- })
-
-test:do_execsql_test(
- 6.8,
- [[
- SELECT x, y FROM t5 WHERE '1.0' IN (x);
- ]], {
- -- <6.8>
- 1, "one", 1, "two", 1, "three", 1, "four"
- -- </6.8>
- })
-
-
-
-test:finish_test()
diff --git a/test/sql-tap/tkt-f973c7ac31.test.lua b/test/sql-tap/tkt-f973c7ac31.test.lua
index 82bdb52f8..381f29c65 100755
--- a/test/sql-tap/tkt-f973c7ac31.test.lua
+++ b/test/sql-tap/tkt-f973c7ac31.test.lua
@@ -39,9 +39,8 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".1",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='2' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='2' ORDER BY c2 DESC
]], {
-
})
test:do_execsql_test(
@@ -55,7 +54,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".3",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='5' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='5' ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -63,7 +62,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".4",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<=5 ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND c2<=5 ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -71,7 +70,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".5",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<='5' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND CAST(c2 AS STRING)<='5' ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -79,9 +78,8 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".6",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='2' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='2' ORDER BY c2 ASC
]], {
-
})
test:do_execsql_test(
@@ -95,7 +93,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".8",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='5' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='5' ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
@@ -103,7 +101,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".9",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<=5 ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND c2<=5 ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
@@ -111,7 +109,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".10",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<='5' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND CAST(c2 AS STRING)<='5' ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
diff --git a/test/sql-tap/tkt3493.test.lua b/test/sql-tap/tkt3493.test.lua
index de77e61e9..82ba828d0 100755
--- a/test/sql-tap/tkt3493.test.lua
+++ b/test/sql-tap/tkt3493.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(26)
+test:plan(25)
--!./tcltestrunner.lua
-- 2008 October 13
@@ -45,7 +45,7 @@ test:do_execsql_test(
[[
SELECT
CASE
- WHEN B.val = 1 THEN 'XYZ'
+ WHEN B.val = '1' THEN 'XYZ'
ELSE A.val
END AS Col1
FROM B
@@ -63,7 +63,7 @@ test:do_execsql_test(
[[
SELECT DISTINCT
CASE
- WHEN B.val = 1 THEN 'XYZ'
+ WHEN B.val = '1' THEN 'XYZ'
ELSE A.val
END AS Col1
FROM B
@@ -79,7 +79,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-1.4",
[[
- SELECT b.val, CASE WHEN b.val = 1 THEN 'xyz' ELSE b.val END AS col1 FROM b;
+ SELECT b.val, CASE WHEN b.val = '1' THEN 'xyz' ELSE b.val END AS col1 FROM b;
]], {
-- <tkt3493-1.4>
"1", "xyz", "2", "2"
@@ -91,7 +91,7 @@ test:do_execsql_test(
[[
SELECT DISTINCT
b.val,
- CASE WHEN b.val = 1 THEN 'xyz' ELSE b.val END AS col1
+ CASE WHEN b.val = '1' THEN 'xyz' ELSE b.val END AS col1
FROM b;
]], {
-- <tkt3493-1.5>
@@ -126,23 +126,13 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.1",
[[
- SELECT a=123 FROM t1 GROUP BY a
+ SELECT a='123' FROM t1 GROUP BY a
]], {
-- <tkt3493-2.2.1>
true
-- </tkt3493-2.2.1>
})
-test:do_execsql_test(
- "tkt3493-2.2.2",
- [[
- SELECT a=123 FROM t1
- ]], {
- -- <tkt3493-2.2.2>
- true
- -- </tkt3493-2.2.2>
- })
-
test:do_execsql_test(
"tkt3493-2.2.3",
[[
@@ -156,7 +146,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.4",
[[
- SELECT count(*), a=123 FROM t1
+ SELECT count(*), a='123' FROM t1
]], {
-- <tkt3493-2.2.4>
1, true
@@ -166,7 +156,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.5",
[[
- SELECT count(*), +a=123 FROM t1
+ SELECT count(*), +a='123' FROM t1
]], {
-- <tkt3493-2.2.5>
1, true
@@ -176,7 +166,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.3",
[[
- SELECT b='456' FROM t1 GROUP BY a
+ SELECT b = 456 FROM t1 GROUP BY a
]], {
-- <tkt3493-2.3.3>
true
@@ -186,7 +176,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.1",
[[
- SELECT b='456' FROM t1 GROUP BY b
+ SELECT b = 456 FROM t1 GROUP BY b
]], {
-- <tkt3493-2.3.1>
true
@@ -196,7 +186,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.2",
[[
- SELECT b='456' FROM t1
+ SELECT b = 456 FROM t1
]], {
-- <tkt3493-2.3.2>
true
@@ -206,7 +196,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.4.1",
[[
- SELECT typeof(a), a FROM t1 GROUP BY a HAVING a=123
+ SELECT typeof(a), a FROM t1 GROUP BY a HAVING a='123'
]], {
-- <tkt3493-2.4.1>
"string", "123"
@@ -216,7 +206,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.4.2",
[[
- SELECT typeof(a), a FROM t1 GROUP BY b HAVING a=123
+ SELECT typeof(a), a FROM t1 GROUP BY b HAVING a='123'
]], {
-- <tkt3493-2.4.2>
"string", "123"
@@ -226,7 +216,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.5.1",
[[
- SELECT typeof(b), b FROM t1 GROUP BY a HAVING b='456'
+ SELECT typeof(b), b FROM t1 GROUP BY a HAVING b=456
]], {
-- <tkt3493-2.5.1>
"integer", 456
@@ -236,7 +226,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.5.2",
[[
- SELECT typeof(b), b FROM t1 GROUP BY b HAVING b='456'
+ SELECT typeof(b), b FROM t1 GROUP BY b HAVING b=456
]], {
-- <tkt3493-2.5.2>
"integer", 456
diff --git a/test/sql-tap/transitive1.test.lua b/test/sql-tap/transitive1.test.lua
index 96895b4a7..cc7e066bf 100755
--- a/test/sql-tap/transitive1.test.lua
+++ b/test/sql-tap/transitive1.test.lua
@@ -63,7 +63,7 @@ test:do_execsql_test(
INSERT INTO t2 VALUES(2, 20,20,'20');
INSERT INTO t2 VALUES(3, 3,3,'3');
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c=20;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c='20';
]], {
-- <transitive1-200>
20, 20, "20"
@@ -73,7 +73,7 @@ test:do_execsql_test(
test:do_execsql_test(
"transitive1-210",
[[
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c>='20' ORDER BY +a;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c>='20' ORDER BY +a;
]], {
-- <transitive1-210>
3, 3, "3", 20, 20, "20"
@@ -83,7 +83,7 @@ test:do_execsql_test(
test:do_execsql_test(
"transitive1-220",
[[
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c<='20' ORDER BY +a;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c<='20' ORDER BY +a;
]], {
-- <transitive1-220>
20, 20, "20", 100, 100, "100"
@@ -402,7 +402,7 @@ test:do_execsql_test(
[[
CREATE TABLE x(i INTEGER PRIMARY KEY, y TEXT);
INSERT INTO x VALUES(10, '10');
- SELECT * FROM x WHERE x.y>='1' AND x.y<'2' AND x.i=x.y;
+ SELECT * FROM x WHERE x.y>='1' AND x.y<'2' AND CAST(x.i AS STRING)=x.y;
]], {
-- <transitive1-500>
10, "10"
@@ -430,7 +430,7 @@ test:do_execsql_test(
[[
CREATE TABLE t3(i INTEGER PRIMARY KEY, t TEXT);
INSERT INTO t3 VALUES(10, '10');
- SELECT * FROM t3 WHERE i=t AND t = '10 ';
+ SELECT * FROM t3 WHERE CAST(i AS STRING)=t AND t = '10 ';
]], {
-- <transitive1-520>
@@ -443,7 +443,7 @@ test:do_execsql_test(
CREATE TABLE u1(x TEXT PRIMARY KEY, y INTEGER, z TEXT);
CREATE INDEX i1 ON u1(x);
INSERT INTO u1 VALUES('00013', 13, '013');
- SELECT * FROM u1 WHERE x=y AND y=z AND z='013';
+ SELECT * FROM u1 WHERE CAST(x AS INTEGER)=y AND y=CAST(z AS INTEGER) AND z='013';
]], {
-- <transitive1-530>
"00013",13,"013"
diff --git a/test/sql-tap/where2.test.lua b/test/sql-tap/where2.test.lua
index f267be8e6..7348a855a 100755
--- a/test/sql-tap/where2.test.lua
+++ b/test/sql-tap/where2.test.lua
@@ -4,7 +4,7 @@ yaml = require("yaml")
fio = require("fio")
ffi = require("ffi")
-test:plan(74)
+test:plan(62)
ffi.cdef[[
int dup(int oldfd);
@@ -622,181 +622,12 @@ test:do_test(
-- </where2-6.6>
})
--- if X(356, "X!cmd", [=[["expr","[permutation] != \"no_optimization\""]]=])
--- then
- -- Ticket #2249. Make sure the OR optimization is not attempted if
- -- comparisons between columns of different affinities are needed.
- --
- test:do_test(
- "where2-6.7",
- function()
- test:execsql [[
- CREATE TABLE t2249a(a TEXT PRIMARY KEY, x VARCHAR(100));
- CREATE TABLE t2249b(b INTEGER PRIMARY KEY);
- INSERT INTO t2249a(a) VALUES('0123');
- INSERT INTO t2249b VALUES(123);
- ]]
- return queryplan([[
- -- Because a is type TEXT and b is type INTEGER, both a and b
- -- will attempt to convert to NUMERIC before the comparison.
- -- They will thus compare equal.
- --
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=b;
- ]])
- end, {
- -- <where2-6.7>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.7>
- })
-
- test:do_test(
- "where2-6.9",
- function()
- return queryplan([[
- -- The + operator doesn't affect RHS.
- --
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b;
- ]])
- end, {
- -- <where2-6.9>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.9>
- })
-
- test:do_test(
- "where2-6.9.2",
- function()
- -- The same thing but with the expression flipped around.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +b=a
- ]])
- end, {
- -- <where2-6.9.2>
- 123, "0123","nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.9.2>
- })
-
- test:do_test(
- "where2-6.10",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +a=+b;
- ]])
- end, {
- -- <where2-6.10>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.10>
- })
-
- test:do_test(
- "where2-6.11",
- function()
- -- This will not attempt the OR optimization because of the a=b
- -- comparison.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=b OR a='hello';
- ]])
- end, {
- -- <where2-6.11>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11>
- })
-
- test:do_test(
- "where2-6.11.2",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE b=a OR a='hello';
- ]])
- end, {
- -- <where2-6.11.2>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.2>
- })
-
- test:do_test(
- "where2-6.11.3",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE 'hello'=a OR b=a;
- ]])
- end, {
- -- <where2-6.11.3>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.3>
- })
-
- test:do_test(
- "where2-6.11.4",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR b=a;
- ]])
- end, {
- -- <where2-6.11.4>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.4>
- })
-
- -- These tests are not run if subquery support is not included in the
- -- build. This is because these tests test the "a = 1 OR a = 2" to
- -- "a IN (1, 2)" optimisation transformation, which is not enabled if
- -- subqueries and the IN operator is not available.
- --
- test:do_test(
- "where2-6.12",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b OR a='hello';
- ]])
- end, {
- -- <where2-6.12>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12>
- })
-
- test:do_test(
- "where2-6.12.2",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR +b=a;
- ]])
- end, {
- -- <where2-6.12.2>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12.2>
- })
-
- test:do_test(
- "where2-6.12.3",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +b=a OR a='hello';
- ]])
- end, {
- -- <where2-6.12.3>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12.3>
- })
-
- test:do_test(
- "where2-6.13",
- function()
- -- The addition of +a on the second term disabled the OR optimization.
- -- But we should still get the same empty-set result as in where2-6.9.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b OR +a='hello';
- ]])
- end, {
- -- <where2-6.13>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.13>
- })
-
-
+ test:execsql [[
+ CREATE TABLE t2249a(a TEXT PRIMARY KEY, x VARCHAR(100));
+ CREATE TABLE t2249b(b INTEGER PRIMARY KEY);
+ INSERT INTO t2249a(a) VALUES('0123');
+ INSERT INTO t2249b VALUES(123);
+ ]]
-- Variations on the order of terms in a WHERE clause in order
-- to make sure the OR optimizer can recognize them all.
diff --git a/test/sql-tap/where5.test.lua b/test/sql-tap/where5.test.lua
index 3aefcaca5..a93ba7854 100755
--- a/test/sql-tap/where5.test.lua
+++ b/test/sql-tap/where5.test.lua
@@ -34,7 +34,7 @@ test:do_test("where5-1.0", function()
INSERT INTO t3 SELECT CAST(x AS INTEGER) FROM t1;
]]
return test:execsql [[
- SELECT * FROM t1 WHERE x<0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<0
]]
end, {
-- <where5-1.0>
@@ -43,7 +43,7 @@ end, {
})
test:do_execsql_test("where5-1.1", [[
- SELECT * FROM t1 WHERE x<=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<=0
]], {
-- <where5-1.1>
'-1', '0'
@@ -51,7 +51,7 @@ test:do_execsql_test("where5-1.1", [[
})
test:do_execsql_test("where5-1.2", [[
- SELECT * FROM t1 WHERE x=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)=0
]], {
-- <where5-1.2>
'0'
@@ -59,7 +59,7 @@ test:do_execsql_test("where5-1.2", [[
})
test:do_execsql_test("where5-1.3", [[
- SELECT * FROM t1 WHERE x>=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)>=0
]], {
-- <where5-1.3>
'0', '1'
@@ -67,7 +67,7 @@ test:do_execsql_test("where5-1.3", [[
})
test:do_execsql_test("where5-1.4", [[
- SELECT * FROM t1 WHERE x>0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)>0
]], {
-- <where5-1.4>
'1'
@@ -75,7 +75,7 @@ test:do_execsql_test("where5-1.4", [[
})
test:do_execsql_test("where5-1.5", [[
- SELECT * FROM t1 WHERE x<>0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<>0
]], {
-- <where5-1.5>
'-1', '1'
diff --git a/test/sql/types.result b/test/sql/types.result
index 54aff460e..62161cfe1 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -339,12 +339,12 @@ box.execute("INSERT INTO tboolean VALUES (TRUE);")
box.execute("SELECT * FROM tboolean WHERE s1 = x'44';")
---
- null
-- 'Type mismatch: can not convert varbinary to boolean'
+- 'Type mismatch: can not convert boolean to varbinary'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 'abc';")
---
- null
-- 'Type mismatch: can not convert abc to boolean'
+- 'Type mismatch: can not convert boolean to text'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 1;")
---
@@ -606,14 +606,6 @@ box.execute("SELECT 18446744073709551615.0 > 18446744073709551615")
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:
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index bd14b342d..f9603c60d 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -151,7 +151,6 @@ 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 18446744073709551614;")
box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
` (5 preceding siblings ...)
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-29 23:52 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error imeevma
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
After previous patches, some functions and the ApplyType opcode
become unused, so this patch removes them.
Follow-up #4230
---
src/box/sql/expr.c | 43 -----------------------------------------
src/box/sql/insert.c | 14 --------------
src/box/sql/sqlInt.h | 25 ------------------------
src/box/sql/vdbe.c | 29 ---------------------------
src/box/sql/wherecode.c | 5 -----
5 files changed, 116 deletions(-)
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 745011d35..61ed89830 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -137,19 +137,6 @@ sql_expr_type(struct Expr *pExpr)
return pExpr->type;
}
-enum field_type *
-field_type_sequence_dup(struct Parse *parse, enum field_type *types,
- uint32_t len)
-{
- uint32_t sz = (len + 1) * sizeof(enum field_type);
- enum field_type *ret_types = sqlDbMallocRaw(parse->db, sz);
- if (ret_types == NULL)
- return NULL;
- memcpy(ret_types, types, sz);
- ret_types[len] = field_type_MAX;
- return ret_types;
-}
-
/*
* Set the collating sequence for expression pExpr to be the collating
* sequence named by pToken. Return a pointer to a new Expr node that
@@ -2246,36 +2233,6 @@ sqlExprCanBeNull(const Expr * p)
}
}
-bool
-sql_expr_needs_no_type_change(const struct Expr *p, enum field_type type)
-{
- u8 op;
- if (type == FIELD_TYPE_SCALAR)
- return true;
- while (p->op == TK_UPLUS || p->op == TK_UMINUS) {
- p = p->pLeft;
- }
- op = p->op;
- if (op == TK_REGISTER)
- op = p->op2;
- switch (op) {
- case TK_INTEGER:
- return type == FIELD_TYPE_INTEGER;
- case TK_FLOAT:
- return type == FIELD_TYPE_DOUBLE;
- case TK_STRING:
- return type == FIELD_TYPE_STRING;
- case TK_BLOB:
- return type == FIELD_TYPE_VARBINARY;
- case TK_COLUMN:
- /* p cannot be part of a CHECK constraint. */
- assert(p->iTable >= 0);
- return p->iColumn < 0 && sql_type_is_numeric(type);
- default:
- return false;
- }
-}
-
/*
* pX is the RHS of an IN operator. If pX is a SELECT statement
* that can be simplified to a direct table access, then return
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 8a89f9904..6639ceff0 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -41,20 +41,6 @@
#include "box/box.h"
#include "box/schema.h"
-enum field_type *
-sql_index_type_str(struct sql *db, const struct index_def *idx_def)
-{
- uint32_t column_count = idx_def->key_def->part_count;
- uint32_t sz = (column_count + 1) * sizeof(enum field_type);
- enum field_type *types = (enum field_type *) sqlDbMallocRaw(db, sz);
- if (types == NULL)
- return NULL;
- for (uint32_t i = 0; i < column_count; i++)
- types[i] = idx_def->key_def->parts[i].type;
- types[column_count] = field_type_MAX;
- return types;
-}
-
void
sql_emit_table_types(struct Vdbe *v, struct space_def *def, int reg)
{
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index f1d0345f9..59c62ebf9 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -3238,19 +3238,6 @@ int sqlExprIsTableConstant(Expr *, int);
int sqlExprIsInteger(Expr *, int *);
int sqlExprCanBeNull(const Expr *);
-/**
- * Return TRUE if the given expression is a constant which would
- * be unchanged by OP_ApplyType with the type given in the second
- * argument.
- *
- * This routine is used to determine if the OP_ApplyType operation
- * can be omitted. When in doubt return FALSE. A false negative
- * is harmless. A false positive, however, can result in the wrong
- * answer.
- */
-bool
-sql_expr_needs_no_type_change(const struct Expr *expr, enum field_type type);
-
/**
* This routine generates VDBE code that causes a single row of a
* single table to be deleted. Both the original table entry and
@@ -3875,10 +3862,6 @@ int sqlVarintLen(u64 v);
#define getVarint sqlGetVarint
#define putVarint sqlPutVarint
-/** Return string consisting of fields types of given index. */
-enum field_type *
-sql_index_type_str(struct sql *db, const struct index_def *idx_def);
-
/**
* Code an OP_ApplyType opcode that will force types
* for given range of register starting from @reg.
@@ -3920,14 +3903,6 @@ expr_cmp_mutual_type(struct Expr *pExpr);
enum field_type
sql_expr_type(struct Expr *pExpr);
-/**
- * This function duplicates first @len entries of types array
- * and terminates new array with field_type_MAX member.
- */
-enum field_type *
-field_type_sequence_dup(struct Parse *parse, enum field_type *types,
- uint32_t len);
-
/**
* Convert z to a 64-bit signed or unsigned integer.
* z must be decimal. This routine does *not* accept
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index f531a2241..cabe5aa9e 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2857,35 +2857,6 @@ case OP_Fetch: {
break;
}
-/* Opcode: ApplyType P1 P2 * P4 *
- * Synopsis: type(r[P1@P2])
- *
- * Apply types to a range of P2 registers starting with P1.
- *
- * P4 is a string that is P2 characters long. The nth character of the
- * string indicates the column type that should be used for the nth
- * memory cell in the range.
- */
-case OP_ApplyType: {
- enum field_type *types = pOp->p4.types;
- assert(types != NULL);
- assert(types[pOp->p2] == field_type_MAX);
- pIn1 = &aMem[pOp->p1];
- enum field_type type;
- while((type = *(types++)) != field_type_MAX) {
- assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
- assert(memIsValid(pIn1));
- if (mem_apply_type(pIn1, type) != 0) {
- diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- sql_value_to_diag_str(pIn1),
- field_type_strs[type]);
- goto abort_due_to_error;
- }
- pIn1++;
- }
- break;
-}
-
/* Opcode: CheckType P1 P2 * P4 *
* Synopsis: type(r[P1@P2])
*
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 1d7c76670..2459054ff 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -568,11 +568,6 @@ codeEqualityTerm(Parse * pParse, /* The parsing context */
* key value of the loop. If one or more IN operators appear, then
* this routine allocates an additional nEq memory cells for internal
* use.
- *
- * Before returning, @types is set to point to a buffer containing a
- * copy of the column types array of the index allocated using
- * sqlDbMalloc(). This array is passed to OP_ApplyType to provide
- * correct implicit conversions.
*/
static int
codeAllEqualityTerms(Parse * pParse, /* Parsing context */
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
` (6 preceding siblings ...)
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions imeevma
@ 2020-06-25 15:17 ` imeevma
2020-06-30 0:22 ` Nikita Pettik
7 siblings, 1 reply; 32+ messages in thread
From: imeevma @ 2020-06-25 15:17 UTC (permalink / raw)
To: korablev, tsafin, tarantool-patches
After this patch value and its type will be shown in description
of type mismatch error
---
src/box/sql/vdbe.c | 17 +-
src/box/sql/vdbemem.c | 13 +-
test/sql-tap/autoinc.test.lua | 4 +-
test/sql-tap/cast.test.lua | 16 +-
.../gh-3809-implicit-cast-assignment.test.lua | 60 +-
.../gh-4230-del-impl-cast-str-to-num.test.lua | 40 +-
...-4766-wrong-cast-from-blob-to-int.test.lua | 9 +-
test/sql-tap/identifier_case.test.lua | 6 +-
test/sql-tap/in1.test.lua | 2 +-
test/sql-tap/in4.test.lua | 2 +-
test/sql-tap/index1.test.lua | 4 +-
test/sql-tap/join.test.lua | 4 +-
test/sql-tap/misc1.test.lua | 2 +-
test/sql-tap/numcast.test.lua | 4 +-
test/sql-tap/select1.test.lua | 6 +-
test/sql-tap/select5.test.lua | 2 +-
test/sql-tap/subquery.test.lua | 2 +-
test/sql-tap/tkt-80e031a00f.test.lua | 4 +-
test/sql/boolean.result | 1484 ++++++++---------
test/sql/integer-overflow.result | 4 +-
test/sql/persistency.result | 2 +-
test/sql/types.result | 61 +-
22 files changed, 867 insertions(+), 881 deletions(-)
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index cabe5aa9e..2bc8c9817 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2327,14 +2327,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
int type_arg1 = flags1 & (MEM_Bool | MEM_Blob);
int type_arg3 = flags3 & (MEM_Bool | MEM_Blob);
if (type_arg1 != type_arg3) {
- char *inconsistent_type = type_arg1 != 0 ?
- mem_type_to_str(pIn3) :
- mem_type_to_str(pIn1);
- char *expected_type = type_arg1 != 0 ?
- mem_type_to_str(pIn1) :
- mem_type_to_str(pIn3);
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- inconsistent_type, expected_type);
+ sql_value_to_diag_str(pIn3),
+ mem_type_to_str(pIn1));
goto abort_due_to_error;
}
res = sqlMemCompare(pIn3, pIn1, NULL);
@@ -2386,13 +2381,13 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
} else if (type == FIELD_TYPE_STRING) {
if ((flags1 & MEM_Str) == 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- mem_type_to_str(pIn3),
+ sql_value_to_diag_str(pIn3),
mem_type_to_str(pIn1));
goto abort_due_to_error;
}
if ((flags3 & MEM_Str) == 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- mem_type_to_str(pIn1),
+ sql_value_to_diag_str(pIn1),
mem_type_to_str(pIn3));
goto abort_due_to_error;
}
@@ -3595,7 +3590,7 @@ skip_truncate:
goto seek_not_found;
}
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- field_type_strs[type], mem_type_to_str(mem));
+ sql_value_to_diag_str(mem), field_type_strs[type]);
goto abort_due_to_error;
}
#ifdef SQL_DEBUG
@@ -4740,7 +4735,7 @@ case OP_IdxGE: { /* jump */
(mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
continue;
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- field_type_strs[type], mem_type_to_str(mem));
+ sql_value_to_diag_str(mem), mem_type_to_str(mem));
goto abort_due_to_error;
}
#ifdef SQL_DEBUG
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index a721afc83..bb7676354 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -1166,12 +1166,15 @@ sqlValueText(sql_value * pVal)
const char *
sql_value_to_diag_str(sql_value *value)
{
- if (sql_value_type(value) == MP_BIN) {
- if (mem_has_msgpack_subtype(value))
- return sqlValueText(value);
+ if (sql_value_mp_type(value) == MP_BIN)
return "varbinary";
- }
- return sqlValueText(value);
+ char *type = mem_type_to_str(value);
+ char *str = (char *)sqlValueText(value);
+ if (str == NULL)
+ return "NULL";
+ if (strlen(str) < 80)
+ return tt_sprintf("'%s' (type: %s)", str, type);
+ return tt_sprintf("'%.80s...' (type: %s)", str, type);
}
/*
diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
index 07442b60a..1547ffcd3 100755
--- a/test/sql-tap/autoinc.test.lua
+++ b/test/sql-tap/autoinc.test.lua
@@ -618,7 +618,7 @@ test:do_catchsql_test(
INSERT INTO t2 VALUES('asd');
]], {
-- <autoinc-10.2>
- 1, "Type mismatch: can not convert asd to integer"
+ 1, "Type mismatch: can not convert 'asd' (type: text) to integer"
-- </autoinc-10.2>
})
@@ -811,7 +811,7 @@ test:do_catchsql_test(
INSERT INTO t1 SELECT s2, s2 FROM t1;
]], {
-- <autoinc-gh-3670>
- 1, "Type mismatch: can not convert a to integer"
+ 1, "Type mismatch: can not convert 'a' (type: text) to integer"
-- </autoinc-gh-3670>
})
diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
index fb0790d04..ceb3e690f 100755
--- a/test/sql-tap/cast.test.lua
+++ b/test/sql-tap/cast.test.lua
@@ -450,7 +450,7 @@ test:do_catchsql_test(
SELECT CAST('123abc' AS NUMBER)
]], {
-- <cast-1.45>
- 1, 'Type mismatch: can not convert 123abc to number'
+ 1, "Type mismatch: can not convert '123abc' (type: text) to number"
-- </cast-1.45>
})
@@ -470,7 +470,7 @@ test:do_catchsql_test(
SELECT CAST('123abc' AS integer)
]], {
-- <cast-1.49>
- 1, 'Type mismatch: can not convert 123abc to integer'
+ 1, "Type mismatch: can not convert '123abc' (type: text) to integer"
-- </cast-1.49>
})
@@ -480,7 +480,7 @@ test:do_catchsql_test(
SELECT CAST('123.5abc' AS NUMBER)
]], {
-- <cast-1.51>
- 1, 'Type mismatch: can not convert 123.5abc to number'
+ 1, "Type mismatch: can not convert '123.5abc' (type: text) to number"
-- </cast-1.51>
})
@@ -490,7 +490,7 @@ test:do_catchsql_test(
SELECT CAST('123.5abc' AS integer)
]], {
-- <cast-1.53>
- 1, 'Type mismatch: can not convert 123.5abc to integer'
+ 1, "Type mismatch: can not convert '123.5abc' (type: text) to integer"
-- </cast-1.53>
})
@@ -561,7 +561,7 @@ test:do_catchsql_test(
SELECT CAST('abc' AS NUMBER)
]], {
-- <case-1.66>
- 1, 'Type mismatch: can not convert abc to number'
+ 1, "Type mismatch: can not convert 'abc' (type: text) to number"
-- </case-1.66>
})
@@ -829,7 +829,7 @@ test:do_test(
]]
end, {
-- <cast-4.1>
- 1, 'Type mismatch: can not convert abc to integer'
+ 1, "Type mismatch: can not convert 'abc' (type: text) to integer"
-- </cast-4.1>
})
@@ -841,7 +841,7 @@ test:do_test(
]]
end, {
-- <cast-4.2>
- 1, 'Type mismatch: can not convert abc to integer'
+ 1, "Type mismatch: can not convert 'abc' (type: text) to integer"
-- </cast-4.2>
})
@@ -853,7 +853,7 @@ test:do_test(
]]
end, {
-- <cast-4.4>
- 1, 'Type mismatch: can not convert abc to number'
+ 1, "Type mismatch: can not convert 'abc' (type: text) to number"
-- </cast-4.4>
})
diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
index a1809b3cb..f1edfa0f6 100755
--- a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
+++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
@@ -28,7 +28,7 @@ test:do_catchsql_test(
[[
INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
]], {
- 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ 1, "Type mismatch: can not convert '1.0e+32' (type: real) to integer"
})
test:do_catchsql_test(
@@ -44,7 +44,7 @@ test:do_catchsql_test(
[[
INSERT INTO ti(i) VALUES (true)
]], {
- 1, "Type mismatch: can not convert TRUE to integer"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to integer"
})
test:do_catchsql_test(
@@ -52,7 +52,7 @@ test:do_catchsql_test(
[[
INSERT INTO ti(i) VALUES ('33')
]], {
- 1, "Type mismatch: can not convert 33 to integer"
+ 1, "Type mismatch: can not convert '33' (type: text) to integer"
})
test:do_catchsql_test(
@@ -100,7 +100,7 @@ test:do_catchsql_test(
[[
INSERT INTO td(d) VALUES (true)
]], {
- 1, "Type mismatch: can not convert TRUE to double"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to double"
})
test:do_catchsql_test(
@@ -108,7 +108,7 @@ test:do_catchsql_test(
[[
INSERT INTO td(d) VALUES ('33')
]], {
- 1, "Type mismatch: can not convert 33 to double"
+ 1, "Type mismatch: can not convert '33' (type: text) to double"
})
test:do_catchsql_test(
@@ -132,7 +132,7 @@ test:do_catchsql_test(
[[
INSERT INTO tb(b) VALUES (11)
]], {
- 1, "Type mismatch: can not convert 11 to boolean"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to boolean"
})
test:do_catchsql_test(
@@ -140,7 +140,7 @@ test:do_catchsql_test(
[[
INSERT INTO tb(b) VALUES (22.2)
]], {
- 1, "Type mismatch: can not convert 22.2 to boolean"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to boolean"
})
test:do_catchsql_test(
@@ -156,7 +156,7 @@ test:do_catchsql_test(
[[
INSERT INTO tb(b) VALUES ('33')
]], {
- 1, "Type mismatch: can not convert 33 to boolean"
+ 1, "Type mismatch: can not convert '33' (type: text) to boolean"
})
test:do_catchsql_test(
@@ -180,7 +180,7 @@ test:do_catchsql_test(
[[
INSERT INTO tt(t) VALUES (11)
]], {
- 1, "Type mismatch: can not convert 11 to string"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to string"
})
test:do_catchsql_test(
@@ -188,7 +188,7 @@ test:do_catchsql_test(
[[
INSERT INTO tt(t) VALUES (22.2)
]], {
- 1, "Type mismatch: can not convert 22.2 to string"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to string"
})
test:do_catchsql_test(
@@ -196,7 +196,7 @@ test:do_catchsql_test(
[[
INSERT INTO tt(t) VALUES (true)
]], {
- 1, "Type mismatch: can not convert TRUE to string"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to string"
})
test:do_catchsql_test(
@@ -228,7 +228,7 @@ test:do_catchsql_test(
[[
INSERT INTO tv(v) VALUES (11)
]], {
- 1, "Type mismatch: can not convert 11 to varbinary"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to varbinary"
})
test:do_catchsql_test(
@@ -236,7 +236,7 @@ test:do_catchsql_test(
[[
INSERT INTO tv(v) VALUES (22.2)
]], {
- 1, "Type mismatch: can not convert 22.2 to varbinary"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to varbinary"
})
test:do_catchsql_test(
@@ -244,7 +244,7 @@ test:do_catchsql_test(
[[
INSERT INTO tv(v) VALUES (true)
]], {
- 1, "Type mismatch: can not convert TRUE to varbinary"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to varbinary"
})
test:do_catchsql_test(
@@ -252,7 +252,7 @@ test:do_catchsql_test(
[[
INSERT INTO tv(v) VALUES ('33')
]], {
- 1, "Type mismatch: can not convert 33 to varbinary"
+ 1, "Type mismatch: can not convert '33' (type: text) to varbinary"
})
test:do_catchsql_test(
@@ -359,7 +359,7 @@ test:do_catchsql_test(
[[
UPDATE ti SET i = 100000000000000000000000000000000.1 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ 1, "Type mismatch: can not convert '1.0e+32' (type: real) to integer"
})
test:do_catchsql_test(
@@ -375,7 +375,7 @@ test:do_catchsql_test(
[[
UPDATE ti SET i = true WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert TRUE to integer"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to integer"
})
test:do_catchsql_test(
@@ -383,7 +383,7 @@ test:do_catchsql_test(
[[
UPDATE ti SET i = '33' WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 33 to integer"
+ 1, "Type mismatch: can not convert '33' (type: text) to integer"
})
test:do_catchsql_test(
@@ -431,7 +431,7 @@ test:do_catchsql_test(
[[
UPDATE td SET d = true WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert TRUE to double"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to double"
})
test:do_catchsql_test(
@@ -439,7 +439,7 @@ test:do_catchsql_test(
[[
UPDATE td SET d = '33' WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 33 to double"
+ 1, "Type mismatch: can not convert '33' (type: text) to double"
})
test:do_catchsql_test(
@@ -463,7 +463,7 @@ test:do_catchsql_test(
[[
UPDATE tb SET b = 11 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 11 to boolean"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to boolean"
})
test:do_catchsql_test(
@@ -471,7 +471,7 @@ test:do_catchsql_test(
[[
UPDATE tb SET b = 22.2 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 22.2 to boolean"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to boolean"
})
test:do_catchsql_test(
@@ -487,7 +487,7 @@ test:do_catchsql_test(
[[
UPDATE tb SET b = '33' WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 33 to boolean"
+ 1, "Type mismatch: can not convert '33' (type: text) to boolean"
})
test:do_catchsql_test(
@@ -511,7 +511,7 @@ test:do_catchsql_test(
[[
UPDATE tt SET t = 11 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 11 to string"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to string"
})
test:do_catchsql_test(
@@ -519,7 +519,7 @@ test:do_catchsql_test(
[[
UPDATE tt SET t = 22.2 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 22.2 to string"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to string"
})
test:do_catchsql_test(
@@ -527,7 +527,7 @@ test:do_catchsql_test(
[[
UPDATE tt SET t = true WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert TRUE to string"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to string"
})
test:do_catchsql_test(
@@ -559,7 +559,7 @@ test:do_catchsql_test(
[[
UPDATE tv SET v = 11 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 11 to varbinary"
+ 1, "Type mismatch: can not convert '11' (type: unsigned) to varbinary"
})
test:do_catchsql_test(
@@ -567,7 +567,7 @@ test:do_catchsql_test(
[[
UPDATE tv SET v = 22.2 WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 22.2 to varbinary"
+ 1, "Type mismatch: can not convert '22.2' (type: real) to varbinary"
})
test:do_catchsql_test(
@@ -575,7 +575,7 @@ test:do_catchsql_test(
[[
UPDATE tv SET v = true WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert TRUE to varbinary"
+ 1, "Type mismatch: can not convert 'TRUE' (type: boolean) to varbinary"
})
test:do_catchsql_test(
@@ -583,7 +583,7 @@ test:do_catchsql_test(
[[
UPDATE tv SET v = '33' WHERE a = 1;
]], {
- 1, "Type mismatch: can not convert 33 to varbinary"
+ 1, "Type mismatch: can not convert '33' (type: text) to varbinary"
})
test:do_catchsql_test(
diff --git a/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
index b405a11b6..536e414ba 100755
--- a/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
+++ b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
@@ -11,7 +11,7 @@ test:do_catchsql_test(
[[
SELECT '1' > 0;
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -19,7 +19,7 @@ test:do_catchsql_test(
[[
SELECT 0 > '1';
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
test:execsql([[
@@ -32,7 +32,7 @@ test:do_catchsql_test(
[[
SELECT * from t where i > s;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -40,7 +40,7 @@ test:do_catchsql_test(
[[
SELECT * from t WHERE s > i;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -48,7 +48,7 @@ test:do_catchsql_test(
[[
SELECT * from t WHERE d > s;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -56,7 +56,7 @@ test:do_catchsql_test(
[[
SELECT * from t WHERE s > d;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -64,7 +64,7 @@ test:do_catchsql_test(
[[
SELECT * from t WHERE i = 1 and n > s;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -72,7 +72,7 @@ test:do_catchsql_test(
[[
SELECT * from t WHERE i = 2 and s > n;
]], {
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
})
test:execsql([[
@@ -89,7 +89,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t1 WHERE x IN (1);
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
@@ -98,7 +98,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t1 WHERE x IN (1.0);
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
test:do_execsql_test(
@@ -121,7 +121,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t1 WHERE 1 IN (x);
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
test:do_catchsql_test(
@@ -129,7 +129,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t1 WHERE 1.0 IN (x);
]], {
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
})
test:do_execsql_test(
@@ -171,7 +171,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t2 WHERE x IN ('1');
]], {
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '1' (type: text) to integer"
})
test:do_catchsql_test(
@@ -179,7 +179,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t2 WHERE x IN ('1.0');
]], {
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '1.0' (type: text) to integer"
})
test:do_execsql_test(
@@ -203,7 +203,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t2 WHERE '1' IN (x);
]], {
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '1' (type: text) to integer"
})
test:do_catchsql_test(
@@ -211,7 +211,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t2 WHERE '1.0' IN (x);
]], {
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '1.0' (type: text) to integer"
})
test:do_execsql_test(
@@ -235,7 +235,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t3 WHERE x IN ('1');
]], {
- 1, "Type mismatch: can not convert double to text"
+ 1, "Type mismatch: can not convert '1' (type: text) to double"
})
test:do_catchsql_test(
@@ -243,7 +243,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t3 WHERE x IN ('1.0');
]], {
- 1, "Type mismatch: can not convert double to text"
+ 1, "Type mismatch: can not convert '1.0' (type: text) to double"
})
test:do_execsql_test(
@@ -267,7 +267,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t3 WHERE '1' IN (x);
]], {
- 1, "Type mismatch: can not convert double to text"
+ 1, "Type mismatch: can not convert '1' (type: text) to double"
})
test:do_catchsql_test(
@@ -275,7 +275,7 @@ test:do_catchsql_test(
[[
SELECT x FROM t3 WHERE '1.0' IN (x);
]], {
- 1, "Type mismatch: can not convert double to text"
+ 1, "Type mismatch: can not convert '1.0' (type: text) to double"
})
test:finish_test()
diff --git a/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua b/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua
index 929870d27..4fdd03b42 100755
--- a/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua
+++ b/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua
@@ -32,14 +32,7 @@ test:do_execsql_test(
test:do_catchsql_test(
"gh-4766-3",
"SELECT CAST('" .. long_str .. "1234'" .. " AS INTEGER);", {
- 1, "Type mismatch: can not convert 000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "0000000000000000000000000000000000000000000000000000000000000000000" ..
- "000000000000000000000000000000000000000000000"
+ 1, "Type mismatch: can not convert '00000000000000000000000000000000000000000000000000000000000000000000000000000000...' (type: text) to integer"
})
test:finish_test()
diff --git a/test/sql-tap/identifier_case.test.lua b/test/sql-tap/identifier_case.test.lua
index 1d56ffb44..96458ada8 100755
--- a/test/sql-tap/identifier_case.test.lua
+++ b/test/sql-tap/identifier_case.test.lua
@@ -242,11 +242,11 @@ data = {
{ 2, [[ 'a' < 'b' collate "binary" ]], {0, {true}}},
{ 3, [[ 'a' < 'b' collate 'binary' ]], {1, [[Syntax error at line 1 near ''binary'']]}},
{ 4, [[ 'a' < 'b' collate "unicode" ]], {0, {true}}},
- { 5, [[ 5 < 'b' collate "unicode" ]], {1, "Type mismatch: can not convert b to numeric"}},
+ { 5, [[ 5 < 'b' collate "unicode" ]], {1, "Type mismatch: can not convert 'b' (type: text) to numeric"}},
{ 6, [[ 5 < 'b' collate unicode ]], {1,"Collation 'UNICODE' does not exist"}},
- { 7, [[ 5 < 'b' collate "unicode_ci" ]], {1, "Type mismatch: can not convert b to numeric"}},
+ { 7, [[ 5 < 'b' collate "unicode_ci" ]], {1, "Type mismatch: can not convert 'b' (type: text) to numeric"}},
{ 8, [[ 5 < 'b' collate NONE ]], {1, "Collation 'NONE' does not exist"}},
- { 9, [[ 5 < 'b' collate "none" ]], {1, "Type mismatch: can not convert b to numeric"}},
+ { 9, [[ 5 < 'b' collate "none" ]], {1, "Type mismatch: can not convert 'b' (type: text) to numeric"}},
}
for _, row in ipairs(data) do
diff --git a/test/sql-tap/in1.test.lua b/test/sql-tap/in1.test.lua
index e2f498889..c55271eeb 100755
--- a/test/sql-tap/in1.test.lua
+++ b/test/sql-tap/in1.test.lua
@@ -642,7 +642,7 @@ test:do_test(
]]
end, {
-- <in-11.2>
- 1, "Type mismatch: can not convert 2 to numeric"
+ 1, "Type mismatch: can not convert '2' (type: text) to numeric"
-- </in-11.2>
})
diff --git a/test/sql-tap/in4.test.lua b/test/sql-tap/in4.test.lua
index a494e846f..1840841b0 100755
--- a/test/sql-tap/in4.test.lua
+++ b/test/sql-tap/in4.test.lua
@@ -153,7 +153,7 @@ test:do_catchsql_test(
SELECT b FROM t2 WHERE a IN ('', '0.0.0', '2')
]], {
-- <in4-2.8>
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '' (type: text) to integer"
-- </in4-2.8>
})
diff --git a/test/sql-tap/index1.test.lua b/test/sql-tap/index1.test.lua
index ce66b7c1e..d6a837e05 100755
--- a/test/sql-tap/index1.test.lua
+++ b/test/sql-tap/index1.test.lua
@@ -777,7 +777,7 @@ test:do_catchsql_test(
SELECT c FROM t6 WHERE a>123;
]], {
-- <index-14.6>
- 1, "Type mismatch: can not convert to numeric"
+ 1, "Type mismatch: can not convert '' (type: text) to numeric"
-- </index-14.6>
})
@@ -787,7 +787,7 @@ test:do_catchsql_test(
SELECT c FROM t6 WHERE a>=123;
]], {
-- <index-14.7>
- 1, "Type mismatch: can not convert to numeric"
+ 1, "Type mismatch: can not convert '' (type: text) to numeric"
-- </index-14.7>
})
diff --git a/test/sql-tap/join.test.lua b/test/sql-tap/join.test.lua
index 792302ab5..7068f0865 100755
--- a/test/sql-tap/join.test.lua
+++ b/test/sql-tap/join.test.lua
@@ -1034,7 +1034,7 @@ test:do_catchsql_test(
SELECT * FROM t1 NATURAL JOIN t2
]], {
-- <join-11.9>
- 1, "Type mismatch: can not convert integer to text"
+ 1, "Type mismatch: can not convert '1' (type: text) to integer"
-- </join-11.9>
})
@@ -1044,7 +1044,7 @@ test:do_catchsql_test(
SELECT * FROM t2 NATURAL JOIN t1
]], {
-- <join-11.10>
- 1, "Type mismatch: can not convert 1 to numeric"
+ 1, "Type mismatch: can not convert '1' (type: text) to numeric"
-- </join-11.10>
})
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index 3cef617f4..528076f00 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -625,7 +625,7 @@ test:do_catchsql_test(
SELECT '0'==0.0
]], {
-- <misc1-12.2>
- 1, "Type mismatch: can not convert 0 to numeric"
+ 1, "Type mismatch: can not convert '0' (type: text) to numeric"
-- </misc1-12.2>
})
diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
index 3161e48fa..b5930daf3 100755
--- a/test/sql-tap/numcast.test.lua
+++ b/test/sql-tap/numcast.test.lua
@@ -107,7 +107,7 @@ test:do_catchsql_test(
[[
SELECT CAST((20000000000000000000.) AS UNSIGNED);
]], {
- 1,"Type mismatch: can not convert 2.0e+19 to unsigned"
+ 1,"Type mismatch: can not convert '2.0e+19' (type: real) to unsigned"
})
test:do_execsql_test(
@@ -135,7 +135,7 @@ test:do_catchsql_test(
INSERT INTO t VALUES(20000000000000000000.01);
SELECT * FROM t;
]], {
- 1,"Type mismatch: can not convert 2.0e+19 to integer"
+ 1,"Type mismatch: can not convert '2.0e+19' (type: real) to integer"
})
test:do_execsql_test(
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index f5a9b63fe..911f24341 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -320,7 +320,7 @@ test:do_catchsql_test(
SELECT count(*),count(a),count(b) FROM t4 WHERE b=5
]], {
-- <select1-2.5.3>
- 1, "Type mismatch: can not convert This is a string that is too big to fit inside a NBFS buffer to numeric"
+ 1, "Type mismatch: can not convert 'This is a string that is too big to fit inside a NBFS buffer' (type: text) to numeric"
-- </select1-2.5.3>
})
@@ -515,7 +515,7 @@ test:do_catchsql_test(
SELECT sum(a) FROM t3
]], {
-- <select1-2.17.1>
- 1, "Type mismatch: can not convert abc to number"
+ 1, "Type mismatch: can not convert 'abc' (type: text) to number"
-- </select1-2.17.1>
})
@@ -1483,7 +1483,7 @@ test:do_catchsql_test(
SELECT f1 FROM test1 WHERE 4.3+2.4 OR 1 ORDER BY f1
]], {
-- <select1-8.1>
- 1, 'Type mismatch: can not convert 6.7 to boolean'
+ 1, "Type mismatch: can not convert '6.7' (type: real) to boolean"
-- </select1-8.1>
})
diff --git a/test/sql-tap/select5.test.lua b/test/sql-tap/select5.test.lua
index d34de3139..f87873b8e 100755
--- a/test/sql-tap/select5.test.lua
+++ b/test/sql-tap/select5.test.lua
@@ -558,7 +558,7 @@ test:do_catchsql_test(
SELECT 1 FROM jj HAVING avg(s2) = 1 AND avg(s2) = 0;
]], {
-- <select5-9.13.2>
- 1, "Type mismatch: can not convert A to number"
+ 1, "Type mismatch: can not convert 'A' (type: text) to number"
-- </select5-9.13.2>
})
diff --git a/test/sql-tap/subquery.test.lua b/test/sql-tap/subquery.test.lua
index bad702de9..2ef474930 100755
--- a/test/sql-tap/subquery.test.lua
+++ b/test/sql-tap/subquery.test.lua
@@ -290,7 +290,7 @@ test:do_catchsql_test(
SELECT a IN (10.0, 20) FROM t3;
]], {
-- <subquery-2.3.2>
- 1, "Type mismatch: can not convert text to real"
+ 1, "Type mismatch: can not convert '10' (type: text) to real"
-- </subquery-2.3.2>
})
diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
index a0e6539e0..8a10508d8 100755
--- a/test/sql-tap/tkt-80e031a00f.test.lua
+++ b/test/sql-tap/tkt-80e031a00f.test.lua
@@ -346,7 +346,7 @@ test:do_catchsql_test(
SELECT 'hello' IN t1
]], {
-- <tkt-80e031a00f.27>
- 1, 'Type mismatch: can not convert hello to integer'
+ 1, "Type mismatch: can not convert 'hello' (type: text) to integer"
-- </tkt-80e031a00f.27>
})
@@ -356,7 +356,7 @@ test:do_catchsql_test(
SELECT 'hello' NOT IN t1
]], {
-- <tkt-80e031a00f.28>
- 1, 'Type mismatch: can not convert hello to integer'
+ 1, "Type mismatch: can not convert 'hello' (type: text) to integer"
-- </tkt-80e031a00f.28>
})
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index 112e41a12..80f88a481 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -138,12 +138,12 @@ INSERT INTO ts(s) VALUES ('abc'), (12.5);
SELECT s FROM ts WHERE s = true;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT s FROM ts WHERE s < true;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT s FROM ts WHERE s IN (true, 1, 'abcd');
| ---
@@ -161,7 +161,7 @@ SELECT s FROM ts WHERE s IN (true, 1, 'abcd');
INSERT INTO ts VALUES (true, 12345);
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
-- Check that we can create index on field of type BOOLEAN.
@@ -339,7 +339,7 @@ SELECT typeof(a) FROM t0;
SELECT AVG(a) FROM t0;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to number'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to number'
| ...
SELECT MIN(a) FROM t0;
| ---
@@ -360,7 +360,7 @@ SELECT MAX(a) FROM t0;
SELECT SUM(a) FROM t0;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to number'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to number'
| ...
SELECT COUNT(a) FROM t0;
| ---
@@ -373,7 +373,7 @@ SELECT COUNT(a) FROM t0;
SELECT TOTAL(a) FROM t0;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to number'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to number'
| ...
SELECT GROUP_CONCAT(a, ' +++ ') FROM t0;
| ---
@@ -1120,438 +1120,438 @@ SELECT a, a1, a OR a1 FROM t, t6;
SELECT -true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT -false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT -a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true + true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true + false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT false + true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false + false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true - true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true - false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT false - true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false - false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true * true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true * false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT false * true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false * false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true / true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true / false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT false / true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false / false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true % true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true % false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT false % true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false % false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, true + a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, false + a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, true - a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, false - a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, true * a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, false * a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, true / a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, false / a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, true % a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, false % a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a + true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a, a + false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a - true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a, a - false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a * true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a, a * false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a / true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a, a / false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a % true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a, a % false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a1, a + a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a1, a - a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a1, a * a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a1, a / a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a, a1, a % a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT ~true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT ~false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true & true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT true & false;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false & true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT false & false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true | true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT true | false;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false | true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT false | false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true << true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT true << false;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false << true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT false << false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true >> true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT true >> false;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false >> true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT false >> false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, true & a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a, false & a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, true | a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a, false | a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, true << a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a, false << a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, true >> a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a, false >> a FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a & true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a & false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a | true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a | false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a << true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a << false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a >> true FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a >> false FROM t;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a1, a & a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a1, a | a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a1, a << a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a, a1, a >> a1 FROM t, t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
-- Check concatenate.
@@ -2461,7 +2461,7 @@ INSERT INTO t7 VALUES (123);
SELECT true AND 2;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT false AND 2;
| ---
@@ -2474,17 +2474,17 @@ SELECT false AND 2;
SELECT true OR 2;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT false OR 2;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 AND true;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 AND false;
| ---
@@ -2497,59 +2497,59 @@ SELECT 2 AND false;
SELECT 2 OR true;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 OR false;
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, a1 AND 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, a1 OR 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, 2 AND a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, 2 OR a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, a2 AND 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, a2 OR 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, 2 AND a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, 2 OR a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2 to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT b, true AND b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, false AND b FROM t7;
| ---
@@ -2564,17 +2564,17 @@ SELECT b, false AND b FROM t7;
SELECT b, true OR b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, false OR b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b AND true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b AND false FROM t7;
| ---
@@ -2589,1273 +2589,1273 @@ SELECT b, b AND false FROM t7;
SELECT b, b OR true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b OR false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, a1 AND b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, a1 OR b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, b AND a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, b OR a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, a2 AND b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, a2 OR b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, b AND a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, b OR a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert 123 to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT true + 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false + 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true - 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false - 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true * 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false * 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true / 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false / 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true % 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false % 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2 + true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2 + false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2 - true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2 - false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2 * true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2 * false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2 / true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2 / false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2 % true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2 % false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 + 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 - 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 * 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 / 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 % 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2 + a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2 - a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2 * a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2 / a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2 % a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 + 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 - 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 * 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 / 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 % 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2 + a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2 - a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2 * a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2 / a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2 % a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, true + b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, false + b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, true - b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, false - b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, true * b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, false * b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, true / b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, false / b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, true % b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, false % b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, b + true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, b + false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, b - true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, b - false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, b * true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, b * false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, b / true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, b / false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT b, b % true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT b, b % false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, a1 + b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, a1 - b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, a1 * b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, a1 / b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, a1 % b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, b + a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, b - a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, b * a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, b / a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, b, b % a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a2, b, a2 + b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, a2 - b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, a2 * b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, a2 / b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, a2 % b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, b + a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, b - a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, b * a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, b / a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, b, b % a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true & 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false & 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true | 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false | 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true << 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false << 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT true >> 2;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false >> 2;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT 2 & true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT 2 & false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT 2 | true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT 2 | false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT 2 << true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT 2 << false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT 2 >> true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT 2 >> false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, a1 & 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, a1 | 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, a1 << 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, a1 >> 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, 2 & a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, 2 | a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, 2 << a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, 2 >> a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a2, a2 & 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, a2 | 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, a2 << 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, a2 >> 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, 2 & a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, 2 | a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, 2 << a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, 2 >> a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, true & b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, false & b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, true | b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, false | b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, true << b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, false << b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, true >> b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, false >> b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, b & true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, b & false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, b | true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, b | false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, b << true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, b << false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT b, b >> true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT b, b >> false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, a1 & b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, a1 | b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, a1 << b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, a1 >> b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, b & a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, b | a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, b << a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, b, b >> a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a2, b, a2 & b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, a2 | b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, a2 << b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, a2 >> b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, b & a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, b | a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, b << a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT a2, b, b >> a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT true > 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false > 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT true < 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false < 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT 2 > true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 > false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 < true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 < false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, a1 > 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, a1 < 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, 2 > a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, 2 < a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, a2 > 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, a2 < 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, 2 > a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, 2 < a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT b, true > b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false > b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, true < b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false < b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, b > true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b > false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b < true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b < false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, a1 > b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, a1 < b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, b > a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, b < a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, a2 > b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, a2 < b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, b > a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, b < a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT true >= 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false >= 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT true <= 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false <= 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT 2 >= true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 >= false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 <= true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 <= false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, a1 >= 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, a1 <= 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, 2 >= a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, 2 <= a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, a2 >= 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, a2 <= 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, 2 >= a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, 2 <= a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT b, true >= b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false >= b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, true <= b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false <= b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, b >= true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b >= false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b <= true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b <= false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, a1 >= b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, a1 <= b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, b >= a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, b <= a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, a2 >= b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, a2 <= b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, b >= a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, b <= a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT true == 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false == 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT true != 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false != 2;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT 2 == true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 == false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 != true;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT 2 != false;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, a1 == 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, a1 != 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, 2 == a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a1, 2 != a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, a2 == 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, a2 != 2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, 2 == a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT a2, 2 != a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''2'' (type: unsigned) to boolean'
| ...
SELECT b, true == b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false == b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, true != b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT b, false != b FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT b, b == true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b == false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b != true FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT b, b != false FROM t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, a1 == b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, a1 != b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, b, b == a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a1, b, b != a1 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, a2 == b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, a2 != b FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT a2, b, b == a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT a2, b, b != a2 FROM t6, t7;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''123'' (type: unsigned) to boolean'
| ...
SELECT true IN (0, 1, 2, 3);
@@ -3877,12 +3877,12 @@ SELECT false IN (0, 1, 2, 3);
SELECT true IN (SELECT b FROM t7);
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to integer'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to integer'
| ...
SELECT false IN (SELECT b FROM t7);
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to integer'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to integer'
| ...
SELECT a1, a1 IN (0, 1, 2, 3) FROM t6
| ---
@@ -3899,22 +3899,22 @@ SELECT a1, a1 IN (0, 1, 2, 3) FROM t6
SELECT true BETWEEN 0 and 10;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
SELECT false BETWEEN 0 and 10;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a1, a1 BETWEEN 0 and 10 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to unsigned'
| ...
SELECT a2, a2 BETWEEN 0 and 10 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert unsigned to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
| ...
-- Check interaction of BOOLEAN and NUMBER.
@@ -3930,7 +3930,7 @@ INSERT INTO t8 VALUES (4.56);
SELECT true AND 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT false AND 2.3;
| ---
@@ -3943,17 +3943,17 @@ SELECT false AND 2.3;
SELECT true OR 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT false OR 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 AND true;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 AND false;
| ---
@@ -3966,59 +3966,59 @@ SELECT 2.3 AND false;
SELECT 2.3 OR true;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 OR false;
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, a1 AND 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, a1 OR 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, 2.3 AND a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, 2.3 OR a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, a2 AND 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, a2 OR 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, 2.3 AND a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, 2.3 OR a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert 2.3 to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT c, true AND c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, false AND c FROM t8;
| ---
@@ -4033,17 +4033,17 @@ SELECT c, false AND c FROM t8;
SELECT c, true OR c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, false OR c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c AND true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c AND false FROM t8;
| ---
@@ -4058,949 +4058,949 @@ SELECT c, c AND false FROM t8;
SELECT c, c OR true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c OR false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, a1 AND c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, a1 OR c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, c AND a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, c OR a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, a2 AND c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, a2 OR c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, c AND a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, c OR a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert 4.56 to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT true + 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false + 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true - 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false - 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true * 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false * 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true / 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false / 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT true % 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT false % 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2.3 + true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2.3 + false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2.3 - true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2.3 - false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2.3 * true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2.3 * false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2.3 / true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2.3 / false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT 2.3 % true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT 2.3 % false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 + 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 - 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 * 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 / 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, a1 % 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2.3 + a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2.3 - a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2.3 * a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2.3 / a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, 2.3 % a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 + 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 - 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 * 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 / 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, a2 % 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2.3 + a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2.3 - a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2.3 * a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2.3 / a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, 2.3 % a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, true + c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, false + c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, true - c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, false - c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, true * c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, false * c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, true / c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, false / c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, true % c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, false % c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, c + true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, c + false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, c - true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, c - false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, c * true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, c * false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, c / true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, c / false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT c, c % true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT c, c % false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, a1 + c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, a1 - c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, a1 * c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, a1 / c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, a1 % c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, c + a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, c - a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, c * a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, c / a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a1, c, c % a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to numeric'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to numeric'
| ...
SELECT a2, c, a2 + c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, a2 - c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, a2 * c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, a2 / c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, a2 % c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, c + a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, c - a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, c * a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, c / a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT a2, c, c % a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to numeric'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to numeric'
| ...
SELECT true > 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false > 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT true < 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false < 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT 2.3 > true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 > false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 < true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 < false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, a1 > 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, a1 < 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, 2.3 > a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, 2.3 < a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, a2 > 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, a2 < 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, 2.3 > a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, 2.3 < a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT c, true > c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false > c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, true < c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false < c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, c > true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c > false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c < true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c < false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, a1 > c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, a1 < c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, c > a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, c < a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, a2 > c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, a2 < c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, c > a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, c < a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT true >= 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false >= 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT true <= 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false <= 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT 2.3 >= true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 >= false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 <= true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 <= false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, a1 >= 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, a1 <= 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, 2.3 >= a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, 2.3 <= a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, a2 >= 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, a2 <= 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, 2.3 >= a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, 2.3 <= a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT c, true >= c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false >= c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, true <= c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false <= c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, c >= true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c >= false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c <= true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c <= false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, a1 >= c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, a1 <= c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, c >= a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, c <= a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, a2 >= c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, a2 <= c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, c >= a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, c <= a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT true == 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false == 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT true != 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false != 2.3;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT 2.3 == true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 == false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 != true;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT 2.3 != false;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, a1 == 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, a1 != 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, 2.3 == a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a1, 2.3 != a1 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, a2 == 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, a2 != 2.3 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, 2.3 == a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT a2, 2.3 != a2 FROM t6
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''2.3'' (type: real) to boolean'
| ...
SELECT c, true == c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false == c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, true != c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT c, false != c FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT c, c == true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c == false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c != true FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT c, c != false FROM t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, a1 == c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, a1 != c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, c, c == a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a1, c, c != a1 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, a2 == c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, a2 != c FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT a2, c, c == a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT a2, c, c != a2 FROM t6, t8;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''4.56'' (type: real) to boolean'
| ...
SELECT true IN (0.1, 1.2, 2.3, 3.4);
@@ -5038,43 +5038,43 @@ SELECT a2 IN (0.1, 1.2, 2.3, 3.4) FROM t6 LIMIT 1;
SELECT true IN (SELECT c FROM t8);
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to number'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to number'
| ...
SELECT false IN (SELECT c FROM t8);
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to number'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to number'
| ...
SELECT a1 IN (SELECT c FROM t8) FROM t6 LIMIT 1;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to number'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to number'
| ...
SELECT a2 IN (SELECT c FROM t8) FROM t6 LIMIT 1;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to number'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to number'
| ...
SELECT true BETWEEN 0.1 and 9.9;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
SELECT false BETWEEN 0.1 and 9.9;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a1, a1 BETWEEN 0.1 and 9.9 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to real'
| ...
SELECT a2, a2 BETWEEN 0.1 and 9.9 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert real to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
| ...
-- Check interaction of BOOLEAN and TEXT.
@@ -5090,7 +5090,7 @@ INSERT INTO t9 VALUES ('AsdF');
SELECT true AND 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT false AND 'abc';
| ---
@@ -5103,17 +5103,17 @@ SELECT false AND 'abc';
SELECT true OR 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT false OR 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' AND true;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' AND false;
| ---
@@ -5126,59 +5126,59 @@ SELECT 'abc' AND false;
SELECT 'abc' OR true;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' OR false;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a1, a1 AND 'abc' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a1, a1 OR 'abc' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a1, 'abc' AND a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a1, 'abc' OR a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a2, a2 AND 'abc' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a2, a2 OR 'abc' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a2, 'abc' AND a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT a2, 'abc' OR a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert abc to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT d, true AND d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, false AND d FROM t9;
| ---
@@ -5193,17 +5193,17 @@ SELECT d, false AND d FROM t9;
SELECT d, true OR d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, false OR d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d AND true FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d AND false FROM t9;
| ---
@@ -5218,176 +5218,176 @@ SELECT d, d AND false FROM t9;
SELECT d, d OR true FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d OR false FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, a1 AND d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, a1 OR d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, d AND a1 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, d OR a1 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, a2 AND d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, a2 OR d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, d AND a2 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, d OR a2 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert AsdF to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT true > 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT false > 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT true < 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT false < 'abc';
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT 'abc' > true;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' > false;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' < true;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT 'abc' < false;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
| ...
SELECT d, true > d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT d, false > d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT d, true < d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT d, false < d FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT d, d > true FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d > false FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d < true FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT d, d < false FROM t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, a1 > d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT a1, d, a1 < d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: boolean) to text'
| ...
SELECT a1, d, d > a1 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a1, d, d < a1 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, a2 > d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT a2, d, a2 < d FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to text'
| ...
SELECT a2, d, d > a2 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT a2, d, d < a2 FROM t6, t9;
| ---
| - null
- | - 'Type mismatch: can not convert text to boolean'
+ | - 'Type mismatch: can not convert ''AsdF'' (type: text) to boolean'
| ...
SELECT true || 'abc';
@@ -5465,7 +5465,7 @@ INSERT INTO t9 VALUES ('TRUE'), ('true'), ('FALSE'), ('false');
SELECT true AND 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT false AND 'TRUE';
| ---
@@ -5478,17 +5478,17 @@ SELECT false AND 'TRUE';
SELECT true OR 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT false OR 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT 'TRUE' AND true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT 'TRUE' AND false;
| ---
@@ -5501,59 +5501,59 @@ SELECT 'TRUE' AND false;
SELECT 'TRUE' OR true;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT 'TRUE' OR false;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, a1 AND 'TRUE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, a1 OR 'TRUE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, 'TRUE' AND a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, 'TRUE' OR a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, a2 AND 'TRUE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, a2 OR 'TRUE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, 'TRUE' AND a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, 'TRUE' OR a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, true AND d FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, false AND d FROM t9 WHERE d = 'TRUE';
| ---
@@ -5568,17 +5568,17 @@ SELECT d, false AND d FROM t9 WHERE d = 'TRUE';
SELECT d, true OR d FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, false OR d FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, d AND true FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, d AND false FROM t9 WHERE d = 'TRUE';
| ---
@@ -5593,59 +5593,59 @@ SELECT d, d AND false FROM t9 WHERE d = 'TRUE';
SELECT d, d OR true FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT d, d OR false FROM t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, d, a1 AND d FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, d, a1 OR d FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, d, d AND a1 FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a1, d, d OR a1 FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, d, a2 AND d FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, d, a2 OR d FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, d, d AND a2 FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT a2, d, d OR a2 FROM t6, t9 WHERE d = 'TRUE';
| ---
| - null
- | - 'Type mismatch: can not convert TRUE to boolean'
+ | - 'Type mismatch: can not convert ''TRUE'' (type: text) to boolean'
| ...
SELECT true AND 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT false AND 'true';
| ---
@@ -5658,17 +5658,17 @@ SELECT false AND 'true';
SELECT true OR 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT false OR 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT 'true' AND true;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT 'true' AND false;
| ---
@@ -5681,59 +5681,59 @@ SELECT 'true' AND false;
SELECT 'true' OR true;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT 'true' OR false;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, a1 AND 'true' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, a1 OR 'true' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, 'true' AND a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, 'true' OR a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, a2 AND 'true' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, a2 OR 'true' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, 'true' AND a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, 'true' OR a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, true AND d FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, false AND d FROM t9 WHERE d = 'true';
| ---
@@ -5748,17 +5748,17 @@ SELECT d, false AND d FROM t9 WHERE d = 'true';
SELECT d, true OR d FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, false OR d FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, d AND true FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, d AND false FROM t9 WHERE d = 'true';
| ---
@@ -5773,59 +5773,59 @@ SELECT d, d AND false FROM t9 WHERE d = 'true';
SELECT d, d OR true FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT d, d OR false FROM t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, d, a1 AND d FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, d, a1 OR d FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, d, d AND a1 FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a1, d, d OR a1 FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, d, a2 AND d FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, d, a2 OR d FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, d, d AND a2 FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT a2, d, d OR a2 FROM t6, t9 WHERE d = 'true';
| ---
| - null
- | - 'Type mismatch: can not convert true to boolean'
+ | - 'Type mismatch: can not convert ''true'' (type: text) to boolean'
| ...
SELECT true AND 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT false AND 'FALSE';
| ---
@@ -5838,17 +5838,17 @@ SELECT false AND 'FALSE';
SELECT true OR 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT false OR 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT 'FALSE' AND true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT 'FALSE' AND false;
| ---
@@ -5861,59 +5861,59 @@ SELECT 'FALSE' AND false;
SELECT 'FALSE' OR true;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT 'FALSE' OR false;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, a1 AND 'FALSE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, a1 OR 'FALSE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, 'FALSE' AND a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, 'FALSE' OR a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, a2 AND 'FALSE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, a2 OR 'FALSE' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, 'FALSE' AND a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, 'FALSE' OR a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, true AND d FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, false AND d FROM t9 WHERE d = 'FALSE';
| ---
@@ -5928,17 +5928,17 @@ SELECT d, false AND d FROM t9 WHERE d = 'FALSE';
SELECT d, true OR d FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, false OR d FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, d AND true FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, d AND false FROM t9 WHERE d = 'FALSE';
| ---
@@ -5953,59 +5953,59 @@ SELECT d, d AND false FROM t9 WHERE d = 'FALSE';
SELECT d, d OR true FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT d, d OR false FROM t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, d, a1 AND d FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, d, a1 OR d FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, d, d AND a1 FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a1, d, d OR a1 FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, d, a2 AND d FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, d, a2 OR d FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, d, d AND a2 FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT a2, d, d OR a2 FROM t6, t9 WHERE d = 'FALSE';
| ---
| - null
- | - 'Type mismatch: can not convert FALSE to boolean'
+ | - 'Type mismatch: can not convert ''FALSE'' (type: text) to boolean'
| ...
SELECT true AND 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT false AND 'false';
| ---
@@ -6018,17 +6018,17 @@ SELECT false AND 'false';
SELECT true OR 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT false OR 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT 'false' AND true;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT 'false' AND false;
| ---
@@ -6041,59 +6041,59 @@ SELECT 'false' AND false;
SELECT 'false' OR true;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT 'false' OR false;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, a1 AND 'false' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, a1 OR 'false' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, 'false' AND a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, 'false' OR a1 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, a2 AND 'false' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, a2 OR 'false' FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, 'false' AND a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, 'false' OR a2 FROM t6;
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, true AND d FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, false AND d FROM t9 WHERE d = 'false';
| ---
@@ -6108,17 +6108,17 @@ SELECT d, false AND d FROM t9 WHERE d = 'false';
SELECT d, true OR d FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, false OR d FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, d AND true FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, d AND false FROM t9 WHERE d = 'false';
| ---
@@ -6133,53 +6133,53 @@ SELECT d, d AND false FROM t9 WHERE d = 'false';
SELECT d, d OR true FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT d, d OR false FROM t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, d, a1 AND d FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, d, a1 OR d FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, d, d AND a1 FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a1, d, d OR a1 FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, d, a2 AND d FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, d, a2 OR d FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, d, d AND a2 FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
SELECT a2, d, d OR a2 FROM t6, t9 WHERE d = 'false';
| ---
| - null
- | - 'Type mismatch: can not convert false to boolean'
+ | - 'Type mismatch: can not convert ''false'' (type: text) to boolean'
| ...
-- Cleaning.
diff --git a/test/sql/integer-overflow.result b/test/sql/integer-overflow.result
index 6269cb547..1048e594a 100644
--- a/test/sql/integer-overflow.result
+++ b/test/sql/integer-overflow.result
@@ -106,7 +106,7 @@ box.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);')
box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
---
- null
-- 'Type mismatch: can not convert 18446744073709551616 to integer'
+- 'Type mismatch: can not convert ''18446744073709551616'' (type: text) to integer'
...
-- Due to inexact represantation of large integers in terms of
-- floating point numbers, numerics with value < UINT64_MAX
@@ -117,7 +117,7 @@ box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
box.execute('SELECT CAST(18446744073709551600. AS INTEGER);')
---
- null
-- 'Type mismatch: can not convert 1.84467440737096e+19 to integer'
+- 'Type mismatch: can not convert ''1.84467440737096e+19'' (type: real) to integer'
...
-- gh-3810: make sure that if space contains integers in range
-- [INT64_MAX, UINT64_MAX], they are handled inside SQL in a
diff --git a/test/sql/persistency.result b/test/sql/persistency.result
index 6d14d4c4e..14534bc51 100644
--- a/test/sql/persistency.result
+++ b/test/sql/persistency.result
@@ -370,7 +370,7 @@ box.execute("SELECT \"name\", \"opts\" FROM \"_trigger\"");
box.execute("INSERT INTO foobar VALUES ('foobar trigger test', 8888)")
---
- null
-- 'Type mismatch: can not convert foobar trigger test to integer'
+- 'Type mismatch: can not convert ''foobar trigger test'' (type: text) to integer'
...
box.execute("SELECT * FROM barfoo WHERE foo = 9999");
---
diff --git a/test/sql/types.result b/test/sql/types.result
index 62161cfe1..d4975af85 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -270,7 +270,7 @@ box.space.T1:drop()
box.execute("SELECT CAST('1.123' AS INTEGER);")
---
- null
-- 'Type mismatch: can not convert 1.123 to integer'
+- 'Type mismatch: can not convert ''1.123'' (type: text) to integer'
...
box.execute("CREATE TABLE t1 (f TEXT PRIMARY KEY);")
---
@@ -283,7 +283,7 @@ box.execute("INSERT INTO t1 VALUES('0.0'), ('1.5'), ('3.9312453');")
box.execute("SELECT CAST(f AS INTEGER) FROM t1;")
---
- null
-- 'Type mismatch: can not convert 0.0 to integer'
+- 'Type mismatch: can not convert ''0.0'' (type: text) to integer'
...
box.space.T1:drop()
---
@@ -339,22 +339,22 @@ box.execute("INSERT INTO tboolean VALUES (TRUE);")
box.execute("SELECT * FROM tboolean WHERE s1 = x'44';")
---
- null
-- 'Type mismatch: can not convert boolean to varbinary'
+- 'Type mismatch: can not convert varbinary to boolean'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 'abc';")
---
- null
-- 'Type mismatch: can not convert boolean to text'
+- 'Type mismatch: can not convert ''abc'' (type: text) to boolean'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 1;")
---
- null
-- 'Type mismatch: can not convert unsigned to boolean'
+- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to unsigned'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 1.123;")
---
- null
-- 'Type mismatch: can not convert real to boolean'
+- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to real'
...
box.space.TBOOLEAN:drop()
---
@@ -624,7 +624,7 @@ box.execute("SELECT 1 LIMIT 1 OFFSET 18446744073709551614;")
box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
---
- null
-- 'Type mismatch: can not convert 18446744073709551616 to integer'
+- 'Type mismatch: can not convert ''18446744073709551616'' (type: text) to integer'
...
box.execute("SELECT CAST('18446744073' || '709551615' AS INTEGER);")
---
@@ -1054,7 +1054,7 @@ box.execute("INSERT INTO t1 VALUES (0), (1), (2);")
box.execute("INSERT INTO t1 VALUES (-3);")
---
- null
-- 'Type mismatch: can not convert -3 to unsigned'
+- 'Type mismatch: can not convert ''-3'' (type: integer) to unsigned'
...
box.execute("SELECT id FROM t1;")
---
@@ -1077,7 +1077,7 @@ box.execute("SELECT CAST(123 AS UNSIGNED);")
box.execute("SELECT CAST(-123 AS UNSIGNED);")
---
- null
-- 'Type mismatch: can not convert -123 to unsigned'
+- 'Type mismatch: can not convert ''-123'' (type: integer) to unsigned'
...
box.execute("SELECT CAST(1.5 AS UNSIGNED);")
---
@@ -1114,7 +1114,7 @@ box.execute("SELECT CAST('123' AS UNSIGNED);")
box.execute("SELECT CAST('-123' AS UNSIGNED);")
---
- null
-- 'Type mismatch: can not convert -123 to unsigned'
+- 'Type mismatch: can not convert ''-123'' (type: text) to unsigned'
...
box.space.T1:drop()
---
@@ -1212,22 +1212,22 @@ box.execute("CREATE TABLE t (id INT PRIMARY KEY, v VARBINARY);")
box.execute("INSERT INTO t VALUES(1, 1);")
---
- null
-- 'Type mismatch: can not convert 1 to varbinary'
+- 'Type mismatch: can not convert ''1'' (type: unsigned) to varbinary'
...
box.execute("INSERT INTO t VALUES(1, 1.123);")
---
- null
-- 'Type mismatch: can not convert 1.123 to varbinary'
+- 'Type mismatch: can not convert ''1.123'' (type: real) to varbinary'
...
box.execute("INSERT INTO t VALUES(1, true);")
---
- null
-- 'Type mismatch: can not convert TRUE to varbinary'
+- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to varbinary'
...
box.execute("INSERT INTO t VALUES(1, 'asd');")
---
- null
-- 'Type mismatch: can not convert asd to varbinary'
+- 'Type mismatch: can not convert ''asd'' (type: text) to varbinary'
...
box.execute("INSERT INTO t VALUES(1, x'616263');")
---
@@ -1236,17 +1236,17 @@ box.execute("INSERT INTO t VALUES(1, x'616263');")
box.execute("SELECT * FROM t WHERE v = 1")
---
- null
-- 'Type mismatch: can not convert unsigned to varbinary'
+- 'Type mismatch: can not convert varbinary to unsigned'
...
box.execute("SELECT * FROM t WHERE v = 1.123")
---
- null
-- 'Type mismatch: can not convert real to varbinary'
+- 'Type mismatch: can not convert varbinary to real'
...
box.execute("SELECT * FROM t WHERE v = 'str'")
---
- null
-- 'Type mismatch: can not convert text to varbinary'
+- 'Type mismatch: can not convert varbinary to text'
...
box.execute("SELECT * FROM t WHERE v = x'616263'")
---
@@ -1444,17 +1444,17 @@ box.space.T1:drop()
box.execute("SELECT CAST(1 AS VARBINARY);")
---
- null
-- 'Type mismatch: can not convert 1 to varbinary'
+- 'Type mismatch: can not convert ''1'' (type: unsigned) to varbinary'
...
box.execute("SELECT CAST(1.123 AS VARBINARY);")
---
- null
-- 'Type mismatch: can not convert 1.123 to varbinary'
+- 'Type mismatch: can not convert ''1.123'' (type: real) to varbinary'
...
box.execute("SELECT CAST(true AS VARBINARY);")
---
- null
-- 'Type mismatch: can not convert TRUE to varbinary'
+- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to varbinary'
...
box.execute("SELECT CAST('asd' AS VARBINARY);")
---
@@ -1609,7 +1609,7 @@ s:insert({1, {1,2,3}})
box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
---
- null
-- 'Type mismatch: can not convert [1, 2, 3] to scalar'
+- 'Type mismatch: can not convert ''[1, 2, 3]'' (type: varbinary) to scalar'
...
s:replace({1, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}})
---
@@ -1619,8 +1619,8 @@ s:replace({1, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
---
- null
-- 'Type mismatch: can not convert [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] to scalar'
+- 'Type mismatch: can not convert ''[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, ...'' (type: varbinary) to scalar'
...
--
-- Make sure that the error will be displayed correctly even if
@@ -1645,13 +1645,8 @@ s:replace({1, long_array})
box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
---
- null
-- 'Type mismatch: can not convert [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 11'
+- 'Type mismatch: can not convert ''[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, ...'' (type: varbinary) to scalar'
...
s:drop()
---
@@ -1672,7 +1667,7 @@ s:insert({1, {b = 1}})
box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
---
- null
-- 'Type mismatch: can not convert {"b": 1} to scalar'
+- 'Type mismatch: can not convert ''{"b": 1}'' (type: varbinary) to scalar'
...
s:drop()
---
@@ -1717,12 +1712,12 @@ box.execute("SELECT CAST(1.123 AS DOUBLE);")
box.execute("SELECT CAST(true AS DOUBLE);")
---
- null
-- 'Type mismatch: can not convert TRUE to double'
+- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to double'
...
box.execute("SELECT CAST('asd' AS DOUBLE);")
---
- null
-- 'Type mismatch: can not convert asd to double'
+- 'Type mismatch: can not convert ''asd'' (type: text) to double'
...
box.execute("SELECT CAST('1' AS DOUBLE);")
---
--
2.25.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double()
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double() imeevma
@ 2020-06-28 13:31 ` Nikita Pettik
2020-07-06 14:02 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-28 13:31 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> The mem_set_double () function is used to properly set MEM as
> containing DOUBLE value.
Nit: it has been introduced a long ago (sqlVdbeMemSetDouble()).
You refactor it and use in several other places.
LGTM
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator imeevma
@ 2020-06-29 12:56 ` Nikita Pettik
2020-07-05 14:28 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-29 12:56 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> index f7681640e..a2147b0e8 100755
> --- a/test/sql-tap/in3.test.lua
> +++ b/test/sql-tap/in3.test.lua
> @@ -1,6 +1,6 @@
> #!/usr/bin/env tarantool
> test = require("sqltester")
> -test:plan(29)
> +test:plan(28)
>
> --!./tcltestrunner.lua
> -- 2007 November 29
> @@ -322,18 +322,6 @@ test:do_test(
> -- </in3-3.2>
> })
>
> -test:do_test(
> - "in3-3.3",
> - function()
> - -- Logically, numeric affinity is applied to both sides before
> - -- the comparison, but index can't be used.
> - return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
> - end, {
> - -- <in3-3.3>
> - 1, true
> - -- </in3-3.3>
> - })
> -
I'd rather not drop this test. It's about scalar-numeric types
interaction. Mb it is not the most suitable place for such test,
but make sure this scenario is covered somewhere else.
The rest is OK as obvious.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt imeevma
@ 2020-06-29 13:29 ` Nikita Pettik
2020-07-05 14:29 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-29 13:29 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 276956170..a609fa985 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -2122,17 +2122,13 @@ case OP_AddImm: { /* in1 */
> */
> case OP_MustBeInt: { /* jump, in1 */
> pIn1 = &aMem[pOp->p1];
> - if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
> - mem_apply_type(pIn1, FIELD_TYPE_INTEGER);
> - if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
> - if (pOp->p2==0) {
> - diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> - sql_value_to_diag_str(pIn1), "integer");
> - goto abort_due_to_error;
> - } else {
> - goto jump_to_p2;
> - }
> - }
> + if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0 &&
> + mem_convert_to_integer(pIn1, true) != 0) {
Please split this conditions into two branches. Like this:
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 2bc8c9817..da76d7321 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2122,13 +2122,14 @@ case OP_AddImm: { /* in1 */
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
- if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0 &&
- mem_convert_to_integer(pIn1, true) != 0) {
- if (pOp->p2 != 0)
- goto jump_to_p2;
- diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
- sql_value_to_diag_str(pIn1), "integer");
- goto abort_due_to_error;
+ if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
+ if (mem_convert_to_integer(pIn1, true) != 0) {
+ if (pOp->p2 != 0)
+ goto jump_to_p2;
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1), "integer");
+ goto abort_due_to_error;
+ }
}
break;
It ehcnances code readability. Or even integrate this check into
mem_covert_to_ingeger().
The rest is OK (hope you carefully verified changed tests, since
I've only briefly looked through).
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison imeevma
@ 2020-06-29 23:51 ` Nikita Pettik
2020-07-05 14:47 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-29 23:51 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> Thank you for review! My answers and new patch below.
>
> On 22.06.2020 15:25, Nikita Pettik wrote:
> > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> >> @@ -2399,14 +2387,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
> >> default: res2 = res>=0; break;
> >> }
> >>
> >> - /* Undo any changes made by mem_apply_type() to the input registers. */
> >> - assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
> >> - pIn1->flags = flags1;
> >> - pIn1->field_type = ft_p1;
> >> - assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
> >> - pIn3->flags = flags3;
> >> - pIn3->field_type = ft_p3;
> >> -
> >
> > Replace these assertions with relevant ones.
> >
> Not sure if this is necessary, since now we have much less flag
> changes after removal of mem_apply_type().
Не понял как это связано...Твои изменения не затрагивают
инвариант MEM_Dyn.
> >> @@ -0,0 +1,281 @@
> >> +#!/usr/bin/env tarantool
> >> +test = require("sqltester")
> >> +test:plan(32)
> >> +
> >> +--
> >> +
> >> +test:execsql([[
> >> + CREATE TABLE t1(x TEXT primary key);
> >> + INSERT INTO t1 VALUES('1');
> >> + CREATE TABLE t2(x INTEGER primary key);
> >> + INSERT INTO t2 VALUES(1);
> >> + CREATE TABLE t3(x DOUBLE primary key);
> >> + INSERT INTO t3 VALUES(1.0);
> >
> > What about table with scalar/any fields?
> >
> I think this is too big a problem to solve it here.
Гораздо лучше потом клепать фоллоу-апы, точечно затыкая креши..
Я бы добавил хотя бы самых базовых примеров.
> i = pIn3->u.i;
> @@ -3617,7 +3595,38 @@ skip_truncate:
> assert(oc!=OP_SeekGE || r.default_rc==+1);
> assert(oc!=OP_SeekLT || r.default_rc==+1);
>
> + /*
> + * Make sure that the types of all the fields in the tuple
> + * that will be used in the iterator match the field types
> + * of the space.
> + */
> r.aMem = &aMem[pOp->p3];
> + for (int i = 0; i < r.nField; ++i) {
> + enum field_type type = r.key_def->parts[i].type;
> + struct Mem *mem = &r.aMem[i];
> + if (mem_check_type(mem, type) == 0 ||
> + mem_convert_numeric(mem, type, true) == 0)
> + continue;
Я бы все-таки разбил бы эту проверку на два условия:
if (...)
continue
if (...)
continue
А еще лучше вынести этот чанк в хелпер.
> + /*
> + * If the number was not converted without loss,
> + * we will not find tuples using the EQ iterator.
> + */
Пожайлуста, не используй двойное отрицание - комментарий очень
сложно воспринимать. Давай это переформулируем, можно пример
добавить. Это довольно скользкое место.
> + if ((mem->flags & MEM_Real) != 0 &&
> + (type == FIELD_TYPE_INTEGER ||
> + type == FIELD_TYPE_UNSIGNED)) {
> + assert(eqOnly == 1);
> + res = 1;
> + goto seek_not_found;
> + }
> + if ((mem->flags & (MEM_Int | MEM_UInt)) != 0 &&
> + type == FIELD_TYPE_DOUBLE && eqOnly == 1) {
> + res = 1;
> + goto seek_not_found;
> + }
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + field_type_strs[type], mem_type_to_str(mem));
> + goto abort_due_to_error;
> + }
> #ifdef SQL_DEBUG
> { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> #endif
> @@ -4744,7 +4753,25 @@ case OP_IdxGE: { /* jump */
> assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
> r.default_rc = 0;
> }
> +
> + /*
> + * Make sure that the types of all the fields in the tuple
> + * that will be used in the iterator comparable with the
> + * fields of the space.
> + */
> r.aMem = &aMem[pOp->p3];
> + for (int i = 0; i < r.nField; ++i) {
> + enum field_type type = r.key_def->parts[i].type;
> + struct Mem *mem = &r.aMem[i];
Как-то мне эти два места (выше в SeekGE) вообще не нравятся.
Какие-то они запутанные. Давай подумаем как можно зарефакторить их.
> + if (mem_check_type(mem, type) == 0)
> + continue;
> + if (sql_type_is_numeric(type) &&
> + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
> + continue;
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + field_type_strs[type], mem_type_to_str(mem));
> + goto abort_due_to_error;
> + }
> #ifdef SQL_DEBUG
> { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> #endif
> diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
> index 6d8768865..1d7c76670 100644
> --- a/src/box/sql/wherecode.c
> +++ b/src/box/sql/wherecode.c
> @@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
> }
> }
>
> -/**
> - * Code an OP_ApplyType opcode to apply the column type string
> - * @types to the n registers starting at @base.
> - *
> - * As an optimization, SCALAR entries (which are no-ops) at the
> - * beginning and end of @types are ignored. If all entries in
> - * @types are SCALAR, then no code gets generated.
> - *
> - * This routine makes its own copy of @types so that the caller is
> - * free to modify @types after this routine returns.
> - */
> -static void
> -emit_apply_type(Parse *pParse, int base, int n, enum field_type *types)
Ты в следующем коммите как раз делаешь клин-ап. Давай эту функцию
там и удалим (как и остальные).
> nConstraint++;
> }
> - sqlDbFree(db, start_types);
> - sqlDbFree(db, end_types);
>
> /* Top of the loop body */
> pLevel->p2 = sqlVdbeCurrentAddr(v);
> diff --git a/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
> new file mode 100755
> index 000000000..b405a11b6
> --- /dev/null
> +++ b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
Когда кто-то ищет где посмотреть тесты связанные с типами,
первое что приходит в голову - грепнуть *types*. Этот тест
по сути ничего и не тестирует (уверен, эти пути уже покрыты
в других тестах), зато хорошо отображает работу системы типов.
Я бы просто подумал о других разработчиках, и все же замержил
его в какой-нибудь тест типа sql/types.test.lua.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions imeevma
@ 2020-06-29 23:52 ` Nikita Pettik
2020-07-05 14:50 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-29 23:52 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> After previous patches, some functions and the ApplyType opcode
> become unused, so this patch removes them.
>
> Follow-up #4230
> ---
Все еще можно нагрепать OP_ApplyType. Перепроверь.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error imeevma
@ 2020-06-30 0:22 ` Nikita Pettik
2020-07-05 15:03 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-30 0:22 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> After this patch value and its type will be shown in description
> of type mismatch error
Какие цели преследует этот патч? Зачем мы это делаем?
Диф то на 1.5 кслок. Забыл точку в конце :)
> }
> #ifdef SQL_DEBUG
> @@ -4740,7 +4735,7 @@ case OP_IdxGE: { /* jump */
> (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
> continue;
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> - field_type_strs[type], mem_type_to_str(mem));
> + sql_value_to_diag_str(mem), mem_type_to_str(mem));
> goto abort_due_to_error;
> }
> #ifdef SQL_DEBUG
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index a721afc83..bb7676354 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -1166,12 +1166,15 @@ sqlValueText(sql_value * pVal)
> const char *
> sql_value_to_diag_str(sql_value *value)
> {
> - if (sql_value_type(value) == MP_BIN) {
> - if (mem_has_msgpack_subtype(value))
> - return sqlValueText(value);
> + if (sql_value_mp_type(value) == MP_BIN)
> return "varbinary";
> - }
> - return sqlValueText(value);
> + char *type = mem_type_to_str(value);
> + char *str = (char *)sqlValueText(value);
> + if (str == NULL)
> + return "NULL";
> + if (strlen(str) < 80)
https://en.wikipedia.org/wiki/Magic_number_(programming)
> + return tt_sprintf("'%s' (type: %s)", str, type);
> + return tt_sprintf("'%.80s...' (type: %s)", str, type);
> }
>
> /*
> diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
> index 07442b60a..1547ffcd3 100755
> --- a/test/sql-tap/autoinc.test.lua
> +++ b/test/sql-tap/autoinc.test.lua
> @@ -618,7 +618,7 @@ test:do_catchsql_test(
> INSERT INTO t2 VALUES('asd');
> ]], {
> -- <autoinc-10.2>
> - 1, "Type mismatch: can not convert asd to integer"
> + 1, "Type mismatch: can not convert 'asd' (type: text) to integer"
Выглядит зачотно, выглядит all right!
> diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> index a1809b3cb..f1edfa0f6 100755
> --- a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> +++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> @@ -28,7 +28,7 @@ test:do_catchsql_test(
> [[
> INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
> ]], {
> - 1, "Type mismatch: can not convert 1.0e+32 to integer"
> + 1, "Type mismatch: can not convert '1.0e+32' (type: real) to integer"
> })
Я бы может еще кавычки вокруг чиселок/буленов не добавлял, но это
в принципе мелочь - тип то печатается.
В остальном - ОК.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment imeevma
@ 2020-06-30 11:50 ` Nikita Pettik
2020-07-05 14:26 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-06-30 11:50 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 25 Jun 18:17, imeevma@tarantool.org wrote:
> On 22.06.2020 11:48, Nikita Pettik wrote:
> > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> >> This patch removes type changing from OP_MakeRecord.
> >
> > Please reflect user-visible changes in commit message.
> >
> Fixed.
Seems to be the next patch..
> On 22.06.2020 12:32, Nikita Pettik wrote:
> > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> >> This patch removes implicit cast from STRING to numeric
> >> and vice versa of left operand of IN operator.
> >>
> >> Part of #4230
> >> Part of #4692
> >> ---
> >> src/box/sql/expr.c | 2 +-
> >> test/sql-tap/in3.test.lua | 14 +-----
> >> test/sql-tap/subquery.test.lua | 69 +---------------------------
> >> test/sql-tap/tkt-80e031a00f.test.lua | 4 +-
> >> test/sql/boolean.result | 12 ++---
> >> 5 files changed, 11 insertions(+), 90 deletions(-)
>
> On 22.06.2020 13:07, Nikita Pettik wrote:
> > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> >> This patch replaces mem_apply_type() with mem_check_types() in
> >> OP_MustBeInt, which allows to remove implicit cast in some places,
> >> for example, in the IN statement.
> >>
> >> Part of #4230
> >> ---
> >> src/box/sql/vdbe.c | 2 +-
> >> test/sql-tap/e_select1.test.lua | 17 +-
> >> test/sql-tap/in4.test.lua | 97 +--
> >> test/sql-tap/join.test.lua | 1 -
> >> test/sql-tap/limit.test.lua | 2 +-
> >> test/sql-tap/tkt-9a8b09f8e6.test.lua | 24 +-
> >> test/sql-tap/tkt-fc7bd6358f.test.lua | 111 ----
> >> test/sql-tap/transitive1.test.lua | 4 +-
> >> test/sql-tap/whereB.test.lua | 900 ---------------------------
> >> test/sql-tap/whereC.test.lua | 8 +-
> >> 10 files changed, 19 insertions(+), 1147 deletions(-)
> >> delete mode 100755 test/sql-tap/tkt-fc7bd6358f.test.lua
> >> delete mode 100755 test/sql-tap/whereB.test.lua
> >>
>
> New patch:
>
> commit 21d7145c1929bc4606c56e9a566477f248637ed1
> Author: Mergen Imeev <imeevma@gmail.com>
> Date: Wed May 27 13:49:11 2020 +0300
>
> diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
> index 37283e506..f1d0345f9 100644
> --- a/src/box/sql/sqlInt.h
> +++ b/src/box/sql/sqlInt.h
> @@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
> enum mp_type
> sql_value_type(sql_value *);
>
> +/*
> + * Return the MP_type of the value of the MEM.
> + *
> + * @param mem MEM with the correct MEM_type.
> + * @retval MP_type of the value.
> + */
> +enum mp_type
> +sql_value_mp_type(struct Mem *mem);
It's not sql_value *, it's struct Mem. So the name of function
is misleading.
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 950f72ddd..009d577d2 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -417,6 +417,143 @@ sql_value_apply_type(
> mem_apply_type((Mem *) pVal, type);
> }
>
> + *
> + * @param mem The MEM that contains the value to check.
> + * @param type The type to check.
> + * @retval 0 if the MEM_type of the value and the given type are
Wrong symbols.
> + * compatible, -1 otherwise.
> + */
> +static int
> +mem_check_type(struct Mem *mem, enum field_type type)
mem_test_type_compatibility
mem_check_type_consistency
mem_is_type_compatible
I'd prefer last one and change return value to boolean.
Then it turns into simple return field_mp_plain_type_is_compatible()..
> + enum mp_type mp_type = sql_value_mp_type(mem);
> + assert(mp_type < MP_EXT);
> + if (field_mp_plain_type_is_compatible(type, mp_type, true))
> + return 0;
> + return -1;
> +}
> +
> +/**
> + * Convert the numeric value contained in MEM to double. If the
> + * is_precise flag is set, the conversion will succeed only if it
> + * is lossless.
> + *
> + * @param mem The MEM that contains the numeric value.
> + * @param is_precise Flag.
> + * @retval 0 if the conversion was successful, -1 otherwise.
> + */
> +static int
> +mem_convert_to_double(struct Mem *mem, bool is_precise)
> +{
> + if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
> + return -1;
> + if ((mem->flags & MEM_Int) != 0) {
> + int64_t i = mem->u.i;
> + double d = (double)i;
> + if (!is_precise || i == (int64_t)d)
> + mem_set_double(mem, d);
> + else
> + return -1;
> + } else {
> + uint64_t u = mem->u.u;
> + double d = (double)u;
> + if (!is_precise || u == (uint64_t)d)
> + mem_set_double(mem, d);
> + else
> + return -1;
> + }
> + mem->field_type = FIELD_TYPE_DOUBLE;
Why not incorparate field_type assingment into mem_set_double()?
The same concerns other converting functions.
> +/**
> + * Convert the numeric value contained in MEM to another numeric
> + * type. If the is_precise flag is set, the conversion will
> + * succeed only if it is lossless.
> + *
> + * @param mem The MEM that contains the numeric value.
> + * @param type The type to convert to.
> + * @param is_precise Flag.
> + * @retval 0 if the conversion was successful, -1 otherwise.
> + */
> +static int
> +mem_convert_numeric(struct Mem *mem, enum field_type type, bool is_precise)
mem_convert_to_numeric ?
mem_cast_to_numeric
> +{
> + if (!sql_type_is_numeric(type) ||
> + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
It's somehow unnatural passing to _numeric function non-numeric type
to convert to. Instead let's use this function properly and replace
branching with assertion.
> + return -1;
> + if (type == FIELD_TYPE_NUMBER)
> + return 0;
> + if (type == FIELD_TYPE_DOUBLE)
> + return mem_convert_to_double(mem, is_precise);
> + if (type == FIELD_TYPE_UNSIGNED)
> + return mem_convert_to_unsigned(mem, is_precise);
> + assert(type == FIELD_TYPE_INTEGER);
> + return mem_convert_to_integer(mem, is_precise);
> +}
> +
> /*
> * pMem currently only holds a string type (or maybe a BLOB that we can
> * interpret as a string if we want to). Compute its corresponding
> @@ -2773,6 +2910,36 @@ case OP_ApplyType: {
> break;
> }
>
> +/* Opcode: CheckType P1 P2 * P4 *
> + * Synopsis: type(r[P1@P2])
> + *
> + * Check that types of P2 registers starting from register
> + * P1 are compatible with given with given field types in P4.
-> double 'with given'
> + * If the MEM_type of the value and the given type are
> + * incompatible, but both are numeric, this opcode attempts to
Incompatible but numeric? Could you please be more specific.
> + * convert the value to the type.
> + */
> +case OP_ImplicitCast: {
> + enum field_type *types = pOp->p4.types;
> + assert(types != NULL);
> + assert(types[pOp->p2] == field_type_MAX);
> + pIn1 = &aMem[pOp->p1];
> + enum field_type type;
> + while((type = *(types++)) != field_type_MAX) {
> + assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
> + assert(memIsValid(pIn1));
> + if (mem_check_type(pIn1, type) != 0 &&
> + mem_convert_numeric(pIn1, type, false) != 0) {
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + sql_value_to_diag_str(pIn1),
> + field_type_strs[type]);
> + goto abort_due_to_error;
> + }
> + pIn1++;
> + }
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-06-30 11:50 ` Nikita Pettik
@ 2020-07-05 14:26 ` Mergen Imeev
2020-07-06 21:27 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 14:26 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
Hi! Thank you for the review. My answers and new patch
below. Sorry, I didn't include diff.
On Tue, Jun 30, 2020 at 11:50:56AM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > On 22.06.2020 11:48, Nikita Pettik wrote:
> > > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> > >> This patch removes type changing from OP_MakeRecord.
> > >
> > > Please reflect user-visible changes in commit message.
> > >
> > Fixed.
>
> Seems to be the next patch..
>
True. Sorry about this.
> > On 22.06.2020 12:32, Nikita Pettik wrote:
> > > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> > >> This patch removes implicit cast from STRING to numeric
> > >> and vice versa of left operand of IN operator.
> > >>
> > >> Part of #4230
> > >> Part of #4692
> > >> ---
> > >> src/box/sql/expr.c | 2 +-
> > >> test/sql-tap/in3.test.lua | 14 +-----
> > >> test/sql-tap/subquery.test.lua | 69 +---------------------------
> > >> test/sql-tap/tkt-80e031a00f.test.lua | 4 +-
> > >> test/sql/boolean.result | 12 ++---
> > >> 5 files changed, 11 insertions(+), 90 deletions(-)
> >
> > On 22.06.2020 13:07, Nikita Pettik wrote:
> > > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> > >> This patch replaces mem_apply_type() with mem_check_types() in
> > >> OP_MustBeInt, which allows to remove implicit cast in some places,
> > >> for example, in the IN statement.
> > >>
> > >> Part of #4230
> > >> ---
> > >> src/box/sql/vdbe.c | 2 +-
> > >> test/sql-tap/e_select1.test.lua | 17 +-
> > >> test/sql-tap/in4.test.lua | 97 +--
> > >> test/sql-tap/join.test.lua | 1 -
> > >> test/sql-tap/limit.test.lua | 2 +-
> > >> test/sql-tap/tkt-9a8b09f8e6.test.lua | 24 +-
> > >> test/sql-tap/tkt-fc7bd6358f.test.lua | 111 ----
> > >> test/sql-tap/transitive1.test.lua | 4 +-
> > >> test/sql-tap/whereB.test.lua | 900 ---------------------------
> > >> test/sql-tap/whereC.test.lua | 8 +-
> > >> 10 files changed, 19 insertions(+), 1147 deletions(-)
> > >> delete mode 100755 test/sql-tap/tkt-fc7bd6358f.test.lua
> > >> delete mode 100755 test/sql-tap/whereB.test.lua
> > >>
> >
> > New patch:
> >
> > commit 21d7145c1929bc4606c56e9a566477f248637ed1
> > Author: Mergen Imeev <imeevma@gmail.com>
> > Date: Wed May 27 13:49:11 2020 +0300
> >
> > diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
> > index 37283e506..f1d0345f9 100644
> > --- a/src/box/sql/sqlInt.h
> > +++ b/src/box/sql/sqlInt.h
> > @@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
> > enum mp_type
> > sql_value_type(sql_value *);
> >
> > +/*
> > + * Return the MP_type of the value of the MEM.
> > + *
> > + * @param mem MEM with the correct MEM_type.
> > + * @retval MP_type of the value.
> > + */
> > +enum mp_type
> > +sql_value_mp_type(struct Mem *mem);
>
> It's not sql_value *, it's struct Mem. So the name of function
> is misleading.
Changed name to 'mem_mp_type'.
>
> > diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> > index 950f72ddd..009d577d2 100644
> > --- a/src/box/sql/vdbe.c
> > +++ b/src/box/sql/vdbe.c
> > @@ -417,6 +417,143 @@ sql_value_apply_type(
> > mem_apply_type((Mem *) pVal, type);
> > }
> >
> > + *
> > + * @param mem The MEM that contains the value to check.
> > + * @param type The type to check.
> > + * @retval 0 if the MEM_type of the value and the given type are
>
> Wrong symbols.
>
Fixed.
> > + * compatible, -1 otherwise.
> > + */
> > +static int
> > +mem_check_type(struct Mem *mem, enum field_type type)
>
> mem_test_type_compatibility
> mem_check_type_consistency
> mem_is_type_compatible
>
> I'd prefer last one and change return value to boolean.
> Then it turns into simple return field_mp_plain_type_is_compatible()..
>
Fixed, used third option.
> > + enum mp_type mp_type = sql_value_mp_type(mem);
> > + assert(mp_type < MP_EXT);
> > + if (field_mp_plain_type_is_compatible(type, mp_type, true))
> > + return 0;
> > + return -1;
> > +}
> > +
> > +/**
> > + * Convert the numeric value contained in MEM to double. If the
> > + * is_precise flag is set, the conversion will succeed only if it
> > + * is lossless.
> > + *
> > + * @param mem The MEM that contains the numeric value.
> > + * @param is_precise Flag.
> > + * @retval 0 if the conversion was successful, -1 otherwise.
> > + */
> > +static int
> > +mem_convert_to_double(struct Mem *mem, bool is_precise)
> > +{
> > + if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
> > + return -1;
> > + if ((mem->flags & MEM_Int) != 0) {
> > + int64_t i = mem->u.i;
> > + double d = (double)i;
> > + if (!is_precise || i == (int64_t)d)
> > + mem_set_double(mem, d);
> > + else
> > + return -1;
> > + } else {
> > + uint64_t u = mem->u.u;
> > + double d = (double)u;
> > + if (!is_precise || u == (uint64_t)d)
> > + mem_set_double(mem, d);
> > + else
> > + return -1;
> > + }
> > + mem->field_type = FIELD_TYPE_DOUBLE;
>
> Why not incorparate field_type assingment into mem_set_double()?
> The same concerns other converting functions.
>
I think this should be done in #4906 issue since it may
lead to not always simple to understand changes.
> > +/**
> > + * Convert the numeric value contained in MEM to another numeric
> > + * type. If the is_precise flag is set, the conversion will
> > + * succeed only if it is lossless.
> > + *
> > + * @param mem The MEM that contains the numeric value.
> > + * @param type The type to convert to.
> > + * @param is_precise Flag.
> > + * @retval 0 if the conversion was successful, -1 otherwise.
> > + */
> > +static int
> > +mem_convert_numeric(struct Mem *mem, enum field_type type, bool is_precise)
>
> mem_convert_to_numeric ?
> mem_cast_to_numeric
>
Used first option.
> > +{
> > + if (!sql_type_is_numeric(type) ||
> > + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
>
> It's somehow unnatural passing to _numeric function non-numeric type
> to convert to. Instead let's use this function properly and replace
> branching with assertion.
>
No, I think it is good as it is. More that that, due to
some other comments I added similar checks to all other
mem_convert_to>* functions.
My reason is: in all places we use this function we have
to check that field type and MEM_type are numeric, so it
make sence to move this check inside of the function.
> > + return -1;
> > + if (type == FIELD_TYPE_NUMBER)
> > + return 0;
> > + if (type == FIELD_TYPE_DOUBLE)
> > + return mem_convert_to_double(mem, is_precise);
> > + if (type == FIELD_TYPE_UNSIGNED)
> > + return mem_convert_to_unsigned(mem, is_precise);
> > + assert(type == FIELD_TYPE_INTEGER);
> > + return mem_convert_to_integer(mem, is_precise);
> > +}
> > +
> > /*
> > * pMem currently only holds a string type (or maybe a BLOB that we can
> > * interpret as a string if we want to). Compute its corresponding
> > @@ -2773,6 +2910,36 @@ case OP_ApplyType: {
> > break;
> > }
> >
> > +/* Opcode: CheckType P1 P2 * P4 *
> > + * Synopsis: type(r[P1@P2])
> > + *
> > + * Check that types of P2 registers starting from register
> > + * P1 are compatible with given with given field types in P4.
>
> -> double 'with given'
>
Fixed.
> > + * If the MEM_type of the value and the given type are
> > + * incompatible, but both are numeric, this opcode attempts to
>
> Incompatible but numeric? Could you please be more specific.
>
Incompatible and incompareble have different definitions
here. I changed to 'incompatible according to
field_mp_plain_type_is_compatible()'.
> > + * convert the value to the type.
> > + */
> > +case OP_ImplicitCast: {
> > + enum field_type *types = pOp->p4.types;
> > + assert(types != NULL);
> > + assert(types[pOp->p2] == field_type_MAX);
> > + pIn1 = &aMem[pOp->p1];
> > + enum field_type type;
> > + while((type = *(types++)) != field_type_MAX) {
> > + assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
> > + assert(memIsValid(pIn1));
> > + if (mem_check_type(pIn1, type) != 0 &&
> > + mem_convert_numeric(pIn1, type, false) != 0) {
> > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > + sql_value_to_diag_str(pIn1),
> > + field_type_strs[type]);
> > + goto abort_due_to_error;
> > + }
> > + pIn1++;
> > + }
New patch:
commit 6468f9c853e51565e73423ccf29b92862783d42e
Author: Mergen Imeev <imeevma@gmail.com>
Date: Wed May 27 13:49:11 2020 +0300
sql: change implicit cast for assignment
This patch changes implicit cast for assignment.
Closes #3809
@TarantoolBot document
Title: change implicit cast for comparison
After this patch, these rules will apply during the implicit cast:
| | STRING | BINARY | BOOLEAN | INTEGER | UNSIGNED | DOUBLE |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
| STRING | A | N | N | N | N | N |
| BINARY | N | A | N | N | N | N |
| BOOLEAN | N | N | A | N | N | N |
| INTEGER | N | N | N | A | S | Aa |
| UNSIGNED | N | N | N | A | A | Aa |
| DOUBLE | N | N | N | Sa | Sa | A |
In this table, the types of the assigned value are on the left,
and the types that should be after the assignment are at the top.
'A' - the assignment will be completed.
'N' - the assignment won't be completed.
'S' - the appointment may be unsuccessful.
'a' - after assignment, the resulting value may be approximated.
Rules for numeric values are these:
1) Loss of significant digits (overflow) is an error.
2) Loss of insignificant digits is not an error.
Example:
```
tarantool> box.execute([[CREATE TABLE t1(i INT PRIMARY KEY);]])
tarantool> box.execute([[INSERT INTO t1 VALUES ('1');]])
---
- null
- 'Type mismatch: can not convert 1 to integer'
...
tarantool> box.execute('INSERT INTO t1 VALUES (1.2345);')
tarantool> box.execute('SELECT * FROM t1;')
---
- metadata:
- name: I
type: integer
rows:
- [1]
...
tarantool> box.execute([[CREATE TABLE t2(t text PRIMARY KEY);]])
tarantool> box.execute([[INSERT INTO t2 VALUES (1);]])
---
- null
- 'Type mismatch: can not convert 1 to string'
...
```
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 588e142d2..8a89f9904 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -69,7 +69,7 @@ sql_emit_table_types(struct Vdbe *v, struct space_def *def, int reg)
for (uint32_t i = 0; i < field_count; ++i)
colls_type[i] = def->fields[i].type;
colls_type[field_count] = field_type_MAX;
- sqlVdbeAddOp4(v, OP_ApplyType, reg, field_count, 0,
+ sqlVdbeAddOp4(v, OP_ImplicitCast, reg, field_count, 0,
(char *)colls_type, P4_DYNAMIC);
}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 37283e506..bd0055668 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
enum mp_type
sql_value_type(sql_value *);
+/*
+ * Return the MP_type of the value of the MEM.
+ *
+ * @param mem MEM with the correct MEM_type.
+ * @retval MP_type of the value.
+ */
+enum mp_type
+mem_mp_type(struct Mem *mem);
+
static inline bool
sql_value_is_null(sql_value *value)
{
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 950f72ddd..1386ea2c0 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -417,6 +417,150 @@ sql_value_apply_type(
mem_apply_type((Mem *) pVal, type);
}
+/**
+ * Check that MEM_type of the mem is compatible with given type.
+ *
+ * @param mem The MEM that contains the value to check.
+ * @param type The type to check.
+ * @retval TRUE if the MEM_type of the value and the given type
+ * are compatible, FALSE otherwise.
+ */
+static bool
+mem_is_type_compatible(struct Mem *mem, enum field_type type)
+{
+ enum mp_type mp_type = mem_mp_type(mem);
+ assert(mp_type < MP_EXT);
+ return field_mp_plain_type_is_compatible(type, mp_type, true);
+}
+
+/**
+ * Convert the numeric value contained in MEM to double. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_double(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & MEM_Real) != 0)
+ return 0;
+ if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
+ return -1;
+ if ((mem->flags & MEM_Int) != 0) {
+ int64_t i = mem->u.i;
+ double d = (double)i;
+ if (!is_precise || i == (int64_t)d)
+ mem_set_double(mem, d);
+ else
+ return -1;
+ } else {
+ uint64_t u = mem->u.u;
+ double d = (double)u;
+ if (!is_precise || u == (uint64_t)d)
+ mem_set_double(mem, d);
+ else
+ return -1;
+ }
+ mem->field_type = FIELD_TYPE_DOUBLE;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to unsigned. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_unsigned(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & MEM_UInt) != 0)
+ return 0;
+ if ((mem->flags & MEM_Int) != 0)
+ return -1;
+ if ((mem->flags & MEM_Real) == 0)
+ return -1;
+ double d = mem->u.r;
+ if (d < 0.0 || d >= (double)UINT64_MAX)
+ return -1;
+ uint64_t u = (uint64_t)d;
+ if (!is_precise || d == (double)u)
+ mem_set_u64(mem, (uint64_t) d);
+ else
+ return -1;
+ mem->field_type = FIELD_TYPE_UNSIGNED;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to integer. If the
+ * is_precise flag is set, the conversion will succeed only if it
+ * is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_integer(struct Mem *mem, bool is_precise)
+{
+ if ((mem->flags & (MEM_UInt | MEM_Int)) != 0)
+ return 0;
+ if ((mem->flags & MEM_Real) == 0)
+ return -1;
+ double d = mem->u.r;
+ if (d >= (double)UINT64_MAX || d < (double)INT64_MIN)
+ return -1;
+ if (d < (double)INT64_MAX) {
+ int64_t i = (int64_t)d;
+ if (!is_precise || d == (double)i)
+ mem_set_i64(mem, (int64_t) d);
+ else
+ return -1;
+ } else {
+ uint64_t u = (uint64_t)d;
+ if (!is_precise || d == (double)u)
+ mem_set_u64(mem, (uint64_t) d);
+ else
+ return -1;
+ }
+ mem->field_type = FIELD_TYPE_INTEGER;
+ return 0;
+}
+
+/**
+ * Convert the numeric value contained in MEM to another numeric
+ * type. If the is_precise flag is set, the conversion will
+ * succeed only if it is lossless.
+ *
+ * @param mem The MEM that contains the numeric value.
+ * @param type The type to convert to.
+ * @param is_precise Flag.
+ * @retval 0 if the conversion was successful, -1 otherwise.
+ */
+static int
+mem_convert_to_numeric(struct Mem *mem, enum field_type type, bool is_precise)
+{
+ if (!sql_type_is_numeric(type))
+ return -1;
+ if ((mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
+ return -1;
+ if (type == FIELD_TYPE_NUMBER)
+ return 0;
+ if (type == FIELD_TYPE_DOUBLE)
+ return mem_convert_to_double(mem, is_precise);
+ if (type == FIELD_TYPE_UNSIGNED)
+ return mem_convert_to_unsigned(mem, is_precise);
+ assert(type == FIELD_TYPE_INTEGER);
+ return mem_convert_to_integer(mem, is_precise);
+}
+
/*
* pMem currently only holds a string type (or maybe a BLOB that we can
* interpret as a string if we want to). Compute its corresponding
@@ -2773,6 +2917,36 @@ case OP_ApplyType: {
break;
}
+/* Opcode: ImplicitCast P1 P2 * P4 *
+ * Synopsis: type(r[P1@P2])
+ *
+ * Check that types of P2 registers starting from register
+ * P1 are compatible with given field types in P4.
+ * If the MEM_type of the value and the given type are
+ * incompatible according to field_mp_plain_type_is_compatible(),
+ * but both are numeric, this opcode attempts to convert the value
+ * to the type.
+ */
+case OP_ImplicitCast: {
+ enum field_type *types = pOp->p4.types;
+ assert(types != NULL);
+ assert(types[pOp->p2] == field_type_MAX);
+ for (int i = 0; types[i] != field_type_MAX; ++i) {
+ enum field_type type = types[i];
+ pIn1 = &aMem[pOp->p1 + i];
+ assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
+ assert(memIsValid(pIn1));
+ if (mem_is_type_compatible(pIn1, type))
+ continue;
+ if (mem_convert_to_numeric(pIn1, type, false) == 0)
+ continue;
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1), field_type_strs[type]);
+ goto abort_due_to_error;
+ }
+ break;
+}
+
/* Opcode: MakeRecord P1 P2 P3 P4 P5
* Synopsis: r[P3]=mkrec(r[P1@P2])
*
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 4e103a653..b106ce6bd 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -225,6 +225,33 @@ sql_value_type(sql_value *pVal)
}
}
+enum mp_type
+mem_mp_type(struct Mem *mem)
+{
+ switch (mem->flags & MEM_PURE_TYPE_MASK) {
+ case MEM_Int:
+ return MP_INT;
+ case MEM_UInt:
+ return MP_UINT;
+ case MEM_Real:
+ return MP_DOUBLE;
+ case MEM_Str:
+ return MP_STR;
+ case MEM_Blob:
+ if ((mem->flags & MEM_Subtype) == 0 ||
+ mem->subtype != SQL_SUBTYPE_MSGPACK)
+ return MP_BIN;
+ assert(mp_typeof(*mem->z) == MP_MAP ||
+ mp_typeof(*mem->z) == MP_ARRAY);
+ return mp_typeof(*mem->z);
+ case MEM_Bool:
+ return MP_BOOL;
+ case MEM_Null:
+ return MP_NIL;
+ default: unreachable();
+ }
+}
+
/* Make a copy of an sql_value object
*/
sql_value *
diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
index 37e65e541..07442b60a 100755
--- a/test/sql-tap/autoinc.test.lua
+++ b/test/sql-tap/autoinc.test.lua
@@ -694,7 +694,7 @@ test:do_test(
INSERT INTO t3928(b) VALUES('after-int-' || CAST(new.b AS TEXT));
END;
DELETE FROM t3928 WHERE a!=1;
- UPDATE t3928 SET b=456 WHERE a=1;
+ UPDATE t3928 SET b='456' WHERE a=1;
SELECT * FROM t3928 ORDER BY a;
]])
end, {
diff --git a/test/sql-tap/default.test.lua b/test/sql-tap/default.test.lua
index d3e35c71c..f1def2b10 100755
--- a/test/sql-tap/default.test.lua
+++ b/test/sql-tap/default.test.lua
@@ -109,16 +109,12 @@ test:do_execsql_test(
f VARCHAR(15), --COLLATE RTRIM,
g INTEGER DEFAULT( 3600*12 )
);
- INSERT INTO t3 VALUES(null, 5, 'row1', 5.25, 8.67, 321, 432);
+ INSERT INTO t3 VALUES(null, 5, 'row1', 5.25, 8.67, '321', 432);
SELECT a, typeof(a), b, typeof(b), c, typeof(c),
d, typeof(d), e, typeof(e), f, typeof(f),
g, typeof(g) FROM t3;
]], {
-- <default-3.1>
- -- TODO: In original test "321" is not a string, its a value.
- -- In current situation I don't know what to do, need Kirill's
- -- advice.
- -- Bulat
1, "integer", 5, "integer", "row1", "string", 5.25, "number", 8.67, "number", "321", "string", 432, "integer"
-- </default-3.1>
})
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index 1d3b964b9..7673426f4 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -753,11 +753,11 @@ test:do_execsql_test(
CREATE TABLE z3(id INT primary key, a NUMBER, b NUMBER);
INSERT INTO z1 VALUES(1, 51.65, -59.58, 'belfries');
- INSERT INTO z1 VALUES(2, -5, NULL, 75);
+ INSERT INTO z1 VALUES(2, -5, NULL, '75');
INSERT INTO z1 VALUES(3, -2.2, -23.18, 'suiters');
INSERT INTO z1 VALUES(4, NULL, 67, 'quartets');
INSERT INTO z1 VALUES(5, -1.04, -32.3, 'aspen');
- INSERT INTO z1 VALUES(6, 63, '0', -26);
+ INSERT INTO z1 VALUES(6, 63, 0, '-26');
INSERT INTO z2 VALUES(1, NULL, 21);
INSERT INTO z2 VALUES(2, 36.0, 6.0);
@@ -1457,13 +1457,13 @@ test:do_execsql_test(
CREATE TABLE q2(id INT primary key, d TEXT, e NUMBER);
CREATE TABLE q3(id INT primary key, f TEXT, g INT);
- INSERT INTO q1 VALUES(1, 16, -87.66, NULL);
+ INSERT INTO q1 VALUES(1, '16', -87.66, NULL);
INSERT INTO q1 VALUES(2, 'legible', 94, -42.47);
INSERT INTO q1 VALUES(3, 'beauty', 36, NULL);
INSERT INTO q2 VALUES(1, 'legible', 1);
INSERT INTO q2 VALUES(2, 'beauty', 2);
- INSERT INTO q2 VALUES(3, -65, 4);
+ INSERT INTO q2 VALUES(3, '-65', 4);
INSERT INTO q2 VALUES(4, 'emanating', -16.56);
INSERT INTO q3 VALUES(1, 'beauty', 2);
@@ -1603,7 +1603,7 @@ test:do_execsql_test(
CREATE TABLE w2(a INT PRIMARY KEY, b TEXT);
INSERT INTO w1 VALUES('1', 4.1);
- INSERT INTO w2 VALUES(1, 4.1);
+ INSERT INTO w2 VALUES(1, '4.1');
]], {
-- <e_select-7.10.0>
diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
new file mode 100755
index 000000000..a1809b3cb
--- /dev/null
+++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
@@ -0,0 +1,653 @@
+#!/usr/bin/env tarantool
+test = require("sqltester")
+test:plan(77)
+
+--
+-- Make sure there are no implicit casts during assignment,
+-- except for the implicit cast between numeric values.
+--
+test:execsql([[
+ CREATE TABLE ti (a INT PRIMARY KEY AUTOINCREMENT, i INTEGER);
+ CREATE TABLE td (a INT PRIMARY KEY AUTOINCREMENT, d DOUBLE);
+ CREATE TABLE tb (a INT PRIMARY KEY AUTOINCREMENT, b BOOLEAN);
+ CREATE TABLE tt (a INT PRIMARY KEY AUTOINCREMENT, t TEXT);
+ CREATE TABLE tv (a INT PRIMARY KEY AUTOINCREMENT, v VARBINARY);
+ CREATE TABLE ts (a INT PRIMARY KEY AUTOINCREMENT, s SCALAR);
+]])
+
+test:do_catchsql_test(
+ "gh-3809-1",
+ [[
+ INSERT INTO ti(i) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-2",
+ [[
+ INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
+ ]], {
+ 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-3",
+ [[
+ INSERT INTO ti(i) VALUES (33.0)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-4",
+ [[
+ INSERT INTO ti(i) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-5",
+ [[
+ INSERT INTO ti(i) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-6",
+ [[
+ INSERT INTO ti(i) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to integer"
+ })
+
+test:do_execsql_test(
+ "gh-3809-7",
+ [[
+ SELECT * FROM ti;
+ ]], {
+ 1, 11, 2, 33
+ })
+
+test:do_catchsql_test(
+ "gh-3809-8",
+ [[
+ INSERT INTO td(d) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-9",
+ [[
+ INSERT INTO td(d) VALUES (100000000000000001);
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-10",
+ [[
+ INSERT INTO td(d) VALUES (22.2)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-11",
+ [[
+ INSERT INTO td(d) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-12",
+ [[
+ INSERT INTO td(d) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-13",
+ [[
+ INSERT INTO td(d) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to double"
+ })
+
+test:do_execsql_test(
+ "gh-3809-14",
+ [[
+ SELECT * FROM td;
+ ]], {
+ 1, 11, 2, 100000000000000000, 3, 22.2
+ })
+
+test:do_catchsql_test(
+ "gh-3809-15",
+ [[
+ INSERT INTO tb(b) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-16",
+ [[
+ INSERT INTO tb(b) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-17",
+ [[
+ INSERT INTO tb(b) VALUES (true)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-18",
+ [[
+ INSERT INTO tb(b) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-19",
+ [[
+ INSERT INTO tb(b) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to boolean"
+ })
+
+test:do_execsql_test(
+ "gh-3809-20",
+ [[
+ SELECT * FROM tb;
+ ]], {
+ 1, true
+ })
+
+test:do_catchsql_test(
+ "gh-3809-21",
+ [[
+ INSERT INTO tt(t) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-22",
+ [[
+ INSERT INTO tt(t) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-23",
+ [[
+ INSERT INTO tt(t) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-24",
+ [[
+ INSERT INTO tt(t) VALUES ('33')
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-25",
+ [[
+ INSERT INTO tt(t) VALUES (X'3434')
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to string"
+ })
+
+test:do_execsql_test(
+ "gh-3809-26",
+ [[
+ SELECT * FROM tt;
+ ]], {
+ 1, "33"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-27",
+ [[
+ INSERT INTO tv(v) VALUES (11)
+ ]], {
+ 1, "Type mismatch: can not convert 11 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-28",
+ [[
+ INSERT INTO tv(v) VALUES (22.2)
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-29",
+ [[
+ INSERT INTO tv(v) VALUES (true)
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-30",
+ [[
+ INSERT INTO tv(v) VALUES ('33')
+ ]], {
+ 1, "Type mismatch: can not convert 33 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-31",
+ [[
+ INSERT INTO tv(v) VALUES (X'3434')
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-32",
+ [[
+ SELECT * FROM tv;
+ ]], {
+ 1, "44"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-33",
+ [[
+ INSERT INTO ts(s) VALUES (11)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-34",
+ [[
+ INSERT INTO ts(s) VALUES (22.2)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-35",
+ [[
+ INSERT INTO ts(s) VALUES (true)
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-36",
+ [[
+ INSERT INTO ts(s) VALUES ('33')
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-37",
+ [[
+ INSERT INTO ts(s) VALUES (X'3434')
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-38",
+ [[
+ SELECT * FROM ts;
+ ]], {
+ 1, 11, 2, 22.2, 3, true, 4, "33", 5, "44"
+ })
+
+--
+-- This test suite verifies that ASSIGNMENT is working correctly
+-- during an UPDATE.
+--
+test:execsql([[
+ DELETE FROM ti;
+ DELETE FROM td;
+ DELETE FROM tb;
+ DELETE FROM tt;
+ DELETE FROM tv;
+ DELETE FROM ts;
+ INSERT INTO ti(a) VALUES(1);
+ INSERT INTO td(a) VALUES(1);
+ INSERT INTO tb(a) VALUES(1);
+ INSERT INTO tt(a) VALUES(1);
+ INSERT INTO tv(a) VALUES(1);
+ INSERT INTO ts(a) VALUES(1);
+]])
+
+test:do_execsql_test(
+ "gh-3809-39",
+ [[
+ SELECT * FROM ti, td, tb, tt, tv, ts;
+ ]], {
+ 1, "", 1, "", 1, "", 1, "", 1, "", 1, ""
+ })
+
+test:do_catchsql_test(
+ "gh-3809-40",
+ [[
+ UPDATE ti SET i = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-41",
+ [[
+ UPDATE ti SET i = 100000000000000000000000000000000.1 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 1.0e+32 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-42",
+ [[
+ UPDATE ti SET i = 33.0 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-43",
+ [[
+ UPDATE ti SET i = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-44",
+ [[
+ UPDATE ti SET i = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to integer"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-45",
+ [[
+ UPDATE ti SET i = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to integer"
+ })
+
+test:do_execsql_test(
+ "gh-3809-46",
+ [[
+ SELECT * FROM ti;
+ ]], {
+ 1, 33
+ })
+
+test:do_catchsql_test(
+ "gh-3809-47",
+ [[
+ UPDATE td SET d = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-48",
+ [[
+ UPDATE td SET d = 100000000000000001 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-49",
+ [[
+ UPDATE td SET d = 22.2 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-50",
+ [[
+ UPDATE td SET d = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-51",
+ [[
+ UPDATE td SET d = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to double"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-52",
+ [[
+ UPDATE td SET d = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to double"
+ })
+
+test:do_execsql_test(
+ "gh-3809-53",
+ [[
+ SELECT * FROM td;
+ ]], {
+ 1, 22.2
+ })
+
+test:do_catchsql_test(
+ "gh-3809-54",
+ [[
+ UPDATE tb SET b = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-55",
+ [[
+ UPDATE tb SET b = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-56",
+ [[
+ UPDATE tb SET b = true WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-57",
+ [[
+ UPDATE tb SET b = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to boolean"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-58",
+ [[
+ UPDATE tb SET b = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to boolean"
+ })
+
+test:do_execsql_test(
+ "gh-3809-59",
+ [[
+ SELECT * FROM tb;
+ ]], {
+ 1, true
+ })
+
+test:do_catchsql_test(
+ "gh-3809-60",
+ [[
+ UPDATE tt SET t = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-61",
+ [[
+ UPDATE tt SET t = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-62",
+ [[
+ UPDATE tt SET t = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to string"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-63",
+ [[
+ UPDATE tt SET t = '33' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-64",
+ [[
+ UPDATE tt SET t = X'3434' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert varbinary to string"
+ })
+
+test:do_execsql_test(
+ "gh-3809-65",
+ [[
+ SELECT * FROM tt;
+ ]], {
+ 1, "33"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-66",
+ [[
+ UPDATE tv SET v = 11 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 11 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-67",
+ [[
+ UPDATE tv SET v = 22.2 WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 22.2 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-68",
+ [[
+ UPDATE tv SET v = true WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert TRUE to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-69",
+ [[
+ UPDATE tv SET v = '33' WHERE a = 1;
+ ]], {
+ 1, "Type mismatch: can not convert 33 to varbinary"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-70",
+ [[
+ UPDATE tv SET v = X'3434' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-71",
+ [[
+ SELECT * FROM tv;
+ ]], {
+ 1, "44"
+ })
+
+test:do_catchsql_test(
+ "gh-3809-72",
+ [[
+ UPDATE ts SET s = 11 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-73",
+ [[
+ UPDATE ts SET s = 22.2 WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-74",
+ [[
+ UPDATE ts SET s = true WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-75",
+ [[
+ UPDATE ts SET s = '33' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_catchsql_test(
+ "gh-3809-76",
+ [[
+ UPDATE ts SET s = X'3434' WHERE a = 1;
+ ]], {
+ 0
+ })
+
+test:do_execsql_test(
+ "gh-3809-77",
+ [[
+ SELECT * FROM ts;
+ ]], {
+ 1, "44"
+ })
+
+test:finish_test()
diff --git a/test/sql-tap/index1.test.lua b/test/sql-tap/index1.test.lua
index e173e685c..ce66b7c1e 100755
--- a/test/sql-tap/index1.test.lua
+++ b/test/sql-tap/index1.test.lua
@@ -593,25 +593,17 @@ test:do_test(
-- </index-11.1>
})
end
--- integrity_check index-11.2
--- Numeric strings should compare as if they were numbers. So even if the
--- strings are not character-by-character the same, if they represent the
--- same number they should compare equal to one another. Verify that this
--- is true in indices.
---
--- Updated for sql v3: sql will now store these values as numbers
--- (because the affinity of column a is NUMERIC) so the quirky
--- representations are not retained. i.e. '+1.0' becomes '1'.
+
test:do_execsql_test(
"index-12.1",
[[
CREATE TABLE t4(id INT primary key, a NUMBER,b INT );
- INSERT INTO t4 VALUES(1, '0.0',1);
- INSERT INTO t4 VALUES(2, '0.00',2);
- INSERT INTO t4 VALUES(4, '-1.0',4);
- INSERT INTO t4 VALUES(5, '+1.0',5);
- INSERT INTO t4 VALUES(6, '0',6);
- INSERT INTO t4 VALUES(7, '00000',7);
+ INSERT INTO t4 VALUES(1, 0.0, 1);
+ INSERT INTO t4 VALUES(2, 0.00, 2);
+ INSERT INTO t4 VALUES(4, -1.0, 4);
+ INSERT INTO t4 VALUES(5, +1.0, 5);
+ INSERT INTO t4 VALUES(6, 0, 6);
+ INSERT INTO t4 VALUES(7, 00000, 7);
SELECT a FROM t4 ORDER BY b;
]], {
-- <index-12.1>
@@ -692,7 +684,7 @@ test:do_execsql_test(
c TEXT,
UNIQUE(a,c)
);
- INSERT INTO t5 VALUES(1,2,3);
+ INSERT INTO t5 VALUES(1,2,'3');
SELECT * FROM t5;
]], {
-- <index-13.1>
diff --git a/test/sql-tap/insert3.test.lua b/test/sql-tap/insert3.test.lua
index 43bb06630..b92bc508e 100755
--- a/test/sql-tap/insert3.test.lua
+++ b/test/sql-tap/insert3.test.lua
@@ -60,7 +60,7 @@ test:do_execsql_test(
CREATE TABLE log2(rowid INTEGER PRIMARY KEY AUTOINCREMENT, x TEXT UNIQUE,y INT );
CREATE TRIGGER r2 BEFORE INSERT ON t1 FOR EACH ROW BEGIN
UPDATE log2 SET y=y+1 WHERE x=new.b;
- INSERT OR IGNORE INTO log2(x, y) VALUES(new.b,1);
+ INSERT OR IGNORE INTO log2(x, y) VALUES(CAST(new.b AS STRING),1);
END;
INSERT INTO t1(a, b) VALUES('hi', 453);
SELECT x,y FROM log ORDER BY x;
@@ -129,8 +129,8 @@ test:do_execsql_test(
INSERT INTO t2dup(a,b,c) VALUES(new.a,new.b,new.c);
END;
INSERT INTO t2(a) VALUES(123);
- INSERT INTO t2(b) VALUES(234);
- INSERT INTO t2(c) VALUES(345);
+ INSERT INTO t2(b) VALUES('234');
+ INSERT INTO t2(c) VALUES('345');
SELECT * FROM t2dup;
]], {
-- <insert3-2.1>
@@ -143,8 +143,8 @@ test:do_execsql_test(
[[
DELETE FROM t2dup;
INSERT INTO t2(a) SELECT 1 FROM t1 LIMIT 1;
- INSERT INTO t2(b) SELECT 987 FROM t1 LIMIT 1;
- INSERT INTO t2(c) SELECT 876 FROM t1 LIMIT 1;
+ INSERT INTO t2(b) SELECT '987' FROM t1 LIMIT 1;
+ INSERT INTO t2(c) SELECT '876' FROM t1 LIMIT 1;
SELECT * FROM t2dup;
]], {
-- <insert3-2.2>
diff --git a/test/sql-tap/intpkey.test.lua b/test/sql-tap/intpkey.test.lua
index b6b186632..684a24114 100755
--- a/test/sql-tap/intpkey.test.lua
+++ b/test/sql-tap/intpkey.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(40)
+test:plan(31)
--!./tcltestrunner.lua
-- 2001 September 15
@@ -770,142 +770,13 @@ test:do_execsql_test(
-- </intpkey-11.1>
})
--- integrity_check intpkey-12.1
--- Try to use a string that looks like a floating point number as
--- an integer primary key. This should actually work when the floating
--- point value can be rounded to an integer without loss of data.
---
-test:do_execsql_test(
- "intpkey-13.1",
- [[
- SELECT * FROM t1 WHERE a=1;
- ]], {
- -- <intpkey-13.1>
-
- -- </intpkey-13.1>
- })
-
-test:do_execsql_test(
- "intpkey-13.2",
- [[
- INSERT INTO t1 VALUES('1',2,3);
- SELECT * FROM t1 WHERE a=1;
- ]], {
- -- <intpkey-13.2>
- 1, "2", "3"
- -- </intpkey-13.2>
- })
-
--- MUST_WORK_TEST
-if (0 > 0) then
- -- Tarantool: issue submitted #2315
- test:do_catchsql_test(
- "intpkey-13.3",
- [[
- INSERT INTO t1 VALUES('1.5',3,4);
- ]], {
- -- <intpkey-13.3>
- 1, "datatype mismatch"
- -- </intpkey-13.3>
- })
-
- test:do_catchsql_test(
- "intpkey-13.4",
- [[
- INSERT INTO t1 VALUES(x'123456',3,4);
- ]], {
- -- <intpkey-13.4>
- 1, "datatype mismatch"
- -- </intpkey-13.4>
- })
-
-
-
-end
-test:do_catchsql_test(
- "intpkey-13.5",
- [[
- INSERT INTO t1 VALUES('+1234567890',3,4);
- ]], {
- -- <intpkey-13.5>
- 0
- -- </intpkey-13.5>
- })
-
--- Compare an INTEGER PRIMARY KEY against a TEXT expression. The INTEGER
--- affinity should be applied to the text value before the comparison
--- takes place.
---
-test:do_execsql_test(
- "intpkey-14.1",
- [[
- CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT);
- INSERT INTO t3 VALUES(1, 1, 'one');
- INSERT INTO t3 VALUES(2, 2, '2');
- INSERT INTO t3 VALUES(3, 3, 3);
- ]], {
- -- <intpkey-14.1>
-
- -- </intpkey-14.1>
- })
-
-test:do_execsql_test(
- "intpkey-14.2",
- [[
- SELECT * FROM t3 WHERE a>2;
- ]], {
- -- <intpkey-14.2>
- 3, 3, "3"
- -- </intpkey-14.2>
- })
-
-test:do_execsql_test(
- "intpkey-14.3",
- [[
- SELECT * FROM t3 WHERE a>'2';
- ]], {
- -- <intpkey-14.3>
- 3, 3, "3"
- -- </intpkey-14.3>
- })
-
-test:do_execsql_test(
- "intpkey-14.4",
- [[
- SELECT * FROM t3 WHERE a<'2';
- ]], {
- -- <intpkey-14.4>
- 1, 1, "one"
- -- </intpkey-14.4>
- })
-
-test:do_execsql_test(
- "intpkey-14.5",
- [[
- SELECT * FROM t3 WHERE a<c;
- ]], {
- -- <intpkey-14.5>
- 1, 1, "one"
- -- </intpkey-14.5>
- })
-
-test:do_execsql_test(
- "intpkey-14.6",
- [[
- SELECT * FROM t3 WHERE a=c;
- ]], {
- -- <intpkey-14.6>
- 2, 2, "2", 3, 3, "3"
- -- </intpkey-14.6>
- })
-
-- Check for proper handling of primary keys greater than 2^31.
-- Ticket #1188
--
test:do_execsql_test(
"intpkey-15.1",
[[
- INSERT INTO t1 VALUES(2147483647, 'big-1', 123);
+ INSERT INTO t1 VALUES(2147483647, 'big-1', '123');
SELECT * FROM t1 WHERE a>2147483648;
]], {
-- <intpkey-15.1>
diff --git a/test/sql-tap/minmax2.test.lua b/test/sql-tap/minmax2.test.lua
index 0e0f0d08e..707d1c4da 100755
--- a/test/sql-tap/minmax2.test.lua
+++ b/test/sql-tap/minmax2.test.lua
@@ -441,9 +441,9 @@ test:do_execsql_test(
"minmax2-8.2",
[[
CREATE TABLE t5(a INTEGER PRIMARY KEY);
- INSERT INTO t5 VALUES('1234');
- INSERT INTO t5 VALUES('234');
- INSERT INTO t5 VALUES('34');
+ INSERT INTO t5 VALUES(1234);
+ INSERT INTO t5 VALUES(234);
+ INSERT INTO t5 VALUES(34);
SELECT min(a), max(a) FROM t5;
]], {
-- <minmax2-8.2>
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index 32f38cc97..e0fe50bbe 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -34,9 +34,9 @@ test:do_test(
end
cmd = cmd .. ")"
test:execsql(cmd)
- cmd = "INSERT INTO manycol VALUES(1, 0"
+ cmd = "INSERT INTO manycol VALUES(1, '0'"
for i = 1, 99, 1 do
- cmd = cmd .. ","..i..""
+ cmd = cmd .. ",'"..i.."'"
end
cmd = cmd .. ")"
test:execsql(cmd)
@@ -61,9 +61,9 @@ test:do_test(
"misc1-1.3.1",
function()
for j = 100, 1000, 100 do
- local cmd = string.format("INSERT INTO manycol VALUES(%s, %s", j, j)
+ local cmd = string.format("INSERT INTO manycol VALUES(%s, '%s'", j, j)
for i = 1, 99, 1 do
- cmd = cmd .. ","..(i + j)..""
+ cmd = cmd .. ",'"..(i + j).."'"
end
cmd = cmd .. ")"
test:execsql(cmd)
@@ -178,12 +178,12 @@ test:do_test(
test:execsql([[
CREATE TABLE agger(one text primary key, two text, three text, four text);
START TRANSACTION;
- INSERT INTO agger VALUES(1, 'one', 'hello', 'yes');
- INSERT INTO agger VALUES(2, 'two', 'howdy', 'no');
- INSERT INTO agger VALUES(3, 'thr', 'howareya', 'yes');
- INSERT INTO agger VALUES(4, 'two', 'lothere', 'yes');
- INSERT INTO agger VALUES(5, 'one', 'atcha', 'yes');
- INSERT INTO agger VALUES(6, 'two', 'hello', 'no');
+ INSERT INTO agger VALUES('1', 'one', 'hello', 'yes');
+ INSERT INTO agger VALUES('2', 'two', 'howdy', 'no');
+ INSERT INTO agger VALUES('3', 'thr', 'howareya', 'yes');
+ INSERT INTO agger VALUES('4', 'two', 'lothere', 'yes');
+ INSERT INTO agger VALUES('5', 'one', 'atcha', 'yes');
+ INSERT INTO agger VALUES('6', 'two', 'hello', 'no');
COMMIT
]])
return test:execsql("SELECT count(*) FROM agger")
@@ -531,7 +531,7 @@ test:do_test(
"misc1-10.7",
function()
where = string.gsub(where, "x0=0", "x0=100")
- return test:catchsql("UPDATE manycol SET x1=x1+1 "..where.."")
+ return test:catchsql("UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where.."")
end, {
-- <misc1-10.7>
0
@@ -553,7 +553,7 @@ test:do_execsql_test(
-- } {0 {}}
test:do_execsql_test(
"misc1-10.9",
- "UPDATE manycol SET x1=x1+1 "..where
+ "UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where
--"UPDATE manycol SET x1=x1+1 $::where AND rowid>0"
, {})
@@ -665,7 +665,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-12.6",
[[
- INSERT OR IGNORE INTO t6 VALUES('y',0);
+ INSERT OR IGNORE INTO t6 VALUES('y','0');
SELECT * FROM t6;
]], {
-- <misc1-12.6>
@@ -679,10 +679,10 @@ test:do_execsql_test(
"misc1-12.7",
[[
CREATE TABLE t7(x INTEGER, y TEXT, z INT primary key);
- INSERT INTO t7 VALUES(0,0,1);
- INSERT INTO t7 VALUES(0.0,0,2);
- INSERT INTO t7 VALUES(0,0.0,3);
- INSERT INTO t7 VALUES(0.0,0.0,4);
+ INSERT INTO t7 VALUES(0,'0',1);
+ INSERT INTO t7 VALUES(0.0,'0',2);
+ INSERT INTO t7 VALUES(0,'0.0',3);
+ INSERT INTO t7 VALUES(0.0,'0.0',4);
SELECT DISTINCT x, y FROM t7 ORDER BY z;
]], {
-- <misc1-12.7>
diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua
index eeac5353a..3161e48fa 100755
--- a/test/sql-tap/numcast.test.lua
+++ b/test/sql-tap/numcast.test.lua
@@ -135,16 +135,16 @@ test:do_catchsql_test(
INSERT INTO t VALUES(20000000000000000000.01);
SELECT * FROM t;
]], {
- 1,"Tuple field 1 type does not match one required by operation: expected integer"
+ 1,"Type mismatch: can not convert 2.0e+19 to integer"
})
-test:do_catchsql_test(
+test:do_execsql_test(
"cast-2.9",
[[
INSERT INTO t VALUES(2.1);
SELECT * FROM t;
]], {
- 1,"Tuple field 1 type does not match one required by operation: expected integer"
+ 2, 9223372036854775808ULL, 18000000000000000000ULL
})
--
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index fbebfab37..9a969bf3c 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -231,7 +231,7 @@ string.format([[
CREATE TABLE t3(id INT, a TEXT, b TEXT, PRIMARY KEY(id));
INSERT INTO t3 VALUES(1, 'abc',NULL);
INSERT INTO t3 VALUES(2, NULL,'xyz');
- INSERT INTO t3 SELECT f1, * FROM test1;
+ INSERT INTO t3 SELECT f1, CAST(f1 AS STRING), CAST(f2 AS STRING) FROM test1;
DROP TABLE IF EXISTS t4;
CREATE TABLE t4(id INT, a INT , b TEXT , PRIMARY KEY(id));
INSERT INTO t4 VALUES(1, NULL,'%s');
@@ -1671,8 +1671,8 @@ test:do_execsql_test(
[[
DELETE FROM t3;
DELETE FROM t4;
- INSERT INTO t3 VALUES(0,1,2);
- INSERT INTO t4 VALUES(0,3,4);
+ INSERT INTO t3 VALUES(0,'1','2');
+ INSERT INTO t4 VALUES(0,3,'4');
SELECT * FROM t3, t4;
]], {
-- <select1-11.1>
@@ -1878,7 +1878,7 @@ test:do_execsql_test(
"select1-12.4",
[[
DELETE FROM t3;
- INSERT INTO t3 VALUES(0,1,2);
+ INSERT INTO t3 VALUES(0,'1','2');
]], {
-- <select1-12.4>
diff --git a/test/sql-tap/select4.test.lua b/test/sql-tap/select4.test.lua
index 23cf1bf1b..f7a320438 100755
--- a/test/sql-tap/select4.test.lua
+++ b/test/sql-tap/select4.test.lua
@@ -761,12 +761,12 @@ test:do_test(
test:execsql [[
CREATE TABLE t3(a text primary key, b NUMBER, c text);
START TRANSACTION;
- INSERT INTO t3 VALUES(1, 1.1, '1.1');
- INSERT INTO t3 VALUES(2, 1.10, '1.10');
- INSERT INTO t3 VALUES(3, 1.10, '1.1');
- INSERT INTO t3 VALUES(4, 1.1, '1.10');
- INSERT INTO t3 VALUES(5, 1.2, '1.2');
- INSERT INTO t3 VALUES(6, 1.3, '1.3');
+ INSERT INTO t3 VALUES('1', 1.1, '1.1');
+ INSERT INTO t3 VALUES('2', 1.10, '1.10');
+ INSERT INTO t3 VALUES('3', 1.10, '1.1');
+ INSERT INTO t3 VALUES('4', 1.1, '1.10');
+ INSERT INTO t3 VALUES('5', 1.2, '1.2');
+ INSERT INTO t3 VALUES('6', 1.3, '1.3');
COMMIT;
]]
return test:execsql [[
diff --git a/test/sql-tap/select7.test.lua b/test/sql-tap/select7.test.lua
index fec5d7a41..e1e43c557 100755
--- a/test/sql-tap/select7.test.lua
+++ b/test/sql-tap/select7.test.lua
@@ -255,7 +255,7 @@ test:do_execsql_test(
[[
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a TEXT primary key, b INT);
- INSERT INTO t5 VALUES(123, 456);
+ INSERT INTO t5 VALUES('123', 456);
SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
]], {
-- <select7-7.7>
diff --git a/test/sql-tap/sort.test.lua b/test/sql-tap/sort.test.lua
index 36074d6ef..18bfd443d 100755
--- a/test/sql-tap/sort.test.lua
+++ b/test/sql-tap/sort.test.lua
@@ -505,10 +505,10 @@ test:do_execsql_test(
a INTEGER PRIMARY KEY,
b VARCHAR(30)
);
- INSERT INTO t4 VALUES(1,1);
- INSERT INTO t4 VALUES(2,2);
- INSERT INTO t4 VALUES(11,11);
- INSERT INTO t4 VALUES(12,12);
+ INSERT INTO t4 VALUES(1,'1');
+ INSERT INTO t4 VALUES(2,'2');
+ INSERT INTO t4 VALUES(11,'11');
+ INSERT INTO t4 VALUES(12,'12');
SELECT a FROM t4 ORDER BY 1;
]], {
-- <sort-7.1>
diff --git a/test/sql-tap/tkt-3998683a16.test.lua b/test/sql-tap/tkt-3998683a16.test.lua
index 885dcf5cd..9bc310358 100755
--- a/test/sql-tap/tkt-3998683a16.test.lua
+++ b/test/sql-tap/tkt-3998683a16.test.lua
@@ -26,29 +26,17 @@ test:do_test(
function()
return test:execsql [[
CREATE TABLE t1(x INT primary key, y NUMBER);
- INSERT INTO t1 VALUES(1, '1.0');
- INSERT INTO t1 VALUES(2, '.125');
- INSERT INTO t1 VALUES(3, '123.');
- INSERT INTO t1 VALUES(4, '123.e+2');
- INSERT INTO t1 VALUES(5, '.125e+3');
- INSERT INTO t1 VALUES(6, '123e4');
- INSERT INTO t1 VALUES(11, ' 1.0');
- INSERT INTO t1 VALUES(12, ' .125');
- INSERT INTO t1 VALUES(13, ' 123.');
- INSERT INTO t1 VALUES(14, ' 123.e+2');
- INSERT INTO t1 VALUES(15, ' .125e+3');
- INSERT INTO t1 VALUES(16, ' 123e4');
- INSERT INTO t1 VALUES(21, '1.0 ');
- INSERT INTO t1 VALUES(22, '.125 ');
- INSERT INTO t1 VALUES(23, '123. ');
- INSERT INTO t1 VALUES(24, '123.e+2 ');
- INSERT INTO t1 VALUES(25, '.125e+3 ');
- INSERT INTO t1 VALUES(26, '123e4 ');
+ INSERT INTO t1 VALUES(1, 1.0);
+ INSERT INTO t1 VALUES(2, .125);
+ INSERT INTO t1 VALUES(3, 123.);
+ INSERT INTO t1 VALUES(4, 123.e+2);
+ INSERT INTO t1 VALUES(5, .125e+3);
+ INSERT INTO t1 VALUES(6, 123e4);
SELECT x FROM t1 WHERE typeof(y)=='number' ORDER BY x;
]]
end, {
-- <tkt-3998683a16.1>
- 1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26
+ 1, 2, 3, 4, 5, 6
-- </tkt-3998683a16.1>
})
diff --git a/test/sql-tap/tkt-54844eea3f.test.lua b/test/sql-tap/tkt-54844eea3f.test.lua
index d6cd56e52..89d0d1218 100755
--- a/test/sql-tap/tkt-54844eea3f.test.lua
+++ b/test/sql-tap/tkt-54844eea3f.test.lua
@@ -62,10 +62,10 @@ test:do_execsql_test(
"1.2",
[[
CREATE TABLE t4(id INT primary key, a TEXT, b TEXT, c TEXT);
- INSERT INTO t4 VALUES(1, 'a', 1, 'one');
- INSERT INTO t4 VALUES(2, 'a', 2, 'two');
- INSERT INTO t4 VALUES(3, 'b', 1, 'three');
- INSERT INTO t4 VALUES(4, 'b', 2, 'four');
+ INSERT INTO t4 VALUES(1, 'a', '1', 'one');
+ INSERT INTO t4 VALUES(2, 'a', '2', 'two');
+ INSERT INTO t4 VALUES(3, 'b', '1', 'three');
+ INSERT INTO t4 VALUES(4, 'b', '2', 'four');
SELECT (
SELECT c FROM (
SELECT a,b,c FROM t4 WHERE a=output.a ORDER BY b LIMIT 10 OFFSET 1
diff --git a/test/sql-tap/tkt-7bbfb7d442.test.lua b/test/sql-tap/tkt-7bbfb7d442.test.lua
index 535303771..bfddcd920 100755
--- a/test/sql-tap/tkt-7bbfb7d442.test.lua
+++ b/test/sql-tap/tkt-7bbfb7d442.test.lua
@@ -109,13 +109,13 @@ if (1 > 0)
T1.Variant AS Variant,
T1.ControlDate AS ControlDate,
1 AS ControlState,
- COALESCE(T2.DeliveredQty,0) AS DeliveredQty
+ CAST(COALESCE(T2.DeliveredQty,0) AS STRING) AS DeliveredQty
FROM (
SELECT
NEW.InventoryControlId AS InventoryControlId,
II.SKU AS SKU,
II.Variant AS Variant,
- COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS ControlDate
+ CAST(COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS STRING) AS ControlDate
FROM
InventoryItem II
LEFT JOIN
diff --git a/test/sql-tap/tkt1444.test.lua b/test/sql-tap/tkt1444.test.lua
index 82a5ded25..fb148bc5f 100755
--- a/test/sql-tap/tkt1444.test.lua
+++ b/test/sql-tap/tkt1444.test.lua
@@ -30,8 +30,8 @@ test:do_execsql_test(
[[
CREATE TABLE DemoTable (id INT primary key, x INTEGER, TextKey TEXT, DKey NUMBER);
CREATE INDEX DemoTableIdx ON DemoTable (TextKey);
- INSERT INTO DemoTable VALUES(1, 9,8,7);
- INSERT INTO DemoTable VALUES(2, 1,2,3);
+ INSERT INTO DemoTable VALUES(1, 9,'8',7);
+ INSERT INTO DemoTable VALUES(2, 1,'2',3);
CREATE VIEW DemoView AS SELECT x, TextKey, DKey FROM DemoTable ORDER BY TextKey;
SELECT x,TextKey,DKey FROM DemoTable UNION ALL SELECT * FROM DemoView ORDER BY 1;
]], {
diff --git a/test/sql-tap/tkt3493.test.lua b/test/sql-tap/tkt3493.test.lua
index 7ceec4702..de77e61e9 100755
--- a/test/sql-tap/tkt3493.test.lua
+++ b/test/sql-tap/tkt3493.test.lua
@@ -29,8 +29,8 @@ test:do_execsql_test(
START TRANSACTION;
INSERT INTO A VALUES(1,'123');
INSERT INTO A VALUES(2,'456');
- INSERT INTO B VALUES(1,1);
- INSERT INTO B VALUES(2,2);
+ INSERT INTO B VALUES(1,'1');
+ INSERT INTO B VALUES(2,'2');
INSERT INTO A_B VALUES(1,1);
INSERT INTO A_B VALUES(2,2);
COMMIT;
@@ -116,7 +116,7 @@ test:do_execsql_test(
"tkt3493-2.1",
[[
CREATE TABLE t1(a TEXT PRIMARY KEY, b INT);
- INSERT INTO t1 VALUES(123, 456);
+ INSERT INTO t1 VALUES('123', 456);
]], {
-- <tkt3493-2.1>
diff --git a/test/sql-tap/tkt3841.test.lua b/test/sql-tap/tkt3841.test.lua
index 5203d0cd4..56668f6a3 100755
--- a/test/sql-tap/tkt3841.test.lua
+++ b/test/sql-tap/tkt3841.test.lua
@@ -31,12 +31,12 @@ test:do_execsql_test(
INSERT INTO table2 VALUES ('a', 'alist');
INSERT INTO table2 VALUES ('b', 'blist');
- INSERT INTO list VALUES ('a', 1);
- INSERT INTO list VALUES ('a', 2);
- INSERT INTO list VALUES ('a', 3);
- INSERT INTO list VALUES ('b', 4);
- INSERT INTO list VALUES ('b', 5);
- INSERT INTO list VALUES ('b', 6);
+ INSERT INTO list VALUES ('a', '1');
+ INSERT INTO list VALUES ('a', '2');
+ INSERT INTO list VALUES ('a', '3');
+ INSERT INTO list VALUES ('b', '4');
+ INSERT INTO list VALUES ('b', '5');
+ INSERT INTO list VALUES ('b', '6');
SELECT
table2.x,
diff --git a/test/sql-tap/triggerA.test.lua b/test/sql-tap/triggerA.test.lua
index fac51ca14..fc8ecfe17 100755
--- a/test/sql-tap/triggerA.test.lua
+++ b/test/sql-tap/triggerA.test.lua
@@ -283,7 +283,7 @@ test:do_test(
CREATE TABLE result2(id INTEGER PRIMARY KEY, a TEXT,b INT);
CREATE TRIGGER r5d INSTEAD OF DELETE ON v5 FOR EACH ROW BEGIN
INSERT INTO result2(id, a,b) VALUES((SELECT coalesce(max(id),0) + 1 FROM result2),
- old.x, old.b);
+ CAST(old.x AS STRING), old.b);
END;
DELETE FROM v5 WHERE x=5;
SELECT a, b FROM result2;
@@ -301,7 +301,7 @@ test:do_test(
DELETE FROM result4;
CREATE TRIGGER r5u INSTEAD OF UPDATE ON v5 FOR EACH ROW BEGIN
INSERT INTO result4(id, a,b,c,d) VALUES((SELECT coalesce(max(id),0) + 1 FROM result4),
- old.x, old.b, new.x, new.b);
+ CAST(old.x AS STRING), old.b, CAST(new.x AS STRING), new.b);
END;
UPDATE v5 SET b = b+9900000 WHERE x BETWEEN 3 AND 5;
SELECT a,b,c,d FROM result4 ORDER BY a;
diff --git a/test/sql-tap/unique.test.lua b/test/sql-tap/unique.test.lua
index 9818f90a8..6b0a7e20d 100755
--- a/test/sql-tap/unique.test.lua
+++ b/test/sql-tap/unique.test.lua
@@ -52,7 +52,7 @@ test:do_catchsql_test(
test:do_catchsql_test(
"unique-1.2",
[[
- INSERT INTO t1(a,b,c) VALUES(1,2,3)
+ INSERT INTO t1(a,b,c) VALUES(1,2,'3')
]], {
-- <unique-1.2>
0
@@ -62,7 +62,7 @@ test:do_catchsql_test(
test:do_catchsql_test(
"unique-1.3",
[[
- INSERT INTO t1(a,b,c) VALUES(1,3,4)
+ INSERT INTO t1(a,b,c) VALUES(1,3,'4')
]], {
-- <unique-1.3>
1, "Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
@@ -83,7 +83,7 @@ test:do_execsql_test(
test:do_catchsql_test(
"unique-1.5",
[[
- INSERT INTO t1(a,b,c) VALUES(3,2,4)
+ INSERT INTO t1(a,b,c) VALUES(3,2,'4')
]], {
-- <unique-1.5>
1, "Duplicate key exists in unique index 'unique_unnamed_T1_2' in space 'T1'"
@@ -104,7 +104,7 @@ test:do_execsql_test(
test:do_catchsql_test(
"unique-1.7",
[[
- INSERT INTO t1(a,b,c) VALUES(3,4,5)
+ INSERT INTO t1(a,b,c) VALUES(3,4,'5')
]], {
-- <unique-1.7>
0
diff --git a/test/sql-tap/view.test.lua b/test/sql-tap/view.test.lua
index e553b91c7..ab14c5edb 100755
--- a/test/sql-tap/view.test.lua
+++ b/test/sql-tap/view.test.lua
@@ -757,7 +757,7 @@ test:do_execsql_test(
"view-10.1",
[=[
CREATE TABLE t3("9" integer primary key, "4" text);
- INSERT INTO t3 VALUES(1,2);
+ INSERT INTO t3 VALUES(1,'2');
CREATE VIEW v_t3_a AS SELECT a."9" FROM t3 AS a;
CREATE VIEW v_t3_b AS SELECT "4" FROM t3;
SELECT * FROM v_t3_a;
diff --git a/test/sql-tap/where5.test.lua b/test/sql-tap/where5.test.lua
index 749201564..3aefcaca5 100755
--- a/test/sql-tap/where5.test.lua
+++ b/test/sql-tap/where5.test.lua
@@ -27,11 +27,11 @@ test:do_test("where5-1.0", function()
CREATE TABLE t1(x TEXT primary key);
CREATE TABLE t2(x integer primary key);
CREATE TABLE t3(x integer PRIMARY KEY);
- INSERT INTO t1 VALUES(-1);
- INSERT INTO t1 VALUES(0);
- INSERT INTO t1 VALUES(1);
- INSERT INTO t2 SELECT * FROM t1;
- INSERT INTO t3 SELECT * FROM t1;
+ INSERT INTO t1 VALUES('-1');
+ INSERT INTO t1 VALUES('0');
+ INSERT INTO t1 VALUES('1');
+ INSERT INTO t2 SELECT CAST(x AS INTEGER) FROM t1;
+ INSERT INTO t3 SELECT CAST(x AS INTEGER) FROM t1;
]]
return test:execsql [[
SELECT * FROM t1 WHERE x<0
diff --git a/test/sql-tap/whereB.test.lua b/test/sql-tap/whereB.test.lua
index d98645fdc..fe5e28c70 100755
--- a/test/sql-tap/whereB.test.lua
+++ b/test/sql-tap/whereB.test.lua
@@ -112,24 +112,16 @@ test:do_execsql_test(
-- </whereB-1.102>
})
--- For this set of tests:
---
--- * t1.y holds a text value with affinity TEXT
--- * t2.b holds an integer value with affinity NONE
---
--- These values are not equal and because neither affinity is NUMERIC
--- no type conversion occurs.
---
test:do_execsql_test(
"whereB-2.1",
[[
DROP TABLE t1;
DROP TABLE t2;
- CREATE TABLE t1(x INT primary key, y TEXT); -- affinity of t1.y is TEXT
- INSERT INTO t1 VALUES(1,99);
+ CREATE TABLE t1(x INT primary key, y TEXT);
+ INSERT INTO t1 VALUES(1,'99');
- CREATE TABLE t2(a INT primary key, b SCALAR); -- affinity of t2.b is NONE
+ CREATE TABLE t2(a INT primary key, b SCALAR);
CREATE INDEX t2b ON t2(b);
INSERT INTO t2 VALUES(2, 99);
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-06-29 12:56 ` Nikita Pettik
@ 2020-07-05 14:28 ` Mergen Imeev
2020-07-06 22:06 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 14:28 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
On Mon, Jun 29, 2020 at 12:56:30PM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > index f7681640e..a2147b0e8 100755
> > --- a/test/sql-tap/in3.test.lua
> > +++ b/test/sql-tap/in3.test.lua
> > @@ -1,6 +1,6 @@
> > #!/usr/bin/env tarantool
> > test = require("sqltester")
> > -test:plan(29)
> > +test:plan(28)
> >
> > --!./tcltestrunner.lua
> > -- 2007 November 29
> > @@ -322,18 +322,6 @@ test:do_test(
> > -- </in3-3.2>
> > })
> >
> > -test:do_test(
> > - "in3-3.3",
> > - function()
> > - -- Logically, numeric affinity is applied to both sides before
> > - -- the comparison, but index can't be used.
> > - return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
> > - end, {
> > - -- <in3-3.3>
> > - 1, true
> > - -- </in3-3.3>
> > - })
> > -
>
> I'd rather not drop this test. It's about scalar-numeric types
> interaction. Mb it is not the most suitable place for such test,
> but make sure this scenario is covered somewhere else.
>
I added a few tests with SCALARS in 'sql: remove implicit
cast for comparison' commit. However, there is a lot
problems with SCALARS at the moment.
> The rest is OK as obvious.
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt
2020-06-29 13:29 ` Nikita Pettik
@ 2020-07-05 14:29 ` Mergen Imeev
0 siblings, 0 replies; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 14:29 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
On Mon, Jun 29, 2020 at 01:29:57PM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> > index 276956170..a609fa985 100644
> > --- a/src/box/sql/vdbe.c
> > +++ b/src/box/sql/vdbe.c
> > @@ -2122,17 +2122,13 @@ case OP_AddImm: { /* in1 */
> > */
> > case OP_MustBeInt: { /* jump, in1 */
> > pIn1 = &aMem[pOp->p1];
> > - if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
> > - mem_apply_type(pIn1, FIELD_TYPE_INTEGER);
> > - if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
> > - if (pOp->p2==0) {
> > - diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > - sql_value_to_diag_str(pIn1), "integer");
> > - goto abort_due_to_error;
> > - } else {
> > - goto jump_to_p2;
> > - }
> > - }
> > + if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0 &&
> > + mem_convert_to_integer(pIn1, true) != 0) {
>
> Please split this conditions into two branches. Like this:
>
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 2bc8c9817..da76d7321 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -2122,13 +2122,14 @@ case OP_AddImm: { /* in1 */
> */
> case OP_MustBeInt: { /* jump, in1 */
> pIn1 = &aMem[pOp->p1];
> - if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0 &&
> - mem_convert_to_integer(pIn1, true) != 0) {
> - if (pOp->p2 != 0)
> - goto jump_to_p2;
> - diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> - sql_value_to_diag_str(pIn1), "integer");
> - goto abort_due_to_error;
> + if ((pIn1->flags & (MEM_Int | MEM_UInt)) == 0) {
> + if (mem_convert_to_integer(pIn1, true) != 0) {
> + if (pOp->p2 != 0)
> + goto jump_to_p2;
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + sql_value_to_diag_str(pIn1), "integer");
> + goto abort_due_to_error;
> + }
> }
> break;
>
> It ehcnances code readability. Or even integrate this check into
> mem_covert_to_ingeger().
>
I integrated this check in mem_convert_to_integer().
> The rest is OK (hope you carefully verified changed tests, since
> I've only briefly looked through).
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison
2020-06-29 23:51 ` Nikita Pettik
@ 2020-07-05 14:47 ` Mergen Imeev
2020-07-06 23:11 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 14:47 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
My answers and new patch below.
On Mon, Jun 29, 2020 at 11:51:29PM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > Thank you for review! My answers and new patch below.
> >
> > On 22.06.2020 15:25, Nikita Pettik wrote:
> > > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> > >> @@ -2399,14 +2387,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
> > >> default: res2 = res>=0; break;
> > >> }
> > >>
> > >> - /* Undo any changes made by mem_apply_type() to the input registers. */
> > >> - assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
> > >> - pIn1->flags = flags1;
> > >> - pIn1->field_type = ft_p1;
> > >> - assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
> > >> - pIn3->flags = flags3;
> > >> - pIn3->field_type = ft_p3;
> > >> -
> > >
> > > Replace these assertions with relevant ones.
> > >
> > Not sure if this is necessary, since now we have much less flag
> > changes after removal of mem_apply_type().
>
> Не понял как это связано...Твои изменения не затрагивают
> инвариант MEM_Dyn.
>
True, however original asserts checked that
mem_apply_type() does not changed it. Now we can say that
it definitely won't be changed. I can return flags*
variables for the sake of these asserts. Should I do this?
Also, after #4906 these asserts become outdated since flags
of the mems won't change at all. Well, it will be so if we
close #4906.
> > >> @@ -0,0 +1,281 @@
> > >> +#!/usr/bin/env tarantool
> > >> +test = require("sqltester")
> > >> +test:plan(32)
> > >> +
> > >> +--
> > >> +
> > >> +test:execsql([[
> > >> + CREATE TABLE t1(x TEXT primary key);
> > >> + INSERT INTO t1 VALUES('1');
> > >> + CREATE TABLE t2(x INTEGER primary key);
> > >> + INSERT INTO t2 VALUES(1);
> > >> + CREATE TABLE t3(x DOUBLE primary key);
> > >> + INSERT INTO t3 VALUES(1.0);
> > >
> > > What about table with scalar/any fields?
> > >
> > I think this is too big a problem to solve it here.
>
> Гораздо лучше потом клепать фоллоу-апы, точечно затыкая креши..
> Я бы добавил хотя бы самых базовых примеров.
>
Added.
> > i = pIn3->u.i;
> > @@ -3617,7 +3595,38 @@ skip_truncate:
> > assert(oc!=OP_SeekGE || r.default_rc==+1);
> > assert(oc!=OP_SeekLT || r.default_rc==+1);
> >
> > + /*
> > + * Make sure that the types of all the fields in the tuple
> > + * that will be used in the iterator match the field types
> > + * of the space.
> > + */
> > r.aMem = &aMem[pOp->p3];
> > + for (int i = 0; i < r.nField; ++i) {
> > + enum field_type type = r.key_def->parts[i].type;
> > + struct Mem *mem = &r.aMem[i];
> > + if (mem_check_type(mem, type) == 0 ||
> > + mem_convert_numeric(mem, type, true) == 0)
> > + continue;
>
> Я бы все-таки разбил бы эту проверку на два условия:
>
> if (...)
> continue
> if (...)
> continue
>
> А еще лучше вынести этот чанк в хелпер.
>
Moved to a new function.
> > + /*
> > + * If the number was not converted without loss,
> > + * we will not find tuples using the EQ iterator.
> > + */
>
> Пожайлуста, не используй двойное отрицание - комментарий очень
> сложно воспринимать. Давай это переформулируем, можно пример
> добавить. Это довольно скользкое место.
>
Removed. Added comment in description of a new function.
> > + if ((mem->flags & MEM_Real) != 0 &&
> > + (type == FIELD_TYPE_INTEGER ||
> > + type == FIELD_TYPE_UNSIGNED)) {
> > + assert(eqOnly == 1);
> > + res = 1;
> > + goto seek_not_found;
> > + }
> > + if ((mem->flags & (MEM_Int | MEM_UInt)) != 0 &&
> > + type == FIELD_TYPE_DOUBLE && eqOnly == 1) {
> > + res = 1;
> > + goto seek_not_found;
> > + }
> > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > + field_type_strs[type], mem_type_to_str(mem));
> > + goto abort_due_to_error;
> > + }
> > #ifdef SQL_DEBUG
> > { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> > #endif
> > @@ -4744,7 +4753,25 @@ case OP_IdxGE: { /* jump */
> > assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
> > r.default_rc = 0;
> > }
> > +
> > + /*
> > + * Make sure that the types of all the fields in the tuple
> > + * that will be used in the iterator comparable with the
> > + * fields of the space.
> > + */
> > r.aMem = &aMem[pOp->p3];
> > + for (int i = 0; i < r.nField; ++i) {
> > + enum field_type type = r.key_def->parts[i].type;
> > + struct Mem *mem = &r.aMem[i];
>
> Как-то мне эти два места (выше в SeekGE) вообще не нравятся.
> Какие-то они запутанные. Давай подумаем как можно зарефакторить их.
>
Moved to a new function. However, previously cast
here didn't always worked since in some cases field_type
and MEM_type of the mem not always were compatible. I think
this was fixed in previous commits. All tests passes.
However, there is another possiblity: it may be that I
already removed tests that fail on convertion but worked
on check. I do not think that it is the case though.
This also can be fully fixed in #4906 issue.
> > + if (mem_check_type(mem, type) == 0)
> > + continue;
> > + if (sql_type_is_numeric(type) &&
> > + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
> > + continue;
> > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > + field_type_strs[type], mem_type_to_str(mem));
> > + goto abort_due_to_error;
> > + }
> > #ifdef SQL_DEBUG
> > { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> > #endif
> > diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
> > index 6d8768865..1d7c76670 100644
> > --- a/src/box/sql/wherecode.c
> > +++ b/src/box/sql/wherecode.c
> > @@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
> > }
> > }
> >
> > -/**
> > - * Code an OP_ApplyType opcode to apply the column type string
> > - * @types to the n registers starting at @base.
> > - *
> > - * As an optimization, SCALAR entries (which are no-ops) at the
> > - * beginning and end of @types are ignored. If all entries in
> > - * @types are SCALAR, then no code gets generated.
> > - *
> > - * This routine makes its own copy of @types so that the caller is
> > - * free to modify @types after this routine returns.
> > - */
> > -static void
> > -emit_apply_type(Parse *pParse, int base, int n, enum field_type *types)
>
> Ты в следующем коммите как раз делаешь клин-ап. Давай эту функцию
> там и удалим (как и остальные).
>
It is a bit troublesome since the functions I remove here
are 'static'. I think, that instead of removing 'static'
keyword here and removing the function in the next commit
it is better to just remove these runctions here.
I can change it if you think that removing in two commits
is better.
> > nConstraint++;
> > }
> > - sqlDbFree(db, start_types);
> > - sqlDbFree(db, end_types);
> >
> > /* Top of the loop body */
> > pLevel->p2 = sqlVdbeCurrentAddr(v);
> > diff --git a/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
> > new file mode 100755
> > index 000000000..b405a11b6
> > --- /dev/null
> > +++ b/test/sql-tap/gh-4230-del-impl-cast-str-to-num.test.lua
>
> Когда кто-то ищет где посмотреть тесты связанные с типами,
> первое что приходит в голову - грепнуть *types*. Этот тест
> по сути ничего и не тестирует (уверен, эти пути уже покрыты
> в других тестах), зато хорошо отображает работу системы типов.
> Я бы просто подумал о других разработчиках, и все же замержил
> его в какой-нибудь тест типа sql/types.test.lua.
Moved to sql/types.test.lua
New patch:
commit f52e6669146e7a06b78d167abf369d67d9327789
Author: Mergen Imeev <imeevma@gmail.com>
Date: Thu Jun 25 12:39:19 2020 +0300
sql: remove implicit cast for comparison
This patch removes implicit cast for comparison.
Closes #4230
@TarantoolBot document
Title: remove implicit cast for comparison
After this patch-set, there will be no implicit casts for
comparison. This means that the values of the field types STRING,
BOOLEAN and VARBINARY can be compared with the values of the same
field type. Any numerical value can be compared with any other
numerical value.
Example:
For comparison:
```
tarantool> box.execute([[SELECT '1' > 0;]])
---
- null
- "Type mismatch: can not convert '1' (type: text) to numeric"
...
tarantool> box.execute([[SELECT true > X'33';]])
---
- null
- 'Type mismatch: can not convert ''TRUE'' (type: boolean) to varbinary'
...
tarantool> box.execute([[SELECT 1.23 > 123;]])
---
- metadata:
- name: 1.23 > 123
type: boolean
rows:
- [false]
...
```
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index ce9edaad9..0d3da49d3 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -561,6 +561,50 @@ mem_convert_to_numeric(struct Mem *mem, enum field_type type, bool is_precise)
return mem_convert_to_integer(mem, is_precise);
}
+/**
+ * Check that MEM types of mems are compatible with the
+ * corresponding types from key_def.
+ *
+ * If mem and type are comparable but incompatible according to
+ * field_mp_plain_type_is_compatible() and the comparison
+ * operation is EQ, we can say that the result of the comparison
+ * will be FALSE. This allows us to compare DOUBLE and INTEGER
+ * values.
+ *
+ * @param mems The first mem of the array.
+ * @param def key_def that contains types to check.
+ * @param size Size of the array.
+ * @param is_op_eq TRUE is comparison operator is EQ.
+ * @param[out] is_not_converted TRUE if operation is EQ and mem
+ and type are comparable but not
+ compatible. FALSE otherwise.
+ * @retval TRUE if the MEM types and types from key_def are
+ * comparable, FALSE otherwise.
+ */
+static bool
+mem_are_types_comparable(struct Mem *mems, struct key_def *def, uint32_t size,
+ bool is_op_eq, bool *is_not_converted) {
+ assert(!is_op_eq || !*is_not_converted);
+ for (uint32_t i = 0; i < size; ++i) {
+ enum field_type type = def->parts[i].type;
+ struct Mem *mem = &mems[i];
+ if (mem_is_type_compatible(mem, type))
+ continue;
+ if (mem_convert_to_numeric(mem, type, true) == 0)
+ continue;
+ if (sql_type_is_numeric(type) &&
+ (mem->flags & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
+ if (is_op_eq)
+ *is_not_converted = true;
+ continue;
+ }
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ field_type_strs[type], mem_type_to_str(mem));
+ return false;
+ }
+ return true;
+}
+
/*
* pMem currently only holds a string type (or maybe a BLOB that we can
* interpret as a string if we want to). Compute its corresponding
@@ -2289,8 +2333,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
- enum field_type ft_p1 = pIn1->field_type;
- enum field_type ft_p3 = pIn3->field_type;
if ((flags1 | flags3)&MEM_Null) {
/* One or both operands are NULL */
if (pOp->p5 & SQL_NULLEQ) {
@@ -2349,22 +2391,17 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
} else {
enum field_type type = pOp->p5 & FIELD_TYPE_MASK;
if (sql_type_is_numeric(type)) {
- if ((flags1 | flags3)&MEM_Str) {
- if ((flags1 & MEM_Str) == MEM_Str) {
- mem_apply_numeric_type(pIn1);
- testcase( flags3!=pIn3->flags); /* Possible if pIn1==pIn3 */
- flags3 = pIn3->flags;
- }
- if ((flags3 & MEM_Str) == MEM_Str) {
- if (mem_apply_numeric_type(pIn3) != 0) {
- diag_set(ClientError,
- ER_SQL_TYPE_MISMATCH,
- sql_value_to_diag_str(pIn3),
- "numeric");
- goto abort_due_to_error;
- }
-
- }
+ if ((flags1 & MEM_Str) == MEM_Str) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn1),
+ "numeric");
+ goto abort_due_to_error;
+ }
+ if ((flags3 & MEM_Str) == MEM_Str) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_to_diag_str(pIn3),
+ "numeric");
+ goto abort_due_to_error;
}
/* Handle the common case of integer comparison here, as an
* optimization, to avoid a call to sqlMemCompare()
@@ -2397,22 +2434,17 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
} else if (type == FIELD_TYPE_STRING) {
- if ((flags1 & MEM_Str) == 0 &&
- (flags1 & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
- testcase( pIn1->flags & MEM_Int);
- testcase( pIn1->flags & MEM_Real);
- sqlVdbeMemStringify(pIn1);
- testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn));
- flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
- assert(pIn1!=pIn3);
+ if ((flags1 & MEM_Str) == 0) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ mem_type_to_str(pIn3),
+ mem_type_to_str(pIn1));
+ goto abort_due_to_error;
}
- if ((flags3 & MEM_Str) == 0 &&
- (flags3 & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
- testcase( pIn3->flags & MEM_Int);
- testcase( pIn3->flags & MEM_Real);
- sqlVdbeMemStringify(pIn3);
- testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn));
- flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
+ if ((flags3 & MEM_Str) == 0) {
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ mem_type_to_str(pIn1),
+ mem_type_to_str(pIn3));
+ goto abort_due_to_error;
}
}
assert(pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0);
@@ -2428,14 +2460,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
default: res2 = res>=0; break;
}
- /* Undo any changes made by mem_apply_type() to the input registers. */
- assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
- pIn1->flags = flags1;
- pIn1->field_type = ft_p1;
- assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
- pIn3->flags = flags3;
- pIn3->field_type = ft_p3;
-
if (pOp->p5 & SQL_STOREP2) {
iCompare = res;
res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */
@@ -3530,8 +3554,6 @@ case OP_SeekGT: { /* jump, in3 */
pIn3 = &aMem[int_field];
if ((pIn3->flags & MEM_Null) != 0)
goto skip_truncate;
- if ((pIn3->flags & MEM_Str) != 0)
- mem_apply_numeric_type(pIn3);
int64_t i;
if ((pIn3->flags & MEM_Int) == MEM_Int) {
i = pIn3->u.i;
@@ -3623,7 +3645,20 @@ skip_truncate:
assert(oc!=OP_SeekGE || r.default_rc==+1);
assert(oc!=OP_SeekLT || r.default_rc==+1);
+ /*
+ * Make sure that the types of all the fields in the tuple
+ * that will be used in the iterator match the field types
+ * of the space.
+ */
r.aMem = &aMem[pOp->p3];
+ bool is_not_found = false;
+ if (!mem_are_types_comparable(r.aMem, r.key_def, r.nField, eqOnly == 1,
+ &is_not_found))
+ goto abort_due_to_error;
+ if (is_not_found) {
+ res = 1;
+ goto seek_not_found;
+ }
#ifdef SQL_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
#endif
@@ -4750,7 +4785,16 @@ case OP_IdxGE: { /* jump */
assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
r.default_rc = 0;
}
+
+ /*
+ * Make sure that the types of mems are comparable with
+ * the field types of the space.
+ */
r.aMem = &aMem[pOp->p3];
+ bool unused = false;
+ if (!mem_are_types_comparable(r.aMem, r.key_def, r.nField, false,
+ &unused))
+ goto abort_due_to_error;
#ifdef SQL_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
#endif
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 6d8768865..1d7c76670 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
}
}
-/**
- * Code an OP_ApplyType opcode to apply the column type string
- * @types to the n registers starting at @base.
- *
- * As an optimization, SCALAR entries (which are no-ops) at the
- * beginning and end of @types are ignored. If all entries in
- * @types are SCALAR, then no code gets generated.
- *
- * This routine makes its own copy of @types so that the caller is
- * free to modify @types after this routine returns.
- */
-static void
-emit_apply_type(Parse *pParse, int base, int n, enum field_type *types)
-{
- Vdbe *v = pParse->pVdbe;
- if (types == NULL) {
- assert(pParse->db->mallocFailed);
- return;
- }
- assert(v != 0);
-
- /*
- * Adjust base and n to skip over SCALAR entries at the
- * beginning and end of the type sequence.
- */
- while (n > 0 && types[0] == FIELD_TYPE_SCALAR) {
- n--;
- base++;
- types++;
- }
- while (n > 1 && types[n - 1] == FIELD_TYPE_SCALAR) {
- n--;
- }
-
- if (n > 0) {
- enum field_type *types_dup = field_type_sequence_dup(pParse,
- types, n);
- sqlVdbeAddOp4(v, OP_ApplyType, base, n, 0,
- (char *) types_dup, P4_DYNAMIC);
- sql_expr_type_cache_change(pParse, base, n);
- }
-}
-
-/**
- * Expression @rhs, which is the RHS of a comparison operation, is
- * either a vector of n elements or, if n==1, a scalar expression.
- * Before the comparison operation, types @types are to be applied
- * to the @rhs values. This function modifies entries within the
- * field sequence to SCALAR if either:
- *
- * * the comparison will be performed with no type, or
- * * the type change in @types is guaranteed not to change the value.
- */
-static void
-expr_cmp_update_rhs_type(struct Expr *rhs, int n, enum field_type *types)
-{
- for (int i = 0; i < n; i++) {
- Expr *p = sqlVectorFieldSubexpr(rhs, i);
- enum field_type expr_type = sql_expr_type(p);
- if (sql_type_result(expr_type, types[i]) == FIELD_TYPE_SCALAR ||
- sql_expr_needs_no_type_change(p, types[i])) {
- types[i] = FIELD_TYPE_SCALAR;
- }
- }
-}
-
/*
* Generate code for a single equality term of the WHERE clause. An equality
* term can be either X=expr or X IN (...). pTerm is the term to be
@@ -644,8 +578,7 @@ static int
codeAllEqualityTerms(Parse * pParse, /* Parsing context */
WhereLevel * pLevel, /* Which nested loop of the FROM we are coding */
int bRev, /* Reverse the order of IN operators */
- int nExtraReg, /* Number of extra registers to allocate */
- enum field_type **res_type)
+ int nExtraReg) /* Number of extra registers to allocate */
{
u16 nEq; /* The number of == or IN constraints to code */
u16 nSkip; /* Number of left-most columns to skip */
@@ -669,9 +602,6 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
nReg = pLoop->nEq + nExtraReg;
pParse->nMem += nReg;
- enum field_type *type = sql_index_type_str(pParse->db, idx_def);
- assert(type != NULL || pParse->db->mallocFailed);
-
if (nSkip) {
int iIdxCur = pLevel->iIdxCur;
sqlVdbeAddOp1(v, (bRev ? OP_Last : OP_Rewind), iIdxCur);
@@ -714,17 +644,7 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
sqlVdbeAddOp2(v, OP_SCopy, r1, regBase + j);
}
}
- if (pTerm->eOperator & WO_IN) {
- if (pTerm->pExpr->flags & EP_xIsSelect) {
- /* No type ever needs to be (or should be) applied to a value
- * from the RHS of an "? IN (SELECT ...)" expression. The
- * sqlFindInIndex() routine has already ensured that the
- * type of the comparison has been applied to the value.
- */
- if (type != NULL)
- type[j] = FIELD_TYPE_SCALAR;
- }
- } else if ((pTerm->eOperator & WO_ISNULL) == 0) {
+ if ((pTerm->eOperator & (WO_IN | WO_ISNULL)) == 0) {
Expr *pRight = pTerm->pExpr->pRight;
if (sqlExprCanBeNull(pRight)) {
sqlVdbeAddOp2(v, OP_IsNull, regBase + j,
@@ -733,7 +653,6 @@ codeAllEqualityTerms(Parse * pParse, /* Parsing context */
}
}
}
- *res_type = type;
return regBase;
}
@@ -904,10 +823,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
int iIdxCur; /* The VDBE cursor for the index */
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
- /* Types for start of range constraint. */
- enum field_type *start_types;
- /* Types for end of range constraint */
- enum field_type *end_types = NULL;
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
int force_integer_reg = -1; /* If non-negative: number of
@@ -994,17 +909,7 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
* and store the values of those terms in an array of registers
* starting at regBase.
*/
- regBase =
- codeAllEqualityTerms(pParse, pLevel, bRev, nExtraReg,
- &start_types);
- if (start_types != NULL && nTop) {
- uint32_t len = 0;
- for (enum field_type *tmp = &start_types[nEq];
- *tmp != field_type_MAX; tmp++, len++);
- uint32_t sz = len * sizeof(enum field_type);
- end_types = sqlDbMallocRaw(db, sz);
- memcpy(end_types, &start_types[nEq], sz);
- }
+ regBase = codeAllEqualityTerms(pParse, pLevel, bRev, nExtraReg);
addrNxt = pLevel->addrNxt;
testcase(pRangeStart && (pRangeStart->eOperator & WO_LE) != 0);
@@ -1029,10 +934,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
VdbeCoverage(v);
}
- if (start_types) {
- expr_cmp_update_rhs_type(pRight, nBtm,
- &start_types[nEq]);
- }
nConstraint += nBtm;
testcase(pRangeStart->wtFlags & TERM_VIRTUAL);
if (sqlExprIsVector(pRight) == 0) {
@@ -1049,94 +950,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
}
struct index_def *idx_pk = space->index[0]->def;
uint32_t pk_part_count = idx_pk->key_def->part_count;
- /*
- * Tarantool's iterator over integer fields doesn't
- * tolerate floating point values. Hence, if term
- * is equality comparison and value of operand is
- * not integer, we can skip it since it always
- * results in false: INT a == 0.5 -> false;
- * It is done using OP_MustBeInt facilities.
- * In case term is greater comparison (a > ?), we
- * should notify OP_SeekGT to process truncation of
- * floating point value: a > 0.5 -> a >= 1;
- * It is done by setting P5 flag for OP_Seek*.
- * It is worth mentioning that we do not need
- * this step when it comes for less (<) comparison
- * of nullable field. Key is NULL in this case:
- * values are ordered as NULL, ... NULL, min_value,
- * so to fetch min value we pass NULL to GT iterator.
- * The only exception is less comparison in
- * conjunction with ORDER BY DESC clause:
- * in such situation we use LE iterator and
- * truncated value to compare. But then
- * pRangeStart == NULL.
- * This procedure is correct for compound index:
- * only one comparison of less/greater type can be
- * used at the same time. For instance,
- * a < 1.5 AND b > 0.5 is handled by SeekGT using
- * column a and fetching column b from tuple and
- * OP_Le comparison.
- *
- * Note that OP_ApplyType, which is emitted before
- * OP_Seek** doesn't truncate floating point to
- * integer. That's why we need this routine.
- * Also, note that terms are separated by OR
- * predicates, so we consider term as sequence
- * of AND'ed predicates.
- */
- size_t addrs_sz;
- int *seek_addrs = region_alloc_array(&pParse->region,
- typeof(seek_addrs[0]), nEq,
- &addrs_sz);
- if (seek_addrs == NULL) {
- diag_set(OutOfMemory, addrs_sz, "region_alloc_array",
- "seek_addrs");
- pParse->is_aborted = true;
- return 0;
- }
- memset(seek_addrs, 0, addrs_sz);
- for (int i = 0; i < nEq; i++) {
- enum field_type type = idx_def->key_def->parts[i].type;
- if (type == FIELD_TYPE_INTEGER ||
- type == FIELD_TYPE_UNSIGNED) {
- /*
- * OP_MustBeInt consider NULLs as
- * non-integer values, so firstly
- * check whether value is NULL or not.
- */
- seek_addrs[i] = sqlVdbeAddOp1(v, OP_IsNull,
- regBase);
- sqlVdbeAddOp2(v, OP_MustBeInt, regBase + i,
- addrNxt);
- start_types[i] = FIELD_TYPE_SCALAR;
- /*
- * We need to notify column cache
- * that type of value may change
- * so we should fetch value from
- * tuple again rather then copy
- * from register.
- */
- sql_expr_type_cache_change(pParse, regBase + i,
- 1);
- }
- }
- /* Inequality constraint comes always at the end of list. */
- part_count = idx_def->key_def->part_count;
- if (pRangeStart != NULL) {
- /*
- * nEq == 0 means that filter condition
- * contains only inequality.
- */
- uint32_t ineq_idx = nEq == 0 ? 0 : nEq - 1;
- assert(ineq_idx < part_count);
- enum field_type ineq_type =
- idx_def->key_def->parts[ineq_idx].type;
- if (ineq_type == FIELD_TYPE_INTEGER ||
- ineq_type == FIELD_TYPE_UNSIGNED)
- force_integer_reg = regBase + nEq;
- }
- emit_apply_type(pParse, regBase, nConstraint - bSeekPastNull,
- start_types);
if (pLoop->nSkip > 0 && nConstraint == pLoop->nSkip) {
/* The skip-scan logic inside the call to codeAllEqualityConstraints()
* above has already left the cursor sitting on the correct row,
@@ -1146,10 +959,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
op = aStartOp[(start_constraints << 2) +
(startEq << 1) + bRev];
assert(op != 0);
- for (uint32_t i = 0; i < nEq; ++i) {
- if (seek_addrs[i] != 0)
- sqlVdbeJumpHere(v, seek_addrs[i]);
- }
sqlVdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
nConstraint);
/* If this is Seek* opcode, and IPK is detected in the
@@ -1189,13 +998,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
addrNxt);
VdbeCoverage(v);
}
- if (end_types) {
- expr_cmp_update_rhs_type(pRight, nTop, end_types);
- emit_apply_type(pParse, regBase + nEq, nTop,
- end_types);
- } else {
- assert(pParse->db->mallocFailed);
- }
nConstraint += nTop;
testcase(pRangeEnd->wtFlags & TERM_VIRTUAL);
@@ -1209,8 +1011,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W
endEq = 0;
nConstraint++;
}
- sqlDbFree(db, start_types);
- sqlDbFree(db, end_types);
/* Top of the loop body */
pLevel->p2 = sqlVdbeCurrentAddr(v);
diff --git a/test/sql-tap/identifier_case.test.lua b/test/sql-tap/identifier_case.test.lua
index 2a00626fc..1d56ffb44 100755
--- a/test/sql-tap/identifier_case.test.lua
+++ b/test/sql-tap/identifier_case.test.lua
@@ -242,11 +242,11 @@ data = {
{ 2, [[ 'a' < 'b' collate "binary" ]], {0, {true}}},
{ 3, [[ 'a' < 'b' collate 'binary' ]], {1, [[Syntax error at line 1 near ''binary'']]}},
{ 4, [[ 'a' < 'b' collate "unicode" ]], {0, {true}}},
- { 5, [[ 5 < 'b' collate "unicode" ]], {0, {true}}},
+ { 5, [[ 5 < 'b' collate "unicode" ]], {1, "Type mismatch: can not convert b to numeric"}},
{ 6, [[ 5 < 'b' collate unicode ]], {1,"Collation 'UNICODE' does not exist"}},
- { 7, [[ 5 < 'b' collate "unicode_ci" ]], {0, {true}}},
+ { 7, [[ 5 < 'b' collate "unicode_ci" ]], {1, "Type mismatch: can not convert b to numeric"}},
{ 8, [[ 5 < 'b' collate NONE ]], {1, "Collation 'NONE' does not exist"}},
- { 9, [[ 5 < 'b' collate "none" ]], {0, {true}}},
+ { 9, [[ 5 < 'b' collate "none" ]], {1, "Type mismatch: can not convert b to numeric"}},
}
for _, row in ipairs(data) do
diff --git a/test/sql-tap/in1.test.lua b/test/sql-tap/in1.test.lua
index 570cc1779..e2f498889 100755
--- a/test/sql-tap/in1.test.lua
+++ b/test/sql-tap/in1.test.lua
@@ -637,12 +637,12 @@ test:do_test(
"in-11.2",
function()
-- The '2' should be coerced into 2 because t6.b is NUMERIC
- return test:execsql [[
+ return test:catchsql [[
SELECT * FROM t6 WHERE b IN ('2');
]]
end, {
-- <in-11.2>
- 1, 2
+ 1, "Type mismatch: can not convert 2 to numeric"
-- </in-11.2>
})
diff --git a/test/sql-tap/in4.test.lua b/test/sql-tap/in4.test.lua
index 33947d0ab..a494e846f 100755
--- a/test/sql-tap/in4.test.lua
+++ b/test/sql-tap/in4.test.lua
@@ -147,12 +147,13 @@ test:do_execsql_test(
-- </in4-2.7>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"in4-2.8",
[[
SELECT b FROM t2 WHERE a IN ('', '0.0.0', '2')
]], {
-- <in4-2.8>
+ 1, "Type mismatch: can not convert integer to text"
-- </in4-2.8>
})
diff --git a/test/sql-tap/insert3.test.lua b/test/sql-tap/insert3.test.lua
index b92bc508e..3276f0db2 100755
--- a/test/sql-tap/insert3.test.lua
+++ b/test/sql-tap/insert3.test.lua
@@ -59,7 +59,7 @@ test:do_execsql_test(
[[
CREATE TABLE log2(rowid INTEGER PRIMARY KEY AUTOINCREMENT, x TEXT UNIQUE,y INT );
CREATE TRIGGER r2 BEFORE INSERT ON t1 FOR EACH ROW BEGIN
- UPDATE log2 SET y=y+1 WHERE x=new.b;
+ UPDATE log2 SET y=y+1 WHERE x=CAST(new.b AS STRING);
INSERT OR IGNORE INTO log2(x, y) VALUES(CAST(new.b AS STRING),1);
END;
INSERT INTO t1(a, b) VALUES('hi', 453);
diff --git a/test/sql-tap/join.test.lua b/test/sql-tap/join.test.lua
index 51e0ecb79..792302ab5 100755
--- a/test/sql-tap/join.test.lua
+++ b/test/sql-tap/join.test.lua
@@ -1028,22 +1028,23 @@ test:do_test(
-- </join-11.8>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"join-11.9",
[[
SELECT * FROM t1 NATURAL JOIN t2
]], {
-- <join-11.9>
+ 1, "Type mismatch: can not convert integer to text"
-- </join-11.9>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"join-11.10",
[[
SELECT * FROM t2 NATURAL JOIN t1
]], {
-- <join-11.10>
- 1, "one", 2, "two"
+ 1, "Type mismatch: can not convert 1 to numeric"
-- </join-11.10>
})
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index e0fe50bbe..3cef617f4 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -88,7 +88,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-1.4",
[[
- SELECT x75 FROM manycol WHERE x50=350
+ SELECT x75 FROM manycol WHERE x50='350'
]], {
-- <misc1-1.4>
"375"
@@ -98,7 +98,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-1.5",
[[
- SELECT x50 FROM manycol WHERE x99=599
+ SELECT x50 FROM manycol WHERE x99='599'
]], {
-- <misc1-1.5>
"550"
@@ -109,7 +109,7 @@ test:do_test(
"misc1-1.6",
function()
test:execsql("CREATE INDEX manycol_idx1 ON manycol(x99)")
- return test:execsql("SELECT x50 FROM manycol WHERE x99=899")
+ return test:execsql("SELECT x50 FROM manycol WHERE x99='899'")
end, {
-- <misc1-1.6>
"850"
@@ -129,7 +129,7 @@ test:do_execsql_test(
test:do_test(
"misc1-1.8",
function()
- test:execsql("DELETE FROM manycol WHERE x98=1234")
+ test:execsql("DELETE FROM manycol WHERE x98='1234'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.8>
@@ -140,7 +140,7 @@ test:do_test(
test:do_test(
"misc1-1.9",
function()
- test:execsql("DELETE FROM manycol WHERE x98=998")
+ test:execsql("DELETE FROM manycol WHERE x98='998'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.9>
@@ -151,7 +151,7 @@ test:do_test(
test:do_test(
"misc1-1.10",
function()
- test:execsql("DELETE FROM manycol WHERE x99=500")
+ test:execsql("DELETE FROM manycol WHERE x99='500'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.10>
@@ -162,7 +162,7 @@ test:do_test(
test:do_test(
"misc1-1.11",
function()
- test:execsql("DELETE FROM manycol WHERE x99=599")
+ test:execsql("DELETE FROM manycol WHERE x99='599'")
return test:execsql("SELECT count(*) FROM manycol")
end, {
-- <misc1-1.11>
@@ -479,9 +479,9 @@ local where = ""
test:do_test(
"misc1-10.1",
function()
- where = "WHERE x0>=0"
+ where = "WHERE x0>='0'"
for i = 1, 99, 1 do
- where = where .. " AND x"..i.."<>0"
+ where = where .. " AND x"..i.."<>'0'"
end
return test:catchsql("SELECT count(*) FROM manycol "..where.."")
end, {
@@ -496,7 +496,7 @@ test:do_test(
test:do_test(
"misc1-10.3",
function()
- where = string.gsub(where,"x0>=0", "x0=0")
+ where = string.gsub(where,"x0>='0'", "x0='0'")
return test:catchsql("DELETE FROM manycol "..where.."")
end, {
-- <misc1-10.3>
@@ -520,7 +520,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-10.6",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.6>
"101"
@@ -530,7 +530,7 @@ test:do_execsql_test(
test:do_test(
"misc1-10.7",
function()
- where = string.gsub(where, "x0=0", "x0=100")
+ where = string.gsub(where, "x0='0'", "x0='100'")
return test:catchsql("UPDATE manycol SET x1=CAST(x1+1 AS STRING) "..where.."")
end, {
-- <misc1-10.7>
@@ -541,7 +541,7 @@ test:do_test(
test:do_execsql_test(
"misc1-10.8",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.8>
"102"
@@ -563,7 +563,7 @@ test:do_execsql_test(
test:do_execsql_test(
"misc1-10.10",
[[
- SELECT x1 FROM manycol WHERE x0=100
+ SELECT x1 FROM manycol WHERE x0='100'
]], {
-- <misc1-10.10>
"103"
@@ -619,13 +619,13 @@ test:do_execsql_test(
-- </misc1-12.1>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"misc1-12.2",
[[
SELECT '0'==0.0
]], {
-- <misc1-12.2>
- true
+ 1, "Type mismatch: can not convert 0 to numeric"
-- </misc1-12.2>
})
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index 9a969bf3c..f5a9b63fe 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -1912,7 +1912,7 @@ test:do_execsql_test(
test:do_execsql_test(
"select1-12.7",
[[
- SELECT * FROM t3 WHERE a=(SELECT 1);
+ SELECT * FROM t3 WHERE a=(SELECT '1');
]], {
-- <select1-12.7>
0, "1", "2"
@@ -1922,7 +1922,7 @@ test:do_execsql_test(
test:do_execsql_test(
"select1-12.8",
[[
- SELECT * FROM t3 WHERE a=(SELECT 2);
+ SELECT * FROM t3 WHERE a=(SELECT '2');
]], {
-- <select1-12.8>
diff --git a/test/sql-tap/select7.test.lua b/test/sql-tap/select7.test.lua
index e1e43c557..0d1390fd6 100755
--- a/test/sql-tap/select7.test.lua
+++ b/test/sql-tap/select7.test.lua
@@ -256,7 +256,7 @@ test:do_execsql_test(
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a TEXT primary key, b INT);
INSERT INTO t5 VALUES('123', 456);
- SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
+ SELECT typeof(a), a FROM t5 GROUP BY a HAVING CAST(a AS INTEGER)<b;
]], {
-- <select7-7.7>
"string", "123"
diff --git a/test/sql-tap/subquery.test.lua b/test/sql-tap/subquery.test.lua
index e0771825e..bad702de9 100755
--- a/test/sql-tap/subquery.test.lua
+++ b/test/sql-tap/subquery.test.lua
@@ -284,13 +284,13 @@ test:do_execsql_test(
-- </subquery-2.3.1>
})
-test:do_execsql_test(
+test:do_catchsql_test(
"subquery-2.3.2",
[[
SELECT a IN (10.0, 20) FROM t3;
]], {
-- <subquery-2.3.2>
- false
+ 1, "Type mismatch: can not convert text to real"
-- </subquery-2.3.2>
})
diff --git a/test/sql-tap/tkt-9a8b09f8e6.test.lua b/test/sql-tap/tkt-9a8b09f8e6.test.lua
deleted file mode 100755
index ac89c7df2..000000000
--- a/test/sql-tap/tkt-9a8b09f8e6.test.lua
+++ /dev/null
@@ -1,506 +0,0 @@
-#!/usr/bin/env tarantool
-test = require("sqltester")
-test:plan(47)
-
---!./tcltestrunner.lua
--- 2014 June 26
---
--- The author disclaims copyright to this source code. In place of
--- a legal notice, here is a blessing:
---
--- May you do good and not evil.
--- May you find forgiveness for yourself and forgive others.
--- May you share freely, never taking more than you give.
---
--------------------------------------------------------------------------
--- This file implements regression tests for sql library.
---
--- This file implements tests to verify that ticket [9a8b09f8e6] has been
--- fixed.
---
--- ["set","testdir",[["file","dirname",["argv0"]]]]
--- ["source",[["testdir"],"\/tester.tcl"]]
-testprefix = "tkt-9a8b09f8e6"
--- MUST_WORK_TEST
-if (0 > 0)
- then
-end
-test:do_execsql_test(
- 1.1,
- [[
- CREATE TABLE t1(x TEXT primary key);
- INSERT INTO t1 VALUES('1');
- ]], {
- -- <1.1>
-
- -- </1.1>
- })
-
-test:do_execsql_test(
- 1.2,
- [[
- CREATE TABLE t2(x INTEGER primary key);
- INSERT INTO t2 VALUES(1);
- ]], {
- -- <1.2>
-
- -- </1.2>
- })
-
-test:do_execsql_test(
- 1.3,
- [[
- CREATE TABLE t3(x NUMBER primary key);
- INSERT INTO t3 VALUES(1.0);
- ]], {
- -- <1.3>
-
- -- </1.3>
- })
-
-test:do_execsql_test(
- 1.4,
- [[
- CREATE TABLE t4(x NUMBER primary key);
- INSERT INTO t4 VALUES(1.11);
- ]], {
- -- <1.4>
-
- -- </1.4>
- })
-
-test:do_execsql_test(
- 1.5,
- [[
- CREATE TABLE t5(id INT primary key, x INT , y TEXT);
- INSERT INTO t5 VALUES(1, 1, 'one');
- INSERT INTO t5 VALUES(2, 1, 'two');
- INSERT INTO t5 VALUES(3, 1.0, 'three');
- INSERT INTO t5 VALUES(4, 1.0, 'four');
- ]], {
- -- <1.5>
-
- -- </1.5>
- })
-
-test:do_execsql_test(
- 2.1,
- [[
- SELECT x FROM t1 WHERE x IN (1);
- ]], {
- -- <2.1>
- "1"
- -- </2.1>
- })
-
-test:do_execsql_test(
- 2.2,
- [[
- SELECT x FROM t1 WHERE x IN (1.0);
- ]], {
- -- <2.2>
- "1"
- -- </2.2>
- })
-
-test:do_execsql_test(
- 2.3,
- [[
- SELECT x FROM t1 WHERE x IN ('1');
- ]], {
- -- <2.3>
- "1"
- -- </2.3>
- })
-
-test:do_execsql_test(
- 2.4,
- [[
- SELECT x FROM t1 WHERE x IN ('1.0');
- ]], {
- -- <2.4>
-
- -- </2.4>
- })
-
-test:do_execsql_test(
- 2.5,
- [[
- SELECT x FROM t1 WHERE 1 IN (x);
- ]], {
- -- <2.5>
- "1"
- -- </2.5>
- })
-
-test:do_execsql_test(
- 2.6,
- [[
- SELECT x FROM t1 WHERE 1.0 IN (x);
- ]], {
- -- <2.6>
- "1"
- -- </2.6>
- })
-
-test:do_execsql_test(
- 2.7,
- [[
- SELECT x FROM t1 WHERE '1' IN (x);
- ]], {
- -- <2.7>
- "1"
- -- </2.7>
- })
-
-test:do_execsql_test(
- 2.8,
- [[
- SELECT x FROM t1 WHERE '1.0' IN (x);
- ]], {
- -- <2.8>
-
- -- </2.8>
- })
-
-test:do_execsql_test(
- 3.1,
- [[
- SELECT x FROM t2 WHERE x IN (1);
- ]], {
- -- <3.1>
- 1
- -- </3.1>
- })
-
-test:do_execsql_test(
- 3.2,
- [[
- SELECT x FROM t2 WHERE x IN (1.0);
- ]], {
- -- <3.2>
- 1
- -- </3.2>
- })
-
-test:do_execsql_test(
- 3.3,
- [[
- SELECT x FROM t2 WHERE x IN ('1');
- ]], {
- -- <3.3>
- -- </3.3>
- })
-
-test:do_execsql_test(
- 3.5,
- [[
- SELECT x FROM t2 WHERE 1 IN (x);
- ]], {
- -- <3.5>
- 1
- -- </3.5>
- })
-
-test:do_execsql_test(
- 3.6,
- [[
- SELECT x FROM t2 WHERE 1.0 IN (x);
- ]], {
- -- <3.6>
- 1
- -- </3.6>
- })
-
-test:do_execsql_test(
- 3.7,
- [[
- SELECT x FROM t2 WHERE '1' IN (x);
- ]], {
- -- <3.7>
- -- </3.7>
- })
-
-test:do_execsql_test(
- 4.1,
- [[
- SELECT x FROM t3 WHERE x IN (1);
- ]], {
- -- <4.1>
- 1.0
- -- </4.1>
- })
-
-test:do_execsql_test(
- 4.2,
- [[
- SELECT x FROM t3 WHERE x IN (1.0);
- ]], {
- -- <4.2>
- 1.0
- -- </4.2>
- })
-
-test:do_execsql_test(
- 4.3,
- [[
- SELECT x FROM t3 WHERE x IN ('1');
- ]], {
- -- <4.3>
- 1.0
- -- </4.3>
- })
-
-test:do_execsql_test(
- 4.4,
- [[
- SELECT x FROM t3 WHERE x IN ('1.0');
- ]], {
- -- <4.4>
- 1.0
- -- </4.4>
- })
-
-test:do_execsql_test(
- 4.5,
- [[
- SELECT x FROM t3 WHERE 1 IN (x);
- ]], {
- -- <4.5>
- 1.0
- -- </4.5>
- })
-
-test:do_execsql_test(
- 4.6,
- [[
- SELECT x FROM t3 WHERE 1.0 IN (x);
- ]], {
- -- <4.6>
- 1.0
- -- </4.6>
- })
-
-test:do_execsql_test(
- 4.7,
- [[
- SELECT x FROM t3 WHERE '1' IN (x);
- ]], {
- -- <4.7>
- 1
- -- </4.7>
- })
-
-test:do_execsql_test(
- 4.8,
- [[
- SELECT x FROM t3 WHERE '1.0' IN (x);
- ]], {
- -- <4.8>
- 1
- -- </4.8>
- })
-
-test:do_execsql_test(
- 5.1,
- [[
- SELECT x FROM t4 WHERE x IN (1);
- ]], {
- -- <5.1>
-
- -- </5.1>
- })
-
-test:do_execsql_test(
- 5.2,
- [[
- SELECT x FROM t4 WHERE x IN (1.0);
- ]], {
- -- <5.2>
-
- -- </5.2>
- })
-
-test:do_execsql_test(
- 5.3,
- [[
- SELECT x FROM t4 WHERE x IN ('1');
- ]], {
- -- <5.3>
-
- -- </5.3>
- })
-
-test:do_execsql_test(
- 5.4,
- [[
- SELECT x FROM t4 WHERE x IN ('1.0');
- ]], {
- -- <5.4>
-
- -- </5.4>
- })
-
-test:do_execsql_test(
- 5.5,
- [[
- SELECT x FROM t4 WHERE x IN (1.11);
- ]], {
- -- <5.5>
- 1.11
- -- </5.5>
- })
-
-test:do_execsql_test(
- 5.6,
- [[
- SELECT x FROM t4 WHERE x IN ('1.11');
- ]], {
- -- <5.6>
- 1.11
- -- </5.6>
- })
-
-test:do_execsql_test(
- 5.7,
- [[
- SELECT x FROM t4 WHERE 1 IN (x);
- ]], {
- -- <5.7>
-
- -- </5.7>
- })
-
-test:do_execsql_test(
- 5.8,
- [[
- SELECT x FROM t4 WHERE 1.0 IN (x);
- ]], {
- -- <5.8>
-
- -- </5.8>
- })
-
-test:do_execsql_test(
- 5.9,
- [[
- SELECT x FROM t4 WHERE '1' IN (x);
- ]], {
- -- <5.9>
-
- -- </5.9>
- })
-
-test:do_execsql_test(
- 5.10,
- [[
- SELECT x FROM t4 WHERE '1.0' IN (x);
- ]], {
- -- <5.10>
-
- -- </5.10>
- })
-
-test:do_execsql_test(
- 5.11,
- [[
- SELECT x FROM t4 WHERE 1.11 IN (x);
- ]], {
- -- <5.11>
- 1.11
- -- </5.11>
- })
-
-test:do_execsql_test(
- 5.12,
- [[
- SELECT x FROM t4 WHERE '1.11' IN (x);
- ]], {
- -- <5.12>
- 1.11
- -- </5.12>
- })
-
-test:do_execsql_test(
- 6.1,
- [[
- SELECT x, y FROM t5 WHERE x IN (1);
- ]], {
- -- <6.1>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.1>
- })
-
-test:do_execsql_test(
- 6.2,
- [[
- SELECT x, y FROM t5 WHERE x IN (1.0);
- ]], {
- -- <6.2>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.2>
- })
-
-test:do_execsql_test(
- 6.3,
- [[
- SELECT x, y FROM t5 WHERE x IN ('1');
- ]], {
- -- <6.3>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.3>
- })
-
-test:do_execsql_test(
- 6.4,
- [[
- SELECT x, y FROM t5 WHERE x IN ('1.0');
- ]], {
- -- <6.4>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.4>
- })
-
-test:do_execsql_test(
- 6.5,
- [[
- SELECT x, y FROM t5 WHERE 1 IN (x);
- ]], {
- -- <6.5>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.5>
- })
-
-test:do_execsql_test(
- 6.6,
- [[
- SELECT x, y FROM t5 WHERE 1.0 IN (x);
- ]], {
- -- <6.6>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.6>
- })
-
-test:do_execsql_test(
- 6.7,
- [[
- SELECT x, y FROM t5 WHERE '1' IN (x);
- ]], {
- -- <6.7>
- 1, "one", 1, "two", 1, "three", 1.0, "four"
- -- </6.7>
- })
-
-test:do_execsql_test(
- 6.8,
- [[
- SELECT x, y FROM t5 WHERE '1.0' IN (x);
- ]], {
- -- <6.8>
- 1, "one", 1, "two", 1, "three", 1, "four"
- -- </6.8>
- })
-
-
-
-test:finish_test()
diff --git a/test/sql-tap/tkt-f973c7ac31.test.lua b/test/sql-tap/tkt-f973c7ac31.test.lua
index 82bdb52f8..381f29c65 100755
--- a/test/sql-tap/tkt-f973c7ac31.test.lua
+++ b/test/sql-tap/tkt-f973c7ac31.test.lua
@@ -39,9 +39,8 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".1",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='2' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='2' ORDER BY c2 DESC
]], {
-
})
test:do_execsql_test(
@@ -55,7 +54,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".3",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='5' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='5' ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -63,7 +62,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".4",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<=5 ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND c2<=5 ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -71,7 +70,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".5",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<='5' ORDER BY c2 DESC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND CAST(c2 AS STRING)<='5' ORDER BY c2 DESC
]], {
5, 5, 5, 4
})
@@ -79,9 +78,8 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".6",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='2' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='2' ORDER BY c2 ASC
]], {
-
})
test:do_execsql_test(
@@ -95,7 +93,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".8",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND c2<='5' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>0 AND CAST(c2 AS STRING)<='5' ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
@@ -103,7 +101,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".9",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<=5 ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND c2<=5 ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
@@ -111,7 +109,7 @@ for tn, sql in ipairs(sqls) do
test:do_execsql_test(
"tkt-f973c7ac3-1."..tn..".10",
[[
- SELECT c1,c2 FROM t WHERE c1 = 5 AND c2>'0' AND c2<='5' ORDER BY c2 ASC
+ SELECT c1,c2 FROM t WHERE c1 = 5 AND CAST(c2 AS STRING)>'0' AND CAST(c2 AS STRING)<='5' ORDER BY c2 ASC
]], {
5, 4, 5, 5
})
diff --git a/test/sql-tap/tkt3493.test.lua b/test/sql-tap/tkt3493.test.lua
index de77e61e9..82ba828d0 100755
--- a/test/sql-tap/tkt3493.test.lua
+++ b/test/sql-tap/tkt3493.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(26)
+test:plan(25)
--!./tcltestrunner.lua
-- 2008 October 13
@@ -45,7 +45,7 @@ test:do_execsql_test(
[[
SELECT
CASE
- WHEN B.val = 1 THEN 'XYZ'
+ WHEN B.val = '1' THEN 'XYZ'
ELSE A.val
END AS Col1
FROM B
@@ -63,7 +63,7 @@ test:do_execsql_test(
[[
SELECT DISTINCT
CASE
- WHEN B.val = 1 THEN 'XYZ'
+ WHEN B.val = '1' THEN 'XYZ'
ELSE A.val
END AS Col1
FROM B
@@ -79,7 +79,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-1.4",
[[
- SELECT b.val, CASE WHEN b.val = 1 THEN 'xyz' ELSE b.val END AS col1 FROM b;
+ SELECT b.val, CASE WHEN b.val = '1' THEN 'xyz' ELSE b.val END AS col1 FROM b;
]], {
-- <tkt3493-1.4>
"1", "xyz", "2", "2"
@@ -91,7 +91,7 @@ test:do_execsql_test(
[[
SELECT DISTINCT
b.val,
- CASE WHEN b.val = 1 THEN 'xyz' ELSE b.val END AS col1
+ CASE WHEN b.val = '1' THEN 'xyz' ELSE b.val END AS col1
FROM b;
]], {
-- <tkt3493-1.5>
@@ -126,23 +126,13 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.1",
[[
- SELECT a=123 FROM t1 GROUP BY a
+ SELECT a='123' FROM t1 GROUP BY a
]], {
-- <tkt3493-2.2.1>
true
-- </tkt3493-2.2.1>
})
-test:do_execsql_test(
- "tkt3493-2.2.2",
- [[
- SELECT a=123 FROM t1
- ]], {
- -- <tkt3493-2.2.2>
- true
- -- </tkt3493-2.2.2>
- })
-
test:do_execsql_test(
"tkt3493-2.2.3",
[[
@@ -156,7 +146,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.4",
[[
- SELECT count(*), a=123 FROM t1
+ SELECT count(*), a='123' FROM t1
]], {
-- <tkt3493-2.2.4>
1, true
@@ -166,7 +156,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.2.5",
[[
- SELECT count(*), +a=123 FROM t1
+ SELECT count(*), +a='123' FROM t1
]], {
-- <tkt3493-2.2.5>
1, true
@@ -176,7 +166,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.3",
[[
- SELECT b='456' FROM t1 GROUP BY a
+ SELECT b = 456 FROM t1 GROUP BY a
]], {
-- <tkt3493-2.3.3>
true
@@ -186,7 +176,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.1",
[[
- SELECT b='456' FROM t1 GROUP BY b
+ SELECT b = 456 FROM t1 GROUP BY b
]], {
-- <tkt3493-2.3.1>
true
@@ -196,7 +186,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.3.2",
[[
- SELECT b='456' FROM t1
+ SELECT b = 456 FROM t1
]], {
-- <tkt3493-2.3.2>
true
@@ -206,7 +196,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.4.1",
[[
- SELECT typeof(a), a FROM t1 GROUP BY a HAVING a=123
+ SELECT typeof(a), a FROM t1 GROUP BY a HAVING a='123'
]], {
-- <tkt3493-2.4.1>
"string", "123"
@@ -216,7 +206,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.4.2",
[[
- SELECT typeof(a), a FROM t1 GROUP BY b HAVING a=123
+ SELECT typeof(a), a FROM t1 GROUP BY b HAVING a='123'
]], {
-- <tkt3493-2.4.2>
"string", "123"
@@ -226,7 +216,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.5.1",
[[
- SELECT typeof(b), b FROM t1 GROUP BY a HAVING b='456'
+ SELECT typeof(b), b FROM t1 GROUP BY a HAVING b=456
]], {
-- <tkt3493-2.5.1>
"integer", 456
@@ -236,7 +226,7 @@ test:do_execsql_test(
test:do_execsql_test(
"tkt3493-2.5.2",
[[
- SELECT typeof(b), b FROM t1 GROUP BY b HAVING b='456'
+ SELECT typeof(b), b FROM t1 GROUP BY b HAVING b=456
]], {
-- <tkt3493-2.5.2>
"integer", 456
diff --git a/test/sql-tap/transitive1.test.lua b/test/sql-tap/transitive1.test.lua
index 96895b4a7..cc7e066bf 100755
--- a/test/sql-tap/transitive1.test.lua
+++ b/test/sql-tap/transitive1.test.lua
@@ -63,7 +63,7 @@ test:do_execsql_test(
INSERT INTO t2 VALUES(2, 20,20,'20');
INSERT INTO t2 VALUES(3, 3,3,'3');
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c=20;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c='20';
]], {
-- <transitive1-200>
20, 20, "20"
@@ -73,7 +73,7 @@ test:do_execsql_test(
test:do_execsql_test(
"transitive1-210",
[[
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c>='20' ORDER BY +a;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c>='20' ORDER BY +a;
]], {
-- <transitive1-210>
3, 3, "3", 20, 20, "20"
@@ -83,7 +83,7 @@ test:do_execsql_test(
test:do_execsql_test(
"transitive1-220",
[[
- SELECT a,b,c FROM t2 WHERE a=b AND c=b AND c<='20' ORDER BY +a;
+ SELECT a,b,c FROM t2 WHERE a=b AND c=CAST(b AS STRING) AND c<='20' ORDER BY +a;
]], {
-- <transitive1-220>
20, 20, "20", 100, 100, "100"
@@ -402,7 +402,7 @@ test:do_execsql_test(
[[
CREATE TABLE x(i INTEGER PRIMARY KEY, y TEXT);
INSERT INTO x VALUES(10, '10');
- SELECT * FROM x WHERE x.y>='1' AND x.y<'2' AND x.i=x.y;
+ SELECT * FROM x WHERE x.y>='1' AND x.y<'2' AND CAST(x.i AS STRING)=x.y;
]], {
-- <transitive1-500>
10, "10"
@@ -430,7 +430,7 @@ test:do_execsql_test(
[[
CREATE TABLE t3(i INTEGER PRIMARY KEY, t TEXT);
INSERT INTO t3 VALUES(10, '10');
- SELECT * FROM t3 WHERE i=t AND t = '10 ';
+ SELECT * FROM t3 WHERE CAST(i AS STRING)=t AND t = '10 ';
]], {
-- <transitive1-520>
@@ -443,7 +443,7 @@ test:do_execsql_test(
CREATE TABLE u1(x TEXT PRIMARY KEY, y INTEGER, z TEXT);
CREATE INDEX i1 ON u1(x);
INSERT INTO u1 VALUES('00013', 13, '013');
- SELECT * FROM u1 WHERE x=y AND y=z AND z='013';
+ SELECT * FROM u1 WHERE CAST(x AS INTEGER)=y AND y=CAST(z AS INTEGER) AND z='013';
]], {
-- <transitive1-530>
"00013",13,"013"
diff --git a/test/sql-tap/where2.test.lua b/test/sql-tap/where2.test.lua
index f267be8e6..7348a855a 100755
--- a/test/sql-tap/where2.test.lua
+++ b/test/sql-tap/where2.test.lua
@@ -4,7 +4,7 @@ yaml = require("yaml")
fio = require("fio")
ffi = require("ffi")
-test:plan(74)
+test:plan(62)
ffi.cdef[[
int dup(int oldfd);
@@ -622,181 +622,12 @@ test:do_test(
-- </where2-6.6>
})
--- if X(356, "X!cmd", [=[["expr","[permutation] != \"no_optimization\""]]=])
--- then
- -- Ticket #2249. Make sure the OR optimization is not attempted if
- -- comparisons between columns of different affinities are needed.
- --
- test:do_test(
- "where2-6.7",
- function()
- test:execsql [[
- CREATE TABLE t2249a(a TEXT PRIMARY KEY, x VARCHAR(100));
- CREATE TABLE t2249b(b INTEGER PRIMARY KEY);
- INSERT INTO t2249a(a) VALUES('0123');
- INSERT INTO t2249b VALUES(123);
- ]]
- return queryplan([[
- -- Because a is type TEXT and b is type INTEGER, both a and b
- -- will attempt to convert to NUMERIC before the comparison.
- -- They will thus compare equal.
- --
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=b;
- ]])
- end, {
- -- <where2-6.7>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.7>
- })
-
- test:do_test(
- "where2-6.9",
- function()
- return queryplan([[
- -- The + operator doesn't affect RHS.
- --
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b;
- ]])
- end, {
- -- <where2-6.9>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.9>
- })
-
- test:do_test(
- "where2-6.9.2",
- function()
- -- The same thing but with the expression flipped around.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +b=a
- ]])
- end, {
- -- <where2-6.9.2>
- 123, "0123","nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.9.2>
- })
-
- test:do_test(
- "where2-6.10",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +a=+b;
- ]])
- end, {
- -- <where2-6.10>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.10>
- })
-
- test:do_test(
- "where2-6.11",
- function()
- -- This will not attempt the OR optimization because of the a=b
- -- comparison.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=b OR a='hello';
- ]])
- end, {
- -- <where2-6.11>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11>
- })
-
- test:do_test(
- "where2-6.11.2",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE b=a OR a='hello';
- ]])
- end, {
- -- <where2-6.11.2>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.2>
- })
-
- test:do_test(
- "where2-6.11.3",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE 'hello'=a OR b=a;
- ]])
- end, {
- -- <where2-6.11.3>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.3>
- })
-
- test:do_test(
- "where2-6.11.4",
- function()
- -- Permutations of the expression terms.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR b=a;
- ]])
- end, {
- -- <where2-6.11.4>
- 123, '0123', "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.11.4>
- })
-
- -- These tests are not run if subquery support is not included in the
- -- build. This is because these tests test the "a = 1 OR a = 2" to
- -- "a IN (1, 2)" optimisation transformation, which is not enabled if
- -- subqueries and the IN operator is not available.
- --
- test:do_test(
- "where2-6.12",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b OR a='hello';
- ]])
- end, {
- -- <where2-6.12>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12>
- })
-
- test:do_test(
- "where2-6.12.2",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR +b=a;
- ]])
- end, {
- -- <where2-6.12.2>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12.2>
- })
-
- test:do_test(
- "where2-6.12.3",
- function()
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE +b=a OR a='hello';
- ]])
- end, {
- -- <where2-6.12.3>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.12.3>
- })
-
- test:do_test(
- "where2-6.13",
- function()
- -- The addition of +a on the second term disabled the OR optimization.
- -- But we should still get the same empty-set result as in where2-6.9.
- return queryplan([[
- SELECT b,a FROM t2249b CROSS JOIN t2249a WHERE a=+b OR +a='hello';
- ]])
- end, {
- -- <where2-6.13>
- 123, "0123", "nosort", "T2249B", "*", "T2249A", "*"
- -- </where2-6.13>
- })
-
-
+ test:execsql [[
+ CREATE TABLE t2249a(a TEXT PRIMARY KEY, x VARCHAR(100));
+ CREATE TABLE t2249b(b INTEGER PRIMARY KEY);
+ INSERT INTO t2249a(a) VALUES('0123');
+ INSERT INTO t2249b VALUES(123);
+ ]]
-- Variations on the order of terms in a WHERE clause in order
-- to make sure the OR optimizer can recognize them all.
diff --git a/test/sql-tap/where5.test.lua b/test/sql-tap/where5.test.lua
index 3aefcaca5..a93ba7854 100755
--- a/test/sql-tap/where5.test.lua
+++ b/test/sql-tap/where5.test.lua
@@ -34,7 +34,7 @@ test:do_test("where5-1.0", function()
INSERT INTO t3 SELECT CAST(x AS INTEGER) FROM t1;
]]
return test:execsql [[
- SELECT * FROM t1 WHERE x<0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<0
]]
end, {
-- <where5-1.0>
@@ -43,7 +43,7 @@ end, {
})
test:do_execsql_test("where5-1.1", [[
- SELECT * FROM t1 WHERE x<=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<=0
]], {
-- <where5-1.1>
'-1', '0'
@@ -51,7 +51,7 @@ test:do_execsql_test("where5-1.1", [[
})
test:do_execsql_test("where5-1.2", [[
- SELECT * FROM t1 WHERE x=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)=0
]], {
-- <where5-1.2>
'0'
@@ -59,7 +59,7 @@ test:do_execsql_test("where5-1.2", [[
})
test:do_execsql_test("where5-1.3", [[
- SELECT * FROM t1 WHERE x>=0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)>=0
]], {
-- <where5-1.3>
'0', '1'
@@ -67,7 +67,7 @@ test:do_execsql_test("where5-1.3", [[
})
test:do_execsql_test("where5-1.4", [[
- SELECT * FROM t1 WHERE x>0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)>0
]], {
-- <where5-1.4>
'1'
@@ -75,7 +75,7 @@ test:do_execsql_test("where5-1.4", [[
})
test:do_execsql_test("where5-1.5", [[
- SELECT * FROM t1 WHERE x<>0
+ SELECT * FROM t1 WHERE CAST(x AS INTEGER)<>0
]], {
-- <where5-1.5>
'-1', '1'
diff --git a/test/sql/types.result b/test/sql/types.result
index 54aff460e..1c8357bce 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -339,12 +339,12 @@ box.execute("INSERT INTO tboolean VALUES (TRUE);")
box.execute("SELECT * FROM tboolean WHERE s1 = x'44';")
---
- null
-- 'Type mismatch: can not convert varbinary to boolean'
+- 'Type mismatch: can not convert boolean to varbinary'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 'abc';")
---
- null
-- 'Type mismatch: can not convert abc to boolean'
+- 'Type mismatch: can not convert boolean to text'
...
box.execute("SELECT * FROM tboolean WHERE s1 = 1;")
---
@@ -606,14 +606,6 @@ box.execute("SELECT 18446744073709551615.0 > 18446744073709551615")
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:
@@ -2152,6 +2144,231 @@ box.execute([[SELECT * FROM "s" WHERE "id" = ?;]])
type: string
rows: []
...
+--
+-- gh-4230: Make sure that there is no implicit cast between
+-- string and number.
+--
+box.execute([[SELECT '1' > 0;]]);
+---
+- null
+- 'Type mismatch: can not convert 1 to numeric'
+...
+box.execute([[SELECT 1 > '0';]]);
+---
+- null
+- 'Type mismatch: can not convert 0 to numeric'
+...
+box.execute([[CREATE TABLE t (i INT PRIMARY KEY, d DOUBLE, n NUMBER, s STRING);]])
+---
+- row_count: 1
+...
+box.execute([[INSERT INTO t VALUES (1, 1.0, 1, '2'), (2, 2.0, 2.0, '2');]])
+---
+- row_count: 2
+...
+box.execute([[SELECT * from t WHERE i > s;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT * from t WHERE s > i;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT * from t WHERE d > s;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT * from t WHERE s > d;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT * from t WHERE i = 1 and n > s;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT * from t WHERE i = 2 and s > n;]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE i in (1);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE d in (1);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE n in (1);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE s in (1);]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE i in (1.0);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE d in (1.0);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE n in (1.0);]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows:
+ - [1]
+...
+box.execute([[SELECT i FROM t WHERE s in (1.0);]])
+---
+- null
+- 'Type mismatch: can not convert 2 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE i in ('1');]])
+---
+- null
+- 'Type mismatch: can not convert integer to text'
+...
+box.execute([[SELECT i FROM t WHERE d in ('1');]])
+---
+- null
+- 'Type mismatch: can not convert 1 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE n in ('1');]])
+---
+- null
+- 'Type mismatch: can not convert 1 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE s in ('1');]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows: []
+...
+box.execute([[SELECT i FROM t WHERE i in ('1.0');]])
+---
+- null
+- 'Type mismatch: can not convert integer to text'
+...
+box.execute([[SELECT i FROM t WHERE d in ('1.0');]])
+---
+- null
+- 'Type mismatch: can not convert 1.0 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE n in ('1.0');]])
+---
+- null
+- 'Type mismatch: can not convert 1.0 to numeric'
+...
+box.execute([[SELECT i FROM t WHERE s in ('1.0');]])
+---
+- metadata:
+ - name: I
+ type: integer
+ rows: []
+...
+box.execute([[DROP TABLE t;]])
+---
+- row_count: 1
+...
+-- Comparison with SCALAR.
+box.execute([[CREATE TABLE t(a SCALAR PRIMARY KEY);]])
+---
+- row_count: 1
+...
+box.execute([[INSERT INTO t VALUES (1), (2.2), ('3');]]);
+---
+- row_count: 3
+...
+box.execute([[SELECT a FROM t WHERE a > 1]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a > 1.0]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a > '1']]);
+---
+- metadata:
+ - name: A
+ type: scalar
+ rows:
+ - ['3']
+...
+box.execute([[SELECT a FROM t WHERE a < 1]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a < 1.0]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a < '1']]);
+---
+- metadata:
+ - name: A
+ type: scalar
+ rows:
+ - [1]
+ - [2.2]
+...
+box.execute([[SELECT a FROM t WHERE a = 1]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a = 1.0]]);
+---
+- null
+- 'Type mismatch: can not convert 3 to numeric'
+...
+box.execute([[SELECT a FROM t WHERE a = '1']]);
+---
+- metadata:
+ - name: A
+ type: scalar
+ rows: []
+...
+box.execute([[DROP TABLE t;]])
+---
+- row_count: 1
+...
s:drop()
---
...
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index bd14b342d..cf0db5ae0 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -151,7 +151,6 @@ 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 18446744073709551614;")
box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
@@ -486,4 +485,56 @@ s:format({ \
})
box.execute([[SELECT * FROM "s" WHERE "id" = ?;]])
+
+--
+-- gh-4230: Make sure that there is no implicit cast between
+-- string and number.
+--
+box.execute([[SELECT '1' > 0;]]);
+box.execute([[SELECT 1 > '0';]]);
+box.execute([[CREATE TABLE t (i INT PRIMARY KEY, d DOUBLE, n NUMBER, s STRING);]])
+box.execute([[INSERT INTO t VALUES (1, 1.0, 1, '2'), (2, 2.0, 2.0, '2');]])
+box.execute([[SELECT * from t WHERE i > s;]])
+box.execute([[SELECT * from t WHERE s > i;]])
+box.execute([[SELECT * from t WHERE d > s;]])
+box.execute([[SELECT * from t WHERE s > d;]])
+box.execute([[SELECT * from t WHERE i = 1 and n > s;]])
+box.execute([[SELECT * from t WHERE i = 2 and s > n;]])
+
+box.execute([[SELECT i FROM t WHERE i in (1);]])
+box.execute([[SELECT i FROM t WHERE d in (1);]])
+box.execute([[SELECT i FROM t WHERE n in (1);]])
+box.execute([[SELECT i FROM t WHERE s in (1);]])
+
+box.execute([[SELECT i FROM t WHERE i in (1.0);]])
+box.execute([[SELECT i FROM t WHERE d in (1.0);]])
+box.execute([[SELECT i FROM t WHERE n in (1.0);]])
+box.execute([[SELECT i FROM t WHERE s in (1.0);]])
+
+box.execute([[SELECT i FROM t WHERE i in ('1');]])
+box.execute([[SELECT i FROM t WHERE d in ('1');]])
+box.execute([[SELECT i FROM t WHERE n in ('1');]])
+box.execute([[SELECT i FROM t WHERE s in ('1');]])
+
+box.execute([[SELECT i FROM t WHERE i in ('1.0');]])
+box.execute([[SELECT i FROM t WHERE d in ('1.0');]])
+box.execute([[SELECT i FROM t WHERE n in ('1.0');]])
+box.execute([[SELECT i FROM t WHERE s in ('1.0');]])
+
+box.execute([[DROP TABLE t;]])
+
+-- Comparison with SCALAR.
+box.execute([[CREATE TABLE t(a SCALAR PRIMARY KEY);]])
+box.execute([[INSERT INTO t VALUES (1), (2.2), ('3');]]);
+box.execute([[SELECT a FROM t WHERE a > 1]]);
+box.execute([[SELECT a FROM t WHERE a > 1.0]]);
+box.execute([[SELECT a FROM t WHERE a > '1']]);
+box.execute([[SELECT a FROM t WHERE a < 1]]);
+box.execute([[SELECT a FROM t WHERE a < 1.0]]);
+box.execute([[SELECT a FROM t WHERE a < '1']]);
+box.execute([[SELECT a FROM t WHERE a = 1]]);
+box.execute([[SELECT a FROM t WHERE a = 1.0]]);
+box.execute([[SELECT a FROM t WHERE a = '1']]);
+box.execute([[DROP TABLE t;]])
+
s:drop()
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions
2020-06-29 23:52 ` Nikita Pettik
@ 2020-07-05 14:50 ` Mergen Imeev
0 siblings, 0 replies; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 14:50 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
On Mon, Jun 29, 2020 at 11:52:17PM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > After previous patches, some functions and the ApplyType opcode
> > become unused, so this patch removes them.
> >
> > Follow-up #4230
> > ---
>
> Все еще можно нагрепать OP_ApplyType. Перепроверь.
>
Fixed:
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index e7826519b..0879ccbfa 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -3863,7 +3863,7 @@ int sqlVarintLen(u64 v);
#define putVarint sqlPutVarint
/**
- * Code an OP_ApplyType opcode that will force types
+ * Code an OP_ImplicitCast opcode that will force types
* for given range of register starting from @reg.
*
* @param v VDBE.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error
2020-06-30 0:22 ` Nikita Pettik
@ 2020-07-05 15:03 ` Mergen Imeev
2020-07-06 21:44 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Mergen Imeev @ 2020-07-05 15:03 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
My answers and diff below.
On Tue, Jun 30, 2020 at 12:22:32AM +0000, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > After this patch value and its type will be shown in description
> > of type mismatch error
>
> Какие цели преследует этот патч? Зачем мы это делаем?
> Диф то на 1.5 кслок.
It is just a refactoring. It can be dropped.
> Забыл точку в конце :)
>
Fixed.
> > }
> > #ifdef SQL_DEBUG
> > @@ -4740,7 +4735,7 @@ case OP_IdxGE: { /* jump */
> > (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
> > continue;
> > diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > - field_type_strs[type], mem_type_to_str(mem));
> > + sql_value_to_diag_str(mem), mem_type_to_str(mem));
> > goto abort_due_to_error;
> > }
> > #ifdef SQL_DEBUG
> > diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> > index a721afc83..bb7676354 100644
> > --- a/src/box/sql/vdbemem.c
> > +++ b/src/box/sql/vdbemem.c
> > @@ -1166,12 +1166,15 @@ sqlValueText(sql_value * pVal)
> > const char *
> > sql_value_to_diag_str(sql_value *value)
> > {
> > - if (sql_value_type(value) == MP_BIN) {
> > - if (mem_has_msgpack_subtype(value))
> > - return sqlValueText(value);
> > + if (sql_value_mp_type(value) == MP_BIN)
> > return "varbinary";
> > - }
> > - return sqlValueText(value);
> > + char *type = mem_type_to_str(value);
> > + char *str = (char *)sqlValueText(value);
> > + if (str == NULL)
> > + return "NULL";
> > + if (strlen(str) < 80)
>
> https://en.wikipedia.org/wiki/Magic_number_(programming)
>
Added a enum here.
> > + return tt_sprintf("'%s' (type: %s)", str, type);
> > + return tt_sprintf("'%.80s...' (type: %s)", str, type);
> > }
> >
> > /*
> > diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
> > index 07442b60a..1547ffcd3 100755
> > --- a/test/sql-tap/autoinc.test.lua
> > +++ b/test/sql-tap/autoinc.test.lua
> > @@ -618,7 +618,7 @@ test:do_catchsql_test(
> > INSERT INTO t2 VALUES('asd');
> > ]], {
> > -- <autoinc-10.2>
> > - 1, "Type mismatch: can not convert asd to integer"
> > + 1, "Type mismatch: can not convert 'asd' (type: text) to integer"
>
> Выглядит зачотно, выглядит all right!
>
> > diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > index a1809b3cb..f1edfa0f6 100755
> > --- a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > +++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > @@ -28,7 +28,7 @@ test:do_catchsql_test(
> > [[
> > INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
> > ]], {
> > - 1, "Type mismatch: can not convert 1.0e+32 to integer"
> > + 1, "Type mismatch: can not convert '1.0e+32' (type: real) to integer"
> > })
>
> Я бы может еще кавычки вокруг чиселок/буленов не добавлял, но это
> в принципе мелочь - тип то печатается.
>
I think it is better as it is now since in some cases
STRING value and BOOLEAN values look the same.
> В остальном - ОК.
Diff:
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 32f4ae0b6..7cff881c0 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -1163,6 +1163,10 @@ sqlValueText(sql_value * pVal)
return valueToText(pVal);
}
+enum {
+ DIAG_STR_LEN_MAX = 80,
+};
+
const char *
sql_value_to_diag_str(sql_value *value)
{
@@ -1172,7 +1176,7 @@ sql_value_to_diag_str(sql_value *value)
char *str = (char *)sqlValueText(value);
if (str == NULL)
return "NULL";
- if (strlen(str) < 80)
+ if (strlen(str) < DIAG_STR_LEN_MAX)
return tt_sprintf("'%s' (type: %s)", str, type);
return tt_sprintf("'%.80s...' (type: %s)", str, type);
}
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double()
2020-06-28 13:31 ` Nikita Pettik
@ 2020-07-06 14:02 ` Nikita Pettik
0 siblings, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-06 14:02 UTC (permalink / raw)
To: imeevma; +Cc: tarantool-patches
On 28 Jun 13:31, Nikita Pettik wrote:
> On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > The mem_set_double () function is used to properly set MEM as
> > containing DOUBLE value.
>
> Nit: it has been introduced a long ago (sqlVdbeMemSetDouble()).
> You refactor it and use in several other places.
>
> LGTM
>
I've fixed a bit commit message and pushed to master as trivial.
sql: refactor sqlVdbeMemSetDouble()
sqlVdbeMemSetDouble() function is used to properly set double value to
VDBE memory cell. Let's refactor it according to our codestyle and
rename it to mem_set_double() since we are going to use it instead of
raw mem's value modification.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-07-05 14:26 ` Mergen Imeev
@ 2020-07-06 21:27 ` Nikita Pettik
2020-07-07 9:29 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-07-06 21:27 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 05 Jul 17:26, Mergen Imeev wrote:
> Hi! Thank you for the review. My answers and new patch
> below. Sorry, I didn't include diff.
> > > commit 21d7145c1929bc4606c56e9a566477f248637ed1
> > > Author: Mergen Imeev <imeevma@gmail.com>
> > > Date: Wed May 27 13:49:11 2020 +0300
> > >
> > > + if (field_mp_plain_type_is_compatible(type, mp_type, true))
> > > + return 0;
> > > + return -1;
> > > +}
> > > +
> > > +/**
> > > + * Convert the numeric value contained in MEM to double. If the
> > > + * is_precise flag is set, the conversion will succeed only if it
> > > + * is lossless.
> > > + *
> > > + * @param mem The MEM that contains the numeric value.
> > > + * @param is_precise Flag.
> > > + * @retval 0 if the conversion was successful, -1 otherwise.
> > > + */
> > > +static int
> > > +mem_convert_to_double(struct Mem *mem, bool is_precise)
> > > +{
> > > + if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
> > > + return -1;
> > > + if ((mem->flags & MEM_Int) != 0) {
> > > + int64_t i = mem->u.i;
> > > + double d = (double)i;
> > > + if (!is_precise || i == (int64_t)d)
> > > + mem_set_double(mem, d);
> > > + else
> > > + return -1;
> > > + } else {
> > > + uint64_t u = mem->u.u;
> > > + double d = (double)u;
> > > + if (!is_precise || u == (uint64_t)d)
> > > + mem_set_double(mem, d);
> > > + else
> > > + return -1;
> > > + }
> > > + mem->field_type = FIELD_TYPE_DOUBLE;
> >
> > Why not incorparate field_type assingment into mem_set_double()?
> > The same concerns other converting functions.
> >
> I think this should be done in #4906 issue since it may
> lead to not always simple to understand changes.
Эм, не очень понял как трактовать твой ответ. Типо тут работает,
а если там засунуть, то что-то начинает падать..? 4906 немного про
другое: в любом случае у нас в меме будет и field_type и mp_type.
К тому же, и то, и это - рефакторинг и функциональных изменений быть
не должно.
> > > +/**
> > > + * Convert the numeric value contained in MEM to another numeric
> > > + * type. If the is_precise flag is set, the conversion will
> > > + * succeed only if it is lossless.
> > > + * @param mem The MEM that contains the numeric value.
> > > + * @param type The type to convert to.
> > > + * @param is_precise Flag.
> > > + * @retval 0 if the conversion was successful, -1 otherwise.
> > > + */
> > > +static int
> > > +mem_convert_numeric(struct Mem *mem, enum field_type type, bool is_precise)
> >
> > mem_convert_to_numeric ?
> > mem_cast_to_numeric
> >
> Used first option.
>
> > > +{
> > > + if (!sql_type_is_numeric(type) ||
> > > + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
> >
> > It's somehow unnatural passing to _numeric function non-numeric type
> > to convert to. Instead let's use this function properly and replace
> > branching with assertion.
> >
> No, I think it is good as it is. More that that, due to
> some other comments I added similar checks to all other
> mem_convert_to>* functions.
В остальных случаях ты туда тип вообще не передаешь.
> My reason is: in all places we use this function we have
> to check that field type and MEM_type are numeric, so it
> make sence to move this check inside of the function.
Еще раз: это полный идиотизм передавать ТИП (отличный от нумерика) к
которому ты собираешься кастовать в функцию, которая по названию
предполагает каст к нумерику. Считай, что я настаиваю на этом
изменении.
> > > + return -1;
> > > + if (type == FIELD_TYPE_NUMBER)
> > > + return 0;
> > > + if (type == FIELD_TYPE_DOUBLE)
> > > + return mem_convert_to_double(mem, is_precise);
> > > + if (type == FIELD_TYPE_UNSIGNED)
> > > + return mem_convert_to_unsigned(mem, is_precise);
> > > + assert(type == FIELD_TYPE_INTEGER);
> > > + return mem_convert_to_integer(mem, is_precise);
> > > +}
> > > +
> > > /*
> index 37283e506..bd0055668 100644
> --- a/src/box/sql/sqlInt.h
> +++ b/src/box/sql/sqlInt.h
> @@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
> enum mp_type
> sql_value_type(sql_value *);
>
> +/*
> + * Return the MP_type of the value of the MEM.
> + *
> + * @param mem MEM with the correct MEM_type.
> + * @retval MP_type of the value.
> + */
> +enum mp_type
> +mem_mp_type(struct Mem *mem);
Я вытащил добавление этой функции в отдельный патч и добавил
рефакторинг чтобы соеденить ее с sql_value_type().
https://github.com/tarantool/tarantool/tree/np/gh-3809-remastered
Если ты ОК, я пушну вне очереди в мастер.
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 950f72ddd..1386ea2c0 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> + uint64_t u = mem->u.u;
> + double d = (double)u;
> + if (!is_precise || u == (uint64_t)d)
> + mem_set_double(mem, d);
> + else
> + return -1;
> + }
> + mem->field_type = FIELD_TYPE_DOUBLE;
> + return 0;
> +}
> +
> + * P1 are compatible with given field types in P4.
> + * If the MEM_type of the value and the given type are
> + * incompatible according to field_mp_plain_type_is_compatible(),
> + * but both are numeric, this opcode attempts to convert the value
> + * to the type.
> + */
> +case OP_ImplicitCast: {
> + enum field_type *types = pOp->p4.types;
> + assert(types != NULL);
> + assert(types[pOp->p2] == field_type_MAX);
> + for (int i = 0; types[i] != field_type_MAX; ++i) {
> + enum field_type type = types[i];
> + pIn1 = &aMem[pOp->p1 + i];
> + assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
> + assert(memIsValid(pIn1));
> + if (mem_is_type_compatible(pIn1, type))
> + continue;
> + if (mem_convert_to_numeric(pIn1, type, false) == 0)
Инвертируй, пожайлуйста условие:
if (mem_convert_to_numeric(pIn1, type, false) !=) {
//raise an error
}
Это будет больще соответствовать нашему кодстайлу.
> + continue;
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + sql_value_to_diag_str(pIn1), field_type_strs[type]);
> + goto abort_due_to_error;
> + }
> + break;
> +}
> +
> /* Opcode: MakeRecord P1 P2 P3 P4 P5
> * Synopsis: r[P3]=mkrec(r[P1@P2])
> *
> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
> index 4e103a653..b106ce6bd 100644
> --- a/src/box/sql/vdbeapi.c
> +++ b/src/box/sql/vdbeapi.c
> @@ -225,6 +225,33 @@ sql_value_type(sql_value *pVal)
> }
> }
>
> +enum mp_type
> +mem_mp_type(struct Mem *mem)
Еще раз: это не апишная функция (хотя бы в терминологии скулайта),
ей место скорее в vdbemem.c. См. мой рефакторинг.
> +{
> --- a/test/sql-tap/autoinc.test.lua
> +++ b/test/sql-tap/autoinc.test.lua
Тесты не смотрел, предполагая что нет изменений по сравнению с
предыдущей версией.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error
2020-07-05 15:03 ` Mergen Imeev
@ 2020-07-06 21:44 ` Nikita Pettik
0 siblings, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-06 21:44 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 05 Jul 18:03, Mergen Imeev wrote:
> My answers and diff below.
>
> On Tue, Jun 30, 2020 at 12:22:32AM +0000, Nikita Pettik wrote:
> > On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > > After this patch value and its type will be shown in description
> > > of type mismatch error
> >
> > Какие цели преследует этот патч? Зачем мы это делаем?
> > Диф то на 1.5 кслок.
> It is just a refactoring. It can be dropped.
Хороший аргумент, добавить нечего.
> > > diff --git a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > > index a1809b3cb..f1edfa0f6 100755
> > > --- a/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > > +++ b/test/sql-tap/gh-3809-implicit-cast-assignment.test.lua
> > > @@ -28,7 +28,7 @@ test:do_catchsql_test(
> > > [[
> > > INSERT INTO ti(i) VALUES (100000000000000000000000000000000.1)
> > > ]], {
> > > - 1, "Type mismatch: can not convert 1.0e+32 to integer"
> > > + 1, "Type mismatch: can not convert '1.0e+32' (type: real) to integer"
> > > })
> >
> > Я бы может еще кавычки вокруг чиселок/буленов не добавлял, но это
> > в принципе мелочь - тип то печатается.
> >
> I think it is better as it is now since in some cases
> STRING value and BOOLEAN values look the same.
В смысле? Булеан без кавычек, стринг - всегда в кавычках.
Но как хочешь, тут настаивать не буду.
> > В остальном - ОК.
>
> Diff:
>
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index 32f4ae0b6..7cff881c0 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -1163,6 +1163,10 @@ sqlValueText(sql_value * pVal)
> return valueToText(pVal);
> }
>
> +enum {
> + DIAG_STR_LEN_MAX = 80,
Но это же не длина диага. Не сильно лучше получилось.
Давай что-нибудь в духи SQL_VALUE_DIAG_LEN_MAX и комментарий
что это такое и почему 80..
> +};
> +
> const char *
> sql_value_to_diag_str(sql_value *value)
> {
> @@ -1172,7 +1176,7 @@ sql_value_to_diag_str(sql_value *value)
> char *str = (char *)sqlValueText(value);
> if (str == NULL)
> return "NULL";
> - if (strlen(str) < 80)
> + if (strlen(str) < DIAG_STR_LEN_MAX)
> return tt_sprintf("'%s' (type: %s)", str, type);
> return tt_sprintf("'%.80s...' (type: %s)", str, type);
У тебя в принте осталась эта константа. Посмотри на магию %.*s
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-07-05 14:28 ` Mergen Imeev
@ 2020-07-06 22:06 ` Nikita Pettik
2020-07-07 11:26 ` Mergen Imeev
0 siblings, 1 reply; 32+ messages in thread
From: Nikita Pettik @ 2020-07-06 22:06 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 05 Jul 17:28, Mergen Imeev wrote:
> On Mon, Jun 29, 2020 at 12:56:30PM +0000, Nikita Pettik wrote:
> > On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > > index f7681640e..a2147b0e8 100755
> > > --- a/test/sql-tap/in3.test.lua
> > > +++ b/test/sql-tap/in3.test.lua
> > > @@ -1,6 +1,6 @@
> > > #!/usr/bin/env tarantool
> > > test = require("sqltester")
> > > -test:plan(29)
> > > +test:plan(28)
> > >
> > > --!./tcltestrunner.lua
> > > -- 2007 November 29
> > > @@ -322,18 +322,6 @@ test:do_test(
> > > -- </in3-3.2>
> > > })
> > >
> > > -test:do_test(
> > > - "in3-3.3",
> > > - function()
> > > - -- Logically, numeric affinity is applied to both sides before
> > > - -- the comparison, but index can't be used.
> > > - return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
> > > - end, {
> > > - -- <in3-3.3>
> > > - 1, true
> > > - -- </in3-3.3>
> > > - })
> > > -
> >
> > I'd rather not drop this test. It's about scalar-numeric types
> > interaction. Mb it is not the most suitable place for such test,
> > but make sure this scenario is covered somewhere else.
> >
> I added a few tests with SCALARS in 'sql: remove implicit
> cast for comparison' commit. However, there is a lot
> problems with SCALARS at the moment.
Давай с этим что-то делать. Проблемы где-то описаны? Если нет,
давай подробно разберем и заведем тикет(ы). Иначе это звучит как
"idgs потом кто-нибудь это разгребет". В тикете 4230 есть
пункт про скаляр, но мы почему-то обходим его, оставляя
проблему as is.
> > The rest is OK as obvious.
> >
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison
2020-07-05 14:47 ` Mergen Imeev
@ 2020-07-06 23:11 ` Nikita Pettik
0 siblings, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-06 23:11 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 05 Jul 17:47, Mergen Imeev wrote:
> My answers and new patch below.
>
> On Mon, Jun 29, 2020 at 11:51:29PM +0000, Nikita Pettik wrote:
> > On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > > Thank you for review! My answers and new patch below.
> > >
> > > On 22.06.2020 15:25, Nikita Pettik wrote:
> > > > On 17 Jun 15:36, imeevma@tarantool.org wrote:
> > > >> @@ -2399,14 +2387,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
> > > >> default: res2 = res>=0; break;
> > > >> }
> > > >>
> > > >> - /* Undo any changes made by mem_apply_type() to the input registers. */
> > > >> - assert((pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn));
> > > >> - pIn1->flags = flags1;
> > > >> - pIn1->field_type = ft_p1;
> > > >> - assert((pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn));
> > > >> - pIn3->flags = flags3;
> > > >> - pIn3->field_type = ft_p3;
> > > >> -
> > > >
> > > > Replace these assertions with relevant ones.
> > > >
> > > Not sure if this is necessary, since now we have much less flag
> > > changes after removal of mem_apply_type().
> >
> > Не понял как это связано...Твои изменения не затрагивают
> > инвариант MEM_Dyn.
> >
> True, however original asserts checked that
> mem_apply_type() does not changed it. Now we can say that
> it definitely won't be changed. I can return flags*
> variables for the sake of these asserts. Should I do this?
>
> Also, after #4906 these asserts become outdated since flags
> of the mems won't change at all. Well, it will be so if we
> close #4906.
У этого тикета даже майлстоуна нет, если что.
> > > @@ -4744,7 +4753,25 @@ case OP_IdxGE: { /* jump */
> > > assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
> > > r.default_rc = 0;
> > > }
> > > +
> > > + /*
> > > + * Make sure that the types of all the fields in the tuple
> > > + * that will be used in the iterator comparable with the
> > > + * fields of the space.
> > > + */
> > > r.aMem = &aMem[pOp->p3];
> > > + for (int i = 0; i < r.nField; ++i) {
> > > + enum field_type type = r.key_def->parts[i].type;
> > > + struct Mem *mem = &r.aMem[i];
> >
> > Как-то мне эти два места (выше в SeekGE) вообще не нравятся.
> > Какие-то они запутанные. Давай подумаем как можно зарефакторить их.
> >
> Moved to a new function. However, previously cast
> here didn't always worked since in some cases field_type
> and MEM_type of the mem not always were compatible. I think
> this was fixed in previous commits. All tests passes.
>
> However, there is another possiblity: it may be that I
> already removed tests that fail on convertion but worked
> on check. I do not think that it is the case though.
Свят-свят. Давай подробнее. То что все тесты (которые перекромсали
десять раз) ходят - не особо важно. Катить в релиз что-то над чем
есть сомнения - не лучшая идея.
> This also can be fully fixed in #4906 issue.
Как?! Тот тикет про рефакторинг!
> > > + if (mem_check_type(mem, type) == 0)
> > > + continue;
> > > + if (sql_type_is_numeric(type) &&
> > > + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) != 0)
> > > + continue;
> > > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> > > + field_type_strs[type], mem_type_to_str(mem));
> > > + goto abort_due_to_error;
> > > + }
> > > #ifdef SQL_DEBUG
> > > { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> > > #endif
> > > diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
> > > index 6d8768865..1d7c76670 100644
> > > --- a/src/box/sql/wherecode.c
> > > +++ b/src/box/sql/wherecode.c
> > > @@ -335,72 +335,6 @@ disableTerm(WhereLevel * pLevel, WhereTerm * pTerm)
> > > }
> > > }
> > >
> > > -/**
> > > - * Code an OP_ApplyType opcode to apply the column type string
> > > - * @types to the n registers starting at @base.
> > > - *
> > > - * As an optimization, SCALAR entries (which are no-ops) at the
> > > - * beginning and end of @types are ignored. If all entries in
> > > - * @types are SCALAR, then no code gets generated.
> > > - *
> > > - * This routine makes its own copy of @types so that the caller is
> > > - * free to modify @types after this routine returns.
> > > - */
> > > -static void
> > > -emit_apply_type(Parse *pParse, int base, int n, enum field_type *types)
> >
> > Ты в следующем коммите как раз делаешь клин-ап. Давай эту функцию
> > там и удалим (как и остальные).
> >
> It is a bit troublesome since the functions I remove here
> are 'static'. I think, that instead of removing 'static'
> keyword here and removing the function in the next commit
> it is better to just remove these runctions here.
>
> I can change it if you think that removing in two commits
> is better.
>
> commit f52e6669146e7a06b78d167abf369d67d9327789
> Author: Mergen Imeev <imeevma@gmail.com>
> Date: Thu Jun 25 12:39:19 2020 +0300
>
> sql: remove implicit cast for comparison
>
> This patch removes implicit cast for comparison.
>
> Closes #4230
>
> @TarantoolBot document
> Title: remove implicit cast for comparison
>
> After this patch-set, there will be no implicit casts for
> comparison. This means that the values of the field types STRING,
> BOOLEAN and VARBINARY can be compared with the values of the same
Непечатные символы в тексте, проверь.
> field type. Any numerical value can be compared with any other
> numerical value.
>
> Example:
>
> For comparison:
> ```
> tarantool> box.execute([[SELECT '1' > 0;]])
> ---
> - null
> - "Type mismatch: can not convert '1' (type: text) to numeric"
> ...
>
> tarantool> box.execute([[SELECT true > X'33';]])
> ---
> - null
> - 'Type mismatch: can not convert ''TRUE'' (type: boolean) to varbinary'
> ...
>
> tarantool> box.execute([[SELECT 1.23 > 123;]])
> ---
> - metadata:
> - name: 1.23 > 123
> type: boolean
> rows:
> - [false]
> ...
> ```
>
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index ce9edaad9..0d3da49d3 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -561,6 +561,50 @@ mem_convert_to_numeric(struct Mem *mem, enum field_type type, bool is_precise)
> return mem_convert_to_integer(mem, is_precise);
> }
>
> +/**
> + * Check that MEM types of mems are compatible with the
> + * corresponding types from key_def.
Так compatible или comparable?
> + * If mem and type are comparable but incompatible according to
> + * field_mp_plain_type_is_compatible() and the comparison
> + * operation is EQ, we can say that the result of the comparison
> + * will be FALSE. This allows us to compare DOUBLE and INTEGER
Почему false? Не очевидно.
> + * values.
> + *
> + * @param mems The first mem of the array.
> + * @param def key_def that contains types to check.
> + * @param size Size of the array.
> + * @param is_op_eq TRUE is comparison operator is EQ.
-> if. Как на результат совместимости типов влияет оператор сравнения?
> + * @param[out] is_not_converted TRUE if operation is EQ and mem
> + and type are comparable but not
> + compatible. FALSE otherwise.
Ты просто перечислил условия, при котором выставляешь этот флаг.
Какой смысл в этом комментарии?
> + * @retval TRUE if the MEM types and types from key_def are
> + * comparable, FALSE otherwise.
Ты про диаг забыл...
> + */
> +static bool
> +mem_are_types_comparable(struct Mem *mems, struct key_def *def, uint32_t size,
> + bool is_op_eq, bool *is_not_converted) {
Извини, но в этой функции плохо просто все. Давай по порядку:
- название: почему mem_are? Откуда types, если там кей деф. Сайз чего?
Что значит is_not_converted, если ты просто делаешь проверку на
совместимость?
- предполагается, что функция что-то проверяет и возвращает как
следствие результат проверки (_are_). Но почему-то она еще и
диаг выставляет. Не надо так.
> + assert(!is_op_eq || !*is_not_converted);
- зачем тебе два флага, которые друг на друга как-то нетривиально
завязаны, причем в половине вызовов (1 из 2) они вообще не использу-
ются?
> + for (uint32_t i = 0; i < size; ++i) {
- где ассерт i < def->part_count ?
> + enum field_type type = def->parts[i].type;
> + struct Mem *mem = &mems[i];
> + if (mem_is_type_compatible(mem, type))
> + continue;
> + if (mem_convert_to_numeric(mem, type, true) == 0)
> + continue;
> + if (sql_type_is_numeric(type) &&
> + (mem->flags & (MEM_Int | MEM_UInt | MEM_Real)) != 0) {
> + if (is_op_eq)
> + *is_not_converted = true;
> + continue;
> + }
- тут вообще не понятно что происходит - тройной if с выставлением
выходного параметра. Я честно говорю, что я не понимаю что тут происходит.
sql_type_is_numeric() уже вызывается в mem_convert_to_numeric()...
Давай на днях вместе сядем и подумаем как это все исправить.
> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> + field_type_strs[type], mem_type_to_str(mem));
> + return false;
> + }
> + return true;
> +}
> +
> @@ -3623,7 +3645,20 @@ skip_truncate:
> assert(oc!=OP_SeekGE || r.default_rc==+1);
> assert(oc!=OP_SeekLT || r.default_rc==+1);
>
> + /*
> + * Make sure that the types of all the fields in the tuple
> + * that will be used in the iterator match the field types
> + * of the space.
> + */
> r.aMem = &aMem[pOp->p3];
> + bool is_not_found = false;
Не очень логично, что функция проверяющая на совместимость типов, еще
принимает флаг is_not_found..?? Что она ищет?
> + if (!mem_are_types_comparable(r.aMem, r.key_def, r.nField, eqOnly == 1,
> + &is_not_found))
> + goto abort_due_to_error;
> + if (is_not_found) {
> + res = 1;
> + goto seek_not_found;
> + }
> #ifdef SQL_DEBUG
> { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> #endif
> @@ -4750,7 +4785,16 @@ case OP_IdxGE: { /* jump */
> assert(pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT);
> r.default_rc = 0;
> }
> +
> + /*
> + * Make sure that the types of mems are comparable with
> + * the field types of the space.
> + */
> r.aMem = &aMem[pOp->p3];
> + bool unused = false;
> + if (!mem_are_types_comparable(r.aMem, r.key_def, r.nField, false,
> + &unused))
> + goto abort_due_to_error;
> #ifdef SQL_DEBUG
> { int i; for(i=0; i<r.nField; i++) assert(memIsValid(&r.aMem[i])); }
> #endif
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-07-06 21:27 ` Nikita Pettik
@ 2020-07-07 9:29 ` Mergen Imeev
2020-07-07 15:35 ` Nikita Pettik
2020-07-10 10:49 ` Nikita Pettik
0 siblings, 2 replies; 32+ messages in thread
From: Mergen Imeev @ 2020-07-07 9:29 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
On 07.07.2020 00:27, Nikita Pettik wrote:
> On 05 Jul 17:26, Mergen Imeev wrote:
>> Hi! Thank you for the review. My answers and new patch
>> below. Sorry, I didn't include diff.
>>>> commit 21d7145c1929bc4606c56e9a566477f248637ed1
>>>> Author: Mergen Imeev <imeevma@gmail.com>
>>>> Date: Wed May 27 13:49:11 2020 +0300
>>>>
>>>> + if (field_mp_plain_type_is_compatible(type, mp_type, true))
>>>> + return 0;
>>>> + return -1;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Convert the numeric value contained in MEM to double. If the
>>>> + * is_precise flag is set, the conversion will succeed only if it
>>>> + * is lossless.
>>>> + *
>>>> + * @param mem The MEM that contains the numeric value.
>>>> + * @param is_precise Flag.
>>>> + * @retval 0 if the conversion was successful, -1 otherwise.
>>>> + */
>>>> +static int
>>>> +mem_convert_to_double(struct Mem *mem, bool is_precise)
>>>> +{
>>>> + if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
>>>> + return -1;
>>>> + if ((mem->flags & MEM_Int) != 0) {
>>>> + int64_t i = mem->u.i;
>>>> + double d = (double)i;
>>>> + if (!is_precise || i == (int64_t)d)
>>>> + mem_set_double(mem, d);
>>>> + else
>>>> + return -1;
>>>> + } else {
>>>> + uint64_t u = mem->u.u;
>>>> + double d = (double)u;
>>>> + if (!is_precise || u == (uint64_t)d)
>>>> + mem_set_double(mem, d);
>>>> + else
>>>> + return -1;
>>>> + }
>>>> + mem->field_type = FIELD_TYPE_DOUBLE;
>>> Why not incorparate field_type assingment into mem_set_double()?
>>> The same concerns other converting functions.
>>>
>> I think this should be done in #4906 issue since it may
>> lead to not always simple to understand changes.
> Эм, не очень понял как трактовать твой ответ. Типо тут работает,
> а если там засунуть, то что-то начинает падать..? 4906 немного про
> другое: в любом случае у нас в меме будет и field_type и mp_type.
> К тому же, и то, и это - рефакторинг и функциональных изменений быть
> не должно.
Не уверен, что это чистый рефакторинг, т.к. точно помны возникала
проблема с тем, что MEM_type мог быть не совместимым с field_type
т.к. field_type не изменился при переписывании мема.
Стоит сделать это изменение для mem_set_* отдельным тикетом?
>
>>>> +/**
>>>> + * Convert the numeric value contained in MEM to another numeric
>>>> + * type. If the is_precise flag is set, the conversion will
>>>> + * succeed only if it is lossless.
>>>> + * @param mem The MEM that contains the numeric value.
>>>> + * @param type The type to convert to.
>>>> + * @param is_precise Flag.
>>>> + * @retval 0 if the conversion was successful, -1 otherwise.
>>>> + */
>>>> +static int
>>>> +mem_convert_numeric(struct Mem *mem, enum field_type type, bool is_precise)
>>> mem_convert_to_numeric ?
>>> mem_cast_to_numeric
>>>
>> Used first option.
>>
>>>> +{
>>>> + if (!sql_type_is_numeric(type) ||
>>>> + (mem->flags & (MEM_Real | MEM_Int | MEM_UInt)) == 0)
>>> It's somehow unnatural passing to _numeric function non-numeric type
>>> to convert to. Instead let's use this function properly and replace
>>> branching with assertion.
>>>
>> No, I think it is good as it is. More that that, due to
>> some other comments I added similar checks to all other
>> mem_convert_to>* functions.
> В остальных случаях ты туда тип вообще не передаешь.
>
>> My reason is: in all places we use this function we have
>> to check that field type and MEM_type are numeric, so it
>> make sence to move this check inside of the function.
> Еще раз: это полный идиотизм передавать ТИП (отличный от нумерика) к
> которому ты собираешься кастовать в функцию, которая по названию
> предполагает каст к нумерику. Считай, что я настаиваю на этом
> изменении.
Сделаю.
>>>> + return -1;
>>>> + if (type == FIELD_TYPE_NUMBER)
>>>> + return 0;
>>>> + if (type == FIELD_TYPE_DOUBLE)
>>>> + return mem_convert_to_double(mem, is_precise);
>>>> + if (type == FIELD_TYPE_UNSIGNED)
>>>> + return mem_convert_to_unsigned(mem, is_precise);
>>>> + assert(type == FIELD_TYPE_INTEGER);
>>>> + return mem_convert_to_integer(mem, is_precise);
>>>> +}
>>>> +
>>>> /*
>> index 37283e506..bd0055668 100644
>> --- a/src/box/sql/sqlInt.h
>> +++ b/src/box/sql/sqlInt.h
>> @@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
>> enum mp_type
>> sql_value_type(sql_value *);
>>
>> +/*
>> + * Return the MP_type of the value of the MEM.
>> + *
>> + * @param mem MEM with the correct MEM_type.
>> + * @retval MP_type of the value.
>> + */
>> +enum mp_type
>> +mem_mp_type(struct Mem *mem);
> Я вытащил добавление этой функции в отдельный патч и добавил
> рефакторинг чтобы соеденить ее с sql_value_type().
> https://github.com/tarantool/tarantool/tree/np/gh-3809-remastered
>
> Если ты ОК, я пушну вне очереди в мастер.
Я ОК.
>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index 950f72ddd..1386ea2c0 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> + uint64_t u = mem->u.u;
>> + double d = (double)u;
>> + if (!is_precise || u == (uint64_t)d)
>> + mem_set_double(mem, d);
>> + else
>> + return -1;
>> + }
>> + mem->field_type = FIELD_TYPE_DOUBLE;
>> + return 0;
>> +}
>> +
>> + * P1 are compatible with given field types in P4.
>> + * If the MEM_type of the value and the given type are
>> + * incompatible according to field_mp_plain_type_is_compatible(),
>> + * but both are numeric, this opcode attempts to convert the value
>> + * to the type.
>> + */
>> +case OP_ImplicitCast: {
>> + enum field_type *types = pOp->p4.types;
>> + assert(types != NULL);
>> + assert(types[pOp->p2] == field_type_MAX);
>> + for (int i = 0; types[i] != field_type_MAX; ++i) {
>> + enum field_type type = types[i];
>> + pIn1 = &aMem[pOp->p1 + i];
>> + assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
>> + assert(memIsValid(pIn1));
>> + if (mem_is_type_compatible(pIn1, type))
>> + continue;
>> + if (mem_convert_to_numeric(pIn1, type, false) == 0)
> Инвертируй, пожайлуйста условие:
>
> if (mem_convert_to_numeric(pIn1, type, false) !=) {
> //raise an error
> }
>
> Это будет больще соответствовать нашему кодстайлу.
Сделаю.
>> + continue;
>> + diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>> + sql_value_to_diag_str(pIn1), field_type_strs[type]);
>> + goto abort_due_to_error;
>> + }
>> + break;
>> +}
>> +
>> /* Opcode: MakeRecord P1 P2 P3 P4 P5
>> * Synopsis: r[P3]=mkrec(r[P1@P2])
>> *
>> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
>> index 4e103a653..b106ce6bd 100644
>> --- a/src/box/sql/vdbeapi.c
>> +++ b/src/box/sql/vdbeapi.c
>> @@ -225,6 +225,33 @@ sql_value_type(sql_value *pVal)
>> }
>> }
>>
>> +enum mp_type
>> +mem_mp_type(struct Mem *mem)
> Еще раз: это не апишная функция (хотя бы в терминологии скулайта),
> ей место скорее в vdbemem.c. См. мой рефакторинг.
>
>> +{
>> --- a/test/sql-tap/autoinc.test.lua
>> +++ b/test/sql-tap/autoinc.test.lua
> Тесты не смотрел, предполагая что нет изменений по сравнению с
> предыдущей версией.
>
Да, тесты не изменились.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-07-06 22:06 ` Nikita Pettik
@ 2020-07-07 11:26 ` Mergen Imeev
2020-07-07 16:29 ` Nikita Pettik
0 siblings, 1 reply; 32+ messages in thread
From: Mergen Imeev @ 2020-07-07 11:26 UTC (permalink / raw)
To: Nikita Pettik; +Cc: tarantool-patches
On 07.07.2020 01:06, Nikita Pettik wrote:
> On 05 Jul 17:28, Mergen Imeev wrote:
>> On Mon, Jun 29, 2020 at 12:56:30PM +0000, Nikita Pettik wrote:
>>> On 25 Jun 18:17, imeevma@tarantool.org wrote:
>>>> index f7681640e..a2147b0e8 100755
>>>> --- a/test/sql-tap/in3.test.lua
>>>> +++ b/test/sql-tap/in3.test.lua
>>>> @@ -1,6 +1,6 @@
>>>> #!/usr/bin/env tarantool
>>>> test = require("sqltester")
>>>> -test:plan(29)
>>>> +test:plan(28)
>>>>
>>>> --!./tcltestrunner.lua
>>>> -- 2007 November 29
>>>> @@ -322,18 +322,6 @@ test:do_test(
>>>> -- </in3-3.2>
>>>> })
>>>>
>>>> -test:do_test(
>>>> - "in3-3.3",
>>>> - function()
>>>> - -- Logically, numeric affinity is applied to both sides before
>>>> - -- the comparison, but index can't be used.
>>>> - return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
>>>> - end, {
>>>> - -- <in3-3.3>
>>>> - 1, true
>>>> - -- </in3-3.3>
>>>> - })
>>>> -
>>> I'd rather not drop this test. It's about scalar-numeric types
>>> interaction. Mb it is not the most suitable place for such test,
>>> but make sure this scenario is covered somewhere else.
>>>
>> I added a few tests with SCALARS in 'sql: remove implicit
>> cast for comparison' commit. However, there is a lot
>> problems with SCALARS at the moment.
> Давай с этим что-то делать. Проблемы где-то описаны? Если нет,
> давай подробно разберем и заведем тикет(ы). Иначе это звучит как
> "idgs потом кто-нибудь это разгребет". В тикете 4230 есть
> пункт про скаляр, но мы почему-то обходим его, оставляя
> проблему as is.
Создал тикет: https://github.com/tarantool/tarantool/issues/5148
В последнем письме ("Re: Check implicit cast between strings and
numbers") Гулузан тоже согласен с тем, что по скалярам мы не
договорились.
>
>>> The rest is OK as obvious.
>>>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-07-07 9:29 ` Mergen Imeev
@ 2020-07-07 15:35 ` Nikita Pettik
2020-07-10 10:49 ` Nikita Pettik
1 sibling, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-07 15:35 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 07 Jul 12:29, Mergen Imeev wrote:
>
> On 07.07.2020 00:27, Nikita Pettik wrote:
> > On 05 Jul 17:26, Mergen Imeev wrote:
> > > Hi! Thank you for the review. My answers and new patch
> > > below. Sorry, I didn't include diff.
> > > > > commit 21d7145c1929bc4606c56e9a566477f248637ed1
> > > > > Author: Mergen Imeev <imeevma@gmail.com>
> > > > > Date: Wed May 27 13:49:11 2020 +0300
> > > > >
> > > > > + if (field_mp_plain_type_is_compatible(type, mp_type, true))
> > > > > + return 0;
> > > > > + return -1;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Convert the numeric value contained in MEM to double. If the
> > > > > + * is_precise flag is set, the conversion will succeed only if it
> > > > > + * is lossless.
> > > > > + *
> > > > > + * @param mem The MEM that contains the numeric value.
> > > > > + * @param is_precise Flag.
> > > > > + * @retval 0 if the conversion was successful, -1 otherwise.
> > > > > + */
> > > > > +static int
> > > > > +mem_convert_to_double(struct Mem *mem, bool is_precise)
> > > > > +{
> > > > > + if ((mem->flags & (MEM_Int | MEM_UInt)) == 0)
> > > > > + return -1;
> > > > > + if ((mem->flags & MEM_Int) != 0) {
> > > > > + int64_t i = mem->u.i;
> > > > > + double d = (double)i;
> > > > > + if (!is_precise || i == (int64_t)d)
> > > > > + mem_set_double(mem, d);
> > > > > + else
> > > > > + return -1;
> > > > > + } else {
> > > > > + uint64_t u = mem->u.u;
> > > > > + double d = (double)u;
> > > > > + if (!is_precise || u == (uint64_t)d)
> > > > > + mem_set_double(mem, d);
> > > > > + else
> > > > > + return -1;
> > > > > + }
> > > > > + mem->field_type = FIELD_TYPE_DOUBLE;
> > > > Why not incorparate field_type assingment into mem_set_double()?
> > > > The same concerns other converting functions.
> > > >
> > > I think this should be done in #4906 issue since it may
> > > lead to not always simple to understand changes.
> > Эм, не очень понял как трактовать твой ответ. Типо тут работает,
> > а если там засунуть, то что-то начинает падать..? 4906 немного про
> > другое: в любом случае у нас в меме будет и field_type и mp_type.
> > К тому же, и то, и это - рефакторинг и функциональных изменений быть
> > не должно.
> Не уверен, что это чистый рефакторинг, т.к. точно помны возникала
> проблема с тем, что MEM_type мог быть не совместимым с field_type
> т.к. field_type не изменился при переписывании мема.
>
> Стоит сделать это изменение для mem_set_* отдельным тикетом?
Тикетом, патчем, фолоу-апом - как хочешь.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator
2020-07-07 11:26 ` Mergen Imeev
@ 2020-07-07 16:29 ` Nikita Pettik
0 siblings, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-07 16:29 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 07 Jul 14:26, Mergen Imeev wrote:
>
> On 07.07.2020 01:06, Nikita Pettik wrote:
> > On 05 Jul 17:28, Mergen Imeev wrote:
> > > On Mon, Jun 29, 2020 at 12:56:30PM +0000, Nikita Pettik wrote:
> > > > On 25 Jun 18:17, imeevma@tarantool.org wrote:
> > > > > index f7681640e..a2147b0e8 100755
> > > > > --- a/test/sql-tap/in3.test.lua
> > > > > +++ b/test/sql-tap/in3.test.lua
> > > > > @@ -1,6 +1,6 @@
> > > > > #!/usr/bin/env tarantool
> > > > > test = require("sqltester")
> > > > > -test:plan(29)
> > > > > +test:plan(28)
> > > > > --!./tcltestrunner.lua
> > > > > -- 2007 November 29
> > > > > @@ -322,18 +322,6 @@ test:do_test(
> > > > > -- </in3-3.2>
> > > > > })
> > > > > -test:do_test(
> > > > > - "in3-3.3",
> > > > > - function()
> > > > > - -- Logically, numeric affinity is applied to both sides before
> > > > > - -- the comparison, but index can't be used.
> > > > > - return exec_neph(" SELECT x IN (SELECT b FROM t1) FROM t2 ")
> > > > > - end, {
> > > > > - -- <in3-3.3>
> > > > > - 1, true
> > > > > - -- </in3-3.3>
> > > > > - })
> > > > > -
> > > > I'd rather not drop this test. It's about scalar-numeric types
> > > > interaction. Mb it is not the most suitable place for such test,
> > > > but make sure this scenario is covered somewhere else.
> > > >
> > > I added a few tests with SCALARS in 'sql: remove implicit
> > > cast for comparison' commit. However, there is a lot
> > > problems with SCALARS at the moment.
> > Давай с этим что-то делать. Проблемы где-то описаны? Если нет,
> > давай подробно разберем и заведем тикет(ы). Иначе это звучит как
> > "idgs потом кто-нибудь это разгребет". В тикете 4230 есть
> > пункт про скаляр, но мы почему-то обходим его, оставляя
> > проблему as is.
> Создал тикет: https://github.com/tarantool/tarantool/issues/5148
>
> В последнем письме ("Re: Check implicit cast between strings and
> numbers") Гулузан тоже согласен с тем, что по скалярам мы не
> договорились.
Можешь поднять старую переписку? Давай распишем пункты где у нас
не совпадало мнение и придем к консенсусу?
> > > > The rest is OK as obvious.
> > > >
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment
2020-07-07 9:29 ` Mergen Imeev
2020-07-07 15:35 ` Nikita Pettik
@ 2020-07-10 10:49 ` Nikita Pettik
1 sibling, 0 replies; 32+ messages in thread
From: Nikita Pettik @ 2020-07-10 10:49 UTC (permalink / raw)
To: Mergen Imeev; +Cc: tarantool-patches
On 07 Jul 12:29, Mergen Imeev wrote:
>
> On 07.07.2020 00:27, Nikita Pettik wrote:
> > On 05 Jul 17:26, Mergen Imeev wrote:
> > > index 37283e506..bd0055668 100644
> > > --- a/src/box/sql/sqlInt.h
> > > +++ b/src/box/sql/sqlInt.h
> > > @@ -397,6 +397,15 @@ sql_value_to_diag_str(sql_value *value);
> > > enum mp_type
> > > sql_value_type(sql_value *);
> > > +/*
> > > + * Return the MP_type of the value of the MEM.
> > > + *
> > > + * @param mem MEM with the correct MEM_type.
> > > + * @retval MP_type of the value.
> > > + */
> > > +enum mp_type
> > > +mem_mp_type(struct Mem *mem);
> > Я вытащил добавление этой функции в отдельный патч и добавил
> > рефакторинг чтобы соеденить ее с sql_value_type().
> > https://github.com/tarantool/tarantool/tree/np/gh-3809-remastered
> >
> > Если ты ОК, я пушну вне очереди в мастер.
> Я ОК.
Pushed to master as trivial refactoring.
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2020-07-10 10:49 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-25 15:17 [Tarantool-patches] [PATCH v3 0/8] Remove implicit cast imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 1/8] sql: introduce mem_set_double() imeevma
2020-06-28 13:31 ` Nikita Pettik
2020-07-06 14:02 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 2/8] sql: change implicit cast for assignment imeevma
2020-06-30 11:50 ` Nikita Pettik
2020-07-05 14:26 ` Mergen Imeev
2020-07-06 21:27 ` Nikita Pettik
2020-07-07 9:29 ` Mergen Imeev
2020-07-07 15:35 ` Nikita Pettik
2020-07-10 10:49 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 3/8] sql: remove mem_apply_type() from OP_MakeRecord imeevma
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 4/8] sql: replace ApplyType by CheckType for IN operator imeevma
2020-06-29 12:56 ` Nikita Pettik
2020-07-05 14:28 ` Mergen Imeev
2020-07-06 22:06 ` Nikita Pettik
2020-07-07 11:26 ` Mergen Imeev
2020-07-07 16:29 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 5/8] sql: remove mem_apply_type() from OP_MustBeInt imeevma
2020-06-29 13:29 ` Nikita Pettik
2020-07-05 14:29 ` Mergen Imeev
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 6/8] sql: remove implicit cast for comparison imeevma
2020-06-29 23:51 ` Nikita Pettik
2020-07-05 14:47 ` Mergen Imeev
2020-07-06 23:11 ` Nikita Pettik
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 7/8] sql: remove unused functions imeevma
2020-06-29 23:52 ` Nikita Pettik
2020-07-05 14:50 ` Mergen Imeev
2020-06-25 15:17 ` [Tarantool-patches] [PATCH v3 8/8] sql: show value and its type in type mismatch error imeevma
2020-06-30 0:22 ` Nikita Pettik
2020-07-05 15:03 ` Mergen Imeev
2020-07-06 21:44 ` Nikita Pettik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox