<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><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><br class=""></div><div>I need it as an analogue of process_rw(), since process_rw() is unavailable </div><div>via public BOX interface (declared as static). If you approve to make it public,</div><div>where should I place it and should I rename it?</div><div>Or, for instance, make sql_execute_dml be complete copy of process_rw()?</div><div>It is unlikely to be useful somewhere except for SQL (and box internals surely).</div><div>Initial indent was to reduce overhead while calling box functions from SQL bindings (sql.c):</div><div>ordinary call stack looks like: box_insert() -> box_process1() -> space lookup + process_rw().</div><div>In such scheme we also process redundant space lookup since we already have struct space * in cursor.</div><div>(Patch where I introduced this function isn’t in trunk, so I can easily fix it).</div><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><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><br class=""></div><div>It might, but it is only applied for _sequence space during DDL routine</div><div>(and this is also answer for the first question: format of system space doesn’t change frequently),</div><div>so I decided to remove cursor/index overhead (as a part of overall DDL refactoring).</div><div>Probably, I should also rename this opcode to make it more clear.</div><br 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="">{<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>char key[16];<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>struct tuple *tuple;<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>char *key_end = mp_encode_array(key, 0);<br class="">-<span class="Apple-tab-span" style="white-space: pre;">    </span>if (box_index_max(cur->space->def->id, cur->index->def->iid,<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-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span> key, key_end, &tuple) != 0)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>if (box_index_max(space_id, 0 /* PK */, key, key_end, &tuple) != 0)<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>return -1;<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>/* Index is empty  */<br class="">@@ -1703,5 +1716,5 @@ 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>return 0;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>}<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span>return tuple_field_u64(tuple, fieldno, max_id);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>return tuple_field_u64(tuple, 0, max_id);<br class="">}<br class="">diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h<br class="">index 6f1ba3784..0b1e22ca2 100644<br class="">--- a/src/box/sql/tarantoolInt.h<br class="">+++ b/src/box/sql/tarantoolInt.h<br class="">@@ -77,6 +77,7 @@ int tarantoolSqlite3Count(BtCursor * pCur, i64 * pnEntry);<br class="">int tarantoolSqlite3Insert(BtCursor * pCur);<br class="">int tarantoolSqlite3Replace(BtCursor * pCur);<br class="">int tarantoolSqlite3Delete(BtCursor * pCur, u8 flags);<br class="">+int sql_delete_by_key(struct space *space, char *key, uint32_t key_size);<br class="">int tarantoolSqlite3ClearTable(struct space *space);<br class=""><br class="">/* Rename table pTab with zNewName by inserting new tuple to _space.<br class="">@@ -112,11 +113,10 @@ int tarantoolSqlite3IdxKeyCompare(BtCursor * pCur, UnpackedRecord * pUnpacked,<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-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span> int *res);<br class=""><br class="">/*<br class="">- * The function assumes the cursor is open on _schema.<br class="">- * Increment max_id and store updated tuple in the cursor<br class="">- * object.<br class="">+ * The function assumes to be applied on _schema space.<br class="">+ * Increment max_id and store updated id in given argument.<br class="">*/<br class="">-int tarantoolSqlite3IncrementMaxid(BtCursor * pCur);<br class="">+int tarantoolSqlite3IncrementMaxid(uint64_t *space_max_id);<br class=""><br class="">/*<br class="">* Render "format" array for _space entry.<br class="">@@ -150,5 +150,4 @@ int tarantoolSqlite3MakeIdxOpts(Index * index, const char *zSql, void *buf);<br class="">* Fetch maximum value from ineger column number `fieldno` of space_id/index_id<br class="">* Return 0 on success, -1 otherwise<br class="">*/<br class="">-int 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-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>uint64_t * max_id);<br class="">+int tarantoolSqlGetMaxId(uint32_t space_id, uint64_t *max_id);<br class="">diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c<br class="">index 5d1227afa..d333d4177 100644<br class="">--- a/src/box/sql/vdbe.c<br class="">+++ b/src/box/sql/vdbe.c<br class="">@@ -3791,28 +3791,18 @@ case OP_Sequence: {           /* out2 */<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span>break;<br class="">}<br class=""><br class="">-/* Opcode: NextId P1 P2 P3 * *<br class="">- * Synopsis: r[P3]=get_max(space_index[P1]{Column[P2]})<br class="">+/* Opcode: NextId P1 P2 * * *<br class="">+ * Synopsis: r[P2]=get_max(space_id[P1])<br class="">*<br class="">- * Get next Id of the table. P1 is a table cursor, P2 is column<br class="">- * number. Return in P3 maximum id found in provided column,<br class="">+ * Get next Id of the table. P1 is a space id.<br class="">+ * Return in P2 maximum id found in provided column,<br class="">* incremented by one.<br class="">- *<br class="">- * This opcode is Tarantool specific and will segfault in case<br class="">- * of SQLite cursor.<br class="">*/<br class="">-case OP_NextId: {     /* out3 */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span>VdbeCursor *pC;    /* The VDBE cursor */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span>int p2;            /* Column number, which stores the id */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span>pC = p->apCsr[pOp->p1];<br class="">-<span class="Apple-tab-span" style="white-space: pre;">       </span>p2 = pOp->p2;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">    </span>pOut = &aMem[pOp->p3];<br class="">-<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span>/* This opcode is Tarantool specific.  */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span>assert(pC->uc.pCursor->curFlags & BTCF_TaCursor);<br class="">+case OP_NextId: {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span>assert(pOp->p1 > 0);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span>pOut = &aMem[pOp->p2];<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span>tarantoolSqlGetMaxId(pC->uc.pCursor, p2,<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-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    (uint64_t *) &pOut->u.i);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>tarantoolSqlGetMaxId(pOp->p1, (uint64_t *) &pOut->u.i);<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span>pOut->u.i += 1;<span class="Apple-converted-space"> </span><br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>pOut->flags = MEM_Int;<br class="">@@ -4456,6 +4446,84 @@ case OP_IdxInsert: {        /* in2 */<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>break;<br class="">}<br 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=""><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);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span>assert(pOp->p2 >= 0);<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>pIn2 = &aMem[pOp->p2];<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span>struct space *space = space_by_id(pOp->p1);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>assert(space != NULL);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>assert(space_is_system(space));<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>/* Create surrogate cursor to pass to SQL bindings. */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>BtCursor surrogate_cur;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>surrogate_cur.space = space;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>surrogate_cur.key = pIn2->z;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>surrogate_cur.nKey = pIn2->n;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>surrogate_cur.curFlags = BTCF_TaCursor;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>rc = tarantoolSqlite3Insert(&surrogate_cur);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>if (rc)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>goto abort_due_to_error;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>if (pOp->p5 & OPFLAG_NCHANGE)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>p->nChange++;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>break;<br class="">+}<br class="">+<br class="">+/* Opcode: SDelete 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="">5. Same as 4 - do you mean DDL?</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="">+ * Delete entry with given key from system space.<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_SDelete: {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>assert(pOp->p1 > 0);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span>assert(pOp->p2 >= 0);<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>pIn2 = &aMem[pOp->p2];<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span>struct space *space = space_by_id(pOp->p1);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>assert(space != NULL);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>assert(space_is_system(space));<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span>rc = sql_delete_by_key(space, pIn2->z, pIn2->n);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span>if (rc)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>goto abort_due_to_error;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>if (pOp->p5 & OPFLAG_NCHANGE)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>p->nChange++;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>break;<br class="">+}<br 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><br class=""></div><div>It is used in the next patch. I don’t want to make a lot of diffs, since introducing of any opcodes</div><div>leads to auto-generating of opcodes.c/h and as a result to vast amount of redundant diff.</div><div>As for your example, during SQL DDL we need to execute queries such as:</div><div>'DELETE FROM BOX_SEQUENCE WHERE name = zName;’</div><div>And ‘name’ is not a key. Hence, we have to open cursor and iterate through the space.</div><div>But if we used pointers to spaces which were fetched at compile state,</div><div>they would become expired at VDBE runtime:</div><div>after first stage of DDL (e.g. deletion from _trigger), schema may change.</div><div>Moreover, we are going to support syntax like: ‘CREATE TABLE AS SELECT …’,</div><div>where DDL and DML are mixing. Thus we need facility to make space lookup at VDBE runtime.</div></div><br class=""></body></html>