From: imeevma@tarantool.org
To: v.shpilevoy@tarantool.org
Cc: tarantool-patches@freelists.org, tarantool-patches@dev.tarantool.org
Subject: [Tarantool-patches] [PATCH v1 3/5] sql: create SET command
Date: Thu, 17 Oct 2019 17:40:17 +0300 [thread overview]
Message-ID: <faf78a87e5c2831855b42806bfbe8459861a7051.1571322776.git.imeevma@gmail.com> (raw)
In-Reply-To: <cover.1571322776.git.imeevma@gmail.com>
This patch creates the SET command for SQL, which will be used
instead of pragmas that modify SQL settings.
Part of #4511
@TarantoolBot document
Title: SET SQL command
The SET SQL command is used to change SQL settings.
Currently available SQL settings:
'defer_foreign_keys'
'full_column_names'
'recursive_triggers'
'reverse_unordered_selects'
'sql_compound_select_limit'
'sql_default_engine'
In addition, SQL debugging settings can also be changed using this
command in the debug build:
'parser_trace'
'select_trace'
'sql_trace'
'vdbe_addoptrace'
'vdbe_debug'
'vdbe_eqp'
'vdbe_listing'
'vdbe_trace'
'where_trace'
Example of usage:
SET full_column_names = true;
SET sql_compound_select_limit(10);
SET sql_default_engine = 'memtx';
---
src/box/sql/build.c | 60 +++++++++++++++++++++
src/box/sql/parse.y | 8 +++
src/box/sql/sqlInt.h | 14 +++++
test/sql/sql-debug.result | 127 ++++++++++++++++++++++++++++++++++++++++++++
test/sql/sql-debug.test.lua | 26 +++++++++
5 files changed, 235 insertions(+)
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 233f567..45bd3c0 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -3241,3 +3241,63 @@ sql_fieldno_by_name(struct Parse *parse_context, struct Expr *field_name,
*fieldno = i;
return 0;
}
+
+void
+sql_set_settings(struct Parse *parse_context, struct Token *name,
+ struct Expr *value)
+{
+ int option_id;
+ struct session *session = current_session();
+ char *name_str = sql_name_from_token(sql_get(), name);
+ if (name_str == NULL) {
+ parse_context->is_aborted = true;
+ return;
+ }
+ for (option_id = 0; option_id < SQL_OPTION_max; ++option_id) {
+ if (strcasecmp(sql_options[option_id].name, name_str) == 0)
+ break;
+ }
+ if (option_id == SQL_OPTION_max) {
+ diag_set(ClientError, ER_SQL_PARSER_GENERIC, "Setting is "
+ "not found");
+ parse_context->is_aborted = true;
+ return;
+ }
+ struct sql_option_metadata *option = &sql_options[option_id];
+ if (value->type != option->field_type) {
+ diag_set(ClientError, ER_INCONSISTENT_TYPES,
+ field_type_strs[option->field_type],
+ field_type_strs[value->type]);
+ parse_context->is_aborted = true;
+ return;
+ }
+ if (value->type == FIELD_TYPE_BOOLEAN) {
+ bool is_set = value->op == TK_TRUE;
+ if (is_set)
+ session->sql_flags |= option->flag;
+ else
+ session->sql_flags &= ~option->flag;
+#ifndef NDEBUG
+ if (option_id == SQL_OPTION_PARSER_TRACE) {
+ if (is_set)
+ sqlParserTrace(stdout, "parser: ");
+ else
+ sqlParserTrace(NULL, NULL);
+ }
+#endif
+ } else if (option_id == SQL_OPTION_DEFAULT_ENGINE) {
+ enum sql_storage_engine engine =
+ STR2ENUM(sql_storage_engine, value->u.zToken);
+ if (engine == sql_storage_engine_MAX) {
+ parse_context->is_aborted = true;
+ diag_set(ClientError, ER_NO_SUCH_ENGINE,
+ value->u.zToken);
+ return;
+ }
+ current_session()->sql_default_engine = engine;
+ } else {
+ assert(option_id == SQL_OPTION_COMPOUND_SELECT_LIMIT);
+ sql_limit(sql_get(), SQL_LIMIT_COMPOUND_SELECT,
+ value->u.iValue);
+ }
+}
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index ed59a87..7bea68d 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -1535,6 +1535,14 @@ cmd ::= DROP INDEX ifexists(E) nm(X) ON fullname(Y). {
sql_drop_index(pParse);
}
+///////////////////////////// The SET command ////////////////////////////////
+cmd ::= SET nm(X) EQ term(Y). {
+ sql_set_settings(pParse,&X,Y.pExpr);
+}
+cmd ::= SET nm(X) LP term(Y) RP. {
+ sql_set_settings(pParse,&X,Y.pExpr);
+}
+
///////////////////////////// The PRAGMA command /////////////////////////////
//
cmd ::= PRAGMA nm(X). {
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index a87590e..9a2b5c8 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4436,4 +4436,18 @@ int
sql_fieldno_by_name(struct Parse *parse_context, struct Expr *field_name,
uint32_t *fieldno);
+/**
+ * Set new value for SQL setting.
+ *
+ * @param parse_context Parsing context.
+ * @param name Name of SQL setting to change.
+ * @param value New values of SQL setting.
+ *
+ * @retval 0 on success.
+ * @retval -1 on error.
+ */
+void
+sql_set_settings(struct Parse *parse_context, struct Token *name,
+ struct Expr *value);
+
#endif /* sqlINT_H */
diff --git a/test/sql/sql-debug.result b/test/sql/sql-debug.result
index 2dba684..07542e3 100644
--- a/test/sql/sql-debug.result
+++ b/test/sql/sql-debug.result
@@ -54,3 +54,130 @@ box.execute('PRAGMA')
- ['vdbe_trace', 0]
- ['where_trace', 0]
...
+--
+-- gh-4511: make sure that SET works.
+--
+box.execute('SELECT "name" FROM "_vsql_settings";')
+---
+- metadata:
+ - name: name
+ type: string
+ rows:
+ - ['defer_foreign_keys']
+ - ['full_column_names']
+ - ['recursive_triggers']
+ - ['reverse_unordered_selects']
+ - ['sql_compound_select_limit']
+ - ['sql_default_engine']
+ - ['parser_trace']
+ - ['select_trace']
+ - ['sql_trace']
+ - ['vdbe_addoptrace']
+ - ['vdbe_debug']
+ - ['vdbe_eqp']
+ - ['vdbe_listing']
+ - ['vdbe_trace']
+ - ['where_trace']
+...
+engine = box.space._vsql_settings:get{'sql_default_engine'}[2]
+---
+...
+order = box.space._vsql_settings:get{'reverse_unordered_selects'}[2]
+---
+...
+box.execute('SET sql_default_engine = 1;')
+---
+- null
+- 'Inconsistent types: expected string got integer'
+...
+box.execute("SET sql_default_engine = 'some_engine';")
+---
+- null
+- Space engine 'some_engine' does not exist
+...
+box.execute("SET engine = 'vinyl';")
+---
+- null
+- Setting is not found
+...
+box.execute("SET defer_foreign_keys('vinyl');")
+---
+- null
+- 'Inconsistent types: expected boolean got string'
+...
+engine == box.space._vsql_settings:get{'sql_default_engine'}[2]
+---
+- true
+...
+order == box.space._vsql_settings:get{'reverse_unordered_selects'}[2]
+---
+- true
+...
+box.execute("SET sql_default_engine = 'vinyl';")
+---
+- row_count: 0
+...
+box.execute("SET reverse_unordered_selects(true);")
+---
+- row_count: 0
+...
+box.execute('SELECT "name" FROM "_vsql_settings";')
+---
+- metadata:
+ - name: name
+ type: string
+ rows:
+ - ['where_trace']
+ - ['vdbe_trace']
+ - ['vdbe_listing']
+ - ['vdbe_eqp']
+ - ['vdbe_debug']
+ - ['vdbe_addoptrace']
+ - ['sql_trace']
+ - ['select_trace']
+ - ['parser_trace']
+ - ['sql_default_engine']
+ - ['sql_compound_select_limit']
+ - ['reverse_unordered_selects']
+ - ['recursive_triggers']
+ - ['full_column_names']
+ - ['defer_foreign_keys']
+...
+box.execute("SET sql_default_engine('memtx');")
+---
+- row_count: 0
+...
+box.execute("SET reverse_unordered_selects = false;")
+---
+- row_count: 0
+...
+box.execute('SELECT "name" FROM "_vsql_settings";')
+---
+- metadata:
+ - name: name
+ type: string
+ rows:
+ - ['defer_foreign_keys']
+ - ['full_column_names']
+ - ['recursive_triggers']
+ - ['reverse_unordered_selects']
+ - ['sql_compound_select_limit']
+ - ['sql_default_engine']
+ - ['parser_trace']
+ - ['select_trace']
+ - ['sql_trace']
+ - ['vdbe_addoptrace']
+ - ['vdbe_debug']
+ - ['vdbe_eqp']
+ - ['vdbe_listing']
+ - ['vdbe_trace']
+ - ['where_trace']
+...
+box.execute("SET sql_default_engine = '"..engine.."';")
+---
+- row_count: 0
+...
+box.execute("SET reverse_unordered_selects = "..tostring(order)..";")
+---
+- row_count: 0
+...
diff --git a/test/sql/sql-debug.test.lua b/test/sql/sql-debug.test.lua
index edd0ef4..60d7fdd 100644
--- a/test/sql/sql-debug.test.lua
+++ b/test/sql/sql-debug.test.lua
@@ -15,3 +15,29 @@ box.execute('PRAGMA parser_trace = '.. result[1][1])
-- Make PRAGMA command return the result as a result set.
--
box.execute('PRAGMA')
+
+--
+-- gh-4511: make sure that SET works.
+--
+box.execute('SELECT "name" FROM "_vsql_settings";')
+
+engine = box.space._vsql_settings:get{'sql_default_engine'}[2]
+order = box.space._vsql_settings:get{'reverse_unordered_selects'}[2]
+
+box.execute('SET sql_default_engine = 1;')
+box.execute("SET sql_default_engine = 'some_engine';")
+box.execute("SET engine = 'vinyl';")
+box.execute("SET defer_foreign_keys('vinyl');")
+engine == box.space._vsql_settings:get{'sql_default_engine'}[2]
+order == box.space._vsql_settings:get{'reverse_unordered_selects'}[2]
+
+box.execute("SET sql_default_engine = 'vinyl';")
+box.execute("SET reverse_unordered_selects(true);")
+box.execute('SELECT "name" FROM "_vsql_settings";')
+
+box.execute("SET sql_default_engine('memtx');")
+box.execute("SET reverse_unordered_selects = false;")
+box.execute('SELECT "name" FROM "_vsql_settings";')
+
+box.execute("SET sql_default_engine = '"..engine.."';")
+box.execute("SET reverse_unordered_selects = "..tostring(order)..";")
--
2.7.4
next prev parent reply other threads:[~2019-10-17 14:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-17 14:40 [Tarantool-patches] [PATCH v1 0/5] Replace control pragmas by SET imeevma
2019-10-17 14:40 ` [Tarantool-patches] [PATCH v1 1/5] sysview: make get() and create_iterator() methods virtual imeevma
2019-10-17 14:40 ` [Tarantool-patches] [PATCH v1 2/5] box: introduce _vsql_settings sysview imeevma
2019-10-18 22:08 ` [Tarantool-patches] [tarantool-patches] " Vladislav Shpilevoy
2019-10-17 14:40 ` imeevma [this message]
2019-10-18 22:08 ` [Tarantool-patches] [tarantool-patches] [PATCH v1 3/5] sql: create SET command Vladislav Shpilevoy
2019-10-17 14:40 ` [Tarantool-patches] [PATCH v1 4/5] temporary: disable boolean.test.sql imeevma
2019-10-17 14:40 ` [Tarantool-patches] [PATCH v1 5/5] sql: replace control pragmas imeevma
2019-10-18 22:08 ` [Tarantool-patches] [tarantool-patches] [PATCH v1 0/5] Replace control pragmas by SET Vladislav Shpilevoy
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=faf78a87e5c2831855b42806bfbe8459861a7051.1571322776.git.imeevma@gmail.com \
--to=imeevma@tarantool.org \
--cc=tarantool-patches@dev.tarantool.org \
--cc=tarantool-patches@freelists.org \
--cc=v.shpilevoy@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH v1 3/5] sql: create SET command' \
/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