From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: "n.pettik" <korablev@tarantool.org>, tarantool-patches@freelists.org Subject: [tarantool-patches] Re: [PATCH 3/3] sql: fix passing FP values to integer iterator Date: Sun, 2 Jun 2019 20:11:07 +0200 [thread overview] Message-ID: <91e73947-30b8-c172-f52c-be109034e0dd@tarantool.org> (raw) In-Reply-To: <F6271685-CFB2-4439-8514-BBD3BE0CBAC4@tarantool.org> Hi! Thanks for the fixes! See 3 comments below. > diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c > index 3025e5e6b..107b9802d 100644 > --- a/src/box/sql/wherecode.c > +++ b/src/box/sql/wherecode.c > @@ -1115,7 +1115,8 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W > int seek_addr = 0; > for (int i = 0; i < nEq; i++) { > enum field_type type = idx_def->key_def->parts[i].type; > - if (type == FIELD_TYPE_INTEGER) { > + if (type == FIELD_TYPE_INTEGER || > + type == FIELD_TYPE_UNSIGNED) { > /* > * OP_MustBeInt consider NULLs as > * non-integer values, so firstly > @@ -1128,8 +1129,9 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W > } > } > /* Inequality constraint comes always at the end of list. */ > - if (pRangeStart != NULL && > - idx_def->key_def->parts[nEq].type == FIELD_TYPE_INTEGER) > + enum field_type ineq_type = idx_def->key_def->parts[nEq].type; > + if (pRangeStart != NULL && (ineq_type == FIELD_TYPE_INTEGER || > + ineq_type == FIELD_TYPE_UNSIGNED)) 1. Please, add a test for unsigned. I thought that it is quite obvious - everything needs a test, especially if the bug was found during a review. > force_integer_reg = regBase + nEq; > emit_apply_type(pParse, regBase, nConstraint - bSeekPastNull, > start_types); > >>> diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c >>> index 977c0fced..e779729c7 100644 >>> --- a/src/box/sql/wherecode.c >>> +++ b/src/box/sql/wherecode.c >>> @@ -1086,31 +1086,61 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W >>> start_constraints = 1; >>> } >>> struct index_def *idx_pk = space->index[0]->def; >>> - int fieldno = idx_pk->key_def->parts[0].fieldno; >>> - >>> uint32_t pk_part_count = idx_pk->key_def->part_count; >>> - if (pk_part_count == 1 && >>> - space->def->fields[fieldno].type == FIELD_TYPE_INTEGER) { >>> - /* Right now INTEGER PRIMARY KEY is the only option to >>> - * get Tarantool's INTEGER column type. Need special handling >>> - * here: try to loosely convert FLOAT to INT. If RHS type >>> - * is not INT or FLOAT - skip this ites, i.e. goto addrNxt. >>> - */ >>> - int limit = pRangeStart == NULL ? nEq : nEq + 1; >>> - for (int i = 0; i < limit; i++) { >>> - if (idx_def->key_def->parts[i].fieldno == >>> - idx_pk->key_def->parts[0].fieldno) { >>> - /* Here: we know for sure that table has INTEGER >>> - PRIMARY KEY, single column, and Index we're >>> - trying to use for scan contains this column. */ >>> - if (i < nEq) >>> - sqlVdbeAddOp2(v, OP_MustBeInt, regBase + i, addrNxt); >>> - else >>> - force_integer_reg = regBase + i; >>> - break; >>> - } >>> + /* >>> + * Tarantool's iterator over integer fields doesn't >>> + * tolerate floating point values. Hence, if term >>> + * is equality comparison and value of operand is >>> + * not integer, we can skip it since it always >>> + * results in false: INT a == 0.5 -> false; >>> + * It is done using OP_MustBeInt facilities. >>> + * In case term is greater comparison (a > ?), we >>> + * should notify OP_SeekGT to process truncation of >>> + * floating point value: a > 0.5 -> a >= 1; >>> + * It is done by setting P5 flag for OP_Seek*. >>> + * It is worth mentioning that we do not need >>> + * this step when it comes for less comparison: >>> + * key is NULL in this case: values are ordered >>> + * as NULL, ... NULL, min_value, ..., so to >>> + * fetch min value we pass NULL to GT iterator. >> >> 4. I did not get the 'less comparator == compare with NULL' >> idea. Firstly you describe how to compare 'a > ?', this is >> fully understandable. Then you, as I see, go to the 'a < ?' >> case, but somewhy say, that it is the same as 'NULL < ?'. >> Do not understand. > > I say that in this case key which is passed to iterator is NULL > and type of iterator is GE. 2. Why? I still do not understand. What if I wrote 'a < 100'? you do not replace 100 with NULL. But the comment says, that for any 'less' operator a key is NULL: "when it comes for less comparison key is NULL". > Consequently, pRangeStart is NULL. > I’ve slightly updated this part of comment: > > diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c > index 3025e5e6b..01ee9ce90 100644 > --- a/src/box/sql/wherecode.c > +++ b/src/box/sql/wherecode.c > @@ -1089,10 +1089,10 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W > * floating point value: a > 0.5 -> a >= 1; > * It is done by setting P5 flag for OP_Seek*. > * It is worth mentioning that we do not need > - * this step when it comes for less comparison: > - * key is NULL in this case: values are ordered > - * as NULL, ... NULL, min_value, ..., so to > - * fetch min value we pass NULL to GT iterator. > + * this step when it comes for less (<) comparison > + * of nullable field. Key is NULL in this case: > + * values are ordered as NULL, ... NULL, min_value, > + * so to fetch min value we pass NULL to GT iterator. > > > @@ -1112,24 +1112,33 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W > /* > * OP_MustBeInt consider NULLs as > * non-integer values, so firstly > * check whether value is NULL or not. > */ > - seek_addr = sqlVdbeAddOp1(v, OP_IsNull, > + seek_addrs[i] = sqlVdbeAddOp1(v, OP_IsNull, > regBase); 3. Now the indentation is broken. > sqlVdbeAddOp2(v, OP_MustBeInt, regBase + i, > addrNxt); > } > } > /* Inequality constraint comes always at the end of list. */ >
next prev parent reply other threads:[~2019-06-02 18:11 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-24 17:39 [tarantool-patches] [PATCH 0/3] Fix passing key with different from iterator's type Nikita Pettik 2019-05-24 17:39 ` [tarantool-patches] [PATCH 1/3] sql: remove redundant check of space format from QP Nikita Pettik 2019-05-24 17:39 ` [tarantool-patches] [PATCH 2/3] sql: remove redundant type derivation " Nikita Pettik 2019-05-27 21:49 ` [tarantool-patches] " Vladislav Shpilevoy 2019-05-28 19:58 ` n.pettik 2019-05-24 17:39 ` [tarantool-patches] [PATCH 3/3] sql: fix passing FP values to integer iterator Nikita Pettik 2019-05-25 5:51 ` [tarantool-patches] " Konstantin Osipov 2019-05-27 21:49 ` Vladislav Shpilevoy 2019-05-28 7:19 ` Konstantin Osipov 2019-05-28 11:31 ` Vladislav Shpilevoy 2019-05-29 7:02 ` Konstantin Osipov 2019-05-28 13:00 ` n.pettik 2019-05-29 9:14 ` Konstantin Osipov 2019-05-27 21:49 ` Vladislav Shpilevoy 2019-05-28 19:58 ` n.pettik 2019-06-02 18:11 ` Vladislav Shpilevoy [this message] 2019-06-06 13:51 ` n.pettik 2019-06-06 19:07 ` Vladislav Shpilevoy 2019-07-11 9:19 ` [tarantool-patches] Re: [PATCH 0/3] Fix passing key with different from iterator's type 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=91e73947-30b8-c172-f52c-be109034e0dd@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH 3/3] sql: fix passing FP values to integer iterator' \ /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