Tarantool development patches archive
 help / color / mirror / Atom feed
From: "n.pettik" <korablev@tarantool.org>
To: tarantool-patches@freelists.org
Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Subject: [tarantool-patches] Re: [PATCH v1 3/3] sql: dissallow bindings for DDL
Date: Tue, 4 Sep 2018 14:00:04 +0300	[thread overview]
Message-ID: <EDD77E8A-40A8-4417-8EFC-CE245976B3D8@tarantool.org> (raw)
In-Reply-To: <5049d3e7b70b7091c51ac99fc64f14a07c879c8a.1535730218.git.kshcherbatov@tarantool.org>

Previous two patches looks OK to me.

> Bindings could not be used in stored ACTs because they allocate

Nit: “AST”.

> memory registers and makes

Nit: “make” (or better “process").

> assignments on parse sequentially.

Nit: “during parsing”.

So? Describe bug in details pls - it could help reviewer as well
as those who will resurrect some day these bindings.
Also, I guess problem is quite more sophisticated as it seems:
a) For check constraint bindings really make no sense
(I can’t come up with example how they can be used there at all).
b) For triggers currently we don’t have proper mechanism, which
would allow to use bindings. Original SQLite also lacks it.
To reuse the same trigger’s body with different parameters we should
not only be able to store it as prepared statement and substitute literals,
but also give trigger new name. 

> Original sqlite3 did validations that persistent AST doesn't have
> auto-assigment Varibles on triggers and checks creation.
> On DDL integration complete we've get rid this mechanism.

Nits: “completion”, “got rid of”.

> Now it should be returned.

Well, actually your approach is slightly different: explain that
DDL (to be more precise - triggers and checks creation) relies on
parse_only flag in parser. Hence, you can check it and throw an
error during parsing.

> 
> Closes #3653.
> ---
> src/box/space_def.c         |  3 ++-
> src/box/sql/parse.y         |  6 +++++-
> src/box/sql/tokenize.c      |  8 ++++----
> test/sql-tap/check.test.lua |  4 ++--
> test/sql/checks.result      | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> test/sql/checks.test.lua    | 18 +++++++++++++++++-
> 6 files changed, 74 insertions(+), 10 deletions(-)
> 
> diff --git a/src/box/space_def.c b/src/box/space_def.c
> index f5ca0b5..542289e 100644
> --- a/src/box/space_def.c
> +++ b/src/box/space_def.c
> @@ -338,7 +338,8 @@ checks_array_decode(const char **str, uint32_t len, char *opt, uint32_t errcode,
> 			box_error_t *err = box_error_last();
> 			if (box_error_code(err) != ENOMEM) {
> 				snprintf(errmsg, TT_STATIC_BUF_LEN,
> -					 "invalid expression specified");
> +					 "invalid expression specified (%s)",
> +					 box_error_message(err));
> 				diag_set(ClientError, errcode, field_no,
> 					 errmsg);
> 			}
> diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
> index d8532d3..60cf3f3 100644
> --- a/src/box/sql/parse.y
> +++ b/src/box/sql/parse.y
> @@ -881,7 +881,11 @@ term(A) ::= INTEGER(X). {
> }
> expr(A) ::= VARIABLE(X).     {
>   Token t = X;
> -  if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
> +  if (pParse->parse_only) {
> +    spanSet(&A, &t, &t);
> +    sqlite3ErrorMsg(pParse, "bindings are not allowed in DDL");
> +    A.pExpr = NULL;
> +  } else if (!(X.z[0]=='#' && sqlite3Isdigit(X.z[1]))) {
>     u32 n = X.n;
>     spanExpr(&A, pParse, TK_VARIABLE, X);
>     if (A.pExpr->u.zToken[0] == '?' && n > 1)
> diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
> index ec06456..4eebfe5 100644
> --- a/src/box/sql/tokenize.c
> +++ b/src/box/sql/tokenize.c
> @@ -561,10 +561,10 @@ sql_expr_compile(sqlite3 *db, const char *expr, int expr_len)
> 	}
> 	sprintf(stmt, "%s%.*s", outer, expr_len, expr);
> 
> -	char *unused;
> -	if (sqlite3RunParser(&parser, stmt, &unused) != SQLITE_OK ||
> +	char *sql_error = NULL;
> +	if (sqlite3RunParser(&parser, stmt, &sql_error) != SQLITE_OK ||
> 	    parser.parsed_ast_type != AST_TYPE_EXPR) {
> -		diag_set(ClientError, ER_SQL_EXECUTE, stmt);
> +		diag_set(ClientError, ER_SQL, sql_error);
> 	} else {
> 		expression = parser.parsed_ast.expr;
> 		parser.parsed_ast.expr = NULL;
> @@ -602,7 +602,7 @@ sql_trigger_compile(struct sqlite3 *db, const char *sql)
> 	struct Parse parser;
> 	sql_parser_create(&parser, db);
> 	parser.parse_only = true;
> -	char *sql_error;
> +	char *sql_error = NULL;
> 	struct sql_trigger *trigger = NULL;
> 	if (sqlite3RunParser(&parser, sql, &sql_error) != SQLITE_OK ||
> 	    parser.parsed_ast_type != AST_TYPE_TRIGGER) {
> diff --git a/test/sql-tap/check.test.lua b/test/sql-tap/check.test.lua
> index ff36552..f03ac7b 100755
> --- a/test/sql-tap/check.test.lua
> +++ b/test/sql-tap/check.test.lua
> @@ -555,7 +555,7 @@ test:do_catchsql_test(
>         );
>     ]], {
>         -- <check-5.1>
> -        1, "Failed to create space 'T5': SQL error: parameters prohibited in CHECK constraints"
> +        1, "Wrong space options (field 5): invalid expression specified (SQL error: bindings are not allowed in DDL)"
>         -- </check-5.1>
>     })

Could we keep previous error message? It looks satisfactory actually.
The same for triggers: could we use message like
“Failed to create trigger ‘…’: parameters prohibited in trigger definition”?
Or present your persuasive arguments :)

