[Tarantool-patches] [PATCH v3 3/5] sql: introduce SET statement

Mergen Imeev imeevma at tarantool.org
Thu Nov 7 17:12:09 MSK 2019


Thank you for review! My answers, new commit-message and
diff below.

On Thu, Nov 07, 2019 at 03:40:39PM +0300, Vladislav Shpilevoy wrote:
> Hi! Thanks for the fixes!
> 
> See 5 comments below.
> 
> On 07/11/2019 13:36, imeevma at tarantool.org wrote:
> > Due to the removal of sql_compound_select_limit from the session
> > options, this patch has been modified.
> > 
> > New patch:
> > 
> > From 12ed4be2e7e433fdca58a43fc3b937eb9a54f52f Mon Sep 17 00:00:00 2001
> > From: Mergen Imeev <imeevma at gmail.com>
> > Date: Wed, 16 Oct 2019 16:43:10 +0300
> > Subject: [PATCH] sql: introduce SET statement
> > 
> > This patch creates an SQL SET statement. This statement replaces
> > pragmas that can modify SQL settings. List of pragmas that will
> > have the corresponding option in SET:
> > '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'
> > 
> > All these pragmas along with the pragmas 'short_column_names' and
> > 'count_changes' will be removed in the next patch.
> > 
> > Part of #4511
> > 
> > @TarantoolBot document
> > Title: SQL SET statement
> > SQL SET statement is used to change SQL settings. To change the
> > value of an SQL parameter, use the following syntax:
> > 
> > SET <name of the setting> = <value of the setting>;
> > 
> > Currently available SQL settings:
> > 'sql_defer_foreign_keys'
> > 'sql_full_column_names'
> > 'sql_recursive_triggers'
> > 'sql_reverse_unordered_selects'
> > 'sql_compound_select_limit'
> > 'sql_default_engine'
> > 
> > In addition, SQL debugging settings can also be changed using this
> > statement in the debug build:
> > 'sql_parser_trace'
> > 'sql_select_trace'
> > 'sql_trace'
> > 'sql_vdbe_addoptrace'
> > 'sql_vdbe_debug'
> > 'sql_vdbe_eqp'
> > 'sql_vdbe_listing'
> > 'sql_vdbe_trace'
> > 'sql_where_trace'
> > 
> > Example of usage:
> > SET full_column_names = true;
> 
> 1. I tried this:
> 
> tarantool> box.execute('SET full_column_names = true;')
> ---
> - null
> - Setting is not found
> ...
> 
> ???
> 
Fixed commit-message. Now this option called
'sql_full_column_names'.

> > SET sql_compound_select_limit = 10;
> > SET sql_default_engine = 'memtx';
> 
> 2. It would be cool to sum up here what is a purpose of
> PRAGMA and SET. How are they different. From the code I
> see, that looks like PRAGMA never changes anything. It
> only returns something. While SET only sets and never
> returns, right?
> 
How pragma works:
PRAGMA vdbe_trace = true; -- Sets vdbe_trace, returns nothing.
PRAGMA vdbe_trace; -- Returns current value of vdbe_trace flag.

How SET works:
SET sql_vdbe_trace = true; -- Sets vdbe_trace, returns nothing.

