From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id C6C552FB1A for ; Sat, 17 Nov 2018 09:04:11 -0500 (EST) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QrycWZdhkbvh for ; Sat, 17 Nov 2018 09:04:11 -0500 (EST) Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 879EE2FB16 for ; Sat, 17 Nov 2018 09:04:11 -0500 (EST) From: imeevma@tarantool.org Subject: [tarantool-patches] [PATCH v1 10/10] sql: check new box.sql.execute() Date: Sat, 17 Nov 2018 17:04:09 +0300 Message-Id: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org, v.shpilevoy@tarantool.org This commit checks that new implementation of box.sql.execute() is able to pass all tests. This is temporary commit and should be dropped later. Needed for #3505 --- src/box/execute.c | 11 ++--- src/box/execute.h | 3 +- src/box/iproto.cc | 3 +- src/box/lua/schema.lua | 23 +++++++++++ src/box/lua/sql.c | 107 +------------------------------------------------ 5 files changed, 35 insertions(+), 112 deletions(-) diff --git a/src/box/execute.c b/src/box/execute.c index a7f8a54..40636d1 100644 --- a/src/box/execute.c +++ b/src/box/execute.c @@ -497,7 +497,7 @@ sql_get_description(struct sqlite3_stmt *stmt, struct vstream *stream, static inline int sql_execute(sqlite3 *db, struct sqlite3_stmt *stmt, struct port *port, - struct region *region) + struct region *region, int error_id) { int rc, column_count = sqlite3_column_count(stmt); if (column_count > 0) { @@ -514,7 +514,7 @@ sql_execute(sqlite3 *db, struct sqlite3_stmt *stmt, struct port *port, assert(rc != SQLITE_ROW && rc != SQLITE_OK); } if (rc != SQLITE_DONE) { - diag_set(ClientError, ER_SQL_EXECUTE, sqlite3_errmsg(db)); + diag_set(ClientError, error_id, sqlite3_errmsg(db)); return -1; } return 0; @@ -522,7 +522,8 @@ sql_execute(sqlite3 *db, struct sqlite3_stmt *stmt, struct port *port, int sql_prepare_and_execute(const struct sql_request *request, - struct sql_response *response, struct region *region) + struct sql_response *response, struct region *region, + int error_id) { const char *sql = request->sql_text; uint32_t len = request->sql_text_len; @@ -533,7 +534,7 @@ sql_prepare_and_execute(const struct sql_request *request, return -1; } if (sqlite3_prepare_v2(db, sql, len, &stmt, NULL) != SQLITE_OK) { - diag_set(ClientError, ER_SQL_EXECUTE, sqlite3_errmsg(db)); + diag_set(ClientError, error_id, sqlite3_errmsg(db)); return -1; } assert(stmt != NULL); @@ -541,7 +542,7 @@ sql_prepare_and_execute(const struct sql_request *request, response->prep_stmt = stmt; response->sync = request->sync; if (sql_bind(request, stmt) == 0 && - sql_execute(db, stmt, &response->port, region) == 0) + sql_execute(db, stmt, &response->port, region, error_id) == 0) return 0; port_destroy(&response->port); sqlite3_finalize(stmt); diff --git a/src/box/execute.h b/src/box/execute.h index 882334f..08efea9 100644 --- a/src/box/execute.h +++ b/src/box/execute.h @@ -147,7 +147,8 @@ sql_bind_list_decode(struct sql_request *request, const char *data, */ int sql_prepare_and_execute(const struct sql_request *request, - struct sql_response *response, struct region *region); + struct sql_response *response, struct region *region, + int error_id); #if defined(__cplusplus) } /* extern "C" { */ diff --git a/src/box/iproto.cc b/src/box/iproto.cc index f823c2d..e082c1b 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1657,7 +1657,8 @@ tx_process_sql(struct cmsg *m) goto error; assert(msg->header.type == IPROTO_EXECUTE); tx_inject_delay(); - if (sql_prepare_and_execute(&msg->sql, &response, &fiber()->gc) != 0) + if (sql_prepare_and_execute(&msg->sql, &response, &fiber()->gc, + ER_SQL_EXECUTE) != 0) goto error; /* * Take an obuf only after execute(). Else the buffer can diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 8a804f0..02ec2fd 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -2456,3 +2456,26 @@ box.feedback.save = function(file_name) end box.NULL = msgpack.NULL + +box.sql.execute = function(sql) + local result = box.sql.new_execute(sql) + if result == nil then return end + local ret = nil + if result.rows ~= nil then + ret = {} + for key, row in pairs(result.rows) do + if type(row) == 'cdata' then + table.insert(ret, row:totable()) + end + end + end + if result.metadata ~= nil then + if ret == nil then ret = {} end + ret[0] = {} + for key, row in pairs(result.metadata) do + table.insert(ret[0], row['name']) + end + setmetatable(ret, {__serialize = 'sequence'}) + end + if ret ~= nil then return ret end +end diff --git a/src/box/lua/sql.c b/src/box/lua/sql.c index b5e428d..89872f6 100644 --- a/src/box/lua/sql.c +++ b/src/box/lua/sql.c @@ -9,109 +9,6 @@ #include "box/execute.h" #include "box/vstream.h" -static void -lua_push_column_names(struct lua_State *L, struct sqlite3_stmt *stmt) -{ - int column_count = sqlite3_column_count(stmt); - lua_createtable(L, column_count, 0); - for (int i = 0; i < column_count; i++) { - const char *name = sqlite3_column_name(stmt, i); - lua_pushstring(L, name == NULL ? "" : name); - lua_rawseti(L, -2, i+1); - } -} - -static void -lua_push_row(struct lua_State *L, struct sqlite3_stmt *stmt) -{ - int column_count = sqlite3_column_count(stmt); - - lua_createtable(L, column_count, 0); - lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_array_metatable_ref); - lua_setmetatable(L, -2); - - for (int i = 0; i < column_count; i++) { - int type = sqlite3_column_type(stmt, i); - switch (type) { - case SQLITE_INTEGER: - luaL_pushint64(L, sqlite3_column_int64(stmt, i)); - break; - case SQLITE_FLOAT: - lua_pushnumber(L, sqlite3_column_double(stmt, i)); - break; - case SQLITE_TEXT: { - const void *text = sqlite3_column_text(stmt, i); - lua_pushlstring(L, text, - sqlite3_column_bytes(stmt, i)); - break; - } - case SQLITE_BLOB: { - const void *blob = sqlite3_column_blob(stmt, i); - if (sql_column_subtype(stmt,i) == SQL_SUBTYPE_MSGPACK) { - luamp_decode(L, luaL_msgpack_default, - (const char **)&blob); - } else { - lua_pushlstring(L, blob, - sqlite3_column_bytes(stmt, i)); - } - break; - } - case SQLITE_NULL: - lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_nil_ref); - break; - default: - assert(0); - } - lua_rawseti(L, -2, i+1); - } -} - -static int -lua_sql_execute(struct lua_State *L) -{ - sqlite3 *db = sql_get(); - if (db == NULL) - return luaL_error(L, "not ready"); - - size_t length; - const char *sql = lua_tolstring(L, 1, &length); - if (sql == NULL) - return luaL_error(L, "usage: box.sql.execute(sqlstring)"); - - struct sqlite3_stmt *stmt; - if (sqlite3_prepare_v2(db, sql, length, &stmt, &sql) != SQLITE_OK) - goto sqlerror; - assert(stmt != NULL); - - int rc; - int retval_count; - if (sqlite3_column_count(stmt) == 0) { - while ((rc = sqlite3_step(stmt)) == SQLITE_ROW); - retval_count = 0; - } else { - lua_newtable(L); - lua_pushvalue(L, lua_upvalueindex(1)); - lua_setmetatable(L, -2); - lua_push_column_names(L, stmt); - lua_rawseti(L, -2, 0); - - int row_count = 0; - while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { - lua_push_row(L, stmt); - lua_rawseti(L, -2, ++row_count); - } - retval_count = 1; - } - if (rc != SQLITE_OK && rc != SQLITE_DONE) - goto sqlerror; - sqlite3_finalize(stmt); - return retval_count; -sqlerror: - lua_pushstring(L, sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return lua_error(L); -} - static int lbox_execute(struct lua_State *L) { @@ -128,7 +25,8 @@ lbox_execute(struct lua_State *L) struct sql_response response = {}; request.sql_text = sql; request.sql_text_len = length; - if (sql_prepare_and_execute(&request, &response, &fiber()->gc) != 0) + if (sql_prepare_and_execute(&request, &response, &fiber()->gc, + ER_SYSTEM) != 0) goto sqlerror; int keys; @@ -158,7 +56,6 @@ void box_lua_sqlite_init(struct lua_State *L) { static const struct luaL_Reg module_funcs [] = { - {"execute", lua_sql_execute}, {"new_execute", lbox_execute}, {"debug", lua_sql_debug}, {NULL, NULL} -- 2.7.4