From: "n.pettik" <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: Ivan Koptelov <ivan.koptelov@tarantool.org> Subject: [tarantool-patches] Re: [PATCH 1/2] sql: add better collation determination in functions Date: Thu, 28 Mar 2019 15:50:19 +0300 [thread overview] Message-ID: <B7D1593D-4A1F-4C45-AE8D-ED86451418BB@tarantool.org> (raw) In-Reply-To: <73268E75-2978-465E-8E82-1EEC0DCE92CA@tarantool.org> > Thank you for noticing, fixed now: > diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > index 8c1889d8a..34abb9665 100644 > --- a/src/box/sql/expr.c > +++ b/src/box/sql/expr.c > @@ -4102,65 +4102,34 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) > * is done using ANSI rules from > * collations_check_compatibility(). > */ > - if (nFarg == 1) { > - bool unused; > - uint32_t id; > - if (sql_expr_coll(pParse, > - pFarg->a[0].pExpr, &unused, > - &id, &coll) != 0) > - return 0; > - } > if ((pDef->funcFlags & SQL_FUNC_NEEDCOLL) != 0 && > - coll == NULL && nFarg > 1) { coll == NULL is redundant check: before this branch this variable is assigned only once with NULL value. > + coll == NULL) { > struct coll *unused = NULL; > uint32_t curr_id = COLL_NONE; > bool is_curr_forced = false; > > - uint32_t temp_id = COLL_NONE; > - bool is_temp_forced = false; > - > - uint32_t lhs_id = COLL_NONE; > - bool is_lhs_forced = false; > + uint32_t next_id = COLL_NONE; > + bool is_next_forced = false; > > - uint32_t rhs_id = COLL_NONE; > - bool is_rhs_forced = false; > + if (sql_expr_coll(pParse, pFarg->a[0].pExpr, > + &is_curr_forced, &curr_id, > + &unused) != 0) > + return 0; > > - for (int i = 0; i < nFarg; i++) { > + for (int j = 1; j < nFarg; j++) { > if (sql_expr_coll(pParse, > - pFarg->a[i].pExpr, > - &is_lhs_forced, > - &lhs_id, > + pFarg->a[j].pExpr, > + &is_next_forced, > + &next_id, > &unused) != 0) > return 0; > > - for (int j = i + 1; j < nFarg; j++) { > - if (sql_expr_coll(pParse, > - pFarg->a[j].pExpr, > - &is_rhs_forced, > - &rhs_id, > - &unused) != 0) > - return 0; > - > - if (collations_check_compatibility( > - lhs_id, is_lhs_forced, > - rhs_id, is_rhs_forced, > - &temp_id) != 0) { > - pParse->is_aborted = true; > - return 0; > - } > - > - is_temp_forced = (temp_id == > - lhs_id) ? > - is_lhs_forced : > - is_rhs_forced; > - > - if (collations_check_compatibility( > - curr_id, is_curr_forced, > - temp_id, is_temp_forced, > - &curr_id) != 0) { > - pParse->is_aborted = true; > - return 0; > - } > + if (collations_check_compatibility( > + curr_id, is_curr_forced, > + next_id, is_next_forced, > + &curr_id) != 0) { > + pParse->is_aborted = true; > + return 0; > } > } > coll = coll_by_id(curr_id)->coll; >> >>> + >>> + if (collations_check_compatibility( >>> + lhs_id, is_lhs_forced, >>> + rhs_id, is_rhs_forced, >>> + &temp_id) != 0) { >>> + pParse->rc = >>> + SQL_TARANTOOL_ERROR; >>> + pParse->nErr++; >>> + return 0; >>> + } >>> + >>> + is_temp_forced = (temp_id == >>> + lhs_id) ? >>> + is_lhs_forced : >>> + is_rhs_forced; >>> + >>> + if (collations_check_compatibility( >>> + curr_id, is_curr_forced, >>> + temp_id, is_temp_forced, >>> + &curr_id) != 0) { >>> + pParse->rc = >>> + SQL_TARANTOOL_ERROR; >>> + pParse->nErr++; >>> + return 0; >>> + } You don’t update is_curr_forced, and it allows to use invalid collation mix: tarantool> select min ('abc', 'asd' collate "binary", 'abc' COLLATE "unicode") --- - - ['abc'] ... >>> + } >>> } >>> + coll = coll_by_id(curr_id)->coll; >>> } >>> if (pFarg) { >>> if (constMask) { >>> diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h >>> index 8967ea3e0..47ee474bb 100644 >>> --- a/src/box/sql/sqlInt.h >>> +++ b/src/box/sql/sqlInt.h >>> @@ -1660,7 +1660,13 @@ struct FuncDestructor { >>> #define SQL_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ >>> #define SQL_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ >>> #define SQL_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ >>> -#define SQL_FUNC_NEEDCOLL 0x0020 /* sqlGetFuncCollSeq() might be called */ >>> +#define SQL_FUNC_NEEDCOLL 0x0020 /* sqlGetFuncCollSeq() might be called. >>> + * The flag is set when the collation >>> + * of function arguments should be >>> + * determined, using rules in >>> + * collations_check_compatibility() >>> + * function. >>> + */ >>> #define SQL_FUNC_LENGTH 0x0040 /* Built-in length() function */ >>> #define SQL_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ >>> #define SQL_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ >>> -- >> >> Please, provide basic test cases involving one or more built-in >> functions and incompatible arguments (at least min-max funcs use it). >> Moreover, this flag can’t be set for user-defined functions, which is pretty sad. > Add a few tests: > diff --git a/test/sql-tap/func5.test.lua b/test/sql-tap/func5.test.lua > index 6605a2ba1..4282fdac8 100755 > --- a/test/sql-tap/func5.test.lua > +++ b/test/sql-tap/func5.test.lua > @@ -1,6 +1,6 @@ > #!/usr/bin/env tarantool > test = require("sqltester") > -test:plan(5) > +test:plan(9) > > --!./tcltestrunner.lua > -- 2010 August 27 > @@ -98,5 +98,59 @@ test:do_execsql_test( > -- </func5-2.2> > }) > > +-- The following tests ensures that max() and min() functions > +-- raise error if argument's collations are incompatible. > + > +test:do_catchsql_test( > + "func-5-3.1", > + [[ > + SELECT max('a' COLLATE "unicode", 'A' COLLATE "unicode_ci"); > + ]], > + { > + -- <func5-3.1> > + 1, "Illegal mix of collations" > + -- </func5-3.1> > + } > +) > + > +test:do_catchsql_test( > + "func-5-3.2", > + [[ > + CREATE TABLE test1 (s1 VARCHAR(5) PRIMARY KEY COLLATE "unicode"); > + CREATE TABLE test2 (s2 VARCHAR(5) PRIMARY KEY COLLATE "unicode_ci"); > + INSERT INTO test1 VALUES ('a'); > + INSERT INTO test2 VALUES ('a'); > + SELECT max(s1, s2) FROM test1 JOIN test2; > + ]], > + { > + -- <func5-3.2> > + 1, "Illegal mix of collations" > + -- </func5-3.2> > + } > +) > + > +test:do_catchsql_test( > + "func-5-3.3", > + [[ > + SELECT min('a' COLLATE "unicode", 'A' COLLATE "unicode_ci”); Please add tests involving more than two params. Example of illegal collation mix passing your tests I pointed out above.
next prev parent reply other threads:[~2019-03-28 12:50 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-20 11:11 [tarantool-patches] [PATCH 0/2] sql: add better coll. determination & position func Ivan Koptelov 2019-03-20 11:11 ` [tarantool-patches] [PATCH 1/2] sql: add better collation determination in functions Ivan Koptelov 2019-03-25 19:26 ` [tarantool-patches] " n.pettik 2019-03-27 13:38 ` i.koptelov 2019-03-28 12:50 ` n.pettik [this message] 2019-03-28 14:08 ` i.koptelov 2019-03-29 9:57 ` n.pettik 2019-03-20 11:11 ` [tarantool-patches] [PATCH 2/2] sql: rename instr to position & add collation usage Ivan Koptelov 2019-03-20 12:59 ` [tarantool-patches] Re: [PATCH 1/2] " i.koptelov 2019-03-26 12:32 ` [tarantool-patches] Re: [PATCH 2/2] " n.pettik 2019-03-27 13:39 ` i.koptelov 2019-03-28 12:57 ` n.pettik 2019-04-01 14:15 ` [tarantool-patches] Re: [PATCH 0/2] sql: add better coll. determination & position func 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=B7D1593D-4A1F-4C45-AE8D-ED86451418BB@tarantool.org \ --to=korablev@tarantool.org \ --cc=ivan.koptelov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH 1/2] sql: add better collation determination in functions' \ /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