From: Nikita Pettik <korablev@tarantool.org> To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org Subject: [Tarantool-patches] [PATCH v2 07/16] port: add dump format and request type to port_sql Date: Thu, 21 Nov 2019 00:28:06 +0300 [thread overview] Message-ID: <10842a572a8b14dd8c96c258ffe372dda45416e5.1574277369.git.korablev@tarantool.org> (raw) In-Reply-To: <cover.1574277369.git.korablev@tarantool.org> In-Reply-To: <cover.1574277369.git.korablev@tarantool.org> Dump formats of DQL and DML queries are different: the last one contains number of affected rows and optionally list of autoincremented ids; the first one comprises all meta-information including column names of resulting set and their types. What is more, dump format is going to be different for execute and prepare requests. So let's introduce separate member to struct port_sql responsible for dump format to be used. What is more, prepared statement finalization is required only for PREPARE-AND-EXECUTE requests. So let's keep request type in port as well. Note that C standard specifies that enums are integers, but it does not specify the size. Hence, let's use simple uint8 - mentioned enums are small enough to fit into it. Needed for #2592 --- src/box/execute.c | 32 +++++++++++++++++++++++--------- src/box/execute.h | 24 ++++++++++++++++++++++++ src/box/lua/execute.c | 20 +++++++++++++------- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/box/execute.c b/src/box/execute.c index 83680b70f..d2a999099 100644 --- a/src/box/execute.c +++ b/src/box/execute.c @@ -100,7 +100,9 @@ static void port_sql_destroy(struct port *base) { port_tuple_vtab.destroy(base); - sql_finalize(((struct port_sql *)base)->stmt); + struct port_sql *port_sql = (struct port_sql *) base; + if (port_sql->request == PREPARE_AND_EXECUTE) + sql_finalize(((struct port_sql *)base)->stmt); } const struct port_vtab port_sql_vtab = { @@ -114,11 +116,15 @@ const struct port_vtab port_sql_vtab = { }; static void -port_sql_create(struct port *port, struct sql_stmt *stmt) +port_sql_create(struct port *port, struct sql_stmt *stmt, + enum sql_dump_format dump_format, enum sql_request_type request) { port_tuple_create(port); - ((struct port_sql *)port)->stmt = stmt; port->vtab = &port_sql_vtab; + struct port_sql *port_sql = (struct port_sql *) port; + port_sql->stmt = stmt; + port_sql->dump_format = dump_format; + port_sql->request = request; } /** @@ -324,9 +330,10 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out) { assert(port->vtab == &port_sql_vtab); sql *db = sql_get(); - struct sql_stmt *stmt = ((struct port_sql *)port)->stmt; - int column_count = sql_column_count(stmt); - if (column_count > 0) { + struct port_sql *sql_port = (struct port_sql *)port; + struct sql_stmt *stmt = sql_port->stmt; + switch (sql_port->dump_format) { + case DQL_EXECUTE: { int keys = 2; int size = mp_sizeof_map(keys); char *pos = (char *) obuf_alloc(out, size); @@ -335,7 +342,7 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out) return -1; } pos = mp_encode_map(pos, keys); - if (sql_get_metadata(stmt, out, column_count) != 0) + if (sql_get_metadata(stmt, out, sql_column_count(stmt)) != 0) return -1; size = mp_sizeof_uint(IPROTO_DATA); pos = (char *) obuf_alloc(out, size); @@ -346,7 +353,9 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out) pos = mp_encode_uint(pos, IPROTO_DATA); if (port_tuple_vtab.dump_msgpack(port, out) < 0) return -1; - } else { + break; + } + case DML_EXECUTE: { int keys = 1; assert(((struct port_tuple *)port)->size == 0); struct stailq *autoinc_id_list = @@ -395,6 +404,9 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out) mp_encode_int(buf, id_entry->id); } } + break; + } + default: unreachable(); } return 0; } @@ -445,7 +457,9 @@ sql_prepare_and_execute(const char *sql, int len, const struct sql_bind *bind, if (sql_compile(sql, len, NULL, &stmt, NULL) != 0) return -1; assert(stmt != NULL); - port_sql_create(port, stmt); + enum sql_dump_format dump_format = sql_column_count(stmt) > 0 ? + DQL_EXECUTE : DML_EXECUTE; + port_sql_create(port, stmt, dump_format, PREPARE_AND_EXECUTE); if (sql_bind(stmt, bind, bind_count) == 0 && sql_execute(stmt, port, region) == 0) return 0; diff --git a/src/box/execute.h b/src/box/execute.h index a85fca5fc..6702a18cc 100644 --- a/src/box/execute.h +++ b/src/box/execute.h @@ -46,6 +46,23 @@ enum sql_info_key { sql_info_key_MAX, }; +/** + * One of possible formats used to dump msgpack/Lua. + * For details see port_sql_dump_msgpack() and port_sql_dump_lua(). + */ +enum sql_dump_format { + DQL_EXECUTE = 0, + DML_EXECUTE = 1, + DQL_PREPARE = 2, + DML_PREPARE = 3, +}; + +enum sql_request_type { + PREPARE_AND_EXECUTE = 0, + PREPARE = 1, + EXECUTE_PREPARED = 2 +}; + extern const char *sql_info_key_strs[]; struct region; @@ -85,6 +102,13 @@ struct port_sql { struct port_tuple port_tuple; /* Prepared SQL statement. */ struct sql_stmt *stmt; + /** + * Dump format depends on type of SQL query: DML or DQL; + * and on type of SQL request: execute or prepare. + */ + uint8_t dump_format; + /** enum sql_request_type */ + uint8_t request; }; extern const struct port_vtab port_sql_vtab; diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index 76ecdd541..1b2f8d235 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -45,18 +45,21 @@ port_sql_dump_lua(struct port *port, struct lua_State *L, bool is_flat) assert(is_flat == false); assert(port->vtab == &port_sql_vtab); struct sql *db = sql_get(); - struct sql_stmt *stmt = ((struct port_sql *)port)->stmt; - int column_count = sql_column_count(stmt); - if (column_count > 0) { + struct port_sql *port_sql = (struct port_sql *)port; + struct sql_stmt *stmt = port_sql->stmt; + switch (port_sql->dump_format) { + case DQL_EXECUTE: { lua_createtable(L, 0, 2); - lua_sql_get_metadata(stmt, L, column_count); + lua_sql_get_metadata(stmt, L, sql_column_count(stmt)); lua_setfield(L, -2, "metadata"); port_tuple_vtab.dump_lua(port, L, false); lua_setfield(L, -2, "rows"); - } else { - assert(((struct port_tuple *)port)->size == 0); + break; + } + case DML_EXECUTE: { + assert(((struct port_tuple *) port)->size == 0); struct stailq *autoinc_id_list = - vdbe_autoinc_id_list((struct Vdbe *)stmt); + vdbe_autoinc_id_list((struct Vdbe *) stmt); lua_createtable(L, 0, stailq_empty(autoinc_id_list) ? 1 : 2); luaL_pushuint64(L, db->nChange); @@ -77,6 +80,9 @@ port_sql_dump_lua(struct port *port, struct lua_State *L, bool is_flat) sql_info_key_strs[SQL_INFO_AUTOINCREMENT_IDS]; lua_setfield(L, -2, field_name); } + break; + } + default: unreachable(); } } -- 2.15.1
next prev parent reply other threads:[~2019-11-20 21:28 UTC|newest] Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-11-20 21:27 [Tarantool-patches] [PATCH v2 00/16] sql: prepared statements Nikita Pettik 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 01/16] sql: remove sql_prepare_v2() Nikita Pettik 2019-12-04 11:36 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 02/16] sql: refactor sql_prepare() and sqlPrepare() Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-04 11:36 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 03/16] sql: move sql_prepare() declaration to box/execute.h Nikita Pettik 2019-12-04 11:37 ` Konstantin Osipov 2019-12-05 13:32 ` Nikita Pettik 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 04/16] sql: rename sqlPrepare() to sql_compile() Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-13 13:49 ` Nikita Pettik 2019-12-04 11:39 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 05/16] sql: move sql_finalize() to execute.h Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-04 11:39 ` Konstantin Osipov 2019-12-13 13:49 ` Nikita Pettik 2019-12-04 11:40 ` Konstantin Osipov 2019-12-05 13:37 ` Nikita Pettik 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 06/16] port: increase padding of struct port Nikita Pettik 2019-12-04 11:42 ` Konstantin Osipov 2019-12-13 13:54 ` Nikita Pettik 2019-11-20 21:28 ` Nikita Pettik [this message] 2019-12-03 22:51 ` [Tarantool-patches] [PATCH v2 07/16] port: add dump format and request type to port_sql Vladislav Shpilevoy 2019-12-13 13:55 ` Nikita Pettik 2019-12-04 11:52 ` Konstantin Osipov 2019-12-13 13:53 ` Nikita Pettik 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 08/16] sql: resurrect sql_bind_parameter_count() function Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-04 11:54 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 09/16] sql: resurrect sql_bind_parameter_name() Nikita Pettik 2019-12-04 11:55 ` Konstantin Osipov 2019-12-04 11:55 ` Konstantin Osipov 2019-12-13 13:55 ` Nikita Pettik 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 10/16] sql: add sql_stmt_schema_version() Nikita Pettik 2019-12-04 11:57 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 11/16] sql: introduce sql_stmt_sizeof() function Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-13 13:56 ` Nikita Pettik 2019-12-04 11:59 ` Konstantin Osipov 2019-12-13 13:56 ` Nikita Pettik 2019-12-13 14:15 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 12/16] box: increment schema_version on ddl operations Nikita Pettik 2019-12-04 12:03 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 13/16] sql: introduce sql_stmt_query_str() method Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-04 12:04 ` Konstantin Osipov 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 14/16] sql: introduce cache for prepared statemets Nikita Pettik 2019-12-03 22:51 ` Vladislav Shpilevoy 2019-12-04 12:11 ` Konstantin Osipov 2019-12-17 14:43 ` Kirill Yukhin 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 15/16] box: introduce prepared statements Nikita Pettik 2019-12-04 12:13 ` Konstantin Osipov 2019-12-06 23:18 ` Vladislav Shpilevoy 2019-11-20 21:28 ` [Tarantool-patches] [PATCH v2 16/16] netbox: " Nikita Pettik 2019-12-06 23:18 ` Vladislav Shpilevoy 2019-12-03 22:51 ` [Tarantool-patches] [PATCH v2 00/16] sql: " Vladislav Shpilevoy 2019-12-17 15:58 ` Georgy Kirichenko
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=10842a572a8b14dd8c96c258ffe372dda45416e5.1574277369.git.korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 07/16] port: add dump format and request type to port_sql' \ /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