From 8482e0c0bc1fa44faa6abf7b7b8a27b77e91db92 Mon Sep 17 00:00:00 2001 From: Mergen Imeev Date: Fri, 16 Nov 2018 14:23:39 +0300 Subject: [PATCH] sql: decode ARRAY and MAP types after SELECT Before this patch MSGPACK received using SELECT statement through net.box was unpacked. Fixed in this patch. --- src/box/execute.c | 22 +++++++++++++++------- test/sql/iproto.result | 32 ++++++++++++++++++++++++++++++++ test/sql/iproto.test.lua | 9 +++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/box/execute.c b/src/box/execute.c index cd809f85ccf5..fb3e08bd301e 100644 --- a/src/box/execute.c +++ b/src/box/execute.c @@ -351,13 +351,21 @@ sql_column_to_messagepack(struct sqlite3_stmt *stmt, int i, } case SQLITE_BLOB: { uint32_t len = sqlite3_column_bytes(stmt, i); - size = mp_sizeof_bin(len); - char *pos = (char *) region_alloc(region, size); - if (pos == NULL) - goto oom; - const char *s; - s = (const char *)sqlite3_column_blob(stmt, i); - mp_encode_bin(pos, s, len); + const char *s = + (const char *)sqlite3_column_blob(stmt, i); + if (sql_column_subtype(stmt, i) == SQL_SUBTYPE_MSGPACK) { + size = len; + char *pos = (char *)region_alloc(region, size); + if (pos == NULL) + goto oom; + memcpy(pos, s, len); + } else { + size = mp_sizeof_bin(len); + char *pos = (char *)region_alloc(region, size); + if (pos == NULL) + goto oom; + mp_encode_bin(pos, s, len); + } break; } case SQLITE_NULL: { diff --git a/test/sql/iproto.result b/test/sql/iproto.result index f229427bd2f5..6c507816f5f5 100644 --- a/test/sql/iproto.result +++ b/test/sql/iproto.result @@ -811,6 +811,38 @@ cn:execute("PRAGMA TABLE_INFO(test);") box.sql.execute('DROP TABLE test') --- ... +-- SELECT returns unpacked msgpack. +format = {{name = 'id', type = 'integer'}, {name = 'x', type = 'any'}} +--- +... +s = box.schema.space.create('test', {format=format}) +--- +... +i1 = s:create_index('i1', {parts = {1, 'int'}}) +--- +... +s:insert({1, {1,2,3}}) +--- +- [1, [1, 2, 3]] +... +s:insert({2, {a = 3}}) +--- +- [2, {'a': 3}] +... +cn:execute('select * from "test"') +--- +- metadata: + - name: id + type: UNKNOWN + - name: x + type: UNKNOWN + rows: + - [1, [1, 2, 3]] + - [2, {'a': 3}] +... +s:drop() +--- +... cn:close() --- ... diff --git a/test/sql/iproto.test.lua b/test/sql/iproto.test.lua index 9bcc7ef0505a..e12decdda4f8 100644 --- a/test/sql/iproto.test.lua +++ b/test/sql/iproto.test.lua @@ -263,6 +263,15 @@ box.sql.execute('CREATE TABLE test (id INT PRIMARY KEY)') cn:execute("PRAGMA TABLE_INFO(test);") box.sql.execute('DROP TABLE test') +-- SELECT returns unpacked msgpack. +format = {{name = 'id', type = 'integer'}, {name = 'x', type = 'any'}} +s = box.schema.space.create('test', {format=format}) +i1 = s:create_index('i1', {parts = {1, 'int'}}) +s:insert({1, {1,2,3}}) +s:insert({2, {a = 3}}) +cn:execute('select * from "test"') +s:drop() + cn:close() box.schema.user.revoke('guest', 'read,write,execute', 'universe')