From: imeevma@tarantool.org To: korablev@tarantool.org Cc: tarantool-patches@freelists.org Subject: [tarantool-patches] [PATCH v2 1/2] sql: add ARRAY, MAP and ANY types to mem_apply_type() Date: Wed, 24 Jul 2019 11:12:01 +0300 [thread overview] Message-ID: <c443305812bd82f5535bb9978a63870c1b74e93f.1563955619.git.imeevma@gmail.com> (raw) In-Reply-To: <cover.1563955619.git.imeevma@gmail.com> Function mem_apply_type() implements implicit type conversion. As a rule, tuple to be inserted to the space is exposed to this conversion which is invoked during execution of OP_MakeRecord opcode (which in turn forms tuple). This function was not adjusted to operate on ARRAY, MAP and ANY field types since they are poorly supported in current SQL implementation. Hence, when tuple to be inserted in space having mentioned field types reaches this function, it results in error. Note that we can't set ARRAY or MAP types in SQL, but such situation may appear during UPDATE operation on space created via Lua interface. This problem is solved by extending implicit type conversions with obvious casts: array field can be casted to array, map to map and any to any. Closes #4189 --- src/box/sql/vdbe.c | 35 ++++++++++++++++++++++++++++++++++- test/sql/types.result | 40 ++++++++++++++++++++++++++++++++++++++++ test/sql/types.test.lua | 15 +++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 6a4a303..1200ff4 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -292,7 +292,19 @@ mem_apply_numeric_type(struct Mem *record) * Convert mem to a string representation. * * SCALAR: - * Mem is unchanged, but flag is set to BLOB. + * Mem is unchanged, but flag is set to BLOB in case of + * scalar-like type. Otherwise, (MAP, ARRAY) conversion + * is impossible. + * + * BOOLEAN: + * If memory holds BOOLEAN no actions take place. + * + * ANY: + * Mem is unchanged, no actions take place. + * + * MAP/ARRAY: + * These types can't be casted to scalar ones, or to each + * other. So the only valid conversion is to type itself. * * @param record The value to apply type to. * @param type The type to be applied. @@ -338,6 +350,27 @@ mem_apply_type(struct Mem *record, enum field_type type) record->flags &= ~(MEM_Real | MEM_Int); return 0; case FIELD_TYPE_SCALAR: + /* Can't cast MAP and ARRAY to scalar types. */ + if ((record->flags & MEM_Subtype) != 0 && + record->subtype == SQL_SUBTYPE_MSGPACK) { + assert(mp_typeof(*record->z) == MP_MAP || + mp_typeof(*record->z) == MP_ARRAY); + return -1; + } + return 0; + case FIELD_TYPE_MAP: + if ((record->flags & MEM_Subtype) != 0 && + record->subtype == SQL_SUBTYPE_MSGPACK && + mp_typeof(*record->z) == MP_MAP) + return 0; + return -1; + case FIELD_TYPE_ARRAY: + if ((record->flags & MEM_Subtype) != 0 && + record->subtype == SQL_SUBTYPE_MSGPACK && + mp_typeof(*record->z) == MP_ARRAY) + return 0; + return -1; + case FIELD_TYPE_ANY: return 0; default: return -1; diff --git a/test/sql/types.result b/test/sql/types.result index 5abe6e0..0dba69f 100644 --- a/test/sql/types.result +++ b/test/sql/types.result @@ -1110,6 +1110,46 @@ box.execute("SELECT a FROM t1 WHERE a IN (1.1, 2.1);") type: unsigned rows: [] ... +-- +-- gh-4189: make sure that update doesn't throw an error if format +-- of table features map/array field types. +-- +format = {} +--- +... +format[1] = {type = 'integer', name = 'I'} +--- +... +format[2] = {type = 'boolean', name = 'B'} +--- +... +format[3] = {type = 'array', name = 'F1'} +--- +... +format[4] = {type = 'map', name = 'F2'} +--- +... +format[5] = {type = 'any', name = 'F3'} +--- +... +s = box.schema.space.create('T', {format = format}) +--- +... +ii = s:create_index('ii') +--- +... +s:insert({1, true, {1, 2}, {a = 3}, 'asd'}) +--- +- [1, true, [1, 2], {'a': 3}, 'asd'] +... +box.execute('UPDATE t SET b = false WHERE i = 1;') +--- +- row_count: 1 +... +s:select() +--- +- - [1, false, [1, 2], {'a': 3}, 'asd'] +... s:drop() --- ... diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua index 410864a..22cb105 100644 --- a/test/sql/types.test.lua +++ b/test/sql/types.test.lua @@ -275,4 +275,19 @@ _ = s:create_index('sk', { parts = { 'A' } }) s:insert({ 1, 1 }) box.execute("SELECT a FROM t1 WHERE a IN (1.1, 2.1);") +-- +-- gh-4189: make sure that update doesn't throw an error if format +-- of table features map/array field types. +-- +format = {} +format[1] = {type = 'integer', name = 'I'} +format[2] = {type = 'boolean', name = 'B'} +format[3] = {type = 'array', name = 'F1'} +format[4] = {type = 'map', name = 'F2'} +format[5] = {type = 'any', name = 'F3'} +s = box.schema.space.create('T', {format = format}) +ii = s:create_index('ii') +s:insert({1, true, {1, 2}, {a = 3}, 'asd'}) +box.execute('UPDATE t SET b = false WHERE i = 1;') +s:select() s:drop() -- 2.7.4
next prev 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] " imeevma 2019-07-24 8:12 ` imeevma [this message] 2019-07-24 8:12 ` [tarantool-patches] [PATCH v2 2/2] sql: fix error in case ARRAY/MAP converted to SCALAR imeevma 2019-07-24 12:24 ` [tarantool-patches] " 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=c443305812bd82f5535bb9978a63870c1b74e93f.1563955619.git.imeevma@gmail.com \ --to=imeevma@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH v2 1/2] sql: add ARRAY, MAP and ANY types to mem_apply_type()' \ /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