From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: Mergen Imeev <imeevma@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v1 2/2] sql: fix comparison in IN with subselect Date: Tue, 28 Apr 2020 00:53:11 +0200 [thread overview] Message-ID: <89021f4c-beb3-e23b-038d-ad41f017e94e@tarantool.org> (raw) In-Reply-To: <20200422100303.GA29050@tarantool.org> Hi! Thanks for the fixes! >>> values from subselect contains a value that is not comparable with >>> the left value, it throws an error. >>> >>> Closes #4692 >>> --- >>> src/box/sql/expr.c | 27 ++++++++++++++++++++++ >>> .../gh-4692-comparison-in-IN-operator.test.lua | 24 ++++++++++++++++++- >>> test/sql-tap/in3.test.lua | 2 +- >>> test/sql-tap/subquery.test.lua | 8 +++---- >>> test/sql-tap/tkt-80e031a00f.test.lua | 8 +++---- >>> test/sql/boolean.result | 12 +++++----- >>> 6 files changed, 65 insertions(+), 16 deletions(-) >>> >>> diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c >>> index 4fe4f83..c20c04b 100644 >>> --- a/src/box/sql/expr.c >>> +++ b/src/box/sql/expr.c >>> @@ -2711,6 +2711,28 @@ expr_in_type(Parse *pParse, Expr *pExpr) >>> return zRet; >>> } >>> >>> +static inline bool >>> +is_in_type_cmp(struct Parse *parse, enum field_type lhs_type, struct Expr *expr) >> >> 2. Sorry, can't parse the name. Can't understand what is 'is cmp'. >> Could you please rename and add a comment maybe? >> > Fixed. I gave it a new name, 'is_comparable'. It is not a > lot better, still since it is just a static inline function, > will this be enough? I am afraid it is too common for a huge file like expr.c. Just extend the old name "is_in_type_cmp()" -> "are_in_args_comparable()". > From 946cd381dd0af8ba1b534e9721417423f315a542 Mon Sep 17 00:00:00 2001 > From: Mergen Imeev <imeevma@gmail.com> > Date: Wed, 15 Apr 2020 02:17:43 +0300 > Subject: [PATCH] sql: fix comparison in IN with subselect > > After this patch, the IN statement checks the compatibility of the > values from subselect on the right with the value on the left. If > values from subselect contains a value that is not comparable with > the left value, it throws an error. > > Closes #4692 > > diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > index 4fe4f83..9cd3a2c 100644 > --- a/src/box/sql/expr.c > +++ b/src/box/sql/expr.c > @@ -2711,6 +2711,49 @@ expr_in_type(Parse *pParse, Expr *pExpr) > return zRet; > } > > +/** > + * Check that arguments on both sides of IN are comparable. > + * > + * @param parse Parsing context. > + * @param pExpr Expr that contains all operands. > + * > + * @retval true if comparable, false otherwise. > + */ > +static inline bool > +is_comparable(struct Parse *parse, struct Expr *pExpr) > +{ > + uint32_t size = sqlExprVectorSize(pExpr->pLeft); > + ExprList *lhs_list = NULL; > + ExprList *rhs_list = pExpr->x.pSelect->pEList; > + u8 op = pExpr->pLeft->op; > + if (op == TK_REGISTER) > + op = pExpr->pLeft->op2; > + if (op == TK_VECTOR) > + lhs_list = pExpr->pLeft->x.pList; > + else if (op == TK_SELECT) > + lhs_list = pExpr->pLeft->x.pSelect->pEList; > + assert(size == 1 || lhs_list != NULL); What is happening on the lines above? Also, I see similar code below is_comparable() invocation: for (i = 0; i < nVal; i++) { Expr *p = sqlVectorFieldSubexpr (pLeft, i); if (sql_binary_compare_coll_seq(pParse, p, pEList->a[i].pExpr, &key_info->parts[i].coll_id) != 0) return 0; } It is ugly, but the point is they use sqlVectorFieldSubexpr(pLeft, i) without any 'TK_VECTOR', 'TK_SELECT', 'TK_REGISTER' checks. How does it work? And shouldn't we move this cycle into is_comparable(), because seems like it also checks if types are comparable when they are strings. However I am not sure. > + > + for (uint32_t i = 0; i < size; ++i) { > + struct Expr *lhs = lhs_list == NULL ? pExpr->pLeft : > + lhs_list->a[i].pExpr; > + struct Expr *rhs = rhs_list->a[i].pExpr; > + enum field_type lhs_type = sql_expr_type(lhs); > + enum field_type rhs_type = sql_expr_type(rhs); > + if (field_type1_contains_type2(lhs_type, rhs_type) || > + field_type1_contains_type2(rhs_type, lhs_type)) > + continue; > + if (sql_type_is_numeric(rhs_type) && > + sql_type_is_numeric(lhs_type)) > + continue; > + parse->is_aborted = true; > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, > + field_type_strs[rhs_type], field_type_strs[lhs_type]); > + return false; > + } > + return true; > +}
next prev parent reply other threads:[~2020-04-27 22:53 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-15 11:47 [Tarantool-patches] [PATCH v1 0/2] sql: fix comparison in IN operator imeevma 2020-04-15 11:47 ` [Tarantool-patches] [PATCH v1 1/2] sql: fix comparison in IN with list of values imeevma 2020-04-27 22:53 ` Vladislav Shpilevoy 2020-04-30 10:32 ` Mergen Imeev 2020-05-03 17:17 ` Vladislav Shpilevoy 2020-04-15 11:47 ` [Tarantool-patches] [PATCH v1 2/2] sql: fix comparison in IN with subselect imeevma 2020-04-19 17:47 ` Vladislav Shpilevoy 2020-04-22 10:03 ` Mergen Imeev 2020-04-27 22:53 ` Vladislav Shpilevoy [this message] 2020-04-30 10:22 ` Mergen Imeev 2020-05-03 17:17 ` 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=89021f4c-beb3-e23b-038d-ad41f017e94e@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=imeevma@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v1 2/2] sql: fix comparison in IN with subselect' \ /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