From: Vladislav Shpilevoy via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: imeevma@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v1 3/7] sql: rework OP_Seek* opcodes Date: Thu, 5 Aug 2021 00:25:49 +0200 [thread overview] Message-ID: <31aa2f05-09e9-ce24-5a46-894d3d23b8f7@tarantool.org> (raw) In-Reply-To: <8722fbfce0455e13c01672793f6a5075dc0fc458.1627504973.git.imeevma@gmail.com> Thanks for the patch! See 3 comments below. > diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h > index 47a940c56..5d1d7592e 100644 > --- a/src/box/sql/mem.h > +++ b/src/box/sql/mem.h > @@ -1028,3 +1028,20 @@ mpstream_encode_vdbe_mem(struct mpstream *stream, struct Mem *var); > char * > sql_vdbe_mem_encode_tuple(struct Mem *fields, uint32_t field_count, > uint32_t *tuple_size, struct region *region); > + > +static inline bool > +is_mem_num_min(const struct Mem *mem) > +{ > + return (mem->field_type == FIELD_TYPE_INTEGER && > + mem->type == MEM_TYPE_INT && mem->u.i == INT64_MIN) || > + (mem->field_type == FIELD_TYPE_UNSIGNED && > + mem->type == MEM_TYPE_UINT && mem->u.u == 0); > +} > + > +static inline bool > +is_mem_num_max(const struct Mem *mem) 1. Could you please name them to mem_is_num_min() and mem_is_num_max()? Also what if they are DOUBLE? Should't these functions be called then mem_is_int_min() and mem_is_int_max()? > +{ > + return (mem->field_type == FIELD_TYPE_INTEGER || > + mem->field_type == FIELD_TYPE_UNSIGNED) && > + mem->type == MEM_TYPE_UINT && mem->u.u == 0; > +} > diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c > index 62f58def9..a69402720 100644 > --- a/src/box/sql/vdbe.c > +++ b/src/box/sql/vdbe.c > @@ -2577,6 +2526,62 @@ case OP_Close: { > * > * See also: Found, NotFound, SeekGt, SeekGe, SeekLe > */ > +case OP_SeekLT: { /* jump, in3 */ > + struct VdbeCursor *cur = p->apCsr[pOp->p1]; > +#ifdef SQL_DEBUG > + cur->seekOp = pOp->opcode; > +#endif > + cur->nullRow = 0; > + cur->uc.pCursor->iter_type = ITER_LT; > + > + uint32_t len = pOp->p4.i; > + assert(pOp->p4type == P4_INT32); > + assert(len <= cur->key_def->part_count); > + struct Mem *mems = &aMem[pOp->p3]; > + bool is_le = false; > + bool is_zero = false; > + for (uint32_t i = 0; i < len; ++i) { > + enum field_type type = cur->key_def->parts[i].type; > + struct Mem *mem = &mems[i]; > + if (mem_is_field_compatible(mem, type)) > + continue; > + if (!sql_type_is_numeric(type) || !mem_is_num(mem)) { > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, > + mem_str(mem), field_type_strs[type]); > + goto abort_due_to_error; > + } > + int cmp = mem_cast_implicit_number(mem, type); > + is_le = is_le || cmp > 0; > + /* > + * If number before cast were less than min possible for given > + * field type, than there is no point to use iterator since we > + * won't find anything. > + */ > + is_zero = is_zero || (is_mem_num_min(mem) && cmp < 0); 2. Do you really need this optimization? Seems like a very rare case. The same in the other places. Also it looks like a lot of code duplication. But I see why, and again I don't see a way to reuse all this code easily. > + } > + if (is_zero) { > + assert(pOp->p2 > 0); > + VdbeBranchTaken(1, 2); > + goto jump_to_p2; > + } <...> > +case OP_SeekLE: { /* jump, in3 */ <...> > + cur->nullRow = 0; > + bool is_eq = (cur->uc.pCursor->hints & OPFLAG_SEEKEQ) != 0; > + cur->uc.pCursor->iter_type = is_eq ? ITER_REQ : ITER_LE; > + assert(!is_eq || pOp[1].opcode == OP_IdxLT); > + > + uint32_t len = pOp->p4.i; > + assert(pOp->p4type == P4_INT32); > + assert(len <= cur->key_def->part_count); > + struct Mem *mems = &aMem[pOp->p3]; > + bool is_lt = false; > + bool is_zero = false; > + for (uint32_t i = 0; i < len; ++i) { > + enum field_type type = cur->key_def->parts[i].type; > + struct Mem *mem = &mems[i]; > + if (mem_is_field_compatible(mem, type)) > + continue; > + if (!sql_type_is_numeric(type) || !mem_is_num(mem)) { > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, > + mem_str(mem), field_type_strs[type]); > + goto abort_due_to_error; > } > - iKey = i; > - > - /* If the P3 value could not be converted into an integer without > - * loss of information, then special processing is required... > + int cmp = mem_cast_implicit_number(mem, type); > + is_lt = is_lt || cmp < 0; 3. You needed to find values <= mem. The mem during cast was turned into mem2 < mem, correct? Then you need to find values <= mem2. Otherwise you skip mem2 itself. Or am I mistaken somewhere? Similar questions to all the other usages of mem_cast_implicit_number for seeking.
next prev parent reply other threads:[~2021-08-04 22:25 UTC|newest] Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-28 20:51 [Tarantool-patches] [PATCH v1 0/7] Rework implicit cast Mergen Imeev via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 1/7] sql: rework implicit cast fo assignment Mergen Imeev via Tarantool-patches 2021-07-30 21:55 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-04 22:21 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-05 23:27 ` Mergen Imeev via Tarantool-patches 2021-08-06 0:13 ` Vladislav Shpilevoy via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 2/7] sql: remove implicit cast from comparison opcodes Mergen Imeev via Tarantool-patches 2021-08-04 22:24 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-05 23:33 ` Mergen Imeev via Tarantool-patches 2021-08-06 0:13 ` Vladislav Shpilevoy via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 3/7] sql: rework OP_Seek* opcodes Mergen Imeev via Tarantool-patches 2021-08-04 22:25 ` Vladislav Shpilevoy via Tarantool-patches [this message] 2021-08-05 23:40 ` Mergen Imeev via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 4/7] sql: remove unnecessary calls of OP_ApplyType Mergen Imeev via Tarantool-patches 2021-08-04 22:26 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-05 23:41 ` Mergen Imeev via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 5/7] sql: remove implicit cast from OP_MakeRecord Mergen Imeev via Tarantool-patches 2021-08-04 22:27 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-05 23:43 ` Mergen Imeev via Tarantool-patches 2021-08-06 0:13 ` Vladislav Shpilevoy via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 6/7] sql: remove implicit cast from OP_MustBeInt Mergen Imeev via Tarantool-patches 2021-08-05 23:47 ` Mergen Imeev via Tarantool-patches 2021-07-28 20:51 ` [Tarantool-patches] [PATCH v1 7/7] sql: remove unused MEM cast functions Mergen Imeev via Tarantool-patches 2021-08-04 22:27 ` Vladislav Shpilevoy via Tarantool-patches 2021-08-05 23:45 ` Mergen Imeev via Tarantool-patches
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=31aa2f05-09e9-ce24-5a46-894d3d23b8f7@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=imeevma@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v1 3/7] sql: rework OP_Seek* opcodes' \ /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