From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org, Nikita Pettik <korablev@tarantool.org> Cc: kostja@tarantool.org Subject: [tarantool-patches] Re: [PATCH 7/9] sql: make predicates accept and return boolean Date: Tue, 16 Apr 2019 17:12:50 +0300 [thread overview] Message-ID: <29403d26-5619-32ec-d2a6-474cc5256994@tarantool.org> (raw) In-Reply-To: <8a92ae4cb6030c442fc540fa0ea07d9e6daa4e98.1555252410.git.korablev@tarantool.org> Thanks for the patch! See 5 comments below. On 14/04/2019 18:04, Nikita Pettik wrote: > This patch make following predicates accept and return only values > of type boolean: IN, EXISTS, OR, AND, NOT, BETWEEN, IS (NULL). > In terms of approach, it is enough to patch opcodes implementing these > predicates. > > Part of #3723 > --- > src/box/sql/expr.c | 26 ++++++++++++-------------- > src/box/sql/parse.y | 4 +++- > src/box/sql/parse_def.c | 5 +++++ > src/box/sql/select.c | 2 +- > src/box/sql/sqlInt.h | 1 + > src/box/sql/vdbe.c | 37 ++++++++++++++----------------------- > test/sql-tap/cse.test.lua | 6 +++--- > test/sql-tap/e_select1.test.lua | 2 +- > test/sql-tap/in1.test.lua | 6 +++--- > test/sql-tap/misc3.test.lua | 2 +- > test/sql-tap/select4.test.lua | 2 +- > test/sql-tap/tkt3541.test.lua | 2 +- > test/sql/types.result | 22 +++++++++++++--------- > 13 files changed, 59 insertions(+), 58 deletions(-) > > diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > index e4de472a8..c5ec55de2 100644 > --- a/src/box/sql/expr.c > +++ b/src/box/sql/expr.c > @@ -1134,7 +1130,10 @@ sql_and_expr_new(struct sql *db, struct Expr *left_expr, > } else if (exprAlwaysFalse(left_expr) || exprAlwaysFalse(right_expr)) { > sql_expr_delete(db, left_expr, false); > sql_expr_delete(db, right_expr, false); > - return sql_expr_new(db, TK_INTEGER, &sqlIntTokens[0]); > + struct Expr *f = sql_expr_new(db, TK_FALSE, > + &sql_boolean_tokens[0]); > + f->type = FIELD_TYPE_BOOLEAN; 1. No check for f == NULL. 2. Why do you need f->type at all, if anyway you use sql_expr_type() to get the type? Why isn't this field dropped still? > + return f; > } else { > struct Expr *new_expr = sql_expr_new_anon(db, TK_AND); > sqlExprAttachSubtrees(db, new_expr, left_expr, right_expr); > diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y > index f64a84948..b520b23d5 100644 > --- a/src/box/sql/parse.y > +++ b/src/box/sql/parse.y > @@ -1237,11 +1237,13 @@ expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] { > ** regardless of the value of expr1. > */ > sql_expr_delete(pParse->db, A.pExpr, false); > - A.pExpr = sql_expr_new_dequoted(pParse->db, TK_INTEGER, &sqlIntTokens[N]); > + int tk = N == 0 ? TK_FALSE : TK_TRUE; > + A.pExpr = sql_expr_new_dequoted(pParse->db, tk, &sql_boolean_tokens[N]); 3. Why do you use 'dequoted'? Do you store not normalized names in sql_boolean_tokens? If you do, then why not to store already normalized names and use sql_expr_new() here so as to avoid ICU calls? A normalized name is always uppercased, but sql_boolean_tokens stores lowercase strings. I tried to do this: - A.pExpr = sql_expr_new_dequoted(pParse->db, tk, &sql_boolean_tokens[N]); + A.pExpr = sql_expr_new(pParse->db, tk, &sql_boolean_tokens[N]); And the tests passed. Why? Another question - why boolean constant needs zToken at all? As I understand, the only reason is that sqlExprCodeTarget parses zToken again even having ready at hand TK_FALSE and TK_TRUE values. If I am right, you can drop boolean_tokens array once you've fixed my comment 5 from the main patch (4/9). The same question could be asked for integer constants stored in struct Expr and having zToken. The only reason for that is the delayed parsing of the tokens, as I understand. First they all are stored in Expr.zToken, and then parsed in CodeTarget. But it would not be necessary if we parsed them right after reading and storing actual value into Expr.u.iValue. In such a case zToken would be used for identifiers and strings only, not for constants which I think appear quite often. The reasoning behind my proposal is that parsing of an integer is likely to be faster itself than calling ICU normalization functions. The same can be said about float/double values, but I do not see such a type in Expr.u. Of course, all these integer/float-related thoughts are not about this patchset. Probably, it is worth opening a separate issue. > if (A.pExpr == NULL) { > pParse->is_aborted = true; > return; > } > + A.pExpr->type = FIELD_TYPE_BOOLEAN; > }else if( Y->nExpr==1 ){ > /* Expressions of the form: > ** > diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua > index 4b25f936d..39c1cc4ca 100755 > --- a/test/sql-tap/cse.test.lua > +++ b/test/sql-tap/cse.test.lua > @@ -132,7 +132,7 @@ test:do_execsql_test( > test:do_execsql_test( > "cse-1.7", > [[ > - SELECT a, -a, ~a, NOT a, NOT NOT a, a-a, a+a, a*a, a/a, a FROM t1 > + SELECT a, -a, ~a, NOT CAST(a AS BOOLEAN), NOT NOT CAST(a AS BOOLEAN), a-a, a+a, a*a, a/a, a FROM t1 > ]], { > -- <cse-1.7> > 1, -1, -2, 0, 1, 0, 2, 1, 1, 1, 2, -2, -3, 0, 1, 0, 4, 4, 1, 2 4. Above the fourth selected column is 'NOT CAST(a AS BOOLEAN)'. It is either true or false, but in the result set it is 0. Why? First I thought, that probably 0 == false in Lua, but it is not as a test showed: tarantool> 0 == false --- - false ... tarantool> 1 == true --- - false ... > diff --git a/test/sql-tap/tkt3541.test.lua b/test/sql-tap/tkt3541.test.lua > index 08a9be557..05247728d 100755 > --- a/test/sql-tap/tkt3541.test.lua > +++ b/test/sql-tap/tkt3541.test.lua > @@ -39,7 +39,7 @@ test:do_test( > "tkt3541-1.2", > function() > return test:execsql [[ > - SELECT CASE NOT max(x) WHEN min(x) THEN 1 ELSE max(x) END FROM t1; > + SELECT CASE max(x) = 0 WHEN min(x) > 0 THEN 1 ELSE max(x) END FROM t1; 5. If negative numbers are not treated as FALSE, then I guess you meant 'min(x) <> 0'. > ]] > end, { > -- <tkt3541-1.2> My total diff which I am not sure why does not break tests: ============================================================================== diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index c5ec55de2..42b60babd 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -1130,10 +1130,7 @@ sql_and_expr_new(struct sql *db, struct Expr *left_expr, } else if (exprAlwaysFalse(left_expr) || exprAlwaysFalse(right_expr)) { sql_expr_delete(db, left_expr, false); sql_expr_delete(db, right_expr, false); - struct Expr *f = sql_expr_new(db, TK_FALSE, - &sql_boolean_tokens[0]); - f->type = FIELD_TYPE_BOOLEAN; - return f; + return sql_expr_new_anon(db, TK_FALSE); } else { struct Expr *new_expr = sql_expr_new_anon(db, TK_AND); sqlExprAttachSubtrees(db, new_expr, left_expr, right_expr); diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index b520b23d5..f75999c35 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -1238,12 +1238,11 @@ expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] { */ sql_expr_delete(pParse->db, A.pExpr, false); int tk = N == 0 ? TK_FALSE : TK_TRUE; - A.pExpr = sql_expr_new_dequoted(pParse->db, tk, &sql_boolean_tokens[N]); + A.pExpr = sql_expr_new(pParse->db, tk, &sql_boolean_tokens[N]); if (A.pExpr == NULL) { pParse->is_aborted = true; return; } - A.pExpr->type = FIELD_TYPE_BOOLEAN; }else if( Y->nExpr==1 ){ /* Expressions of the form: ** ==============================================================================
next prev parent reply other threads:[~2019-04-16 14:12 UTC|newest] Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-14 15:03 [tarantool-patches] [PATCH 0/9] Introduce type BOOLEAN in SQL Nikita Pettik 2019-04-14 15:03 ` [tarantool-patches] [PATCH 1/9] sql: refactor mem_apply_numeric_type() Nikita Pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 2/9] sql: disallow text values participate in sum() aggregate Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:54 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:58 ` n.pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 3/9] sql: use msgpack types instead of custom ones Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:54 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:58 ` n.pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 4/9] sql: introduce type boolean Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:54 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:58 ` n.pettik 2019-04-23 21:06 ` Vladislav Shpilevoy 2019-04-14 15:04 ` [tarantool-patches] [PATCH 5/9] sql: improve type determination for column meta Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:54 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:58 ` n.pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 6/9] sql: make comparison predicate return boolean Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:54 ` n.pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 7/9] sql: make predicates accept and " Nikita Pettik 2019-04-16 14:12 ` Vladislav Shpilevoy [this message] 2019-04-18 17:55 ` [tarantool-patches] " n.pettik 2019-04-14 15:04 ` [tarantool-patches] [PATCH 9/9] sql: make <search condition> accept only boolean Nikita Pettik 2019-04-16 14:12 ` [tarantool-patches] " Vladislav Shpilevoy 2019-04-18 17:55 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:59 ` n.pettik 2019-04-23 21:06 ` Vladislav Shpilevoy 2019-04-23 22:01 ` n.pettik [not found] ` <b2a84f129c2343d3da3311469cbb7b20488a21c2.1555252410.git.korablev@tarantool.org> 2019-04-16 14:12 ` [tarantool-patches] Re: [PATCH 8/9] sql: make LIKE predicate return boolean result Vladislav Shpilevoy 2019-04-18 17:55 ` n.pettik 2019-04-22 18:02 ` Vladislav Shpilevoy 2019-04-23 19:58 ` n.pettik 2019-04-24 10:28 ` [tarantool-patches] Re: [PATCH 0/9] Introduce type BOOLEAN in SQL Vladislav Shpilevoy 2019-04-25 8:46 ` 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=29403d26-5619-32ec-d2a6-474cc5256994@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=korablev@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH 7/9] sql: make predicates accept and return boolean' \ /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