> diff --git a/test/sql/checks.test.lua b/test/sql/checks.test.lua
> index fb95809..3506d5c 100644
> --- a/test/sql/checks.test.lua
> +++ b/test/sql/checks.test.lua
> @@ -43,11 +43,27 @@ format = {{name = 'X', type = 'unsigned'}}
> t = {513, 1, 'test', 'memtx', 0, opts, format}
> s = box.space._space:insert(t)
> 
> -
> --
> -- gh-3611: Segfault on table creation with check referencing this table
> --
> box.sql.execute("CREATE TABLE w2 (s1 INT PRIMARY KEY, CHECK ((SELECT COUNT(*) FROM w2) = 0));")
> box.sql.execute("DROP TABLE w2;")
> 
> +--
> +-- gh-3653: Dissallow bindings for DDL
> +--
> +box.sql.execute("CREATE TABLE t1(a INT PRIMARY KEY, b INT);")
> +space_id = box.space.T1.id
> +box.sql.execute("CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.a = ? BEGIN SELECT 1; END;")
> +tuple = {"TR1", space_id, {sql = [[CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.a = ? BEGIN SELECT 1; END;]]}}

This test should be moved to test/sql/triggers.test.lua
(Since this test is about checks only).

  reply	other threads:[~2018-09-04 11:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-31 15:45 [tarantool-patches] [PATCH v1 0/3] " Kirill Shcherbatov
2018-08-31 15:45 ` [tarantool-patches] [PATCH v1 1/3] sql: fix sql_check_list_item_init double free Kirill Shcherbatov
2018-08-31 15:45 ` [tarantool-patches] [PATCH v1 2/3] sql: fix sql_*_compile functions leak on error Kirill Shcherbatov
2018-08-31 15:45 ` [tarantool-patches] [PATCH v1 3/3] sql: dissallow bindings for DDL Kirill Shcherbatov
2018-09-04 11:00   ` n.pettik [this message]
2018-09-06 13:04     ` [tarantool-patches] " Kirill Shcherbatov
2018-09-10 21:52       ` n.pettik
2018-09-11  7:21         ` Kirill Shcherbatov
2018-09-11 23:03           ` n.pettik
2018-09-13  6:13             ` Kirill Shcherbatov
2018-09-13 10:12 ` [tarantool-patches] Re: [PATCH v1 0/3] " Kirill Yukhin

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=EDD77E8A-40A8-4417-8EFC-CE245976B3D8@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=kshcherbatov@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='[tarantool-patches] Re: [PATCH v1 3/3] sql: dissallow bindings for DDL' \
    /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