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 ED8152FC8A for ; Thu, 22 Nov 2018 14:11:06 -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 iWcPhgdxl-HS for ; Thu, 22 Nov 2018 14:11:06 -0500 (EST) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (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 8A46A2FCD3 for ; Thu, 22 Nov 2018 14:11:06 -0500 (EST) From: imeevma@tarantool.org Subject: [tarantool-patches] [PATCH v2 7/7] sql: check new box.sql.execute() Date: Thu, 22 Nov 2018 22:11:04 +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: v.shpilevoy@tarantool.org, tarantool-patches@freelists.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 | 117 ++++--------------------------------------------- 5 files changed, 42 insertions(+), 115 deletions(-) diff --git a/src/box/execute.c b/src/box/execute.c index 44cc7ea..433e71e 100644 --- a/src/box/execute.c +++ b/src/box/execute.c @@ -697,7 +697,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) { @@ -714,7 +714,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; @@ -722,7 +722,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; @@ -733,7 +734,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); @@ -741,7 +742,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 8ee0a89..46b2ce1 100644 --- a/src/box/execute.h +++ b/src/box/execute.h @@ -157,7 +157,8 @@ lua_sql_bind_list_decode(struct lua_State *L, struct sql_request *request, */ 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 380a6ee..9d03bdf 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1596,7 +1596,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 05556f9..c56dd4a 100644 --- a/src/box/lua/sql.c +++ b/src/box/lua/sql.c @@ -117,109 +117,6 @@ lua_vstream_init(struct vstream *vstream, struct lua_State *L) vstream->L = L; } -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) { @@ -237,10 +134,12 @@ lbox_execute(struct lua_State *L) request.sql_text_len = length; if (lua_gettop(L) == 2) if (lua_sql_bind_list_decode(L, &request, 2, &fiber()->gc) != 0) - return luaT_error(L); + goto sqlerror; + struct sql_response response = {.is_flatten = true}; - if (sql_prepare_and_execute(&request, &response, &fiber()->gc) != 0) - return luaT_error(L); + if (sql_prepare_and_execute(&request, &response, &fiber()->gc, + ER_SYSTEM) != 0) + goto sqlerror; int keys; struct vstream vstream; @@ -248,9 +147,12 @@ lbox_execute(struct lua_State *L) lua_newtable(L); if (sql_response_dump(&response, &keys, &vstream) != 0) { lua_pop(L, 1); - return luaT_error(L); + goto sqlerror; } return 1; +sqlerror: + lua_pushstring(L, sqlite3_errmsg(db)); + return lua_error(L); } static int @@ -266,7 +168,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