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 1074026F01 for ; Wed, 20 Jun 2018 13:06:37 -0400 (EDT) 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 LAVu0GMxjlMN for ; Wed, 20 Jun 2018 13:06:36 -0400 (EDT) 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 842F526EEB for ; Wed, 20 Jun 2018 13:06:36 -0400 (EDT) From: Kirill Shcherbatov Subject: [tarantool-patches] [PATCH v1 1/2] sql: introduce pragma sql_default_engine Date: Wed, 20 Jun 2018 20:06:26 +0300 Message-Id: In-Reply-To: References: 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 Cc: v.shpilevoy@tarantool.org, Kirill Shcherbatov Part of #2199. @TarantoolBot document Title: new pragma sql_default_engine Now it is allowed to create vinyl spaces using special pragma setting default engine for SQL requests. Example: \set language sql pragma sql_default_engine='vinyl'; CREATE TABLE t3(a primary key,b,c); --- src/box/session.cc | 1 + src/box/session.h | 2 ++ src/box/sql/build.c | 43 +++++++++++++++++++++++++++++++++++- src/box/sql/pragma.c | 8 +++++++ src/box/sql/pragma.h | 6 +++++ src/box/sql/sqliteInt.h | 14 ++++++++++++ test/sql-tap/gh-2367-pragma.test.lua | 14 +++++++++++- 7 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/box/session.cc b/src/box/session.cc index e487280..810dd19 100644 --- a/src/box/session.cc +++ b/src/box/session.cc @@ -107,6 +107,7 @@ session_create(enum session_type type) memset(&session->meta, 0, sizeof(session->meta)); session->type = type; session->sql_flags = default_flags; + session->sql_default_engine = 0; /* For on_connect triggers. */ credentials_init(&session->credentials, guest_user->auth_token, diff --git a/src/box/session.h b/src/box/session.h index 515c30a..df1dcbc 100644 --- a/src/box/session.h +++ b/src/box/session.h @@ -92,6 +92,8 @@ union session_meta { struct session { /** Session id. */ uint64_t id; + /** SQL Tarantool Default storage engine. */ + uint8_t sql_default_engine; /** SQL Connection flag for current user session */ uint32_t sql_flags; enum session_type type; diff --git a/src/box/sql/build.c b/src/box/sql/build.c index fff7c19..bcd4d31 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -493,6 +493,43 @@ sqlite3PrimaryKeyIndex(Table * pTab) } /** + * Get default engine name set in current_session. + * @retval engine name string. + */ +static const char * +sql_default_engine_name(void) +{ + switch (current_session()->sql_default_engine) { + case SQL_STORAGE_ENGINE_MEMTX: + return "memtx"; + case SQL_STORAGE_ENGINE_VINYL: + return "vinyl"; + default: + unreachable(); + } +} + +int +sql_default_engine_set(const char *engine_name) +{ + enum sql_storage_engine_t engine = 0; + size_t engine_name_len = strlen(engine_name); + + if (engine_name_len == strlen("memtx") && + sqlite3_stricmp(engine_name, "memtx") == 0) { + engine = SQL_STORAGE_ENGINE_MEMTX; + } else if (engine_name_len == strlen("vinyl") && + sqlite3_stricmp(engine_name, "vinyl") == 0) { + engine = SQL_STORAGE_ENGINE_VINYL; + } else { + diag_set(ClientError, ER_NO_SUCH_ENGINE, engine_name); + return -1; + } + current_session()->sql_default_engine = engine; + return 0; +} + +/** * Create and initialize a new SQL Table object. * All memory except table object itself is allocated on region. * @param parser SQL Parser object. @@ -510,6 +547,9 @@ sql_table_new(Parse *parser, char *name) if (table == NULL) return NULL; + snprintf(table->def->engine_name, sizeof(table->def->engine_name), "%s", + sql_default_engine_name()); + table->iPKey = -1; table->iAutoIncPKey = -1; table->pSchema = db->pSchema; @@ -1602,7 +1642,8 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt) sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 2 /* name */ , 0, sqlite3DbStrDup(pParse->db, p->def->name), P4_DYNAMIC); sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 3 /* engine */ , 0, - "memtx", P4_STATIC); + sqlite3DbStrDup(pParse->db, p->def->engine_name), + P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_Integer, p->def->field_count, iFirstCol + 4 /* field_count */ ); sqlite3VdbeAddOp4(v, OP_Blob, zOptsSz, iFirstCol + 5, MSGPACK_SUBTYPE, diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 5fb29c7..90d1cc1 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -870,6 +870,14 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ } break; } + case PragTyp_DEFAULT_ENGINE: { + if (sql_default_engine_set(zRight) != 0) { + pParse->rc = SQL_TARANTOOL_ERROR; + pParse->nErr++; + goto pragma_out; + } + break; + } /* * PRAGMA busy_timeout * PRAGMA busy_timeout = N * * diff --git a/src/box/sql/pragma.h b/src/box/sql/pragma.h index f966018..6e921d6 100644 --- a/src/box/sql/pragma.h +++ b/src/box/sql/pragma.h @@ -17,6 +17,7 @@ #define PragTyp_STATS 15 #define PragTyp_TABLE_INFO 17 #define PragTyp_PARSER_TRACE 24 +#define PragTyp_DEFAULT_ENGINE 25 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -247,6 +248,11 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ShortColNames}, #endif + { /* zName: */ "sql_default_engine", + /* ePragTyp: */ PragTyp_DEFAULT_ENGINE, + /* ePragFlg: */ PragFlg_Result0 | PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0}, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if defined(SQLITE_DEBUG) { /* zName: */ "sql_trace", diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index acda23d..8f5ef39 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -4560,6 +4560,20 @@ void sqlite3VdbeIOTraceSql(Vdbe *); #define sqlite3VdbeIOTraceSql(X) #endif +enum sql_storage_engine_t { + SQL_STORAGE_ENGINE_MEMTX = 0, + SQL_STORAGE_ENGINE_VINYL = 1, +}; + +/** + * Set tarantool backend default engine for SQL interface. + * @param engine_name to set default. + * @retval -1 on error. + * @retval 0 on success. + */ +int +sql_default_engine_set(const char *engine_name); + /* * These routines are available for the mem2.c debugging memory allocator * only. They are used to verify that different "types" of memory diff --git a/test/sql-tap/gh-2367-pragma.test.lua b/test/sql-tap/gh-2367-pragma.test.lua index a41a026..2ee8424 100755 --- a/test/sql-tap/gh-2367-pragma.test.lua +++ b/test/sql-tap/gh-2367-pragma.test.lua @@ -1,7 +1,7 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(1) +test:plan(2) test:do_catchsql_test( "pragma-1.3", @@ -11,4 +11,16 @@ test:do_catchsql_test( 1, "no such pragma: KEK" }) +--- +--- gh-2199: SQL default engine pragma +--- +test:do_catchsql_test( + "pragma-2.1", + [[ + pragma sql_default_engine='creepy'; + ]], { + 1, "Space engine 'creepy' does not exist" +}) + + test:finish_test() -- 2.7.4