[tarantool-patches] [PATCH v1 10/10] sql: check new box.sql.execute()
imeevma at tarantool.org
imeevma at tarantool.org
Sat Nov 17 17:04:09 MSK 2018
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
More information about the Tarantool-patches
mailing list