> In the next patch I see diff like this:
> 
> > -        return test:execsql "PRAGMA full_column_names"
> > -    end, {
> > +        return box.space._vsession_settings:get("sql_full_column_names").value
> > +    end,
> 
> Is there any plan how to make it simpler? Seems like it is
> impossible for a user to get session settings other than via
> direct select from a system space. It was simpler with PRAGMA.
> 
As far as I know, there is no such plans. It definitely was
simpler with PRAGMA, but it was decided to remove PRAGMA.
I do not know exact reaso why.

> > 
> > diff --git a/src/box/sql/build.c b/src/box/sql/build.c
> > index ce87b88..77f8dd4 100644
> > --- a/src/box/sql/build.c
> > +++ b/src/box/sql/build.c
> > @@ -3275,6 +3275,21 @@ enum {
> >  	SQL_SESSION_OPTION_max,
> >  };
> >  
> > +
> 
> 3. Nit: unnecessary empty line.
> 
Fixed. Diff below.

> > +/**
> > + * Identifiers of all SQL global options that can be viewed. The
> > + * identifier of the option is equal to its place in the sorted
> > + * list of global options, which starts at 0.
> > + *
> > + * It is IMPORTANT that these options are sorted by name. If this
> > + * is not the case, the result returned by the _vsession_settings
> > + * space iterator will not be sorted properly.
> 
> 4. First question - why should they be sorted? Second question -
> aren't they removed from _vsession_settings space?
> 
Fixed:
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -3275,16 +3275,7 @@ enum {
 	SQL_SESSION_OPTION_max,
 };
 
-
-/**
- * Identifiers of all SQL global options that can be viewed. The
- * identifier of the option is equal to its place in the sorted
- * list of global options, which starts at 0.
- *
- * It is IMPORTANT that these options are sorted by name. If this
- * is not the case, the result returned by the _vsession_settings
- * space iterator will not be sorted properly.
- */
+/**  Identifiers of all SQL global options that can be set. */
 enum {
 	SQL_GLOBAL_OPTION_COMPOUND_SELECT_LIMIT = 0,
 	SQL_GLOBAL_OPTION_max,
@@ -3347,8 +3338,6 @@ static struct sql_option_metadata sql_session_opts[] = {
 /**
  * Variable that contains names of the SQL global options, their
  * field types and mask if they have one or 0 if don't have.
- *
- * It is IMPORTANT that these options sorted by name.
  */
 static struct sql_option_metadata sql_global_opts[] = {
 	/** SQL_GLOBAL_OPTION_COMPOUND_SELECT_LIMIT */


> > + */
> > +enum {
> > +	SQL_GLOBAL_OPTION_COMPOUND_SELECT_LIMIT = 0,
> > +	SQL_GLOBAL_OPTION_max,
> > +};
> > @@ -3382,3 +3408,82 @@ sql_session_opt_tuple(struct tuple_format *format, int option_id,
> >  	*result = tuple;
> >  	return 0;
> >  }
> > +
> > +static void
> > +sql_set_session_option(struct Parse *parse_context, int id, struct Expr *value)
> > +{
> > +	struct session *session = current_session();
> > +	struct sql_option_metadata *option = &sql_session_opts[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->mask;
> > +		else
> > +			session->sql_flags &= ~option->mask;
> > +#ifndef NDEBUG
> > +		if (id == SQL_SESSION_OPTION_PARSER_TRACE) {
> > +			if (is_set)
> > +				sqlParserTrace(stdout, "parser: ");
> > +			else
> > +				sqlParserTrace(NULL, NULL);
> > +		}
> > +#endif
> > +	} else {
> > +		assert(id == SQL_SESSION_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;
> > +	}
> > +}
> 
> 5. Wait. So the settings are set during parsing? Isn't it wrong?
> 'Parser only parses' and everything? PRAGMA works in runtime.
No, PRAGMA also set during parsing. I once suggested to
change it, so parser would only parse, but my suggestion
was declined.

Examples of pragma:

tarantool> box.execute('pragma vdbe_trace = 1')
---
- row_count: 0
...

tarantool> box.execute('pragma full_column_names = 1')
SQL: [pragma full_column_names = 1]
VDBE Trace:
 102>    0 Init             0    1    0               00 Start at 1
 102>    1 Halt             0    0    0               00 
---
- row_count: 0
...

tarantool> box.execute('pragma vdbe_trace = 1')
SQL: [pragma vdbe_trace = 1]
VDBE Trace:
 102>    0 Init             0    1    0               00 Start at 1
 102>    1 Halt             0    0    0               00 
---
- row_count: 0
...

New description:

    sql: introduce SET statement
    
    This patch creates an SQL SET statement. This statement replaces
    pragmas that can modify SQL settings. List of pragmas that will
    have the corresponding option in SET:
    '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'
    
    All these pragmas along with the pragmas 'short_column_names' and
    'count_changes' will be removed in the next patch.
    
    Part of #4511
    
    @TarantoolBot document
    Title: SQL SET statement
    SQL SET statement is used to change SQL settings. To change the
    value of an SQL parameter, use the following syntax:
    
    SET <name of the setting> = <value of the setting>;
    
    Currently available SQL settings:
    'sql_defer_foreign_keys'
    'sql_full_column_names'
    'sql_recursive_triggers'
    'sql_reverse_unordered_selects'
    'sql_compound_select_limit'
    'sql_default_engine'
    
    In addition, SQL debugging settings can also be changed using this
    statement in the debug build:
    'sql_parser_trace'
    'sql_select_trace'
    'sql_trace'
    'sql_vdbe_addoptrace'
    'sql_vdbe_debug'
    'sql_vdbe_eqp'
    'sql_vdbe_listing'
    'sql_vdbe_trace'
    'sql_where_trace'
    
    All of these setting with exception of 'sql_compound_select_limit'
    are session-local settings. Their value can be viewed in
    _vsession_settings sysview.
    
    Example of usage:
    SET sql_full_column_names = true;
    SET sql_compound_select_limit = 10;
    SET sql_default_engine = 'memtx';



More information about the Tarantool-patches mailing list