Tarantool development patches archive
 help / color / mirror / Atom feed
From: imeevma@tarantool.org
To: korablev@tarantool.org
Cc: tarantool-patches@freelists.org
Subject: [tarantool-patches] [PATCH v2 2/2] sql: fix error in case ARRAY/MAP converted to SCALAR
Date: Wed, 24 Jul 2019 11:12:03 +0300	[thread overview]
Message-ID: <67e721f4818f51861383cdf71cc88c63e45ab450.1563955619.git.imeevma@gmail.com> (raw)
In-Reply-To: <cover.1563955619.git.imeevma@gmail.com>

Since ARRAY and MAP cannot be converted to a scalar, this
operation should throw an error. But when the error was throws
from SQL, the error was unreadable. The reason for this is that
the given array or map was not correctly converted to a string.
This patch fixes the problem by printing an 'array' or 'map' in
case of an error due to a conversion from ARRAY or MAP,
respectively.
For example:

box.execute('CREATE TABLE t1(i INT PRIMARY KEY, a SCALAR);')
format = {}
format[1] = {type = 'integer', name = 'I'}
format[2] = {type = 'array', name = 'A'}
s = box.schema.space.create('T2', {format=format})
i = s:create_index('ii')
s:insert({1, {1,2,3}})
box.execute('INSERT INTO t1 SELECT * FROM t2;')

Should return:
- error: 'Type mismatch: can not convert array to scalar'

Follow-up #4189
---
 src/box/sql/vdbe.c      | 13 +++++++++--
 test/sql/types.result   | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 test/sql/types.test.lua | 22 ++++++++++++++++++
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 1200ff4..f6aaaa6 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2704,8 +2704,17 @@ case OP_ApplyType: {
 		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_text(pIn1),
+			const char *value;
+			if ((pIn1->flags & MEM_Subtype) != 0 &&
+			    pIn1->subtype == SQL_SUBTYPE_MSGPACK) {
+				if (mp_typeof(*pIn1->z) == MP_MAP)
+					value = "map";
+				else
+					value = "array";
+			} else {
+				value = (const char *)sql_value_text(pIn1);
+			}
+			diag_set(ClientError, ER_SQL_TYPE_MISMATCH, value,
 				 field_type_strs[type]);
 			goto abort_due_to_error;
 		}
diff --git a/test/sql/types.result b/test/sql/types.result
index 0dba69f..61a760f 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -1153,3 +1153,65 @@ s:select()
 s:drop()
 ---
 ...
+--
+-- Make sure that the array/map conversion to scalar error is
+-- displayed correctly.
+--
+box.execute('DROP TABLE IF EXISTS t1;')
+---
+- row_count: 1
+...
+box.execute('CREATE TABLE t1(i INT PRIMARY KEY AUTOINCREMENT, a SCALAR);')
+---
+- row_count: 1
+...
+format = {}
+---
+...
+format[1] = {type = 'integer', name = 'I'}
+---
+...
+format[2] = {type = 'array', name = 'A'}
+---
+...
+s = box.schema.space.create('T2', {format=format})
+---
+...
+i = s:create_index('ii')
+---
+...
+s:insert({1, {1,2,3}})
+---
+- [1, [1, 2, 3]]
+...
+box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
+---
+- error: 'Type mismatch: can not convert array to scalar'
+...
+s:drop()
+---
+...
+format[2].type = 'map'
+---
+...
+s = box.schema.space.create('T2', {format=format})
+---
+...
+i = s:create_index('ii')
+---
+...
+s:insert({1, {b = 1}})
+---
+- [1, {'b': 1}]
+...
+box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
+---
+- error: 'Type mismatch: can not convert map to scalar'
+...
+s:drop()
+---
+...
+box.execute('DROP TABLE t1;')
+---
+- row_count: 1
+...
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index 22cb105..a99cc9f 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -291,3 +291,25 @@ s:insert({1, true, {1, 2}, {a = 3}, 'asd'})
 box.execute('UPDATE t SET b = false WHERE i = 1;')
 s:select()
 s:drop()
+
+--
+-- Make sure that the array/map conversion to scalar error is
+-- displayed correctly.
+--
+box.execute('DROP TABLE IF EXISTS t1;')
+box.execute('CREATE TABLE t1(i INT PRIMARY KEY AUTOINCREMENT, a SCALAR);')
+format = {}
+format[1] = {type = 'integer', name = 'I'}
+format[2] = {type = 'array', name = 'A'}
+s = box.schema.space.create('T2', {format=format})
+i = s:create_index('ii')
+s:insert({1, {1,2,3}})
+box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
+s:drop()
+format[2].type = 'map'
+s = box.schema.space.create('T2', {format=format})
+i = s:create_index('ii')
+s:insert({1, {b = 1}})
+box.execute('INSERT INTO t1(a) SELECT a FROM t2;')
+s:drop()
+box.execute('DROP TABLE t1;')
-- 
2.7.4

  parent reply	other threads:[~2019-07-24  8:12 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-24  8:11 [tarantool-patches] [PATCH v2 0/2] sql: add ARRAY, MAP and ANY types to mem_apply_type() imeevma
2019-07-24  8:12 ` [tarantool-patches] [PATCH v2 1/2] " imeevma
2019-07-24  8:12 ` imeevma [this message]
2019-07-24 12:24   ` [tarantool-patches] Re: [PATCH v2 2/2] sql: fix error in case ARRAY/MAP converted to SCALAR n.pettik
2019-07-24 22:37     ` Konstantin Osipov
2019-07-24 23:30       ` n.pettik
2019-07-27 10:16     ` Mergen Imeev
2019-08-07 18:25       ` n.pettik
2019-08-28 13:30         ` Mergen Imeev
2019-08-29 12:19           ` Nikita Pettik
2019-09-02 13:53             ` Mergen Imeev
2019-09-10 13:54               ` korablev
2019-09-11  8:13                 ` Mergen Imeev
2019-09-11  9:25                   ` Nikita Pettik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67e721f4818f51861383cdf71cc88c63e45ab450.1563955619.git.imeevma@gmail.com \
    --to=imeevma@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH v2 2/2] sql: fix error in case ARRAY/MAP converted to SCALAR' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

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