<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">22 марта 2018 г., в 15:23, n.pettik <<a href="mailto:korablev@tarantool.org" class="">korablev@tarantool.org</a>> написал(а):</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 22 Mar 2018, at 14:42, <a href="mailto:v.shpilevoy@tarantool.org" class="">v.shpilevoy@tarantool.org</a> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">See below 6 comments.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">21 марта 2018 г., в 2:48, Nikita Pettik <<a href="mailto:korablev@tarantool.org" class="">korablev@tarantool.org</a>> написал(а):<br class=""><br class="">Since it is impossible to use space pointers during execution of DDL<br class="">(after any DDL schema may change and pointers fetched at compile time<br class="">can become expired), special opcodes to operate on system spaces have<br class="">been introduced: OP_SInsert and OP_SDelete. They take space id as<br class="">an argument and make space lookup each time before insertion or deletion.<br class="">However, sometimes it is still required to iterate through space (e.g.<br class="">to satisfy WHERE clause) during DDL. As far as now cursors rely on<br class="">pointers to space, it is required to convert space id to space pointer<br class="">during VDBE execution. Hence, another opcode is added: OP_SIDtoPtr.<br class="">Finally, existing opcodes, which are invoked only during DDL, have been<br class="">also refactored.<br class=""><br class="">Part of #3252<br class="">---<br class="">src/box/sql.c              |  51 ++++++++++++-------<br class="">src/box/sql/opcodes.c      |  45 +++++++++--------<br class="">src/box/sql/opcodes.h      |  53 ++++++++++----------<br class="">src/box/sql/tarantoolInt.h |  11 ++---<br class="">src/box/sql/vdbe.c         | 121 ++++++++++++++++++++++++++++++++++-----------<br class="">5 files changed, 182 insertions(+), 99 deletions(-)<br class=""><br class="">diff --git a/src/box/sql.c b/src/box/sql.c<br class="">index e943131ae..db4c7e7ea 100644<br class="">--- a/src/box/sql.c<br class="">+++ b/src/box/sql.c<br class="">+int<br class="">+sql_delete_by_key(struct space *space, char *key, uint32_t key_size)<br class="">+{<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span>struct request request;<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>memset(&request, 0, sizeof(request));<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>request.type = IPROTO_DELETE;<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>request.key = key;<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span>request.key_end = key + key_size;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span>request.space_id = pCur->space->def->id;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span>rc = sql_execute_dml(&request, pCur->space);<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span>request.space_id = space->def->id;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>int rc = sql_execute_dml(&request, space);<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">1. Why do you need sql_execute_dml? It does exactly the same as process_rw, but process_rw can also return a tuple. And this process_rw feature is needed for the patch on last inserted tuple returning.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div class=""><br class=""></div><div class="">I need it as an analogue of process_rw(), since process_rw() is unavailable </div><div class="">via public BOX interface (declared as static). If you approve to make it public,</div><div class="">where should I place it and should I rename it?</div><div class="">Or, for instance, make sql_execute_dml be complete copy of process_rw()?</div><div class="">It is unlikely to be useful somewhere except for SQL (and box internals surely).</div><div class="">Initial indent was to reduce overhead while calling box functions from SQL bindings (sql.c):</div><div class="">ordinary call stack looks like: box_insert() -> box_process1() -> space lookup + process_rw().</div><div class="">In such scheme we also process redundant space lookup since we already have struct space * in cursor.</div><div class="">(Patch where I introduced this function isn’t in trunk, so I can easily fix it).</div></div></div></div></blockquote><div><br class=""></div><div>Yes, I very like the removal of box_process1. I just do not like code duplicate. But also I can not see a place for declaration of process_rw in any header. So lets make it extern "C" non-static in <a href="http://box.cc" class="">box.cc</a>, and declare it as extern in sql.c.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">@@ -1088,20 +1107,16 @@ int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>request.ops = ops;<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span>request.ops_end = ops + sizeof(ops);<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>request.type = IPROTO_UPSERT;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">       </span>request.space_id = pCur->space->def->id;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span>rc = sql_execute_dml(&request, pCur->space);<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span>request.space_id = BOX_SCHEMA_ID;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>rc = sql_execute_dml(&request, space_schema);<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">2. If you use process_rw, then you do not need iterator to get the previous max_id and increment it - you just do process_rw, get result and do tuple_field_u64(result, 1, space_max_id);</span></div></blockquote></div></div></div></blockquote><div><br class=""></div><div>Suppose, this will be fixed, if you will use process_rw, as described above.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><span class="Apple-tab-span" style="white-space: pre;">       </span>if (rc != 0) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>iterator_delete(it);<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>return SQL_TARANTOOL_ERROR;<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span>if (pCur->last_tuple != NULL) {<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>box_tuple_unref(pCur->last_tuple);<br class="">-<span class="Apple-tab-span" style="white-space: pre;">       </span>}<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span>box_tuple_ref(res);<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span>pCur->last_tuple = res;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span>pCur->eState = CURSOR_VALID;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>rc = tuple_field_u64(res, 1, space_max_id);<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span>(*space_max_id)++;<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span>iterator_delete(it);<br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span>return SQLITE_OK;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>return rc  == 0 ? SQLITE_OK : SQL_TARANTOOL_ERROR;<br class="">}<br class=""><br class="">/*<br class="">@@ -1687,14 +1702,12 @@ int tarantoolSqlite3EphemeralGetMaxId(BtCursor *pCur, uint32_t fieldno,<br class="">* If index is empty - return 0 in max_id and success status<br class="">*/<br class="">int<br class="">-tarantoolSqlGetMaxId(BtCursor *cur, uint32_t fieldno,<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    uint64_t *max_id)<br class="">+tarantoolSqlGetMaxId(uint32_t space_id, uint64_t *max_id)<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">3. After changing a function signature, please, fix a comments too. And why this function is sure, that the max id stored in the first column? And why it can not be used for secondary indexes?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div class=""><br class=""></div><div class="">It might, but it is only applied for _sequence space during DDL routine</div><div class="">(and this is also answer for the first question: format of system space doesn’t change frequently),</div><div class="">so I decided to remove cursor/index overhead (as a part of overall DDL refactoring).</div><div class="">Probably, I should also rename this opcode to make it more clear.</div></div></div></div></blockquote><div><br class=""></div><div>Yes, lets rename it, and remove space_id argument, if it is always used for _sequence space.</div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">+/* Opcode: SInsert P1 P2 * * P5<br class="">+ * Synopsis: space id = P1, key = r[P2]<br class="">+ *<br class="">+ * This opcode is used only during DML routine.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">4. Do you mean DDL instead of DML?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote></div></div></div></blockquote><div><br class=""></div><div>Hm?</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+ * In contrast to ordinary insertion, insertion to system spaces<br class="">+ * such as _space or _index will lead to schema changes.<br class="">+ * Thus, usage of space pointers is going to be impossible,<br class="">+ * as far as pointers can be expired since compilation time.<br class="">+ *<br class="">+ * If P5 is set to OPFLAG_NCHANGE, account overall changes<br class="">+ * made to database.<br class="">+ */<br class="">+case OP_SInsert: {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>assert(pOp->p1 > 0);</blockquote><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<br class="">+/* Opcode: SIDtoPtr P1 P2 * * *<br class="">+ * Synopsis: space id = P1, space[out] = r[P2]<br class="">+ *<br class="">+ * This opcode makes look up by space id and save found space<br class="">+ * into register, specified by the content of register P2.<br class="">+ * Such trick is needed during DML routine, since schema may<br class="">+ * change and pointers become expired.<br class="">+ */<br class="">+case OP_SIDtoPtr: {<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">6. It seems to be unused in the patch. Can you use it for all these things, introduced by the previous patch?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pIdx->tnum));</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">assert(space != NULL);</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">sqlite3VdbeAddOp4Ptr(v, OP_LoadPtr, 0, space_ptr_reg, 0, (void *) space);</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, space_ptr_reg);</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Using OP_SIDtoPtr you already in this patch can defer space_by_id lookup.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div class=""><br class=""></div><div class="">It is used in the next patch. I don’t want to make a lot of diffs, since introducing of any opcodes</div><div class="">leads to auto-generating of opcodes.c/h and as a result to vast amount of redundant diff.</div></div></div></div></blockquote><div><br class=""></div><div>Ok, then lets leave it in this patch.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">As for your example, during SQL DDL we need to execute queries such as:</div><div class="">'DELETE FROM BOX_SEQUENCE WHERE name = zName;’</div><div class="">And ‘name’ is not a key. Hence, we have to open cursor and iterate through the space.</div><div class="">But if we used pointers to spaces which were fetched at compile state,</div><div class="">they would become expired at VDBE runtime:</div><div class="">after first stage of DDL (e.g. deletion from _trigger), schema may change.</div><div class="">Moreover, we are going to support syntax like: ‘CREATE TABLE AS SELECT …’,</div><div class="">where DDL and DML are mixing. Thus we need facility to make space lookup at VDBE runtime.</div></div></div></div></blockquote><div><br class=""></div><div>I agree, that we must have this opcode, but why it can not be used for DML too? In my example you at compile time get space *, store it by <span style="font-family: Helvetica;" class="">OP_LoadPtr, and then use to open iterator (but I can not see where - I commented this in a previous patch review), but for DML you can replace compile lookups on runtime lookups using </span>OP_SIDtoPtr. And it also solves the problem, that a prepared VDBE statement (which in a future we will store for a long time) must store space * in opcodes - we can use OP_SIDtoPtr and do not store it until execution. Sorry, can not explain more clear. We can also discuss it face-to-face.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div></div></blockquote></div><br class=""></body></html>