From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: Imeev Mergen <imeevma@tarantool.org>,
"n.pettik" <korablev@tarantool.org>,
tarantool-patches@freelists.org
Subject: [tarantool-patches] Re: [PATCH 1/3] sql: EXPLAIN through net.box leads to SEGFAULT
Date: Thu, 22 Nov 2018 21:31:14 +0300 [thread overview]
Message-ID: <6104171d-f355-733c-d01b-016127ec389a@tarantool.org> (raw)
In-Reply-To: <f5a6d3d2-b4bf-cbfb-e53c-b128ad497538@tarantool.org>
It was just a question, "why did you decide to do not
send type". It was not necessary to start sending UNKNOWN. I
think, that unknown type should be sent never.
On 22/11/2018 21:08, Imeev Mergen wrote:
> Hi! Thank you for review! Diff between versions and new patch
> below.
>
> On 11/19/18 8:27 PM, n.pettik wrote:
>
>>> EXPLAIN envokes SEGMENTATION FAULT when being executed through
>> Typo: invokes.
>>
>>> net.box. It happens due to column type of the result of this
>>> function being NULL.
>> I’ve checked and not only EXPLAIN results, but also EXPLAIN QUERY PLAN,
>> several pragmas (for instance, pragma table_info()) etc. So, initially problem
>> was not only in EXPLAIN statement. Please exposed commit message and
>> add tests on other cases.
>>
>> Also, why did you decide to avoid sending type at all, instead of sending
>> UNKNOWN for example?
>
> *Diff between versions:*
>
> diff --git a/src/box/execute.c b/src/box/execute.c
> index 5b747cf..cd809f8 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
> @@ -529,6 +529,9 @@ sql_get_description(struct sqlite3_stmt *stmt, struct obuf *out,
> return -1;
>
> for (int i = 0; i < column_count; ++i) {
> + size_t size = mp_sizeof_map(2) +
> + mp_sizeof_uint(IPROTO_FIELD_NAME) +
> + mp_sizeof_uint(IPROTO_FIELD_TYPE);
> const char *name = sqlite3_column_name(stmt, i);
> const char *type = sqlite3_column_datatype(stmt, i);
> /*
> @@ -537,27 +540,20 @@ sql_get_description(struct sqlite3_stmt *stmt, struct obuf *out,
> * column_name simply returns them.
> */
> assert(name != NULL);
> - size_t size = mp_sizeof_uint(IPROTO_FIELD_NAME) +
> - mp_sizeof_str(strlen(name));
> - if (type != NULL) {
> - size += mp_sizeof_map(2) +
> - mp_sizeof_uint(IPROTO_FIELD_TYPE) +
> - mp_sizeof_str(strlen(type));
> - } else {
> - size += mp_sizeof_map(1);
> - }
> + if (type == NULL)
> + type = "UNKNOWN";
> + size += mp_sizeof_str(strlen(name));
> + size += mp_sizeof_str(strlen(type));
> char *pos = (char *) obuf_alloc(out, size);
> if (pos == NULL) {
> diag_set(OutOfMemory, size, "obuf_alloc", "pos");
> return -1;
> }
> - pos = mp_encode_map(pos, 1 + (type != NULL));
> + pos = mp_encode_map(pos, 2);
> pos = mp_encode_uint(pos, IPROTO_FIELD_NAME);
> pos = mp_encode_str(pos, name, strlen(name));
> - if (type != NULL) {
> - pos = mp_encode_uint(pos, IPROTO_FIELD_TYPE);
> - pos = mp_encode_str(pos, type, strlen(type));
> - }
> + pos = mp_encode_uint(pos, IPROTO_FIELD_TYPE);
> + pos = mp_encode_str(pos, type, strlen(type));
> }
> return 0;
> }
> diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
> index 342c6a7..c7063d9 100644
> --- a/src/box/lua/net_box.c
> +++ b/src/box/lua/net_box.c
> @@ -644,7 +644,8 @@ netbox_decode_metadata(struct lua_State *L, const char **data)
> lua_createtable(L, count, 0);
> for (uint32_t i = 0; i < count; ++i) {
> uint32_t map_size = mp_decode_map(data);
> - assert(map_size == 1 || map_size == 2);
> + assert(map_size == 2);
> + (void) map_size;
> uint32_t key = mp_decode_uint(data);
> assert(key == IPROTO_FIELD_NAME);
> (void) key;
> @@ -653,13 +654,11 @@ netbox_decode_metadata(struct lua_State *L, const char **data)
> const char *str = mp_decode_str(data, &len);
> lua_pushlstring(L, str, len);
> lua_setfield(L, -2, "name");
> - if (map_size == 2) {
> - key = mp_decode_uint(data);
> - assert(key == IPROTO_FIELD_TYPE);
> - const char *type = mp_decode_str(data, &len);
> - lua_pushlstring(L, type, len);
> - lua_setfield(L, -2, "type");
> - }
> + key = mp_decode_uint(data);
> + assert(key == IPROTO_FIELD_TYPE);
> + const char *type = mp_decode_str(data, &len);
> + lua_pushlstring(L, type, len);
> + lua_setfield(L, -2, "type");
> lua_rawseti(L, -2, i + 1);
> }
> }
> diff --git a/test/sql/iproto.result b/test/sql/iproto.result
> index 31e5d2e..f229427 100644
> --- a/test/sql/iproto.result
> +++ b/test/sql/iproto.result
> @@ -774,9 +774,9 @@ cn:close()
> ---
> ...
> --
> --- EXPLAIN could lead to segfault because it does not send column
> --- data type, but looks like DQL. Netbox had been trying to decode
> --- type for any DQL.
> +-- Some commands, e.g. EXPLAIN, could lead to segfault because it
> +-- does not send column data type, but looks like DQL. Netbox had
> +-- been trying to decode type for any DQL.
> --
> cn = remote.connect(box.cfg.listen)
> ---
> @@ -785,6 +785,32 @@ cn = remote.connect(box.cfg.listen)
> _ = cn:execute("EXPLAIN SELECT 1;")
> ---
> ...
> +-- Segmentation fault when PRAGMA TABLE_INFO() executed using
> +-- net.box.
> +box.sql.execute('CREATE TABLE test (id INT PRIMARY KEY)')
> +---
> +...
> +cn:execute("PRAGMA TABLE_INFO(test);")
> +---
> +- metadata:
> + - name: cid
> + type: UNKNOWN
> + - name: name
> + type: UNKNOWN
> + - name: type
> + type: UNKNOWN
> + - name: notnull
> + type: UNKNOWN
> + - name: dflt_value
> + type: UNKNOWN
> + - name: pk
> + type: UNKNOWN
> + rows:
> + - [0, 'ID', 'integer', 1, null, 1]
> +...
> +box.sql.execute('DROP TABLE test')
> +---
> +...
> cn:close()
> ---
> ...
> diff --git a/test/sql/iproto.test.lua b/test/sql/iproto.test.lua
> index a0f0f15..9bcc7ef 100644
> --- a/test/sql/iproto.test.lua
> +++ b/test/sql/iproto.test.lua
> @@ -248,15 +248,21 @@ cn:execute('drop table test')
> cn:close()
>
> --
> --- EXPLAIN could lead to segfault because it does not send column
> --- data type, but looks like DQL. Netbox had been trying to decode
> --- type for any DQL.
> +-- Some commands, e.g. EXPLAIN, could lead to segfault because it
> +-- does not send column data type, but looks like DQL. Netbox had
> +-- been trying to decode type for any DQL.
> --
> cn = remote.connect(box.cfg.listen)
>
> -- Segmentation fault when EXPLAIN executed using net.box.
> _ = cn:execute("EXPLAIN SELECT 1;")
>
> +-- Segmentation fault when PRAGMA TABLE_INFO() executed using
> +-- net.box.
> +box.sql.execute('CREATE TABLE test (id INT PRIMARY KEY)')
> +cn:execute("PRAGMA TABLE_INFO(test);")
> +box.sql.execute('DROP TABLE test')
> +
> cn:close()
>
> box.schema.user.revoke('guest', 'read,write,execute', 'universe')
>
>
> *New version:*
>
> commit 29dde0365922bfcec0d159b36c6454854adf34f7
> Author: Mergen Imeev <imeevma@gmail.com>
> Date: Fri Nov 16 13:34:46 2018 +0300
>
> sql: Print column type even if it is NULL
>
> Some commands, e.g. EXPLAIN, invokes SEGMENTATION FAULT when being
> executed through net.box. It happens due to column type of the
> result of this function being NULL. This patch adds checks for
> received column type.
>
> diff --git a/src/box/execute.c b/src/box/execute.c
> index e450444..cd809f8 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
> @@ -540,6 +540,8 @@ sql_get_description(struct sqlite3_stmt *stmt, struct obuf *out,
> * column_name simply returns them.
> */
> assert(name != NULL);
> + if (type == NULL)
> + type = "UNKNOWN";
> size += mp_sizeof_str(strlen(name));
> size += mp_sizeof_str(strlen(type));
> char *pos = (char *) obuf_alloc(out, size);
> diff --git a/test/sql/iproto.result b/test/sql/iproto.result
> index d077ee8..f229427 100644
> --- a/test/sql/iproto.result
> +++ b/test/sql/iproto.result
> @@ -773,6 +773,47 @@ cn:execute('drop table test')
> cn:close()
> ---
> ...
> +--
> +-- Some commands, e.g. EXPLAIN, could lead to segfault because it
> +-- does not send column data type, but looks like DQL. Netbox had
> +-- been trying to decode type for any DQL.
> +--
> +cn = remote.connect(box.cfg.listen)
> +---
> +...
> +-- Segmentation fault when EXPLAIN executed using net.box.
> +_ = cn:execute("EXPLAIN SELECT 1;")
> +---
> +...
> +-- Segmentation fault when PRAGMA TABLE_INFO() executed using
> +-- net.box.
> +box.sql.execute('CREATE TABLE test (id INT PRIMARY KEY)')
> +---
> +...
> +cn:execute("PRAGMA TABLE_INFO(test);")
> +---
> +- metadata:
> + - name: cid
> + type: UNKNOWN
> + - name: name
> + type: UNKNOWN
> + - name: type
> + type: UNKNOWN
> + - name: notnull
> + type: UNKNOWN
> + - name: dflt_value
> + type: UNKNOWN
> + - name: pk
> + type: UNKNOWN
> + rows:
> + - [0, 'ID', 'integer', 1, null, 1]
> +...
> +box.sql.execute('DROP TABLE test')
> +---
> +...
> +cn:close()
> +---
> +...
> box.schema.user.revoke('guest', 'read,write,execute', 'universe')
> ---
> ...
> diff --git a/test/sql/iproto.test.lua b/test/sql/iproto.test.lua
> index 1470eda..9bcc7ef 100644
> --- a/test/sql/iproto.test.lua
> +++ b/test/sql/iproto.test.lua
> @@ -247,10 +247,27 @@ cn:execute('drop table test')
>
> cn:close()
>
> +--
> +-- Some commands, e.g. EXPLAIN, could lead to segfault because it
> +-- does not send column data type, but looks like DQL. Netbox had
> +-- been trying to decode type for any DQL.
> +--
> +cn = remote.connect(box.cfg.listen)
> +
> +-- Segmentation fault when EXPLAIN executed using net.box.
> +_ = cn:execute("EXPLAIN SELECT 1;")
> +
> +-- Segmentation fault when PRAGMA TABLE_INFO() executed using
> +-- net.box.
> +box.sql.execute('CREATE TABLE test (id INT PRIMARY KEY)')
> +cn:execute("PRAGMA TABLE_INFO(test);")
> +box.sql.execute('DROP TABLE test')
> +
> +cn:close()
> +
> box.schema.user.revoke('guest', 'read,write,execute', 'universe')
> box.schema.user.revoke('guest', 'create', 'space')
> space = nil
>
> -- Cleanup xlog
> box.snapshot()
> -
>
next prev parent reply other threads:[~2018-11-22 18:31 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-19 13:47 [tarantool-patches] [PATCH 0/3] A set of small SQL fixes Vladislav Shpilevoy
2018-11-19 13:47 ` [tarantool-patches] [PATCH 1/3] sql: EXPLAIN through net.box leads to SEGFAULT Vladislav Shpilevoy
2018-11-19 17:27 ` [tarantool-patches] " n.pettik
2018-11-22 18:08 ` Imeev Mergen
2018-11-22 18:31 ` Vladislav Shpilevoy [this message]
2018-11-22 20:55 ` [tarantool-patches] Re[2]: " Мерген Имеев
2018-11-23 6:04 ` [tarantool-patches] Re: Re[2]: " Kirill Yukhin
2018-11-28 12:36 ` [tarantool-patches] " n.pettik
2018-11-29 14:58 ` Konstantin Osipov
2018-11-19 13:47 ` [tarantool-patches] [PATCH 2/3] sql: SELECT from system spaces returns unpacked msgpack Vladislav Shpilevoy
2018-11-19 17:27 ` [tarantool-patches] " n.pettik
2018-11-22 18:09 ` Imeev Mergen
2018-11-27 8:51 ` n.pettik
2018-11-19 13:47 ` [tarantool-patches] [PATCH 3/3] sql: too many autogenerated ids leads to SEGFAULT Vladislav Shpilevoy
2018-11-19 17:27 ` [tarantool-patches] " n.pettik
2018-11-22 18:09 ` Imeev Mergen
2018-11-27 8:50 ` n.pettik
2018-11-27 10:09 ` [tarantool-patches] Re: [PATCH 0/3] A set of small SQL fixes Kirill Yukhin
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=6104171d-f355-733c-d01b-016127ec389a@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=imeevma@tarantool.org \
--cc=korablev@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='[tarantool-patches] Re: [PATCH 1/3] sql: EXPLAIN through net.box leads to SEGFAULT' \
/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