<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 16:09, <a href="mailto:v.shpilevoy@tarantool.org" class="">v.shpilevoy@tarantool.org</a> wrote:</div><br class="Apple-interchange-newline"><div class=""><br class="Apple-interchange-newline"><br class="" 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;"><blockquote type="cite" class="" 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;"><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=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 22 Mar 2018, at 14:42,<span class="Apple-converted-space"> </span><a href="mailto:v.shpilevoy@tarantool.org" class="">v.shpilevoy@tarantool.org</a><span class="Apple-converted-space"> </span>wrote:</div><br class="Apple-interchange-newline"><div class=""><span class="" 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;">See below 6 comments.</span><br class="" 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;"><br class="" 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;"><blockquote type="cite" class="" 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;">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 class="" 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;"><span class="" 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;">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 class="" 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;"></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 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 class=""></div><div 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="">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<span class="Apple-converted-space"> </span><a href="http://box.cc/" class="">box.cc</a>, and declare it as extern in sql.c.</div></div></blockquote><div><br class=""></div><div>Ok, I’m attaching patch to email (since it belongs to another patch-set: np/gh-3122-remove-pgnoRoot)</div><br class=""><blockquote type="cite" class=""><div class=""><br class="" 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;"><blockquote type="cite" class="" 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" class="" 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;"><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 class="" 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;"><span class="" 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;">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 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 class=""></div><div 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="">Suppose, this will be fixed, if you will use process_rw, as described above.</div></div></blockquote><div><br class=""></div><div>Fixed (I am attaching changes at the end of mail).</div><br class=""><blockquote type="cite" class=""><div class=""><br class="" 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;"><blockquote type="cite" class="" 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><br class="" 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;"><blockquote type="cite" class="" 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;"><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 class="" 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;"><span class="" 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;">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 class="" 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;"></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 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 class=""></div><div 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="">Yes, lets rename it, and remove space_id argument, if it is always used for _sequence space.</div></div></blockquote><div><br class=""></div><div>Done (I am attaching changes at the end of mail).</div><div><div><div class=""><br class=""></div></div></div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" class="" 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" class="" 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;"><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 class="" 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;"><span class="" 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;">4. Do you mean DDL instead of DML?</span><br class="" 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;"></div></blockquote></div></div></div></blockquote><div 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 class=""></div><div 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="">Hm?</div></div></blockquote><div><br class=""></div><div>Fixed (at both places).</div><br class=""><blockquote type="cite" class=""><div class=""><br class="" 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;"><blockquote type="cite" class="" 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><br class="" 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;"><blockquote type="cite" class="" 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;">+ * 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" class="" 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;">+<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 class="" 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;"><span class="" 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;">6. It seems to be unused in the patch. Can you use it for all these things, introduced by the previous patch?</span><br class="" 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;"><span class="" 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;">struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pIdx->tnum));</span><br class="" 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;"><span class="" 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;">assert(space != NULL);</span><br class="" 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;"><span class="" 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;">sqlite3VdbeAddOp4Ptr(v, OP_LoadPtr, 0, space_ptr_reg, 0, (void *) space);</span><br class="" 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;"><span class="" 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;">sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, space_ptr_reg);</span><br class="" 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;"><br class="" 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;"><span class="" 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;">Using OP_SIDtoPtr you already in this patch can defer space_by_id lookup.</span><br class="" 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;"></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 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 class=""></div><div 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="">Ok, then lets leave it in this patch.</div><br class="" 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;"><blockquote type="cite" class="" 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><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 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 class=""></div><div 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="">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 class="" style="font-family: Helvetica;">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></div></blockquote><br class=""></div><div>Now I get what you mean. Yep, currently space is slightly used during compile time, </div><div>so its lookup can be always deferred until runtime. But in the nearest future, all properties </div><div>will be fetched directly from space (at compile time), so there will be no need to make</div><div>additional space lookup at runtime, if we load it into VDBE during compile time. </div><div><br class=""></div><div>Patches on process_rw() and updates from this one are below.</div><div><br class=""></div><div>=======================================================================</div><div><br class=""></div><div><div>Originally, process_rw() function implements internal logic (such as txn</div><div>or metrics routine) and calls DML executor. However, it isn't available</div><div>for other modules (i.e. declared as static). On the other hand, it seems</div><div>to be very useful for SQL, since it allows to reduce call stack and get</div><div>rid of redundant space lookup.  Thus, lets rename it to</div><div>'box_process_rw()' and declare in box.h</div><div>---</div><div> src/box/<a href="http://box.cc" class="">box.cc</a> | 11 ++++++-----</div><div> src/box/box.h  | 17 ++++++++++++++++-</div><div> 2 files changed, 22 insertions(+), 6 deletions(-)</div><div><br class=""></div><div>diff --git a/src/box/<a href="http://box.cc" class="">box.cc</a> b/src/box/<a href="http://box.cc" class="">box.cc</a></div><div>index a3bbdfce8..12c662dd8 100644</div><div>--- a/src/box/<a href="http://box.cc" class="">box.cc</a></div><div>+++ b/src/box/<a href="http://box.cc" class="">box.cc</a></div><div>@@ -160,8 +160,9 @@ box_check_memtx_min_tuple_size(ssize_t memtx_min_tuple_size)</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>  "specified value is out of bounds");</div><div> }</div><div> </div><div>-static int</div><div>-process_rw(struct request *request, struct space *space, struct tuple **result)</div><div>+int</div><div>+box_process_rw(struct request *request, struct space *space,</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>       struct tuple **result)</div><div> {</div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>assert(iproto_type_is_dml(request->type));</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>rmean_collect(rmean_box, request->type, 1);</div><div>@@ -279,7 +280,7 @@ apply_row(struct xstream *stream, struct xrow_header *row)</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>struct request request;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>xrow_decode_dml_xc(row, &request, dml_request_key_map(row->type));</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>struct space *space = space_cache_find_xc(request.space_id);</div><div>-<span class="Apple-tab-span" style="white-space:pre">        </span>if (process_rw(&request, space, NULL) != 0) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>if (box_process_rw(&request, space, NULL) != 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">          </span>say_error("error applying row: %s", request_str(&request));</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>diag_raise();</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>}</div><div>@@ -821,7 +822,7 @@ boxk(int type, uint32_t space_id, const char *format, ...)</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>struct space *space = space_cache_find(space_id);</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if (space == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">             </span>return -1;</div><div>-<span class="Apple-tab-span" style="white-space:pre">  </span>return process_rw(&request, space, NULL);</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>return box_process_rw(&request, space, NULL);</div><div> }</div><div> </div><div> int</div><div>@@ -893,7 +894,7 @@ box_process1(struct request *request, box_tuple_t **result)</div><div> <span class="Apple-tab-span" style="white-space:pre">             </span>return -1;</div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>if (!space->def->opts.temporary && box_check_writable() != 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>return -1;</div><div>-<span class="Apple-tab-span" style="white-space:pre">  </span>return process_rw(request, space, result);</div><div>+<span class="Apple-tab-span" style="white-space:pre">  </span>return box_process_rw(request, space, result);</div><div> }</div><div> </div><div> int</div><div>diff --git a/src/box/box.h b/src/box/box.h</div><div>index c9b5aad01..e337cb0ee 100644</div><div>--- a/src/box/box.h</div><div>+++ b/src/box/box.h</div><div>@@ -50,6 +50,7 @@ struct xrow_header;</div><div> struct obuf;</div><div> struct ev_io;</div><div> struct auth_request;</div><div>+struct space;</div><div> </div><div> /*</div><div>  * Initialize box library</div><div>@@ -379,15 +380,29 @@ box_sequence_reset(uint32_t seq_id);</div><div> /** \endcond public */</div><div> </div><div> /**</div><div>- * The main entry point to the</div><div>+ * Used to be entry point to the</div><div>  * Box: callbacks into the request processor.</div><div>  * These are function pointers since they can</div><div>  * change when entering/leaving read-only mode</div><div>  * (master->slave propagation).</div><div>+ * However, it makes space lookup. If space is already obtained,</div><div>+ * one can simply use internal box_process_rw().</div><div>  */</div><div> int</div><div> box_process1(struct request *request, box_tuple_t **result);</div><div> </div><div>+/**</div><div>+ * Execute request on given space.</div><div>+ *</div><div>+ * \param request Request to be executed</div><div>+ * \param space Space to be updated</div><div>+ * \param result Result of executed request</div><div>+ * \retval 0 in success, -1 otherwise</div><div>+ */</div><div>+int</div><div>+box_process_rw(struct request *request, struct space *space,</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>       struct tuple **result);</div><div>+</div><div> int</div><div> boxk(int type, uint32_t space_id, const char *format, ...);</div><div> </div><div>-- </div><div>2.15.1</div><div class=""><br class=""></div><div class=""><div>=======================================================================</div></div><div class=""><br class=""></div><div class=""><div class=""><br class=""></div><div class=""> /*</div><div class="">  * The function assumes the cursor is open on _schema.</div><div class="">- * Increment max_id and store updated tuple in the cursor</div><div class="">- * object.</div><div class="">+ * Increment max_id and store updated value it output parameter.</div><div class="">  */</div><div class="">-int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)</div><div class="">+int tarantoolSqlite3IncrementMaxid(uint64_t *space_max_id)</div><div class=""> {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">      </span>assert(pCur->curFlags & BTCF_TaCursor);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">      </span>/* ["max_id"] */</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>static const char key[] = {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">         </span>(char)0x91, /* MsgPack array(1) */</div><div class="">@@ -1035,6 +1050,8 @@ int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)</div><div class=""> </div><div class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>struct tuple *res = NULL;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>int rc;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>struct space *space_schema = space_by_id(BOX_SCHEMA_ID);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>assert(space_schema != NULL);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">       </span>struct request request;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&request, 0, sizeof(request));</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>request.tuple = ops;</div><div class="">@@ -1042,18 +1059,14 @@ int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">    </span>request.key = key;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>request.key_end = key + sizeof(key);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>request.type = IPROTO_UPDATE;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>request.space_id = pCur->space->def->id;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>rc = box_process_rw(&request, pCur->space, &res);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">     </span>request.space_id = space_schema->def->id;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>rc = box_process_rw(&request, space_schema, &res);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>if (rc != 0 || res == NULL) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">               </span>return SQL_TARANTOOL_ERROR;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>if (pCur->last_tuple != NULL) {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">               </span>box_tuple_unref(pCur->last_tuple);</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>box_tuple_ref(res);</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">      </span>pCur->last_tuple = res;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">       </span>pCur->eState = CURSOR_VALID;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">  </span>return SQLITE_OK;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">        </span>rc = tuple_field_u64(res, 1, space_max_id);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">      </span>(*space_max_id)++;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">       </span>return rc  == 0 ? SQLITE_OK : SQL_TARANTOOL_ERROR;</div><div class=""> }</div><div class=""> </div><div class=""> /*</div><div class="">@@ -1633,25 +1646,20 @@ int tarantoolSqlite3EphemeralGetMaxId(BtCursor *pCur, uint32_t fieldno,</div><div class=""> }</div><div class=""> </div><div class=""> /**</div><div class="">- * Extract maximum integer value from:</div><div class="">- * @param index space_id</div><div class="">- * @param index_id</div><div class="">- * @param field number fieldno</div><div class="">- * @param[out] fetched value in max_id</div><div class="">+ * Extract next id from _sequence space.</div><div class="">+ * If index is empty - return 0 in max_id and success status</div><div class="">  *</div><div class="">+ * @param[out] max_id Fetched value.</div><div class="">  * @retval 0 on success, -1 otherwise.</div><div class="">- *</div><div class="">- * If index is empty - return 0 in max_id and success status</div><div class="">  */</div><div class=""> int</div><div class="">-tarantoolSqlGetMaxId(BtCursor *cur, uint32_t fieldno,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">            </span>     uint64_t *max_id)</div><div class="">+tarantoolSqlNextSeqId(uint64_t *max_id)</div><div class=""> {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>char key[16];</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">       </span>struct tuple *tuple;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>char *key_end = mp_encode_array(key, 0);</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>if (box_index_max(cur->space->def->id, cur->index->def->iid,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                   </span>  key, key_end, &tuple) != 0)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>if (box_index_max(BOX_SEQUENCE_ID, 0 /* PK */, key,</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                      </span>  key_end, &tuple) != 0)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">           </span>return -1;</div><div class=""> </div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>/* Index is empty  */</div><div class="">@@ -1660,5 +1668,5 @@ tarantoolSqlGetMaxId(BtCursor *cur, uint32_t fieldno,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">             </span>return 0;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div class=""> </div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>return tuple_field_u64(tuple, fieldno, max_id);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>return tuple_field_u64(tuple, 0, max_id);</div><div class=""> }</div><div class="">diff --git a/src/box/sql/build.c b/src/box/sql/build.c</div><div class="">index d5b0f6001..db7ffe24e 100644</div><div class="">--- a/src/box/sql/build.c</div><div class="">+++ b/src/box/sql/build.c</div><div class="">@@ -2018,7 +2018,8 @@ sqlite3EndTable(Parse * pParse,<span class="Apple-tab-span" style="white-space:pre">  </span>/* Parse context */</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                 </span>sqlite3OpenTable(pParse, iCursor, sys_sequence,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                     </span> OP_OpenWrite);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                     </span>reg_seq_id = ++pParse->nMem;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                  </span>sqlite3VdbeAddOp3(v, OP_NextId, iCursor, 0, reg_seq_id);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                 </span>sqlite3VdbeAddOp3(v, OP_NextSequenceId, iCursor, 0,</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                                      </span>  reg_seq_id);</div><div class=""> </div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                 </span>reg_seq_record = emitNewSysSequenceRecord(pParse,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                                           </span>  reg_seq_id,</div><div class=""><br class=""></div><div class="">--- a/src/box/sql/tarantoolInt.h</div><div class="">+++ b/src/box/sql/tarantoolInt.h</div><div class="">@@ -77,6 +77,7 @@ int tarantoolSqlite3Count(BtCursor * pCur, i64 * pnEntry);</div><div class=""> int tarantoolSqlite3Insert(BtCursor * pCur);</div><div class=""> int tarantoolSqlite3Replace(BtCursor * pCur);</div><div class=""> int tarantoolSqlite3Delete(BtCursor * pCur, u8 flags);</div><div class="">+int sql_delete_by_key(struct space *space, char *key, uint32_t key_size);</div><div class=""> int tarantoolSqlite3ClearTable(struct space *space);</div><div class=""> </div><div class=""> /* Rename table pTab with zNewName by inserting new tuple to _space.</div><div class="">@@ -112,11 +113,10 @@ int tarantoolSqlite3IdxKeyCompare(BtCursor * pCur, UnpackedRecord * pUnpacked,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                </span>  int *res);</div><div class=""> </div><div class=""> /*</div><div class="">- * The function assumes the cursor is open on _schema.</div><div class="">- * Increment max_id and store updated tuple in the cursor</div><div class="">- * object.</div><div class="">+ * The function assumes to be applied on _schema space.</div><div class="">+ * Increment max_id and store updated id in given argument.</div><div class="">  */</div><div class="">-int tarantoolSqlite3IncrementMaxid(BtCursor * pCur);</div><div class="">+int tarantoolSqlite3IncrementMaxid(uint64_t *space_max_id);</div><div class=""> </div><div class=""> /*</div><div class="">  * Render "format" array for _space entry.</div><div class="">@@ -147,8 +147,6 @@ int tarantoolSqlite3MakeIdxParts(Index * index, void *buf);</div><div class=""> int tarantoolSqlite3MakeIdxOpts(Index * index, const char *zSql, void *buf);</div><div class=""> </div><div class=""> /*</div><div class="">- * Fetch maximum value from ineger column number `fieldno` of space_id/index_id</div><div class="">- * Return 0 on success, -1 otherwise</div><div class="">+ * Fetch next id from _sequence space.</div><div class="">  */</div><div class="">-int tarantoolSqlGetMaxId(BtCursor *cur, uint32_t fieldno,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                      </span> uint64_t * max_id);</div><div class="">+int tarantoolSqlNextSeqId(uint64_t *max_id);</div><div class="">diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c</div><div class="">index 0ae682f9e..3d9ac8e26 100644</div><div class="">--- a/src/box/sql/vdbe.c</div><div class="">+++ b/src/box/sql/vdbe.c</div><div class="">@@ -3830,28 +3830,16 @@ case OP_Sequence: {           /* out2 */</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>break;</div><div class=""> }</div><div class=""> </div><div class="">-/* Opcode: NextId P1 P2 P3 * *</div><div class="">- * Synopsis: r[P3]=get_max(space_index[P1]{Column[P2]})</div><div class="">+/* Opcode: NextSequenceId * P2 * * *</div><div class="">+ * Synopsis: r[P2]=get_max(_sequence)</div><div class="">  *</div><div class="">- * Get next Id of the table. P1 is a table cursor, P2 is column</div><div class="">- * number. Return in P3 maximum id found in provided column,</div><div class="">+ * Get next Id of the _sequence space.</div><div class="">+ * Return in P2 maximum id found in _sequence,</div><div class="">  * incremented by one.</div><div class="">- *</div><div class="">- * This opcode is Tarantool specific and will segfault in case</div><div class="">- * of SQLite cursor.</div><div class="">  */</div><div class="">-case OP_NextId: {     /* out3 */</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>VdbeCursor *pC;    /* The VDBE cursor */</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">       </span>int p2;            /* Column number, which stores the id */</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>pC = p->apCsr[pOp->p1];</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>p2 = pOp->p2;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>pOut = &aMem[pOp->p3];</div><div class="">-</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>/* This opcode is Tarantool specific.  */</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">   </span>assert(pC->uc.pCursor->curFlags & BTCF_TaCursor);</div><div class="">-</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">   </span>tarantoolSqlGetMaxId(pC->uc.pCursor, p2,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                      </span>     (uint64_t *) &pOut->u.i);</div><div class="">+case OP_NextSequenceId: {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">      </span>pOut = &aMem[pOp->p2];</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">    </span>tarantoolSqlNextSeqId((uint64_t *) &pOut->u.i);</div><div class=""> </div><div class=""> <span class="Apple-tab-span" style="white-space:pre">      </span>pOut->u.i += 1;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>pOut->flags = MEM_Int;</div><div class="">@@ -4495,6 +4483,85 @@ case OP_IdxInsert: {        /* in2 */</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>break;</div><div class=""> }</div><div class=""> </div><div class="">+/* Opcode: SInsert P1 P2 * * P5</div><div class="">+ * Synopsis: space id = P1, key = r[P2]</div><div class="">+ *</div><div class="">+ * This opcode is used only during DDL routine.</div><div class="">+ * In contrast to ordinary insertion, insertion to system spaces</div><div class="">+ * such as _space or _index will lead to schema changes.</div><div class="">+ * Thus, usage of space pointers is going to be impossible,</div><div class="">+ * as far as pointers can be expired since compilation time.</div><div class="">+ *</div><div class="">+ * If P5 is set to OPFLAG_NCHANGE, account overall changes</div><div class="">+ * made to database.</div><div class="">+ */</div><div class="">+case OP_SInsert: {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">        </span>assert(pOp->p1 > 0);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">       </span>assert(pOp->p2 >= 0);</div><div class="">+</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>pIn2 = &aMem[pOp->p2];</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">    </span>struct space *space = space_by_id(pOp->p1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(space != NULL);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(space_is_system(space));</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>/* Create surrogate cursor to pass to SQL bindings. */</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>BtCursor surrogate_cur;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>surrogate_cur.space = space;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">     </span>surrogate_cur.key = pIn2->z;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>surrogate_cur.nKey = pIn2->n;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>surrogate_cur.curFlags = BTCF_TaCursor;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>rc = tarantoolSqlite3Insert(&surrogate_cur);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (rc)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">          </span>goto abort_due_to_error;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (pOp->p5 & OPFLAG_NCHANGE)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">             </span>p->nChange++;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>break;</div><div class="">+}</div><div class="">+</div><div class="">+/* Opcode: SDelete P1 P2 * * P5</div><div class="">+ * Synopsis: space id = P1, key = r[P2]</div><div class="">+ *</div><div class="">+ * This opcode is used only during DDL routine.</div><div class="">+ * Delete entry with given key from system space.</div><div class="">+ *</div><div class="">+ * If P5 is set to OPFLAG_NCHANGE, account overall changes</div><div class="">+ * made to database.</div><div class="">+ */</div><div class="">+case OP_SDelete: {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>assert(pOp->p1 > 0);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">       </span>assert(pOp->p2 >= 0);</div><div class="">+</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>pIn2 = &aMem[pOp->p2];</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">    </span>struct space *space = space_by_id(pOp->p1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(space != NULL);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(space_is_system(space));</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>rc = sql_delete_by_key(space, pIn2->z, pIn2->n);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>if (rc)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">          </span>goto abort_due_to_error;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (pOp->p5 & OPFLAG_NCHANGE)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">             </span>p->nChange++;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>break;</div><div class="">+}</div><div class="">+</div><div class="">+/* Opcode: SIDtoPtr P1 P2 * * *</div><div class="">+ * Synopsis: space id = P1, space[out] = r[P2]</div><div class="">+ *</div><div class="">+ * This opcode makes look up by space id and save found space</div><div class="">+ * into register, specified by the content of register P2.</div><div class="">+ * Such trick is needed during DLL routine, since schema may</div><div class="">+ * change and pointers become expired.</div><div class="">+ */</div><div class="">+case OP_SIDtoPtr: {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(pOp->p1 > 0);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">       </span>assert(pOp->p2 >= 0);</div><div class="">+</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>pIn2 = out2Prerelease(p, pOp);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>struct space *space = space_by_id(pOp->p1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>assert(space != NULL);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>pIn2->u.p = (void *) space;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">   </span>pIn2->flags = MEM_Ptr;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">        </span>break;</div><div class="">+}</div><div class="">+</div><div class=""> /* Opcode: IdxDelete P1 P2 P3 * *</div><div class="">  * Synopsis: key=r[P2@P3]</div><div class="">  *</div><div class="">@@ -5424,22 +5491,19 @@ case OP_Init: {          /* jump */</div><div class=""> </div><div class=""> /* Opcode: IncMaxid P1 * * * *</div><div class="">  *</div><div class="">- * The cursor (P1) should be open on _schema.</div><div class="">- * Increment the max_id (max space id) and store updated tuple in the</div><div class="">- * cursor.</div><div class="">+ * Increment the max_id from _schema (max space id)</div><div class="">+ * and store updated id in register specified by first operand.</div><div class="">+ * It is system opcode and must be used only during DDL routine.</div><div class="">  */</div><div class=""> case OP_IncMaxid: {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>VdbeCursor *pC;</div><div class="">-</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">       </span>assert(pOp->p1>=0 && pOp->p1<p->nCursor);</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>pC = p->apCsr[pOp->p1];</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>assert(pC != 0);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>assert(pOp->p1 > 0);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">       </span>pOut = &aMem[pOp->p1];</div><div class=""> </div><div class="">-<span class="Apple-tab-span" style="white-space:pre">    </span>rc = tarantoolSqlite3IncrementMaxid(pC->uc.pCursor);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">  </span>rc = tarantoolSqlite3IncrementMaxid((uint64_t*) &pOut->u.i);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (rc!=SQLITE_OK) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                </span>goto abort_due_to_error;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">        </span>pC->nullRow = 0;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">      </span>pOut->flags = MEM_Int;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>break;</div><div class=""> }</div><div class=""> </div><div class="">-- </div><div class="">2.15.1</div><div class=""><br class=""></div></div><div class=""><br class=""></div><div class=""><br class=""></div></div><br class=""></body></html>