<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=""><pre style="background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br class=""></span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br class=""></span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><blockquote type="cite" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">1. Please, do not paste SMTP headers in the body.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">2. Looks like in the diff below all tabs are turned into 4 spaces. Please</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">cope with it. Maybe, your IDE made it.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""></blockquote><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""></pre><blockquote type="cite" class=""><pre style="background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Now every sqlite struct Index is created with tnt struct</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index_def inside. This allows us to use tnt index_def</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> in work with sqlite indexes in the same manner as with</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> tnt index and is a step to remove sqlite Index with</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> tnt index.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Fields coll_array, coll_id_array, aiColumn, sort_order</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> and zName are removed from Index. All usages of this</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> fields changed to usage of corresponding index_def</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> fields.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index_is_unique(), sql_index_collation() and</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index_column_count() are removed with calls of</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index_def corresponding fields.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Closes: #3369</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Github branch: </span><a href="https://github.com/tarantool/tarantool/tree/sb/gh-3369-use-index-def-in-select-and-where" target="_blank" rel="noopener" style="color: rgb(0, 119, 204); font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">https://github.com/tarantool/tarantool/tree/sb/gh-3369-use-index-def-in-select-and-where</a><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">3. Please, put branch link below ---.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> ---</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">Here. And do not forget about link to the issue.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">     Branch: <link></span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">     Issue: <link></span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql.c | 18 +--</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/analyze.c | 24 +--</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/build.c | 398 ++++++++++++++++++++++++------------------------</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/delete.c | 16 +-</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/expr.c | 59 ++++---</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/fkey.c | 41 +++--</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/insert.c | 134 +++++++---------</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/pragma.c | 19 ++-</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/select.c | 2 +-</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/sqliteInt.h | 25 +--</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/trigger.c | 2 -</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/update.c | 10 +-</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/vdbemem.c | 2 +-</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/where.c | 140 ++++++++---------</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/wherecode.c | 43 +++---</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> src/box/sql/whereexpr.c | 15 --</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> 16 files changed, 433 insertions(+), 515 deletions(-)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">>> diff --git a/src/box/sql/build.c b/src/box/sql/build.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index 28e4d7a4d..74fb66565 100644</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> --- a/src/box/sql/build.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +++ b/src/box/sql/build.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -1072,11 +1075,9 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> * collation type was added. Correct this if it is the case.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> for (pIdx = p->pIndex; pIdx; pIdx = pIdx->pNext) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(pIdx->nColumn == 1);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - if (pIdx->aiColumn[0] == i) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - id = &pIdx->coll_id_array[0];</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - pIdx->coll_array[0] =</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - sql_column_collation(p->def, i, id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + assert(pIdx->def->key_def->part_count == 1);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if ((int)pIdx->def->key_def->parts[0].fieldno == i) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + id = &pIdx->def->key_def->parts[0].coll_id;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">4. I have just noticed the zColl leaks here. It is not deleted if</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">coll != NULL, but must.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">5. Here you have removed coll * initialization.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">sql_column_collation function here was used to set coll id and collation,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">by column number. But now this whole cycle does nothing as you can see.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">Please, return this initialization. You sill must init</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">key_def->parts[0].coll_id and coll.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> } else {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -1123,52 +1124,10 @@ sql_index_key_def(struct Index *idx)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> enum sort_order</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sql_index_column_sort_order(Index *idx, uint32_t column)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">6. Now this function is useless one line wrapper. Please,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">remove it too.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(idx != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->pTable->tnum);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct space *space = space_by_id(space_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(column < idx->nColumn);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - /*</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - * If space is still under construction, or it is</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - * an ephemeral space, then fetch collation from</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - * SQL internal structure.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - if (space == NULL) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(column < idx->nColumn);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - return idx->sort_order[column];</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct key_def *key_def = sql_index_key_def(idx);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(key_def != NULL && key_def->part_count >= column);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - return key_def->parts[column].sort_order;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return idx->def->key_def->parts[column].sort_order;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> /**</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -1383,14 +1342,16 @@ createTableStmt(sqlite3 * db, Table * p)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return zStmt;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -/* Return true if value x is found any of the first nCol entries of aiCol[]</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> static int</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -hasColumn(const i16 * aiCol, int nCol, int x)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +hasColumn(const struct key_part *key_parts, int nCol, const struct key_part key_part)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">7. Passing a struct by value is very bad idea. Please, don't do it ever.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">And looks like here fieldno is enough.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - while (nCol-- > 0)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - if (x == *(aiCol++))</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + int i = 0;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + while (i < nCol) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (key_part.fieldno == key_parts->fieldno)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return 1;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + key_parts++;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + i++;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return 0;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -1410,13 +1371,13 @@ static void</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> convertToWithoutRowidTable(Parse * pParse, Table * pTab)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Index *pPk;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - int i, j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + uint32_t i, j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">8. Please, do not predeclare cycle iterators when possible. It is</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">SQLite code style, not Tarantool. When you change the SQLite code,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">it must turn into Tarantool style.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -1454,14 +1415,17 @@ convertToWithoutRowidTable(Parse * pParse, Table * pTab)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> * "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> * code assumes the PRIMARY KEY contains no repeated columns.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - for (i = j = 1; i < pPk->nColumn; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - if (hasColumn(pPk->aiColumn, j, pPk->aiColumn[i])) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - pPk->nColumn--;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + for (i = j = 1; i < pPk->def->key_def->part_count; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (hasColumn(pPk->def->key_def->parts, j,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pPk->def->key_def->parts[i])) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pPk->def->key_def->part_count--;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> } else {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - pPk->aiColumn[j++] = pPk->aiColumn[i];</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pPk->def->key_def->parts[j++] =</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pPk->def->key_def->parts[i];</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">9. Wrong alignments almost on all new lines. And please, save a</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">key_def->parts in a separate variable and use it instead of the full</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">path pPk->def->key_def->parts. It is too long to be used 4 times on</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">6 lines.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">10. I see that cycle iterates until pPk->def->key_def->part_count,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">but this variable is decremented inside the cycle. So the last</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">columns are not checked. This value must be saved in a separate</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">variable before usage as a 'for' guard.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - pPk->nColumn = j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pPk->def->key_def->part_count = j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">11. This line makes no sense. You have already updated part_count</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">inside the cycle. Either you update here, or in the cycle.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> assert(pPk != 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -2654,8 +2618,9 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> /* Open the sorter cursor if we are to use one. */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> iSorter = pParse->nTab++;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nColumn,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - (char *)def, P4_KEYDEF);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pIndex->def->key_def->part_count,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + (char *)def, P4_KEYDEF);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">12. Wrong alignment.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> /* Open the table. Loop through all rows of the table, inserting index</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> * records into the sorter.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -2687,7 +2652,7 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3VdbeGoto(v, j2);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> addr2 = sqlite3VdbeCurrentAddr(v);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - regRecord, pIndex->nColumn);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + regRecord, pIndex->def->key_def->part_count);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">13. Same.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> VdbeCoverage(v);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3UniqueConstraint(pParse, ON_CONFLICT_ACTION_ABORT,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pIndex);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -2733,16 +2698,11 @@ sqlite3AllocateIndexObject(sqlite3 * db, /* Database connection */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> p = sqlite3DbMallocZero(db, nByte + nExtra);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> if (p) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> char *pExtra = ((char *)p) + ROUND8(sizeof(Index));</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - p->coll_array = (struct coll **)pExtra;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">14. I still see coll_array in build.c in comments.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pExtra += ROUND8(sizeof(struct coll **) * nCol);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - p->coll_id_array = (uint32_t *) pExtra;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">15. Same.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pExtra += ROUND8(sizeof(uint32_t) * nCol);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> p->aiRowLogEst = (LogEst *) pExtra;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pExtra += sizeof(LogEst) * (nCol + 1);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - p->aiColumn = (i16 *) pExtra;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">16. Same. And in very many places.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pExtra += sizeof(i16) * nCol;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - p->sort_order = (enum sort_order *) pExtra;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - p->nColumn = nCol;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> *ppExtra = ((char *)p) + nByte;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">17. You have removed the fields, but did not update</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">sqlite3AllocateIndexObject that still allocates memory for them.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return p;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -2831,18 +2791,119 @@ addIndexToTable(Index * pIndex, Table * pTab)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -bool</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -index_is_unique(Index *idx)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +void</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +append(struct region *r, const char *str, size_t *total_sql_size)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(idx != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct space *space = space_by_id(space_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(space != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct index *tnt_index = space_index(space, index_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(tnt_index != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + memcpy(region_alloc(r, strlen(str)), str, strlen(str));</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + *total_sql_size += strlen(str);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +}</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">18. Please, rename append function. This name is too common. And</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">make it static inline.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">19. You do not check region_alloc fails.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +char *</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +create_sql(const char *idx_name, struct space_def *space_def, ExprList *expr_list)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">20. Same as 18.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">21. Out of 80 symbols.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">22. Please, use struct ExprList, not ExprList.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">23. I still can not understand why can not you merge this function into</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">index_def building. It is needed in a single place, and makes redundant</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">scan of ExprList.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +{</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct region *r = &fiber()->gc;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + size_t total_sql_size = 0;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, "CREATE INDEX ", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, idx_name, &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, " ON ", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, space_def->name, &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, " (", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + for (int i = 0; i < expr_list->nExpr; i++){</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + Expr *expr = expr_list->a[i].pExpr;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + assert(expr->op == TK_COLLATE || expr->op == TK_COLUMN);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + Expr *column_expr = sqlite3ExprSkipCollate(expr);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + const char *name = space_def->fields[column_expr->iColumn].name;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (expr->op == TK_COLLATE){</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, name, &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, " COLLATE ", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + const char *coll_name = expr->u.zToken;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, coll_name, &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, ", ", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + } else {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, name, &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + append(r, ", ", &total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + memcpy(region_alloc(r, 1), "\0", 1);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + total_sql_size += 1;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + char *res = region_join(r, total_sql_size);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + /*</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + * fix last ", " with ")\0"</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + res[strlen(res) - 2] = ')';</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + res[strlen(res) - 1] = '\0';</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">24. strlen has O(N) complexity. And here you already know the</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">result: total_sql_size.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return res;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +}</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +void</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +set_index_def(Parse *parse, Index *index, Table *table, uint32_t iid,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + const char *name, uint32_t name_len, int on_error,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + ExprList *expr_list, u8 idx_type)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">25. Still bad alignment. And make this function be static.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +{</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct space_def *space_def = table->def;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct index_opts opts;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + index_opts_create(&opts);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + opts.is_unique = on_error != ON_CONFLICT_ACTION_NONE;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct key_def *key_def = key_def_new(expr_list->nExpr);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (key_def == NULL)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">26. If key_def_new fails, you should inform the parser or</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">db: either set Parse.nErr and Parser.rc, or sqlite3OomFaul(). Same</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">about all other errors got from Tarantool functions.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + for (int i = 0; i < expr_list->nExpr; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + Expr *expr = expr_list->a[i].pExpr;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + sql_resolve_self_reference(parse, table, NC_IdxExpr,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + expr, 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">27. Bad alignment. And as I can see it fits in one line.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">Please check alignment during another self-review iteration in</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">the whole patch. I will not mention it below again.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (parse->nErr > 0)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + Expr *column_expr = sqlite3ExprSkipCollate(expr);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (column_expr->op != TK_COLUMN) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + sqlite3ErrorMsg(parse,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + "functional indexes aren't supported "</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + "in the current version");</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + uint32_t fieldno = column_expr->iColumn;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + uint32_t coll_id;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct coll *coll;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (expr->op == TK_COLLATE)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + coll = sql_get_coll_seq(parse, expr->u.zToken,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + &coll_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + else</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + coll = sql_column_collation(space_def, fieldno,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + &coll_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">28. Please, use {}, when 'if' body consists of multiple lines.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (sqlite3StrICmp(expr->u.zToken, "binary") != 0 &&</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + coll == NULL && expr->op == TK_COLLATE)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">29. This check is needed in 'if (expr->op == TK_COLLATE)' above.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">And why do you do this youself? sql_get_coll_seq already sets</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">the nErr in parser for this error.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + /* Tarantool: DESC indexes are not supported so far.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + * See gh-3016.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">30. Please, obey Tarantool comment style:</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">/*</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">  * My comment inside the function.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">  * Second line.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">  */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">And wrap the comment line on 66 ruler.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> void</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -2853,12 +2914,11 @@ sql_create_index(struct Parse *parse, struct Token *token,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Table *pTab = 0; /* Table to be indexed */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Index *pIndex = 0; /* The index to be created */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - char *zName = 0; /* Name of the index */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + char *name = 0; /* Name of the index */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">31. Please, use explicit NULL.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> int nName; /* Number of characters in zName */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - int i, j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + int i;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> DbFixer sFix; /* For assigning database names to pTable */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3 *db = parse->db;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct ExprList_item *col_listItem; /* For looping over col_list */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> int nExtra = 0; /* Space allocated for zExtra[] */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> char *zExtra = 0; /* Extra space after the Index object */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> struct session *user_session = current_session();</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -3159,6 +3189,7 @@ sql_create_index(struct Parse *parse, struct Token *token,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> if (idx_type == SQLITE_IDXTYPE_PRIMARYKEY)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> pIdx->idxType = idx_type;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> goto exit_create_index;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">32. Garbage diff. Please, find other garbage diffs and remove them.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -3268,28 +3299,7 @@ sql_create_index(struct Parse *parse, struct Token *token,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sql_expr_delete(db, where, false);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sql_expr_list_delete(db, col_list);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3SrcListDelete(db, tbl_name);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">33. I have noticed than on line 3056 collation names add extra bytes</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">to struct Index object. Can you please investigate if they are not</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">needed anymore and remove this code?</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">I am talking about it:</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">/* Figure out how many bytes of space are required to store explicitly</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">* specified collation sequence names.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">*/</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">for (i = 0; i < col_list->nExpr; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">Expr *pExpr = col_list->a[i].pExpr;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">assert(pExpr != 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">if (pExpr->op == TK_COLLATE) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">}</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">}</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">We do not store collation names in struct Index anymore.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -3297,15 +3307,8 @@ bool</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index_is_unique_not_null(const Index *idx)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> assert(idx != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct space *space = space_by_id(space_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(space != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> -</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct index *index = space_index(space, index_id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(index != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - return (index->def->opts.is_unique &&</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - !index->def->key_def->is_nullable);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + assert(idx->def != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + return (idx->def->key_def->is_nullable && idx->def->opts.is_unique);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">34. This one-line function is used in a single place. Please, inline</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">it and remove.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> void</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -3933,18 +3936,18 @@ sqlite3UniqueConstraint(Parse * pParse, /* Parsing context */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> )</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> char *zErr;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - int j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + uint32_t j;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> StrAccum errMsg;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> Table *pTab = pIdx->pTable;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> </span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> if (pIdx->aColExpr) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + sqlite3XPrintf(&errMsg, "index '%q'", pIdx->def->name);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> } else {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - for (j = 0; j < pIdx->nColumn; j++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + for (j = 0; j < pIdx->def->key_def->part_count; j++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> char *zCol;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(pIdx->aiColumn[j] >= 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - zCol = pTab->def->fields[pIdx->aiColumn[j]].name;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + uint32_t fieldno = pIdx->def->key_def->parts[j].fieldno;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + zCol = pTab->def->fields[fieldno].name;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> if (j)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3StrAccumAppend(&errMsg, ", ", 2);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3XPrintf(&errMsg, "%s.%s", pTab->def->name, zCol);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -3967,11 +3970,10 @@ static bool</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> collationMatch(struct coll *coll, struct Index *index)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> assert(coll != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - for (int i = 0; i < index->nColumn; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - uint32_t id;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - struct coll *idx_coll = sql_index_collation(index, i, &id);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(idx_coll != 0 || index->aiColumn[i] < 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - if (index->aiColumn[i] >= 0 && coll == idx_coll)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + for (uint32_t i = 0; i < index->def->key_def->part_count; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + struct coll *idx_coll = index->def->key_def->parts[i].coll;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + assert(idx_coll != NULL);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + if (coll == idx_coll)</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return true;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> }</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> return false;</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> index ddad54b3e..504738cd5 100644</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> --- a/src/box/sql/delete.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> +++ b/src/box/sql/delete.c</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> @@ -252,11 +252,11 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> /* Extract the primary key for the current row */</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> if (!is_view) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> for (int i = 0; i < pk_len; i++) {</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - assert(pk->aiColumn[i] >= 0);</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> sqlite3ExprCodeGetColumnOfTable(v, table->def,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> tab_cursor,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - pk-></span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> - aiColumn[i],</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + pk->def-></span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + key_def-></span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">> + parts[i].fieldno,</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">35. Please, just save pk->def->key_def->parts above in a separate</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""><span style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class="">variable, and use here only part->fieldno and ++part above.</span><br style="font-family: Helvetica, Arial, Tahoma, Verdana, sans-serif; font-size: 15px; font-variant-ligatures: normal; orphans: 2; white-space: normal; widows: 2;" class=""></pre></blockquote><pre style="orphans: 2; widows: 2; background-color: rgb(255, 255, 255);" class=""><font face="Helvetica, Arial, Tahoma, Verdana, sans-serif" class=""><span style="font-size: 15px; white-space: normal;" class="">—</span></font></pre><pre style="orphans: 2; widows: 2; background-color: rgb(255, 255, 255);" class=""><font face="Helvetica, Arial, Tahoma, Verdana, sans-serif" class=""><span style="font-size: 15px; white-space: normal;" class="">Thank you for the review. All the issues are fixed. Here is the patch:</span></font></pre><pre style="background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">sql: add index_def to Index

Now every sqlite struct Index is created with tnt struct
index_def inside. This allows us to use tnt index_def
in work with sqlite indexes in the same manner as with
tnt index and is a step to remove sqlite Index with
tnt index.
Fields coll_array, coll_id_array, aiColumn, sort_order
and zName are removed from Index. All usages of this
fields changed to usage of corresponding index_def
fields.
index_is_unique(), sql_index_collation() and
index_column_count() are removed with calls of
index_def corresponding fields.

Closes: #3369
---
Branch: <a href="https://github.com/tarantool/tarantool/tree/sb/gh-3369-use-index-def-in-select-and-where" class="">https://github.com/tarantool/tarantool/tree/sb/gh-3369-use-index-def-in-select-and-where</a>
Issue: <a href="https://github.com/tarantool/tarantool/issues/3369" class="">https://github.com/tarantool/tarantool/issues/3369</a>

 src/box/sql.c           |  54 +++---
 src/box/sql/analyze.c   |  40 ++--
 src/box/sql/build.c     | 488 +++++++++++++++++++++++-------------------------
 src/box/sql/delete.c    |  17 +-
 src/box/sql/expr.c      |  60 +++---
 src/box/sql/fkey.c      |  47 ++---
 src/box/sql/insert.c    | 148 ++++++---------
 src/box/sql/pragma.c    |  32 ++--
 src/box/sql/select.c    |   2 +-
 src/box/sql/sqliteInt.h |  63 +------
 src/box/sql/trigger.c   |   2 -
 src/box/sql/update.c    |  10 +-
 src/box/sql/vdbeaux.c   |   2 +-
 src/box/sql/vdbemem.c   |   4 +-
 src/box/sql/where.c     | 168 ++++++++---------
 src/box/sql/wherecode.c |  54 +++---
 src/box/sql/whereexpr.c |  15 --
 17 files changed, 532 insertions(+), 674 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index 7379cb418..213f8e453 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1442,8 +1442,8 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
 
        /* If table's PK is single column which is INTEGER, then
         * treat it as strict type, not affinity.  */
-       if (pk_idx && pk_idx->nColumn == 1) {
-               int pk = pk_idx->aiColumn[0];
+       if (pk_idx != NULL && pk_idx->def->key_def->part_count == 1) {
+               int pk = pk_idx->def->key_def->parts[0].fieldno;
                if (def->fields[pk].type == FIELD_TYPE_INTEGER)
                        pk_forced_int = pk;
        }
@@ -1552,20 +1552,19 @@ tarantoolSqlite3MakeTableOpts(Table *pTable, const char *zSql, char *buf)
  */
 int tarantoolSqlite3MakeIdxParts(SqliteIndex *pIndex, void *buf)
 {
-       struct space_def *def = pIndex->pTable->def;
-       assert(def != NULL);
+       struct field_def *fields = pIndex->pTable->def->fields;
+       struct key_def *key_def = pIndex->def->key_def;
        const struct Enc *enc = get_enc(buf);
-       struct SqliteIndex *primary_index;
-       char *base = buf, *p;
-       int pk_forced_int = -1;
-
-       primary_index = sqlite3PrimaryKeyIndex(pIndex->pTable);
+       char *base = buf;
+       uint32_t pk_forced_int = UINT32_MAX;
+       struct SqliteIndex *primary_index =
+               sqlite3PrimaryKeyIndex(pIndex->pTable);
 
        /* If table's PK is single column which is INTEGER, then
         * treat it as strict type, not affinity.  */
-       if (primary_index->nColumn == 1) {
-               int pk = primary_index->aiColumn[0];
-               if (def->fields[pk].type == FIELD_TYPE_INTEGER)
+       if (primary_index->def->key_def->part_count == 1) {
+               int pk = primary_index->def->key_def->parts[0].fieldno;
+               if (fields[pk].type == FIELD_TYPE_INTEGER)
                        pk_forced_int = pk;
        }
 
@@ -1575,46 +1574,45 @@ int tarantoolSqlite3MakeIdxParts(SqliteIndex *pIndex, void *buf)
         * primary key columns. Query planner depends on this particular
         * data layout.
         */
-       int i, n = pIndex->nColumn;
-
-       p = enc->encode_array(base, n);
-       for (i = 0; i < n; i++) {
-               int col = pIndex->aiColumn[i];
-               assert(def->fields[col].is_nullable ==
-                      action_is_nullable(def->fields[col].nullable_action));
+       struct key_part *part = key_def->parts;
+       char *p = enc->encode_array(base, key_def->part_count);
+       for (uint32_t i = 0; i < key_def->part_count; ++i, ++part) {
+               uint32_t col = part->fieldno;
+               assert(fields[col].is_nullable ==
+                      action_is_nullable(fields[col].nullable_action));
                const char *t;
                if (pk_forced_int == col) {
                        t = "integer";
                } else {
-                       enum affinity_type affinity = def->fields[col].affinity;
-                       t = convertSqliteAffinity(affinity,
-                                                 def->fields[col].is_nullable);
+                       t = convertSqliteAffinity(fields[col].affinity,
+                                                 fields[col].is_nullable);
                }
                /* do not decode default collation */
-               uint32_t cid = pIndex->coll_id_array[i];
+               uint32_t cid = part->coll_id;
                p = enc->encode_map(p, cid == COLL_NONE ? 5 : 6);
                p = enc->encode_str(p, "type", sizeof("type")-1);
                p = enc->encode_str(p, t, strlen(t));
                p = enc->encode_str(p, "field", sizeof("field")-1);
                p = enc->encode_uint(p, col);
                if (cid != COLL_NONE) {
-                       p = enc->encode_str(p, "collation", sizeof("collation")-1);
+                       p = enc->encode_str(p, "collation",
+                                           sizeof("collation") - 1);
                        p = enc->encode_uint(p, cid);
                }
                p = enc->encode_str(p, "is_nullable", 11);
-               p = enc->encode_bool(p, def->fields[col].is_nullable);
+               p = enc->encode_bool(p, fields[col].is_nullable);
                p = enc->encode_str(p, "nullable_action", 15);
                const char *action_str =
-                       on_conflict_action_strs[def->fields[col].nullable_action];
+                       on_conflict_action_strs[fields[col].nullable_action];
                p = enc->encode_str(p, action_str, strlen(action_str));
 
                p = enc->encode_str(p, "sort_order", 10);
-               enum sort_order sort_order = pIndex->sort_order[i];
+               enum sort_order sort_order = part->sort_order;
                assert(sort_order < sort_order_MAX);
                const char *sort_order_str = sort_order_strs[sort_order];
                p = enc->encode_str(p, sort_order_str, strlen(sort_order_str));
        }
-       return (int)(p - base);
+       return p - base;
 }
 
 /*
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index afc824a1a..31de7ab05 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -849,7 +849,6 @@ analyzeOneTable(Parse * pParse,     /* Parser context */
                int addrRewind; /* Address of "OP_Rewind iIdxCur" */
                int addrNextRow;        /* Address of "next_row:" */
                const char *zIdxName;   /* Name of the index */
-               int nColTest;   /* Number of columns to test for changes */
 
                if (pOnlyIdx && pOnlyIdx != pIdx)
                        continue;
@@ -860,9 +859,9 @@ analyzeOneTable(Parse * pParse,     /* Parser context */
                if (IsPrimaryKeyIndex(pIdx)) {
                        zIdxName = pTab->def->name;
                } else {
-                       zIdxName = pIdx->zName;
+                       zIdxName = pIdx->def->name;
                }
-               nColTest = index_column_count(pIdx);
+               int nColTest = pIdx->def->key_def->part_count;
 
                /* Populate the register containing the index name. */
                sqlite3VdbeLoadString(v, regIdxname, zIdxName);
@@ -917,7 +916,7 @@ analyzeOneTable(Parse * pParse,     /* Parser context */
                sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
                                  space_ptr_reg);
                sql_vdbe_set_p4_key_def(pParse, pIdx);
-               VdbeComment((v, "%s", pIdx->zName));
+               VdbeComment((v, "%s", pIdx->def->name));
 
                /* Invoke the stat_init() function. The arguments are:
                 *
@@ -969,7 +968,7 @@ analyzeOneTable(Parse * pParse,     /* Parser context */
                         */
                        sqlite3VdbeAddOp0(v, OP_Goto);
                        addrNextRow = sqlite3VdbeCurrentAddr(v);
-                       if (nColTest == 1 && index_is_unique(pIdx)) {
+                       if (nColTest == 1 && pIdx->def->opts.is_unique) {
                                /* For a single-column UNIQUE index, once we have found a non-NULL
                                 * row, we know that all the rest will be distinct, so skip
                                 * subsequent distinctness tests.
@@ -978,13 +977,12 @@ analyzeOneTable(Parse * pParse,   /* Parser context */
                                                  endDistinctTest);
                                VdbeCoverage(v);
                        }
-                       for (i = 0; i < nColTest; i++) {
-                               uint32_t id;
-                               struct coll *coll =
-                                       sql_index_collation(pIdx, i, &id);
+                       struct key_part *part = pIdx->def->key_def->parts;
+                       for (i = 0; i < nColTest; ++i, ++part) {
+                               struct coll *coll = part->coll;
                                sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
                                sqlite3VdbeAddOp3(v, OP_Column, iIdxCur,
-                                                 pIdx->aiColumn[i], regTemp);
+                                                 part->fieldno, regTemp);
                                aGotoChng[i] =
                                    sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0,
                                                      regPrev + i, (char *)coll,
@@ -1006,7 +1004,8 @@ analyzeOneTable(Parse * pParse,   /* Parser context */
                        for (i = 0; i < nColTest; i++) {
                                sqlite3VdbeJumpHere(v, aGotoChng[i]);
                                sqlite3VdbeAddOp3(v, OP_Column, iIdxCur,
-                                                 pIdx->aiColumn[i],
+                                                 pIdx->def->key_def->
+                                                         parts[i].fieldno,
                                                  regPrev + i);
                        }
                        sqlite3VdbeResolveLabel(v, endDistinctTest);
@@ -1022,15 +1021,14 @@ analyzeOneTable(Parse * pParse, /* Parser context */
                 */
                assert(regKey == (regStat4 + 2));
                Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
-               int j, k, regKeyStat;
-               int nPkColumn = (int)index_column_count(pPk);
-               regKeyStat = sqlite3GetTempRange(pParse, nPkColumn);
-               for (j = 0; j < nPkColumn; j++) {
-                       k = pPk->aiColumn[j];
-                       assert(k >= 0 && k < (int)pTab->def->field_count);
-                       sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKeyStat + j);
-                       VdbeComment((v, "%s",
-                               pTab->def->fields[pPk->aiColumn[j]].name));
+               int nPkColumn = (int) pPk->def->key_def->part_count;
+               int regKeyStat = sqlite3GetTempRange(pParse, nPkColumn);
+               for (int j = 0; j < nPkColumn; ++j) {
+                       int k = pPk->def->key_def->parts[j].fieldno;
+                       assert(k >= 0 && k < (int) pTab->def->field_count);
+                       sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k,
+                                         regKeyStat + j);
+                       VdbeComment((v, "%s", pTab->def->fields[k].name));
                }
                sqlite3VdbeAddOp3(v, OP_MakeRecord, regKeyStat,
                                  nPkColumn, regKey);
@@ -1150,7 +1148,7 @@ analyzeTable(Parse * pParse, Table * pTab, Index * pOnlyIdx)
        iStatCur = pParse->nTab;
        pParse->nTab += 3;
        if (pOnlyIdx) {
-               openStatTable(pParse, iStatCur, pOnlyIdx->zName, "idx");
+               openStatTable(pParse, iStatCur, pOnlyIdx->def->name, "idx");
        } else {
                openStatTable(pParse, iStatCur, pTab->def->name, "tbl");
        }
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 62d687b17..f18727c61 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -253,6 +253,8 @@ freeIndex(sqlite3 * db, Index * p)
 {
        sql_expr_delete(db, p->pPartIdxWhere, false);
        sql_expr_list_delete(db, p->aColExpr);
+       if (p->def != NULL)
+               index_def_delete(p->def);
        sqlite3DbFree(db, p->zColAff);
        sqlite3DbFree(db, p);
 }
@@ -271,7 +273,8 @@ sqlite3UnlinkAndDeleteIndex(sqlite3 * db, Index * pIndex)
 
        struct session *user_session = current_session();
 
-       pIndex = sqlite3HashInsert(&pIndex->pTable->idxHash, pIndex->zName, 0);
+       pIndex = sqlite3HashInsert(&pIndex->pTable->idxHash,
+                                  pIndex->def->name, 0);
        if (ALWAYS(pIndex)) {
                if (pIndex->pTable->pIndex == pIndex) {
                        pIndex->pTable->pIndex = pIndex->pNext;
@@ -388,7 +391,7 @@ deleteTable(sqlite3 * db, Table * pTable)
                pNext = pIndex->pNext;
                assert(pIndex->pSchema == pTable->pSchema);
                if ((db == 0 || db->pnBytesFreed == 0)) {
-                       char *zName = pIndex->zName;
+                       char *zName = pIndex->def->name;
                        TESTONLY(Index *
                                 pOld =) sqlite3HashInsert(&pTable->idxHash,
                                                           zName, 0);
@@ -1058,7 +1061,7 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken)
        Table *p = pParse->pNewTable;
        if (p == NULL)
                return;
-       int i = p->def->field_count - 1;
+       uint32_t i = p->def->field_count - 1;
        sqlite3 *db = pParse->db;
        char *zColl = sqlite3NameFromToken(db, pToken);
        if (!zColl)
@@ -1066,22 +1069,20 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken)
        uint32_t *id = &p->def->fields[i].coll_id;
        p->aCol[i].coll = sql_get_coll_seq(pParse, zColl, id);
        if (p->aCol[i].coll != NULL) {
-               Index *pIdx;
                /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
                 * then an index may have been created on this column before the
                 * collation type was added. Correct this if it is the case.
                 */
-               for (pIdx = p->pIndex; pIdx; pIdx = pIdx->pNext) {
-                       assert(pIdx->nColumn == 1);
-                       if (pIdx->aiColumn[0] == i) {
-                               id = &pIdx->coll_id_array[0];
-                               pIdx->coll_array[0] =
+               for (struct Index *pIdx = p->pIndex; pIdx; pIdx = pIdx->pNext) {
+                       assert(pIdx->def->key_def->part_count == 1);
+                       if (pIdx->def->key_def->parts[0].fieldno == i) {
+                               pIdx->def->key_def->parts[0].coll_id = *id;
+                               pIdx->def->key_def->parts[0].coll =
                                        sql_column_collation(p->def, i, id);
                        }
                }
-       } else {
-               sqlite3DbFree(db, zColl);
        }
+       sqlite3DbFree(db, zColl);
 }
 
 struct coll *
@@ -1111,66 +1112,6 @@ sql_column_collation(struct space_def *def, uint32_t column, uint32_t *coll_id)
        return space->format->fields[column].coll;
 }
 
-struct key_def*
-sql_index_key_def(struct Index *idx)
-{
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);
-       uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);
-       struct space *space = space_by_id(space_id);
-       assert(space != NULL);
-       struct index *index = space_index(space, index_id);
-       assert(index != NULL && index->def != NULL);
-       return index->def->key_def;
-}
-
-struct coll *
-sql_index_collation(Index *idx, uint32_t column, uint32_t *coll_id)
-{
-       assert(idx != NULL);
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->pTable->tnum);
-       struct space *space = space_by_id(space_id);
-
-       assert(column < idx->nColumn);
-       /*
-        * If space is still under construction, or it is
-        * an ephemeral space, then fetch collation from
-        * SQL internal structure.
-        */
-       if (space == NULL) {
-               assert(column < idx->nColumn);
-               *coll_id = idx->coll_id_array[column];
-               return idx->coll_array[column];
-       }
-
-       struct key_def *key_def = sql_index_key_def(idx);
-       assert(key_def != NULL && key_def->part_count >= column);
-       *coll_id = key_def->parts[column].coll_id;
-       return key_def->parts[column].coll;
-}
-
-enum sort_order
-sql_index_column_sort_order(Index *idx, uint32_t column)
-{
-       assert(idx != NULL);
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->pTable->tnum);
-       struct space *space = space_by_id(space_id);
-
-       assert(column < idx->nColumn);
-       /*
-        * If space is still under construction, or it is
-        * an ephemeral space, then fetch collation from
-        * SQL internal structure.
-        */
-       if (space == NULL) {
-               assert(column < idx->nColumn);
-               return idx->sort_order[column];
-       }
-
-       struct key_def *key_def = sql_index_key_def(idx);
-       assert(key_def != NULL && key_def->part_count >= column);
-       return key_def->parts[column].sort_order;
-}
-
 /**
  * Return true if space which corresponds to
  * given table has view option.
@@ -1383,14 +1324,16 @@ createTableStmt(sqlite3 * db, Table * p)
        return zStmt;
 }
 
-/* Return true if value x is found any of the first nCol entries of aiCol[]
- */
 static int
-hasColumn(const i16 * aiCol, int nCol, int x)
+hasColumn(const struct key_part *key_parts, int nCol, uint32_t fieldno)
 {
-       while (nCol-- > 0)
-               if (x == *(aiCol++))
+       int i = 0;
+       while (i < nCol) {
+               if (fieldno == key_parts->fieldno)
                        return 1;
+               key_parts++;
+               i++;
+       }
        return 0;
 }
 
@@ -1410,13 +1353,12 @@ static void
 convertToWithoutRowidTable(Parse * pParse, Table * pTab)
 {
        Index *pPk;
-       int i, j;
        sqlite3 *db = pParse->db;
 
        /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
         */
        if (!db->init.imposterTable) {
-               for (i = 0; i < (int)pTab->def->field_count; i++) {
+               for (uint32_t i = 0; i < pTab->def->field_count; i++) {
                        if (pTab->aCol[i].is_primkey) {
                                pTab->def->fields[i].nullable_action
                                        = ON_CONFLICT_ACTION_ABORT;
@@ -1454,14 +1396,28 @@ convertToWithoutRowidTable(Parse * pParse, Table * pTab)
                 * "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
                 * code assumes the PRIMARY KEY contains no repeated columns.
                 */
-               for (i = j = 1; i < pPk->nColumn; i++) {
-                       if (hasColumn(pPk->aiColumn, j, pPk->aiColumn[i])) {
-                               pPk->nColumn--;
-                       } else {
-                               pPk->aiColumn[j++] = pPk->aiColumn[i];
+
+               struct key_part *parts = pPk->def->key_def->parts;
+               uint32_t part_count = pPk->def->key_def->part_count;
+               uint32_t new_part_count = part_count;
+
+               for (uint32_t i = 1; i < part_count; i++) {
+                       if (hasColumn(parts, i, parts[i].fieldno)){
+                               new_part_count--;
+                               bool is_found = false;
+                               for (uint32_t j = i + 1; j < part_count; j++){
+                                       if (!(hasColumn(parts, j,
+                                                       parts[j].fieldno))) {
+                                               parts[i] = parts[j];
+                                               is_found = true;
+                                               break;
+                                       }
+                               }
+                               if (!(is_found))
+                                       break;
                        }
                }
-               pPk->nColumn = j;
+               pPk->def->key_def->part_count = new_part_count;
        }
        assert(pPk != 0);
 }
@@ -1543,7 +1499,7 @@ createIndex(Parse * pParse, Index * pIndex, int iSpaceId, int iIndexId,
        }
        sqlite3VdbeAddOp4(v,
                          OP_String8, 0, iFirstCol + 2, 0,
-                         sqlite3DbStrDup(pParse->db, pIndex->zName),
+                         sqlite3DbStrDup(pParse->db, pIndex->def->name),
                          P4_DYNAMIC);
        sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 3, 0, "tree",
                          P4_STATIC);
@@ -1580,7 +1536,7 @@ makeIndexSchemaRecord(Parse * pParse,
 
        sqlite3VdbeAddOp4(v,
                          OP_String8, 0, iFirstCol, 0,
-                         sqlite3DbStrDup(pParse->db, pIndex->zName),
+                         sqlite3DbStrDup(pParse->db, pIndex->def->name),
                          P4_DYNAMIC);
 
        if (pParse->pNewTable) {
@@ -2652,14 +2608,15 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage)
        } else {
                tnum = pIndex->tnum;
        }
-       struct key_def *def = key_def_dup(sql_index_key_def(pIndex));
+       struct key_def *def = key_def_dup(pIndex->def->key_def);
        if (def == NULL) {
                sqlite3OomFault(db);
                return;
        }
        /* Open the sorter cursor if we are to use one. */
        iSorter = pParse->nTab++;
-       sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nColumn,
+       sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0,
+                         pIndex->def->key_def->part_count,
                          (char *)def, P4_KEYDEF);
 
        /* Open the table. Loop through all rows of the table, inserting index
@@ -2692,7 +2649,7 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage)
                sqlite3VdbeGoto(v, j2);
                addr2 = sqlite3VdbeCurrentAddr(v);
                sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2,
-                                    regRecord, pIndex->nColumn);
+                                    regRecord, pIndex->def->key_def->part_count);
                VdbeCoverage(v);
                sqlite3UniqueConstraint(pParse, ON_CONFLICT_ACTION_ABORT,
                                        pIndex);
@@ -2730,24 +2687,13 @@ sqlite3AllocateIndexObject(sqlite3 * db,        /* Database connection */
        int nByte;              /* Bytes of space for Index object + arrays */
 
        nByte = ROUND8(sizeof(Index)) +             /* Index structure   */
-           ROUND8(sizeof(struct coll *) * nCol) +  /* Index.coll_array  */
-           ROUND8(sizeof(uint32_t) * nCol) +       /* Index.coll_id_array*/
-           ROUND8(sizeof(LogEst) * (nCol + 1) +    /* Index.aiRowLogEst */
-                  sizeof(i16) * nCol +             /* Index.aiColumn    */
-                  sizeof(enum sort_order) * nCol); /* Index.sort_order  */
+           ROUND8(sizeof(LogEst) * (nCol + 1));    /* Index.aiRowLogEst */
        p = sqlite3DbMallocZero(db, nByte + nExtra);
        if (p) {
                char *pExtra = ((char *)p) + ROUND8(sizeof(Index));
-               p->coll_array = (struct coll **)pExtra;
-               pExtra += ROUND8(sizeof(struct coll **) * nCol);
-               p->coll_id_array = (uint32_t *) pExtra;
-               pExtra += ROUND8(sizeof(uint32_t) * nCol);
                p->aiRowLogEst = (LogEst *) pExtra;
                pExtra += sizeof(LogEst) * (nCol + 1);
-               p->aiColumn = (i16 *) pExtra;
                pExtra += sizeof(i16) * nCol;
-               p->sort_order = (enum sort_order *) pExtra;
-               p->nColumn = nCol;
                *ppExtra = ((char *)p) + nByte;
        }
        return p;
@@ -2836,18 +2782,133 @@ addIndexToTable(Index * pIndex, Table * pTab)
        }
 }
 
-bool
-index_is_unique(Index *idx)
+static inline void
+append_string_part(struct region *r, const char *str,
+                 size_t *total_sql_size, Parse *parse)
 {
-       assert(idx != NULL);
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);
-       uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);
-       struct space *space = space_by_id(space_id);
-       assert(space != NULL);
-       struct index *tnt_index = space_index(space, index_id);
-       assert(tnt_index != NULL);
+       char * str_part = region_alloc(r, strlen(str));
+       if (str_part == NULL){
+               diag_set(OutOfMemory, strlen(str),
+                        "region_alloc", "str_part");
+               parse->rc = SQL_TARANTOOL_ERROR;
+               parse->nErr++;
+       }
+       memcpy(str_part, str, strlen(str));
+       *total_sql_size += strlen(str);
+}
+
+void static
+set_index_def(Parse *parse, Index *index, Table *table, uint32_t iid,
+             const char *name, uint32_t name_len, int on_error,
+             struct ExprList *expr_list, u8 idx_type)
+{
+       struct space_def *space_def = table->def;
+       struct index_opts opts;
+       index_opts_create(&opts);
+       opts.is_unique = on_error != ON_CONFLICT_ACTION_NONE;
+
+       struct key_def *key_def = key_def_new(expr_list->nExpr);
+       if (key_def == NULL) {
+               parse->rc = SQL_TARANTOOL_ERROR;
+               parse->nErr++;
+               return;
+       }
+
+       /*
+        * Build initial parts of SQL statement.
+        */
+
+       struct region *r = &fiber()->gc;
+       size_t total_sql_size = 0;
+
+       if (idx_type == SQLITE_IDXTYPE_APPDEF) {
+               append_string_part(r, "CREATE INDEX ", &total_sql_size,
+                                  parse);
+               append_string_part(r, name, &total_sql_size, parse);
+               append_string_part(r, " ON ", &total_sql_size, parse);
+               append_string_part(r, space_def->name, &total_sql_size,
+                                  parse);
+               append_string_part(r, " (", &total_sql_size, parse);
+       }
+
+       for (int i = 0; i < expr_list->nExpr; i++) {
+               Expr *expr = expr_list->a[i].pExpr;
+               sql_resolve_self_reference(parse, table, NC_IdxExpr, expr, 0);
+               if (parse->nErr > 0)
+                       return;
+
+               Expr *column_expr = sqlite3ExprSkipCollate(expr);
+               if (column_expr->op != TK_COLUMN) {
+                       sqlite3ErrorMsg(parse,
+                                       "functional indexes aren't supported "
+                                       "in the current version");
+                       return;
+               }
+
+               uint32_t fieldno = column_expr->iColumn;
+               uint32_t coll_id;
+               struct coll *coll;
+               if (expr->op == TK_COLLATE) {
+                       coll = sql_get_coll_seq(parse, expr->u.zToken,
+                                               &coll_id);
+
+                       if (idx_type == SQLITE_IDXTYPE_APPDEF) {
+                               append_string_part(r, name,
+                                                  &total_sql_size, parse);
+                               append_string_part(r, " COLLATE ",
+                                                  &total_sql_size, parse);
+                               const char *coll_name = expr->u.zToken;
+                               append_string_part(r, coll_name,
+                                                  &total_sql_size, parse);
+                               append_string_part(r, ", ",
+                                                  &total_sql_size, parse);
+                       }
+               } else {
+                       coll = sql_column_collation(space_def, fieldno,
+                                                   &coll_id);
+                       if (idx_type == SQLITE_IDXTYPE_APPDEF) {
+                               append_string_part(r, name,
+                                                  &total_sql_size, parse);
+                               append_string_part(r, ", ",
+                                                  &total_sql_size, parse);
+                       }
+               }
+
+               /*
+               * Tarantool: DESC indexes are not supported so far.
+               * See gh-3016.
+               */
+               key_def_set_part(key_def, i, fieldno,
+                                space_def->fields[fieldno].type,
+                                space_def->fields[fieldno].nullable_action,
+                                coll, coll_id, SORT_ORDER_ASC);
+       }
 
-       return tnt_index->def->opts.is_unique;
+       if (parse->nErr > 0) {
+               index->def = NULL;
+               return;
+       }
+
+       if (idx_type == SQLITE_IDXTYPE_APPDEF) {
+               memcpy(region_alloc(r, 1), "\0", 1);
+               total_sql_size += 1;
+               opts.sql = region_join(r, total_sql_size);
+
+               /*
+                * fix last ", " with ")\0" to finish the statement.
+                */
+               opts.sql[total_sql_size - 3] = ')';
+               opts.sql[total_sql_size - 2] = '\0';
+       }
+
+       struct key_def *pk_key_def;
+       if (idx_type == SQLITE_IDXTYPE_APPDEF)
+               pk_key_def = table->pIndex->def->key_def;
+       else
+               pk_key_def = NULL;
+
+       index->def = index_def_new(space_def->id, iid, name, name_len,
+                                  TREE, &opts, key_def, pk_key_def);
 }
 
 void
@@ -2856,16 +2917,14 @@ sql_create_index(struct Parse *parse, struct Token *token,
                 int on_error, struct Token *start, struct Expr *where,
                 enum sort_order sort_order, bool if_not_exist, u8 idx_type)
 {
-       Table *pTab = 0;        /* Table to be indexed */
-       Index *pIndex = 0;      /* The index to be created */
-       char *zName = 0;        /* Name of the index */
-       int nName;              /* Number of characters in zName */
-       int i, j;
+       Table *pTab = NULL;     /* Table to be indexed */
+       Index *pIndex = NULL;   /* The index to be created */
+       char *name = NULL;      /* Name of the index */
+       int name_len;           /* Number of characters in zName */
        DbFixer sFix;           /* For assigning database names to pTable */
        sqlite3 *db = parse->db;
-       struct ExprList_item *col_listItem;     /* For looping over col_list */
        int nExtra = 0;         /* Space allocated for zExtra[] */
-       char *zExtra = 0;       /* Extra space after the Index object */
+       char *zExtra = NULL;    /* Extra space after the Index object */
        struct session *user_session = current_session();
 
        if (db->mallocFailed || parse->nErr > 0) {
@@ -2939,24 +2998,24 @@ sql_create_index(struct Parse *parse, struct Token *token,
         * our own name.
         */
        if (token) {
-               zName = sqlite3NameFromToken(db, token);
-               if (zName == 0)
+               name = sqlite3NameFromToken(db, token);
+               if (name == NULL)
                        goto exit_create_index;
                assert(token->z != 0);
                if (!db->init.busy) {
-                       if (sqlite3HashFind(&db->pSchema->tblHash, zName) !=
+                       if (sqlite3HashFind(&db->pSchema->tblHash, name) !=
                            NULL) {
                                sqlite3ErrorMsg(parse,
                                                "there is already a table named %s",
-                                               zName);
+                                               name);
                                goto exit_create_index;
                        }
                }
-               if (sqlite3HashFind(&pTab->idxHash, zName) != NULL) {
+               if (sqlite3HashFind(&pTab->idxHash, name) != NULL) {
                        if (!if_not_exist) {
                                sqlite3ErrorMsg(parse,
                                                "index %s.%s already exists",
-                                               pTab->def->name, zName);
+                                               pTab->def->name, name);
                        } else {
                                assert(!db->init.busy);
                        }
@@ -2968,10 +3027,9 @@ sql_create_index(struct Parse *parse, struct Token *token,
                for (pLoop = pTab->pIndex, n = 1; pLoop;
                     pLoop = pLoop->pNext, n++) {
                }
-               zName =
-                   sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->def->name,
-                                  n);
-               if (zName == 0) {
+               name = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d",
+                                     pTab->def->name, n);
+               if (name == NULL) {
                        goto exit_create_index;
                }
        }
@@ -2997,31 +3055,27 @@ sql_create_index(struct Parse *parse, struct Token *token,
                sqlite3ExprListCheckLength(parse, col_list, "index");
        }
 
-       /* Figure out how many bytes of space are required to store explicitly
-        * specified collation sequence names.
-        */
-       for (i = 0; i < col_list->nExpr; i++) {
-               Expr *pExpr = col_list->a[i].pExpr;
-               assert(pExpr != 0);
-               if (pExpr->op == TK_COLLATE) {
-                       nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
-               }
-       }
-
        /*
         * Allocate the index structure.
         */
-       nName = sqlite3Strlen30(zName);
+       name_len = sqlite3Strlen30(name);
+
+       if (name_len > BOX_NAME_MAX) {
+               sqlite3ErrorMsg(parse,
+                               "%s.%s exceeds indexes' names length limit",
+                               pTab->def->name, name);
+               goto exit_create_index;
+       }
+
+       if (sqlite3CheckIdentifierName(parse, name) != SQLITE_OK)
+               goto exit_create_index;
+
        pIndex = sqlite3AllocateIndexObject(db, col_list->nExpr,
-                                           nName + nExtra + 1, &zExtra);
+                                           name_len + nExtra + 1, &zExtra);
        if (db->mallocFailed) {
                goto exit_create_index;
        }
        assert(EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst));
-       assert(EIGHT_BYTE_ALIGNMENT(pIndex->coll_array));
-       pIndex->zName = zExtra;
-       zExtra += nName + 1;
-       memcpy(pIndex->zName, zName, nName + 1);
        pIndex->pTable = pTab;
        pIndex->onError = (u8) on_error;
        /*
@@ -3036,7 +3090,6 @@ sql_create_index(struct Parse *parse, struct Token *token,
                pIndex->idxType = idx_type;
        }
        pIndex->pSchema = db->pSchema;
-       pIndex->nColumn = col_list->nExpr;
        /* Tarantool have access to each column by any index */
        if (where) {
                sql_resolve_self_reference(parse, pTab, NC_PartIdx, where,
@@ -3045,60 +3098,27 @@ sql_create_index(struct Parse *parse, struct Token *token,
                where = NULL;
        }
 
-       /* Analyze the list of expressions that form the terms of the index and
-        * report any errors.  In the common case where the expression is exactly
-        * a table column, store that column in aiColumn[].  For general expressions,
-        * populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
-        *
+       /*
         * TODO: Issue a warning if two or more columns of the index are identical.
         * TODO: Issue a warning if the table primary key is used as part of the
         * index key.
         */
-       for (i = 0, col_listItem = col_list->a; i < col_list->nExpr;
-            i++, col_listItem++) {
-               Expr *pCExpr;   /* The i-th index expression */
-               sql_resolve_self_reference(parse, pTab, NC_IdxExpr,
-                                          col_listItem->pExpr, NULL);
-               if (parse->nErr > 0)
-                       goto exit_create_index;
-               pCExpr = sqlite3ExprSkipCollate(col_listItem->pExpr);
-               if (pCExpr->op != TK_COLUMN) {
-                       sqlite3ErrorMsg(parse,
-                                       "functional indexes aren't supported "
-                                       "in the current version");
-                       goto exit_create_index;
-               } else {
-                       j = pCExpr->iColumn;
-                       assert(j <= 0x7fff);
-                       if (j < 0) {
-                               j = pTab->iPKey;
-                       }
-                       pIndex->aiColumn[i] = (i16) j;
-               }
-               struct coll *coll;
-               uint32_t id;
-               if (col_listItem->pExpr->op == TK_COLLATE) {
-                       const char *coll_name = col_listItem->pExpr->u.zToken;
-                       coll = sql_get_coll_seq(parse, coll_name, &id);
 
-                       if (coll == NULL &&
-                           sqlite3StrICmp(coll_name, "binary") != 0) {
-                               goto exit_create_index;
-                       }
-               } else if (j >= 0) {
-                       coll = sql_column_collation(pTab->def, j, &id);
-               } else {
-                       id = COLL_NONE;
-                       coll = NULL;
-               }
-               pIndex->coll_array[i] = coll;
-               pIndex->coll_id_array[i] = id;
+       uint32_t max_iid = 0;
+       for (Index *index = pTab->pIndex; index; index = index->pNext) {
+               max_iid = max_iid > index->def->iid ?
+                         max_iid :
+                         index->def->iid + 1;
+       }
 
-               /* Tarantool: DESC indexes are not supported so far.
-                * See gh-3016.
-                */
-               pIndex->sort_order[i] = SORT_ORDER_ASC;
+       set_index_def(parse, pIndex, pTab, max_iid, name, name_len, on_error,
+                     col_list, idx_type);
+
+       if (pIndex->def == NULL ||
+           !index_def_is_valid(pIndex->def, pTab->def->name)) {
+               goto exit_create_index;
        }
+
        if (pTab == parse->pNewTable) {
                /* This routine has been called to create an automatic index as a
                 * result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -3123,25 +3143,27 @@ sql_create_index(struct Parse *parse, struct Token *token,
                 */
                Index *pIdx;
                for (pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext) {
-                       int k;
+                       uint32_t k;
                        assert(IsUniqueIndex(pIdx));
                        assert(pIdx->idxType != SQLITE_IDXTYPE_APPDEF);
                        assert(IsUniqueIndex(pIndex));
 
-                       if (pIdx->nColumn != pIndex->nColumn)
+                       if (pIdx->def->key_def->part_count !=
+                           pIndex->def->key_def->part_count) {
                                continue;
-                       for (k = 0; k < pIdx->nColumn; k++) {
-                               assert(pIdx->aiColumn[k] >= 0);
-                               if (pIdx->aiColumn[k] != pIndex->aiColumn[k])
+                       }
+                       for (k = 0; k < pIdx->def->key_def->part_count; k++) {
+                               if (pIdx->def->key_def->parts[k].fieldno !=
+                                   pIndex->def->key_def->parts[k].fieldno) {
                                        break;
+                               }
                                struct coll *coll1, *coll2;
-                               uint32_t id;
-                               coll1 = sql_index_collation(pIdx, k, &id);
-                               coll2 = sql_index_collation(pIndex, k, &id);
+                               coll1 = pIdx->def->key_def->parts[k].coll;
+                               coll2 = pIndex->def->key_def->parts[k].coll;
                                if (coll1 != coll2)
                                        break;
                        }
-                       if (k == pIdx->nColumn) {
+                       if (k == pIdx->def->key_def->part_count) {
                                if (pIdx->onError != pIndex->onError) {
                                        /* This constraint creates the same index as a previous
                                         * constraint specified somewhere in the CREATE TABLE statement.
@@ -3175,7 +3197,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
        assert(parse->nErr == 0);
        if (db->init.busy) {
                Index *p;
-               p = sqlite3HashInsert(&pTab->idxHash, pIndex->zName, pIndex);
+               p = sqlite3HashInsert(&pTab->idxHash, pIndex->def->name, pIndex);
                if (p) {
                        assert(p == pIndex);    /* Malloc must have failed */
                        sqlite3OomFault(db);
@@ -3273,44 +3295,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
        sql_expr_delete(db, where, false);
        sql_expr_list_delete(db, col_list);
        sqlite3SrcListDelete(db, tbl_name);
-       sqlite3DbFree(db, zName);
-}
-
-/**
- * Return number of columns in given index.
- * If space is ephemeral, use internal
- * SQL structure to fetch the value.
- */
-uint32_t
-index_column_count(const Index *idx)
-{
-       assert(idx != NULL);
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);
-       struct space *space = space_by_id(space_id);
-       /* It is impossible to find an ephemeral space by id. */
-       if (space == NULL)
-               return idx->nColumn;
-
-       uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);
-       struct index *index = space_index(space, index_id);
-       assert(index != NULL);
-       return index->def->key_def->part_count;
-}
-
-/** Return true if given index is unique and not nullable. */
-bool
-index_is_unique_not_null(const Index *idx)
-{
-       assert(idx != NULL);
-       uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(idx->tnum);
-       struct space *space = space_by_id(space_id);
-       assert(space != NULL);
-
-       uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(idx->tnum);
-       struct index *index = space_index(space, index_id);
-       assert(index != NULL);
-       return (index->def->opts.is_unique &&
-               !index->def->key_def->is_nullable);
+       sqlite3DbFree(db, name);
 }
 
 void
@@ -3938,18 +3923,19 @@ sqlite3UniqueConstraint(Parse * pParse, /* Parsing context */
     )
 {
        char *zErr;
-       int j;
+       uint32_t j;
        StrAccum errMsg;
        Table *pTab = pIdx->pTable;
 
        sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
        if (pIdx->aColExpr) {
-               sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
+               sqlite3XPrintf(&errMsg, "index '%q'", pIdx->def->name);
        } else {
-               for (j = 0; j < pIdx->nColumn; j++) {
+               struct key_part *part = pIdx->def->key_def->parts;
+               for (j = 0; j < pIdx->def->key_def->part_count; j++, part++) {
                        char *zCol;
-                       assert(pIdx->aiColumn[j] >= 0);
-                       zCol = pTab->def->fields[pIdx->aiColumn[j]].name;
+                       uint32_t fieldno = part->fieldno;
+                       zCol = pTab->def->fields[fieldno].name;
                        if (j)
                                sqlite3StrAccumAppend(&errMsg, ", ", 2);
                        sqlite3XPrintf(&errMsg, "%s.%s", pTab->def->name, zCol);
@@ -3972,11 +3958,11 @@ static bool
 collationMatch(struct coll *coll, struct Index *index)
 {
        assert(coll != NULL);
-       for (int i = 0; i < index->nColumn; i++) {
-               uint32_t id;
-               struct coll *idx_coll = sql_index_collation(index, i, &id);
-               assert(idx_coll != 0 || index->aiColumn[i] < 0);
-               if (index->aiColumn[i] >= 0 && coll == idx_coll)
+       struct key_part *part = index->def->key_def->parts;
+       for (uint32_t i = 0; i < index->def->key_def->part_count; i++, part++) {
+               struct coll *idx_coll = part->coll;
+               assert(idx_coll != NULL);
+               if (coll == idx_coll)
                        return true;
        }
        return false;
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index ddad54b3e..0314382f7 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -209,7 +209,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
                } else {
                        pk = sqlite3PrimaryKeyIndex(table);
                        assert(pk != NULL);
-                       pk_len = index_column_count(pk);
+                       pk_len = pk->def->key_def->part_count;
                        parse->nMem += pk_len;
                        sqlite3VdbeAddOp2(v, OP_OpenTEphemeral, eph_cursor,
                                          pk_len);
@@ -251,12 +251,11 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 
                /* Extract the primary key for the current row */
                if (!is_view) {
-                       for (int i = 0; i < pk_len; i++) {
-                               assert(pk->aiColumn[i] >= 0);
+                       struct key_part *part = pk->def->key_def->parts;
+                       for (int i = 0; i < pk_len; i++, part++) {
                                sqlite3ExprCodeGetColumnOfTable(v, table->def,
                                                                tab_cursor,
-                                                               pk->
-                                                               aiColumn[i],
+                                                               part->fieldno,
                                                                reg_pk + i);
                        }
                } else {
@@ -326,7 +325,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
                        sqlite3VdbeAddOp3(v, OP_OpenWrite, tab_cursor,
                                          table->tnum, space_ptr_reg);
                        sql_vdbe_set_p4_key_def(parse, pk);
-                       VdbeComment((v, "%s", pk->zName));
+                       VdbeComment((v, "%s", pk->def->name));
 
                        if (one_pass == ONEPASS_MULTI)
                                sqlite3VdbeJumpHere(v, iAddrOnce);
@@ -536,14 +535,14 @@ sql_generate_index_key(struct Parse *parse, struct Index *index, int cursor,
                        *part_idx_label = 0;
                }
        }
-       int col_cnt = index_column_count(index);
+       int col_cnt = index->def->key_def->part_count;
        int reg_base = sqlite3GetTempRange(parse, col_cnt);
        if (prev != NULL && (reg_base != reg_prev ||
                             prev->pPartIdxWhere != NULL))
                prev = NULL;
        for (int j = 0; j < col_cnt; j++) {
-               if (prev != NULL && prev->aiColumn[j] == index->aiColumn[j]
-                   && prev->aiColumn[j] != XN_EXPR) {
+               if (prev->def->key_def->parts[j].fieldno ==
+                   index->def->key_def->parts[j].fieldno && prev == NULL) {
                        /*
                         * This column was already computed by the
                         * previous index.
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 8866f6fed..a756535f0 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -2422,20 +2422,24 @@ sqlite3FindInIndex(Parse * pParse,      /* Parsing context */
                             pIdx = pIdx->pNext) {
                                Bitmask colUsed; /* Columns of the index used */
                                Bitmask mCol;   /* Mask for the current column */
-                               if (pIdx->nColumn < nExpr)
+                               uint32_t part_count = pIdx->def->key_def->
+                                       part_count;
+                               struct key_part *parts = pIdx->def->key_def->
+                                       parts;
+                               if ((int)part_count < nExpr)
                                        continue;
                                /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
                                 * BITMASK(nExpr) without overflowing
                                 */
-                               testcase(pIdx->nColumn == BMS - 2);
-                               testcase(pIdx->nColumn == BMS - 1);
-                               if (pIdx->nColumn >= BMS - 1)
+                               testcase(part_count == BMS - 2);
+                               testcase(>part_count == BMS - 1);
+                               if (part_count >= BMS - 1)
                                        continue;
                                if (mustBeUnique) {
-                                       if (pIdx->nColumn > nExpr
-                                           || (pIdx->nColumn > nExpr
-                                           && !index_is_unique(pIdx))) {
-                                                       continue;       /* This index is not unique over the IN RHS columns */
+                                       if ((int)part_count > nExpr
+                                           || !pIdx->def->opts.is_unique) {
+                                               /* This index is not unique over the IN RHS columns */
+                                               continue;
                                        }
                                }
 
@@ -2449,12 +2453,13 @@ sqlite3FindInIndex(Parse * pParse,      /* Parsing context */
                                        int j;
 
                                        for (j = 0; j < nExpr; j++) {
-                                               if (pIdx->aiColumn[j] !=
-                                                   pRhs->iColumn) {
+                                               if ((int) parts[j].fieldno
+                                                   != pRhs->iColumn) {
                                                        continue;
                                                }
-                                               struct coll *idx_coll;
-                                               idx_coll = sql_index_collation(pIdx, j, &id);
+
+                                               struct coll *idx_coll =
+                                                            parts[j].coll;
                                                if (pReq != NULL &&
                                                    pReq != idx_coll) {
                                                        continue;
@@ -2483,17 +2488,16 @@ sqlite3FindInIndex(Parse * pParse,      /* Parsing context */
                                                          0, 0, 0,
                                                          sqlite3MPrintf(db,
                                                          "USING INDEX %s FOR IN-OPERATOR",
-                                                         pIdx->zName),
+                                                         pIdx->def->name),
                                                          P4_DYNAMIC);
                                        emit_open_cursor(pParse, iTab,
                                                         pIdx->tnum);
                                        sql_vdbe_set_p4_key_def(pParse, pIdx);
-                                       VdbeComment((v, "%s", pIdx->zName));
+                                       VdbeComment((v, "%s", pIdx->def->name));
                                        assert(IN_INDEX_INDEX_DESC ==
                                               IN_INDEX_INDEX_ASC + 1);
                                        eType = IN_INDEX_INDEX_ASC +
-                                               sql_index_column_sort_order(pIdx,
-                                                                           0);
+                                               parts[0].sort_order;
 
                                        if (prRhsHasNull) {
 #ifdef SQLITE_ENABLE_COLUMN_USED_MASK
@@ -2515,7 +2519,7 @@ sqlite3FindInIndex(Parse * pParse,        /* Parsing context */
                                                        /* Tarantool: Check for null is performed on first key of the index.  */
                                                        sqlite3SetHasNullFlag(v,
                                                                              iTab,
-                                                                             pIdx->aiColumn[0],
+                                                                             parts[0].fieldno,
                                                                              *prRhsHasNull);
                                                }
                                        }
@@ -3146,12 +3150,12 @@ sqlite3ExprCodeIN(Parse * pParse,       /* Parsing and code generating context */
                struct Index *pk = sqlite3PrimaryKeyIndex(tab);
                assert(pk);
 
+               uint32_t fieldno = pk->def->key_def->parts[0].fieldno;
                enum affinity_type affinity =
-                       tab->def->fields[pk->aiColumn[0]].affinity;
-               if (pk->nColumn == 1
+                       tab->def->fields[fieldno].affinity;
+               if (pk->def->key_def->part_count == 1
                    && affinity == AFFINITY_INTEGER
-                   && pk->aiColumn[0] < nVector) {
-                       int reg_pk = rLhs + pk->aiColumn[0];
+                   && (int) fieldno < nVector) { int reg_pk = rLhs + (int)fieldno;
                        sqlite3VdbeAddOp2(v, OP_MustBeInt, reg_pk, destIfFalse);
                }
        }
@@ -3483,17 +3487,9 @@ sqlite3ExprCodeLoadIndexColumn(Parse * pParse,   /* The parsing context */
                               int regOut       /* Store the index column value in this register */
     )
 {
-       i16 iTabCol = pIdx->aiColumn[iIdxCol];
-       if (iTabCol == XN_EXPR) {
-               assert(pIdx->aColExpr);
-               assert(pIdx->aColExpr->nExpr > iIdxCol);
-               pParse->iSelfTab = iTabCur;
-               sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr,
-                                   regOut);
-       } else {
-               sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable->def,
-                                               iTabCur, iTabCol, regOut);
-       }
+       i16 iTabCol = pIdx->def->key_def->parts[iIdxCol].fieldno;
+       sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable->def,
+                                       iTabCur, iTabCol, regOut);
 }
 
 void
diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c
index 70ebef89f..79320eced 100644
--- a/src/box/sql/fkey.c
+++ b/src/box/sql/fkey.c
@@ -256,8 +256,8 @@ sqlite3FkLocateIndex(Parse * pParse,        /* Parse context to store any error in */
        }
 
        for (pIdx = pParent->pIndex; pIdx; pIdx = pIdx->pNext) {
-               int nIdxCol = index_column_count(pIdx);
-               if (nIdxCol == nCol && index_is_unique(pIdx)
+               int nIdxCol = pIdx->def->key_def->part_count;
+               if (nIdxCol == nCol && pIdx->def->opts.is_unique
                    && pIdx->pPartIdxWhere == 0) {
                        /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
                         * of columns. If each indexed column corresponds to a foreign key
@@ -286,8 +286,10 @@ sqlite3FkLocateIndex(Parse * pParse,       /* Parse context to store any error in */
                                 * the default collation sequences for each column.
                                 */
                                int i, j;
-                               for (i = 0; i < nCol; i++) {
-                                       i16 iCol = pIdx->aiColumn[i];        /* Index of column in parent tbl */
+                               struct key_part *part =
+                                       pIdx->def->key_def->parts;
+                               for (i = 0; i < nCol; i++, part++) {
+                                       i16 iCol = (int) part->fieldno;      /* Index of column in parent tbl */
                                        char *zIdxCol;  /* Name of indexed column */
 
                                        if (iCol < 0)
@@ -302,9 +304,7 @@ sqlite3FkLocateIndex(Parse * pParse,        /* Parse context to store any error in */
                                        def_coll = sql_column_collation(pParent->def,
                                                                        iCol,
                                                                        &id);
-                                       struct coll *coll =
-                                               sql_index_collation(pIdx, i,
-                                                                   &id);
+                                       struct coll *coll = part->coll;
                                        if (def_coll != coll)
                                                break;
 
@@ -464,13 +464,15 @@ fkLookupParent(Parse * pParse,    /* Parse context */
                                for (i = 0; i < nCol; i++) {
                                        int iChild = aiCol[i] + 1 + regData;
                                        int iParent =
-                                           pIdx->aiColumn[i] + 1 + regData;
-                                       assert(pIdx->aiColumn[i] >= 0);
+                                               (int) pIdx->def->key_def->parts[i].fieldno
+                                               + 1 + regData;
                                        assert(aiCol[i] != pTab->iPKey);
-                                       if (pIdx->aiColumn[i] == pTab->iPKey) {
+                                       if ((int)pIdx->def->key_def->
+                                               parts[i].fieldno == pTab->iPKey) {
                                                /* The parent key is a composite key that includes the IPK column */
                                                iParent = regData;
                                        }
+
                                        sqlite3VdbeAddOp3(v, OP_Ne, iChild,
                                                          iJump, iParent);
                                        VdbeCoverage(v);
@@ -622,7 +624,7 @@ fkScanChildren(Parse * pParse,      /* Parse context */
        Vdbe *v = sqlite3GetVdbe(pParse);
 
        assert(pIdx == 0 || pIdx->pTable == pTab);
-       assert(pIdx == 0 || (int)index_column_count(pIdx) == pFKey->nCol);
+       assert(pIdx == 0 || (int) pIdx->def->key_def->part_count == pFKey->nCol);
        assert(pIdx != 0);
 
        if (nIncr < 0) {
@@ -646,7 +648,7 @@ fkScanChildren(Parse * pParse,      /* Parse context */
                i16 iCol;       /* Index of column in child table */
                const char *zCol;       /* Name of column in child table */
 
-               iCol = pIdx ? pIdx->aiColumn[i] : -1;
+               iCol = pIdx ? pIdx->def->key_def->parts[i].fieldno : -1;
                pLeft = exprTableRegister(pParse, pTab, regData, iCol);
                iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
                assert(iCol >= 0);
@@ -671,10 +673,9 @@ fkScanChildren(Parse * pParse,     /* Parse context */
                Expr *pEq, *pAll = 0;
                Index *pPk = sqlite3PrimaryKeyIndex(pTab);
                assert(pIdx != 0);
-               int col_count = index_column_count(pPk);
+               int col_count = pPk->def->key_def->part_count;
                for (i = 0; i < col_count; i++) {
-                       i16 iCol = pIdx->aiColumn[i];
-                       assert(iCol >= 0);
+                       i16 iCol = (int) pIdx->def->key_def->parts[i].fieldno;
                        pLeft = exprTableRegister(pParse, pTab, regData, iCol);
                        pRight =
                                exprTableColumn(db, pTab->def,
@@ -992,7 +993,6 @@ sqlite3FkCheck(Parse * pParse,      /* Parse context */
                        if (aiCol[i] == pTab->iPKey) {
                                aiCol[i] = -1;
                        }
-                       assert(pIdx == 0 || pIdx->aiColumn[i] >= 0);
                }
 
                pParse->nTab++;
@@ -1126,10 +1126,10 @@ sqlite3FkOldmask(Parse * pParse,        /* Parse context */
                        Index *pIdx = 0;
                        sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
                        if (pIdx) {
-                               int nIdxCol = index_column_count(pIdx);
+                               int nIdxCol = pIdx->def->key_def->part_count;
                                for (i = 0; i < nIdxCol; i++) {
-                                       assert(pIdx->aiColumn[i] >= 0);
-                                       mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+                                       mask |= COLUMN_MASK(pIdx->def->
+                                               key_def->parts[i].fieldno);
                                }
                        }
                }
@@ -1264,11 +1264,12 @@ fkActionTrigger(Parse * pParse, /* Parse context */
                               || (pTab->iPKey >= 0
                                   && pTab->iPKey <
                                      (int)pTab->def->field_count));
-                       assert(pIdx == 0 || pIdx->aiColumn[i] >= 0);
+
+                       uint32_t fieldno = pIdx != NULL ?
+                                            pIdx->def->key_def->parts[i].fieldno
+                                          : pTab->iPKey;
                        sqlite3TokenInit(&tToCol,
-                                        pTab->def->fields[pIdx ? pIdx->
-                                                   aiColumn[i] : pTab->iPKey].
-                                        name);
+                                        pTab->def->fields[fieldno].name);
                        sqlite3TokenInit(&tFromCol,
                                         pFKey->pFrom->def->fields[
                                                iFromCol].name);
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 59c61c703..fc9f85165 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -89,7 +89,7 @@ sqlite3IndexAffinityStr(sqlite3 * db, Index * pIdx)
                 * up.
                 */
                int n;
-               int nColumn = index_column_count(pIdx);
+               int nColumn = pIdx->def->key_def->part_count;
                pIdx->zColAff =
                    (char *)sqlite3DbMallocRaw(0, nColumn + 1);
                if (!pIdx->zColAff) {
@@ -97,22 +97,8 @@ sqlite3IndexAffinityStr(sqlite3 * db, Index * pIdx)
                        return 0;
                }
                for (n = 0; n < nColumn; n++) {
-                       i16 x = pIdx->aiColumn[n];
-                       if (x >= 0) {
-                               char affinity = pIdx->pTable->
-                                       def->fields[x].affinity;
-                               pIdx->zColAff[n] = affinity;
-                       } else {
-                               char aff;
-                               assert(x == XN_EXPR);
-                               assert(pIdx->aColExpr != 0);
-                               aff =
-                                   sqlite3ExprAffinity(pIdx->aColExpr->a[n].
-                                                       pExpr);
-                               if (aff == 0)
-                                       aff = AFFINITY_BLOB;
-                               pIdx->zColAff[n] = aff;
-                       }
+                       i16 x = pIdx->def->key_def->parts[n].fieldno;
+                       pIdx->zColAff[n] = pIdx->pTable->def->fields[x].affinity;
                }
                pIdx->zColAff[n] = 0;
        }
@@ -645,7 +631,7 @@ sqlite3Insert(Parse * pParse,       /* Parser context */
                     pIdx = pIdx->pNext, i++) {
                        assert(pIdx);
                        aRegIdx[i] = ++pParse->nMem;
-                       pParse->nMem += index_column_count(pIdx);
+                       pParse->nMem += pIdx->def->key_def->part_count;
                }
        }
 
@@ -1088,7 +1074,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,           /* The parser context */
        nCol = pTab->def->field_count;
 
        pPk = sqlite3PrimaryKeyIndex(pTab);
-       nPkField = index_column_count(pPk);
+       nPkField = pPk->def->key_def->part_count;
 
        /* Record that this module has started */
        VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
@@ -1252,38 +1238,27 @@ sqlite3GenerateConstraintChecks(Parse * pParse,         /* The parser context */
                 * the insert or update.  Store that record in the aRegIdx[ix] register
                 */
                regIdx = aRegIdx[ix] + 1;
-               int nIdxCol = (int)index_column_count(pIdx);
+               int nIdxCol = pIdx->def->key_def->part_count;
                for (i = 0; i < nIdxCol; i++) {
-                       int iField = pIdx->aiColumn[i];
+                       int iField = (int) pIdx->def->key_def->parts[i].fieldno;
                        int x;
-                       if (iField == XN_EXPR) {
-                               pParse->ckBase = regNewData + 1;
-                               sqlite3ExprCodeCopy(pParse,
-                                                   pIdx->aColExpr->a[i].pExpr,
-                                                   regIdx + i);
-                               pParse->ckBase = 0;
-                               VdbeComment((v, "%s column %d", pIdx->zName,
-                                            i));
-                       } else {
-                               /* OP_SCopy copies value in separate register,
-                                * which later will be used by OP_NoConflict.
-                                * But OP_NoConflict is necessary only in cases
-                                * when bytecode is needed for proper UNIQUE
-                                * constraint handling.
-                                */
-                               if (uniqueByteCodeNeeded) {
-                                       if (iField == pTab->iPKey)
-                                               x = regNewData;
-                                       else
-                                               x = iField + regNewData + 1;
-
-                                       assert(iField >= 0);
-                                       sqlite3VdbeAddOp2(v, OP_SCopy,
-                                                         x, regIdx + i);
-                                       VdbeComment((v, "%s",
-                                                    pTab->def->fields[
-                                                       iField].name));
-                               }
+                       /* OP_SCopy copies value in separate register,
+                        * which later will be used by OP_NoConflict.
+                        * But OP_NoConflict is necessary only in cases
+                        * when bytecode is needed for proper UNIQUE
+                        * constraint handling.
+                        */
+                       if (uniqueByteCodeNeeded) {
+                               if (iField == pTab->iPKey)
+                                       x = regNewData;
+                               else
+                                       x = iField + regNewData + 1;
+
+                               assert(iField >= 0);
+                               sqlite3VdbeAddOp2(v, OP_SCopy,
+                                                 x, regIdx + i);
+                               VdbeComment((v, "%s",
+                                            pTab->def->fields[iField].name));
                        }
                }
 
@@ -1293,8 +1268,12 @@ sqlite3GenerateConstraintChecks(Parse * pParse,          /* The parser context */
                        /* If PK is marked as INTEGER, use it as strict type,
                         * not as affinity. Emit code for type checking */
                        if (nIdxCol == 1) {
-                               reg_pk = regNewData + 1 + pIdx->aiColumn[0];
-                               if (pTab->zColAff[pIdx->aiColumn[0]] ==
+                               reg_pk = regNewData + 1 +
+                                       pIdx->def->key_def->parts[0].fieldno;
+
+                               int fieldno = (int)pIdx->def->key_def->
+                                       parts[0].fieldno;
+                               if (pTab->zColAff[fieldno] ==
                                    AFFINITY_INTEGER) {
                                        int skip_if_null = sqlite3VdbeMakeLabel(v);
                                        if ((pTab->tabFlags & TF_Autoincrement) != 0) {
@@ -1311,8 +1290,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse,           /* The parser context */
                        }
 
                        sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData + 1,
-                                       pTab->def->field_count, aRegIdx[ix]);
-                       VdbeComment((v, "for %s", pIdx->zName));
+                                         pTab->def->field_count, aRegIdx[ix]);
+                       VdbeComment((v, "for %s", pIdx->def->name));
                }
 
                /* In an UPDATE operation, if this index is the PRIMARY KEY
@@ -1400,7 +1379,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,           /* The parser context */
                if (uniqueByteCodeNeeded) {
                        sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur,
                                             addrUniqueOk, regIdx,
-                                            index_column_count(pIdx));
+                                            pIdx->def->key_def->part_count);
                }
                VdbeCoverage(v);
 
@@ -1410,19 +1389,17 @@ sqlite3GenerateConstraintChecks(Parse * pParse,         /* The parser context */
                                                                 nPkField);
                if (isUpdate || on_error == ON_CONFLICT_ACTION_REPLACE) {
                        int x;
-                       int nPkCol = index_column_count(pPk);
+                       int nPkCol = pPk->def->key_def->part_count;
                        /* Extract the PRIMARY KEY from the end of the index entry and
                         * store it in registers regR..regR+nPk-1
                         */
                        if (pIdx != pPk) {
                                for (i = 0; i < nPkCol; i++) {
-                                       assert(pPk->aiColumn[i] >= 0);
-                                       x = pPk->aiColumn[i];
+                                       x = pPk->def->key_def->parts[i].fieldno;
                                        sqlite3VdbeAddOp3(v, OP_Column,
                                                          iThisCur, x, regR + i);
                                        VdbeComment((v, "%s.%s", pTab->def->name,
-                                               pTab->def->fields[
-                                                       pPk->aiColumn[i]].name));
+                                               pTab->def->fields[x].name));
                                }
                        }
                        if (isUpdate && uniqueByteCodeNeeded) {
@@ -1440,10 +1417,11 @@ sqlite3GenerateConstraintChecks(Parse * pParse,         /* The parser context */
                                              regIdx : regR);
 
                                for (i = 0; i < nPkCol; i++) {
-                                       uint32_t id;
-                                       char *p4 = (char *)sql_index_collation(pPk, i, &id);
-                                       x = pPk->aiColumn[i];
-                                       assert(x >= 0);
+                                       char *p4 = (char *) pPk->def->key_def->parts[i].coll;
+                                       x = pPk->def->key_def->parts[i].fieldno;
+                                       if (pPk->tnum==0) {
+                                               x = -1;
+                                       }
                                        if (i == (nPkCol - 1)) {
                                                addrJump = addrUniqueOk;
                                                op = OP_Eq;
@@ -1620,8 +1598,8 @@ sqlite3OpenTableAndIndices(Parse * pParse,        /* Parsing context */
                    IsPrimaryKeyIndex(pIdx) ||          /* Condition 2 */
                    sqlite3FkReferences(pTab) ||        /* Condition 3 */
                    /* Condition 4 */
-                   (index_is_unique(pIdx) && pIdx->onError !=
-                    ON_CONFLICT_ACTION_DEFAULT &&
+                   (pIdx->def->opts.is_unique &&
+                    pIdx->onError != ON_CONFLICT_ACTION_DEFAULT &&
                     /* Condition 4.1 */
                     pIdx->onError != ON_CONFLICT_ACTION_ABORT) ||
                     /* Condition 4.2 */
@@ -1639,7 +1617,7 @@ sqlite3OpenTableAndIndices(Parse * pParse,        /* Parsing context */
                                                  space_ptr_reg);
                                sql_vdbe_set_p4_key_def(pParse, pIdx);
                                sqlite3VdbeChangeP5(v, p5);
-                               VdbeComment((v, "%s", pIdx->zName));
+                               VdbeComment((v, "%s", pIdx->def->name));
                        }
                }
        }
@@ -1676,35 +1654,23 @@ xferCompatibleIndex(Index * pDest, Index * pSrc)
        uint32_t i;
        assert(pDest && pSrc);
        assert(pDest->pTable != pSrc->pTable);
-       uint32_t nDestCol = index_column_count(pDest);
-       uint32_t nSrcCol = index_column_count(pSrc);
+       uint32_t nDestCol = pDest->def->key_def->part_count;
+       uint32_t nSrcCol = pSrc->def->key_def->part_count;
        if (nDestCol != nSrcCol) {
                return 0;       /* Different number of columns */
        }
        if (pDest->onError != pSrc->onError) {
                return 0;       /* Different conflict resolution strategies */
        }
-       for (i = 0; i < nSrcCol; i++) {
-               if (pSrc->aiColumn[i] != pDest->aiColumn[i]) {
+       struct key_part *src_part = pSrc->def->key_def->parts;
+       struct key_part *dest_part = pDest->def->key_def->parts;
+       for (i = 0; i < nSrcCol; i++, src_part++, dest_part++) {
+               if (src_part->fieldno != dest_part->fieldno)
                        return 0;       /* Different columns indexed */
-               }
-               if (pSrc->aiColumn[i] == XN_EXPR) {
-                       assert(pSrc->aColExpr != 0 && pDest->aColExpr != 0);
-                       if (sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
-                                              pDest->aColExpr->a[i].pExpr,
-                                              -1) != 0) {
-                               return 0;       /* Different expressions in the index */
-                       }
-               }
-               if (sql_index_column_sort_order(pSrc, i) !=
-                   sql_index_column_sort_order(pDest, i)) {
+               if (src_part->sort_order != dest_part->sort_order)
                        return 0;       /* Different sort orders */
-               }
-               uint32_t id;
-               if (sql_index_collation(pSrc, i, &id) !=
-                   sql_index_collation(pDest, i, &id)) {
+               if (src_part->coll != dest_part->coll)
                        return 0;       /* Different collating sequences */
-               }
        }
        if (sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1)) {
                return 0;       /* Different WHERE clauses */
@@ -1876,16 +1842,14 @@ xferOptimization(Parse * pParse,        /* Parser context */
                }
        }
        for (pDestIdx = pDest->pIndex; pDestIdx; pDestIdx = pDestIdx->pNext) {
-               if (index_is_unique(pDestIdx)) {
+               if (pDestIdx->def->opts.is_unique)
                        destHasUniqueIdx = 1;
-               }
                for (pSrcIdx = pSrc->pIndex; pSrcIdx; pSrcIdx = pSrcIdx->pNext) {
                        if (xferCompatibleIndex(pDestIdx, pSrcIdx))
                                break;
                }
-               if (pSrcIdx == 0) {
+               if (pSrcIdx == 0)
                        return 0;       /* pDestIdx has no corresponding index in pSrc */
-               }
        }
        /* Get server checks. */
        ExprList *pCheck_src = space_checks_expr_list(
@@ -1960,11 +1924,11 @@ xferOptimization(Parse * pParse,        /* Parser context */
                assert(pSrcIdx);
                emit_open_cursor(pParse, iSrc, pSrcIdx->tnum);
                sql_vdbe_set_p4_key_def(pParse, pSrcIdx);
-               VdbeComment((v, "%s", pSrcIdx->zName));
+               VdbeComment((v, "%s", pSrcIdx->def->name));
                emit_open_cursor(pParse, iDest, pDestIdx->tnum);
                sql_vdbe_set_p4_key_def(pParse, pDestIdx);
                sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
-               VdbeComment((v, "%s", pDestIdx->zName));
+               VdbeComment((v, "%s", pDestIdx->def->name));
                addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
                VdbeCoverage(v);
                sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 9dab5a7fd..45896811b 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -370,8 +370,11 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
                                                for (k = 1;
                                                     k <=
                                                     (int)pTab->def->field_count
-                                                    && pPk->aiColumn[k - 1] !=
-                                                    i; k++) {
+                                                    && (int) pPk->def->
+                                                            key_def->
+                                                            parts[k - 1].
+                                                            fieldno != i;
+                                                    k++) {
                                                }
                                        }
                                        bool nullable =
@@ -430,7 +433,7 @@ sqlite3Pragma(Parse * pParse, Token * pId,  /* First part of [schema.]id field */
                                        size_t avg_tuple_size_idx =
                                                sql_index_tuple_size(space, idx);
                                        sqlite3VdbeMultiLoad(v, 2, "sii",
-                                                            pIdx->zName,
+                                                            pIdx->def->name,
                                                             avg_tuple_size_idx,
                                                             index_field_tuple_est(pIdx, 0));
                                        sqlite3VdbeAddOp2(v, OP_ResultRow, 1,
@@ -459,11 +462,13 @@ sqlite3Pragma(Parse * pParse, Token * pId,        /* First part of [schema.]id field */
                                                 */
                                                pParse->nMem = 3;
                                        }
-                                       mx = index_column_count(pIdx);
+                                       mx = pIdx->def->key_def->part_count;
                                        assert(pParse->nMem <=
                                               pPragma->nPragCName);
-                                       for (i = 0; i < mx; i++) {
-                                               i16 cnum = pIdx->aiColumn[i];
+                                       struct key_part *part =
+                                               pIdx->def->key_def->parts;
+                                       for (i = 0; i < mx; i++, part++) {
+                                               i16 cnum = (int) part->fieldno;
                                                assert(pIdx->pTable);
                                                sqlite3VdbeMultiLoad(v, 1,
                                                                     "iis", i,
@@ -477,19 +482,18 @@ sqlite3Pragma(Parse * pParse, Token * pId,        /* First part of [schema.]id field */
                                                                     name);
                                                if (pPragma->iArg) {
                                                        const char *c_n;
-                                                       uint32_t id;
+                                                       uint32_t id =
+                                                               part->coll_id;
                                                        struct coll *coll =
-                                                               sql_index_collation(pIdx, i, &id);
+                                                               part->coll;
                                                        if (coll != NULL)
                                                                c_n = coll_by_id(id)->name;
                                                        else
                                                                c_n = "BINARY";
-                                                       enum sort_order sort_order;
-                                                       sort_order = sql_index_column_sort_order(pIdx,
-                                                                                                i);
                                                        sqlite3VdbeMultiLoad(v,
                                                                             4,
                                                                             "isi",
+                                                                            part->
                                                                             sort_order,
                                                                             c_n,
                                                                             i <
@@ -519,10 +523,8 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
                                                    { "c", "u", "pk" };
                                                sqlite3VdbeMultiLoad(v, 1,
                                                                     "isisi", i,
-                                                                    pIdx->
-                                                                    zName,
-                                                                    index_is_unique
-                                                                    (pIdx),
+                                                                    pIdx->def->name,
+                                                                    pIdx->def->opts.is_unique,
                                                                     azOrigin
                                                                     [pIdx->
                                                                      idxType],
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 2aa35a114..2646a99c3 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -4291,7 +4291,7 @@ sqlite3IndexedByLookup(Parse * pParse, struct SrcList_item *pFrom)
                char *zIndexedBy = pFrom->u1.zIndexedBy;
                Index *pIdx;
                for (pIdx = pTab->pIndex;
-                    pIdx && strcmp(pIdx->zName, zIndexedBy);
+                    pIdx && strcmp(pIdx->def->name, zIndexedBy);
                     pIdx = pIdx->pNext) ;
                if (!pIdx) {
                        sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy,
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 01351a183..36b46ed4f 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -2071,21 +2071,6 @@ struct UnpackedRecord {
  * Each SQL index is represented in memory by an
  * instance of the following structure.
  *
- * The columns of the table that are to be indexed are described
- * by the aiColumn[] field of this structure.  For example, suppose
- * we have the following table and index:
- *
- *     CREATE TABLE Ex1(c1 int, c2 int, c3 text);
- *     CREATE INDEX Ex2 ON Ex1(c3,c1);
- *
- * In the Table structure describing Ex1, nCol==3 because there are
- * three columns in the table.  In the Index structure describing
- * Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
- * The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the
- * first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
- * The second column to be indexed (c1) has an index of 0 in
- * Ex1.aCol[], hence Ex2.aiColumn[1]==0.
- *
  * The Index.onError field determines whether or not the indexed columns
  * must be unique and what to do if they are not.  When Index.onError=
  * ON_CONFLICT_ACTION_NONE, it means this is not a unique index.
@@ -2102,27 +2087,19 @@ struct UnpackedRecord {
  * program is executed). See convertToWithoutRowidTable() for details.
  */
 struct Index {
-       char *zName;            /* Name of this index */
-       i16 *aiColumn;          /* Which columns are used by this index.  1st is 0 */
        LogEst *aiRowLogEst;    /* From ANALYZE: Est. rows selected by each column */
        Table *pTable;          /* The SQL table being indexed */
        char *zColAff;          /* String defining the affinity of each column */
        Index *pNext;           /* The next index associated with the same table */
        Schema *pSchema;        /* Schema containing this index */
-       /** Sorting order for each column. */
-       enum sort_order *sort_order;
-       /** Array of collation sequences for index. */
-       struct coll **coll_array;
-       /** Array of collation identifiers. */
-       uint32_t *coll_id_array;
        Expr *pPartIdxWhere;    /* WHERE clause for partial indices */
        ExprList *aColExpr;     /* Column expressions */
        int tnum;               /* DB Page containing root of this index */
-       u16 nColumn;            /* Number of columns stored in the index */
        u8 onError;             /* ON_CONFLICT_ACTION_ABORT, _IGNORE, _REPLACE,
                                 * or _NONE
                                 */
        unsigned idxType:2;     /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
+       struct index_def *def;
 };
 
 /**
@@ -2161,11 +2138,6 @@ index_field_tuple_est(struct Index *idx, uint32_t field);
 #define IsUniqueIndex(X)      (((X)->idxType == SQLITE_IDXTYPE_UNIQUE) || \
                                ((X)->idxType == SQLITE_IDXTYPE_PRIMARYKEY))
 
-/* The Index.aiColumn[] values are normally positive integer.  But
- * there are some negative values that have special meaning:
- */
-#define XN_EXPR      (-2)      /* Indexed column is an expression */
-
 #ifdef DEFAULT_TUPLE_COUNT
 #undef DEFAULT_TUPLE_COUNT
 #endif
@@ -3526,37 +3498,10 @@ void sqlite3AddCollateType(Parse *, Token *);
  */
 struct coll *
 sql_column_collation(struct space_def *def, uint32_t column, uint32_t *coll_id);
-/**
- * Return name of given column collation from index.
- *
- * @param idx Index which is used to fetch column.
- * @param column Number of column.
- * @param[out] coll_id Collation identifier.
- * @retval Pointer to collation.
- */
-struct coll *
-sql_index_collation(Index *idx, uint32_t column, uint32_t *id);
+
 bool
 space_is_view(Table *);
 
-/**
- * Return key_def of provided struct Index.
- * @param idx Pointer to `struct Index` object.
- * @retval Pointer to `struct key_def`.
- */
-struct key_def*
-sql_index_key_def(struct Index *idx);
-
-/**
- * Return sort order of given column from index.
- *
- * @param idx Index which is used to fetch column.
- * @param column Number of column.
- * @retval Sort order of requested column.
- */
-enum sort_order
-sql_index_column_sort_order(Index *idx, uint32_t column);
-
 void sqlite3EndTable(Parse *, Token *, Token *, Select *);
 int
 emit_open_cursor(Parse *, int, int);
@@ -3607,8 +3552,6 @@ void sqlite3SrcListAssignCursors(Parse *, SrcList *);
 void sqlite3IdListDelete(sqlite3 *, IdList *);
 void sqlite3SrcListDelete(sqlite3 *, SrcList *);
 Index *sqlite3AllocateIndexObject(sqlite3 *, i16, int, char **);
-bool
-index_is_unique(Index *);
 
 /**
  * Create a new index for an SQL table.  name is the name of the
@@ -4293,8 +4236,6 @@ int sqlite3InvokeBusyHandler(BusyHandler *);
 int
 sql_analysis_load(struct sqlite3 *db);
 
-uint32_t
-index_column_count(const Index *);
 bool
 index_is_unique_not_null(const Index *);
 void sqlite3RegisterLikeFunctions(sqlite3 *, int);
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index e1126b2d2..ea3521133 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -872,8 +872,6 @@ codeRowTrigger(Parse * pParse,      /* Current parse context */
        pSubParse->pToplevel = pTop;
        pSubParse->eTriggerOp = pTrigger->op;
        pSubParse->nQueryLoop = pParse->nQueryLoop;
-       struct region *region = &fiber()->gc;
-       pSubParse->region_initial_size = region_used(region);
 
        v = sqlite3GetVdbe(pSubParse);
        if (v) {
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 590aad28b..6545b3b06 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -237,14 +237,14 @@ sqlite3Update(Parse * pParse,             /* The parser context */
         */
        for (j = 0, pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext, j++) {
                int reg;
-               int nIdxCol = index_column_count(pIdx);
+               int nIdxCol = pIdx->def->key_def->part_count;
                if (chngPk || hasFK || pIdx->pPartIdxWhere || pIdx == pPk) {
                        reg = ++pParse->nMem;
                        pParse->nMem += nIdxCol;
                } else {
                        reg = 0;
                        for (i = 0; i < nIdxCol; i++) {
-                               i16 iIdxCol = pIdx->aiColumn[i];
+                               i16 iIdxCol = pIdx->def->key_def->parts[i].fieldno;
                                if (iIdxCol < 0 || aXRef[iIdxCol] >= 0) {
                                        reg = ++pParse->nMem;
                                        pParse->nMem += nIdxCol;
@@ -306,7 +306,7 @@ sqlite3Update(Parse * pParse,               /* The parser context */
                nPk = nKey;
        } else {
                assert(pPk != 0);
-               nPk = index_column_count(pPk);
+               nPk = pPk->def->key_def->part_count;
        }
        iPk = pParse->nMem + 1;
        pParse->nMem += nPk;
@@ -333,9 +333,9 @@ sqlite3Update(Parse * pParse,               /* The parser context */
                }
        } else {
                for (i = 0; i < nPk; i++) {
-                       assert(pPk->aiColumn[i] >= 0);
                        sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iDataCur,
-                                                       pPk->aiColumn[i],
+                                                       pPk->def->key_def->
+                                                               parts[i].fieldno,
                                                        iPk + i);
                }
        }
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 679bd0bc1..520b309d9 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1165,7 +1165,7 @@ sql_vdbe_set_p4_key_def(struct Parse *parse, struct Index *idx)
        struct Vdbe *v = parse->pVdbe;
        assert(v != NULL);
        assert(idx != NULL);
-       struct key_def *def = key_def_dup(sql_index_key_def(idx));
+       struct key_def *def = key_def_dup(idx->def->key_def);
        if (def == NULL)
                sqlite3OomFault(parse->db);
        else
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index f408b7701..51b5d516e 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -1087,7 +1087,7 @@ valueNew(sqlite3 * db, struct ValueNewStat4Ctx *p)
                        Index *pIdx = p->pIdx;       /* Index being probed */
                        int nByte;      /* Bytes of space to allocate */
                        int i;  /* Counter variable */
-                       int nCol = index_column_count(pIdx);
+                       int nCol = pIdx->def->key_def->part_count;
 
                        nByte = sizeof(Mem) * nCol +
                                ROUND8(sizeof(UnpackedRecord));
@@ -1095,7 +1095,7 @@ valueNew(sqlite3 * db, struct ValueNewStat4Ctx *p)
                            (UnpackedRecord *) sqlite3DbMallocZero(db, nByte);
                        if (pRec == NULL)
                                return NULL;
-                       pRec->key_def = key_def_dup(sql_index_key_def(pIdx));
+                       pRec->key_def = key_def_dup(pIdx->def->key_def);
                        if (pRec->key_def == NULL) {
                                sqlite3DbFree(db, pRec);
                                sqlite3OomFault(db);
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index e79164781..9f5de50f9 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -265,11 +265,6 @@ whereScanNext(WhereScan * pScan)
                        for (pTerm = pWC->a + k; k < pWC->nTerm; k++, pTerm++) {
                                if (pTerm->leftCursor == iCur
                                    && pTerm->u.leftColumn == iColumn
-                                   && (iColumn != XN_EXPR
-                                       || sqlite3ExprCompare(pTerm->pExpr->
-                                                             pLeft,
-                                                             pScan->pIdxExpr,
-                                                             iCur) == 0)
                                    && (pScan->iEquiv <= 1
                                        || !ExprHasProperty(pTerm->pExpr,
                                                            EP_FromJoin))
@@ -376,19 +371,21 @@ whereScanInit(WhereScan * pScan,  /* The WhereScan object being initialized */
        pScan->is_column_seen = false;
        if (pIdx) {
                int j = iColumn;
-               iColumn = pIdx->aiColumn[j];
-               if (iColumn == XN_EXPR) {
-                       pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
-               } else if (iColumn >= 0) {
+               iColumn = pIdx->def->key_def->parts[j].fieldno;
+               /*
+                * pIdx->tnum == 0 means that pIdx is a fake integer
+                * primary key index
+                */
+               if (pIdx->tnum == 0)
+                       iColumn = -1;
+
+               if (iColumn >= 0) {
                        char affinity =
                                pIdx->pTable->def->fields[iColumn].affinity;
                        pScan->idxaff = affinity;
-                       uint32_t id;
-                       pScan->coll = sql_index_collation(pIdx, j, &id);
+                       pScan->coll = pIdx->def->key_def->parts[j].coll;
                        pScan->is_column_seen = true;
                }
-       } else if (iColumn == XN_EXPR) {
-               return 0;
        }
        pScan->opMask = opMask;
        pScan->k = 0;
@@ -464,18 +461,17 @@ findIndexCol(Parse * pParse,      /* Parse context */
             Index * pIdx,      /* Index to match column of */
             int iCol)          /* Column of index to match */
 {
+       struct key_part *part_to_match = &pIdx->def->key_def->parts[iCol];
        for (int i = 0; i < pList->nExpr; i++) {
                Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
-               if (p->op == TK_COLUMN &&
-                   p->iColumn == pIdx->aiColumn[iCol] &&
-                   p->iTable == iBase) {
+               if (p->op == TK_COLUMN && p->iTable == iBase &&
+                   p->iColumn == (int) part_to_match->fieldno) {
                        bool is_found;
                        uint32_t id;
                        struct coll *coll = sql_expr_coll(pParse,
                                                          pList->a[i].pExpr,
                                                          &is_found, &id);
-                       if (is_found &&
-                           coll == sql_index_collation(pIdx, iCol, &id)) {
+                       if (is_found && coll == part_to_match->coll) {
                                return i;
                        }
                }
@@ -484,27 +480,6 @@ findIndexCol(Parse * pParse,       /* Parse context */
        return -1;
 }
 
-/*
- * Return TRUE if the iCol-th column of index pIdx is NOT NULL
- */
-static int
-indexColumnNotNull(Index * pIdx, int iCol)
-{
-       int j;
-       assert(pIdx != 0);
-       assert(iCol >= 0 && iCol < (int)index_column_count(pIdx));
-       j = pIdx->aiColumn[iCol];
-       if (j >= 0) {
-               return !pIdx->pTable->def->fields[j].is_nullable;
-       } else if (j == (-1)) {
-               return 1;
-       } else {
-               assert(j == (-2));
-               return 0;       /* Assume an indexed expression can always yield a NULL */
-
-       }
-}
-
 /*
  * Return true if the DISTINCT expression-list passed as the third argument
  * is redundant.
@@ -556,9 +531,9 @@ isDistinctRedundant(Parse * pParse,         /* Parsing context */
         *      contain a "col=X" term are subject to a NOT NULL constraint.
         */
        for (pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext) {
-               if (!index_is_unique(pIdx))
+               if (!pIdx->def->opts.is_unique)
                        continue;
-               int col_count = index_column_count(pIdx);
+               int col_count = pIdx->def->key_def->part_count;
                for (i = 0; i < col_count; i++) {
                        if (0 ==
                            sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask) 0,
@@ -566,11 +541,12 @@ isDistinctRedundant(Parse * pParse,               /* Parsing context */
                                if (findIndexCol
                                    (pParse, pDistinct, iBase, pIdx, i) < 0)
                                        break;
-                               if (indexColumnNotNull(pIdx, i) == 0)
+                               uint32_t j = pIdx->def->key_def->parts[i].fieldno;
+                               if (!pIdx->pTable->def->fields[j].is_nullable == 0)
                                        break;
                        }
                }
-               if (i == (int)index_column_count(pIdx)) {
+               if (i == (int) pIdx->def->key_def->part_count) {
                        /* This index implies that the DISTINCT qualifier is redundant. */
                        return 1;
                }
@@ -1107,7 +1083,7 @@ whereRangeAdjust(WhereTerm * pTerm, LogEst nNew)
 char
 sqlite3IndexColumnAffinity(sqlite3 * db, Index * pIdx, int iCol)
 {
-       assert(iCol >= 0 && iCol < (int)index_column_count(pIdx));
+       assert(iCol >= 0 && iCol < (int) pIdx->def->key_def->part_count);
        if (!pIdx->zColAff) {
                if (sqlite3IndexAffinityStr(db, pIdx) == 0)
                        return AFFINITY_BLOB;
@@ -1169,13 +1145,12 @@ whereRangeSkipScanEst(Parse * pParse,           /* Parsing & code generating context */
        int nUpper = index->def->opts.stat->sample_count + 1;
        int rc = SQLITE_OK;
        u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
-       uint32_t id;
 
        sqlite3_value *p1 = 0;  /* Value extracted from pLower */
        sqlite3_value *p2 = 0;  /* Value extracted from pUpper */
        sqlite3_value *pVal = 0;        /* Value extracted from record */
 
-       struct coll *pColl = sql_index_collation(p, nEq, &id);
+       struct coll *pColl = p->def->key_def->parts[nEq].coll;
        if (pLower) {
                rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight,
                                               aff, &p1);
@@ -1371,7 +1346,7 @@ whereRangeScanEst(Parse * pParse, /* Parsing & code generating context */
                               || (pLower->eOperator & (WO_GT | WO_GE)) != 0);
                        assert(pUpper == 0
                               || (pUpper->eOperator & (WO_LT | WO_LE)) != 0);
-                       if (sql_index_column_sort_order(p, nEq) !=
+                       if (p->def->key_def->parts[nEq].sort_order !=
                            SORT_ORDER_ASC) {
                                /* The roles of pLower and pUpper are swapped for a DESC index */
                                SWAP(pLower, pUpper);
@@ -1521,7 +1496,7 @@ whereEqualScanEst(Parse * pParse, /* Parsing & code generating context */
        int bOk;
 
        assert(nEq >= 1);
-       assert(nEq <= (int)index_column_count(p));
+       assert(nEq <= (int) p->def->key_def->part_count);
        assert(pBuilder->nRecValid < nEq);
 
        /* If values are not available for all fields of the index to the left
@@ -1542,7 +1517,7 @@ whereEqualScanEst(Parse * pParse, /* Parsing & code generating context */
 
        whereKeyStats(pParse, p, pRec, 0, a);
        WHERETRACE(0x10, ("equality scan regions %s(%d): %d\n",
-                         p->zName, nEq - 1, (int)a[1]));
+                         p->def->name, nEq - 1, (int)a[1]));
        *pnRow = a[1];
 
        return rc;
@@ -1674,7 +1649,7 @@ whereLoopPrint(WhereLoop * p, WhereClause * pWC)
                           pItem->zAlias ? pItem->zAlias : pTab->def->name);
 #endif
        const char *zName;
-       if (p->pIndex && (zName = p->pIndex->zName) != 0) {
+       if (p->pIndex && (zName = p->pIndex->def->name) != 0) {
                if (strncmp(zName, "sqlite_autoindex_", 17) == 0) {
                        int i = sqlite3Strlen30(zName) - 1;
                        while (zName[i] != '_')
@@ -2236,7 +2211,7 @@ whereRangeVectorLen(Parse * pParse,       /* Parsing context */
        int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
        int i;
 
-       nCmp = MIN(nCmp, (int)(index_column_count(pIdx) - nEq));
+       nCmp = MIN(nCmp, (int)(pIdx->def->key_def->part_count - nEq));
        for (i = 1; i < nCmp; i++) {
                /* Test if comparison i of pTerm is compatible with column (i+nEq)
                 * of the index. If not, exit the loop.
@@ -2257,11 +2232,10 @@ whereRangeVectorLen(Parse * pParse,     /* Parsing context */
                 * order of the index column is the same as the sort order of the
                 * leftmost index column.
                 */
-               if (pLhs->op != TK_COLUMN
-                   || pLhs->iTable != iCur
-                   || pLhs->iColumn != pIdx->aiColumn[i + nEq]
-                   || sql_index_column_sort_order(pIdx, i + nEq) !=
-                      sql_index_column_sort_order(pIdx, nEq)) {
+               if (pLhs->op != TK_COLUMN || pLhs->iTable != iCur
+                   || pLhs->iColumn != (int)pIdx->def->key_def->parts[i + nEq].fieldno
+                   || pIdx->def->key_def->parts[i + nEq].sort_order !=
+                      pIdx->def->key_def->parts[nEq].sort_order) {
                        break;
                }
 
@@ -2275,7 +2249,7 @@ whereRangeVectorLen(Parse * pParse,       /* Parsing context */
                pColl = sql_binary_compare_coll_seq(pParse, pLhs, pRhs, &id);
                if (pColl == 0)
                        break;
-               if (sql_index_collation(pIdx, i + nEq, &id) != pColl)
+               if (pIdx->def->key_def->parts[(i + nEq)].coll != pColl)
                        break;
        }
        return i;
@@ -2318,13 +2292,13 @@ whereLoopAddBtreeIndex(WhereLoopBuilder * pBuilder,     /* The WhereLoop factory */
        LogEst rSize;           /* Number of rows in the table */
        LogEst rLogSize;        /* Logarithm of table size */
        WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
-       uint32_t nProbeCol = index_column_count(pProbe);
+       uint32_t nProbeCol = pProbe->def->key_def->part_count;
 
        pNew = pBuilder->pNew;
        if (db->mallocFailed)
                return SQLITE_NOMEM_BKPT;
        WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n",
-                          pProbe->zName, pNew->nEq));
+                          pProbe->def->name, pNew->nEq));
 
        assert((pNew->wsFlags & WHERE_TOP_LIMIT) == 0);
        if (pNew->wsFlags & WHERE_BTM_LIMIT) {
@@ -2374,8 +2348,9 @@ whereLoopAddBtreeIndex(WhereLoopBuilder * pBuilder,       /* The WhereLoop factory */
                LogEst nOutUnadjusted;  /* nOut before IN() and WHERE adjustments */
                int nIn = 0;
                int nRecValid = pBuilder->nRecValid;
+               uint32_t j = pProbe->def->key_def->parts[saved_nEq].fieldno;
                if ((eOp == WO_ISNULL || (pTerm->wtFlags & TERM_VNULL) != 0)
-                   && indexColumnNotNull(pProbe, saved_nEq)
+                   && !pProbe->pTable->def->fields[j].is_nullable
                    ) {
                        continue;       /* ignore IS [NOT] NULL constraints on NOT NULL columns */
                }
@@ -2445,14 +2420,16 @@ whereLoopAddBtreeIndex(WhereLoopBuilder * pBuilder,     /* The WhereLoop factory */
                                                         */
                        }
                } else if (eOp & WO_EQ) {
-                       int iCol = pProbe->aiColumn[saved_nEq];
+                       int iCol = pProbe->def->key_def->parts[saved_nEq].fieldno;
                        pNew->wsFlags |= WHERE_COLUMN_EQ;
                        assert(saved_nEq == pNew->nEq);
-                       if ((iCol > 0 && nInMul == 0
-                               && saved_nEq == nProbeCol - 1)
-                           ) {
-                               if (iCol >= 0 &&
-                                   !index_is_unique_not_null(pProbe)) {
+                       if ((iCol > 0 && nInMul == 0 &&
+                            saved_nEq == nProbeCol - 1)) {
+                               bool index_is_unique_not_null =
+                                       pProbe->def->key_def->is_nullable &&
+                                       pProbe->def->opts.is_unique;
+                               if (pProbe->tnum != 0 &&
+                                   !index_is_unique_not_null) {
                                        pNew->wsFlags |= WHERE_UNQ_WANTED;
                                } else {
                                        pNew->wsFlags |= WHERE_ONEROW;
@@ -2514,8 +2491,7 @@ whereLoopAddBtreeIndex(WhereLoopBuilder * pBuilder,       /* The WhereLoop factory */
                        assert(eOp & (WO_ISNULL | WO_EQ | WO_IN));
 
                        assert(pNew->nOut == saved_nOut);
-                       if (pTerm->truthProb <= 0
-                           && pProbe->aiColumn[saved_nEq] >= 0) {
+                       if (pTerm->truthProb <= 0 && pProbe->tnum != 0 ) {
                                assert((eOp & WO_IN) || nIn == 0);
                                testcase(eOp & WO_IN);
                                pNew->nOut += pTerm->truthProb;
@@ -2671,7 +2647,7 @@ whereLoopAddBtreeIndex(WhereLoopBuilder * pBuilder,       /* The WhereLoop factory */
        }
 
        WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n",
-                          pProbe->zName, saved_nEq, rc));
+                          pProbe->def->name, saved_nEq, rc));
        return rc;
 }
 
@@ -2715,7 +2691,7 @@ indexMightHelpWithOrderBy(WhereLoopBuilder * pBuilder,
        ExprList *pOB;
        ExprList *aColExpr;
        int ii, jj;
-       int nIdxCol = index_column_count(pIndex);
+       int nIdxCol = pIndex->def->key_def->part_count;
        if (index_is_unordered(pIndex))
                return 0;
        if ((pOB = pBuilder->pWInfo->pOrderBy) == 0)
@@ -2726,13 +2702,12 @@ indexMightHelpWithOrderBy(WhereLoopBuilder * pBuilder,
                        if (pExpr->iColumn < 0)
                                return 1;
                        for (jj = 0; jj < nIdxCol; jj++) {
-                               if (pExpr->iColumn == pIndex->aiColumn[jj])
+                               if (pExpr->iColumn == (int)
+                                   pIndex->def->key_def->parts[jj].fieldno)
                                        return 1;
                        }
                } else if ((aColExpr = pIndex->aColExpr) != 0) {
                        for (jj = 0; jj < nIdxCol; jj++) {
-                               if (pIndex->aiColumn[jj] != XN_EXPR)
-                                       continue;
                                if (sqlite3ExprCompare
                                    (pExpr, aColExpr->a[jj].pExpr,
                                     iCursor) == 0) {
@@ -2815,7 +2790,6 @@ whereLoopAddBtree(WhereLoopBuilder * pBuilder,    /* WHERE clause information */
        Index *pProbe;          /* An index we are evaluating */
        Index sPk;              /* A fake index object for the primary key */
        LogEst aiRowEstPk[2];   /* The aiRowLogEst[] value for the sPk index */
-       i16 aiColumnPk = -1;    /* The aColumn[] value for the sPk index */
        SrcList *pTabList;      /* The FROM clause */
        struct SrcList_item *pSrc;      /* The FROM clause btree term to add */
        WhereLoop *pNew;        /* Template WhereLoop object */
@@ -2846,11 +2820,27 @@ whereLoopAddBtree(WhereLoopBuilder * pBuilder,  /* WHERE clause information */
                 */
                Index *pFirst;  /* First of real indices on the table */
                memset(&sPk, 0, sizeof(Index));
-               sPk.nColumn = 1;
-               sPk.aiColumn = &aiColumnPk;
                sPk.aiRowLogEst = aiRowEstPk;
                sPk.onError = ON_CONFLICT_ACTION_REPLACE;
                sPk.pTable = pTab;
+
+               struct key_def *key_def = key_def_new(1);
+               if (key_def == NULL)
+                       return SQLITE_ERROR;
+
+               key_def_set_part(key_def, 0, 0, pTab->def->fields[0].type,
+                                ON_CONFLICT_ACTION_ABORT,
+                                NULL, COLL_NONE, SORT_ORDER_ASC);
+
+               struct index_opts index_opts = index_opts_default;
+
+               sPk.def = index_def_new(pTab->def->id, 0, "primary",
+                                       sizeof("primary") - 1, TREE, &index_opts,
+                                       key_def, NULL);
+
+               if (sPk.def == NULL)
+                       return SQLITE_ERROR;
+
                aiRowEstPk[0] = sql_space_tuple_log_count(pTab);
                aiRowEstPk[1] = 0;
                pFirst = pSrc->pTab->pIndex;
@@ -3325,8 +3315,8 @@ wherePathSatisfiesOrderBy(WhereInfo * pWInfo,     /* The WHERE clause */
                                   index_is_unordered(pIndex)) {
                                return 0;
                        } else {
-                               nColumn = index_column_count(pIndex);
-                               isOrderDistinct = index_is_unique(pIndex);
+                               nColumn = pIndex->def->key_def->part_count;
+                               isOrderDistinct = pIndex->def->opts.is_unique;
                        }
 
                        /* Loop through all columns of the index and deal with the ones
@@ -3387,9 +3377,10 @@ wherePathSatisfiesOrderBy(WhereInfo * pWInfo,    /* The WHERE clause */
                                 * (revIdx) for the j-th column of the index.
                                 */
                                if (pIndex) {
-                                       iColumn = pIndex->aiColumn[j];
-                                       revIdx = sql_index_column_sort_order(pIndex,
-                                                                            j);
+                                       iColumn = pIndex->def->key_def->
+                                               parts[j].fieldno;
+                                       revIdx = pIndex->def->key_def->
+                                               parts[j].sort_order;
                                        if (iColumn == pIndex->pTable->iPKey)
                                                iColumn = -1;
                                } else {
@@ -3442,8 +3433,7 @@ wherePathSatisfiesOrderBy(WhereInfo * pWInfo,     /* The WHERE clause */
                                                                      pOrderBy->a[i].pExpr,
                                                                      &is_found, &id);
                                                struct coll *idx_coll =
-                                                       sql_index_collation(pIndex,
-                                                                           j, &id);
+                                                       pIndex->def->key_def->parts[j].coll;
                                                if (is_found &&
                                                    coll != idx_coll)
                                                        continue;
@@ -4105,13 +4095,13 @@ whereShortCut(WhereLoopBuilder * pBuilder)
        } else {
                for (pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext) {
                        int opMask;
-                       int nIdxCol = index_column_count(pIdx);
+                       int nIdxCol = pIdx->def->key_def->part_count;
                        assert(pLoop->aLTermSpace == pLoop->aLTerm);
-                       if (!index_is_unique(pIdx)
+                       if (!pIdx->def->opts.is_unique
                            || pIdx->pPartIdxWhere != 0
-                           || nIdxCol > ArraySize(pLoop->aLTermSpace)
-                           )
+                           || nIdxCol > ArraySize(pLoop->aLTermSpace)) {
                                continue;
+                       }
                        opMask = WO_EQ;
                        for (j = 0; j < nIdxCol; j++) {
                                pTerm =
@@ -4650,7 +4640,7 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */
                                        wctrlFlags & WHERE_ORDERBY_MIN) == 0) {
                                        sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);  /* Hint to COMDB2 */
                                }
-                               VdbeComment((v, "%s", pIx->zName));
+                               VdbeComment((v, "%s", pIx->def->name));
 #ifdef SQLITE_ENABLE_COLUMN_USED_MASK
                                {
                                        u64 colUsed = 0;
@@ -4781,7 +4771,7 @@ sqlite3WhereEnd(WhereInfo * pWInfo)
                if (pLevel->addrSkip) {
                        sqlite3VdbeGoto(v, pLevel->addrSkip);
                        VdbeComment((v, "next skip-scan on %s",
-                                    pLoop->pIndex->zName));
+                                    pLoop->pIndex->def->name));
                        sqlite3VdbeJumpHere(v, pLevel->addrSkip);
                        sqlite3VdbeJumpHere(v, pLevel->addrSkip - 2);
                }
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 09b267194..22bb76013 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -47,9 +47,7 @@
 static const char *
 explainIndexColumnName(Index * pIdx, int i)
 {
-       i = pIdx->aiColumn[i];
-       if (i == XN_EXPR)
-               return "<expr>";
+       i = pIdx->def->key_def->parts[i].fieldno;
        return pIdx->pTable->def->fields[i].name;
 }
 
@@ -222,7 +220,7 @@ sqlite3WhereExplainOneScan(Parse * pParse,  /* Parse context */
                        }
                        if (zFmt) {
                                sqlite3StrAccumAppend(&str, " USING ", 7);
-                               sqlite3XPrintf(&str, zFmt, pIdx->zName);
+                               sqlite3XPrintf(&str, zFmt, pIdx->def->name);
                                explainIndexRange(&str, pLoop);
                        }
                } else if ((flags & WHERE_IPK) != 0
@@ -463,7 +461,7 @@ codeEqualityTerm(Parse * pParse,    /* The parsing context */
                int *aiMap = 0;
 
                if (pLoop->pIndex != 0 &&
-                   sql_index_column_sort_order(pLoop->pIndex, iEq)) {
+                   pLoop->pIndex->def->key_def->parts[iEq].sort_order) {
                        testcase(iEq == 0);
                        testcase(bRev);
                        bRev = !bRev;
@@ -708,7 +706,7 @@ codeAllEqualityTerms(Parse * pParse,        /* Parsing context */
                sqlite3VdbeAddOp1(v, (bRev ? OP_Last : OP_Rewind), iIdxCur);
                VdbeCoverageIf(v, bRev == 0);
                VdbeCoverageIf(v, bRev != 0);
-               VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
+               VdbeComment((v, "begin skip-scan on %s", pIdx->def->name));
                j = sqlite3VdbeAddOp0(v, OP_Goto);
                pLevel->addrSkip =
                    sqlite3VdbeAddOp4Int(v, (bRev ? OP_SeekLT : OP_SeekGT),
@@ -718,8 +716,8 @@ codeAllEqualityTerms(Parse * pParse,        /* Parsing context */
                sqlite3VdbeJumpHere(v, j);
                for (j = 0; j < nSkip; j++) {
                        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur,
-                                         pIdx->aiColumn[j], regBase + j);
-                       testcase(pIdx->aiColumn[j] == XN_EXPR);
+                                         pIdx->def->key_def->parts[j].fieldno,
+                                         regBase + j);
                        VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
                }
        }
@@ -1245,10 +1243,10 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,        /* Complete information about t
                assert(pWInfo->pOrderBy == 0
                       || pWInfo->pOrderBy->nExpr == 1
                       || (pWInfo->wctrlFlags & WHERE_ORDERBY_MIN) == 0);
-               int nIdxCol = index_column_count(pIdx);
+               int nIdxCol = pIdx->def->key_def->part_count;
                if ((pWInfo->wctrlFlags & WHERE_ORDERBY_MIN) != 0
                    && pWInfo->nOBSat > 0 && (nIdxCol > nEq)) {
-                       j = pIdx->aiColumn[nEq];
+                       j = pIdx->def->key_def->parts[nEq].fieldno;
                        /* Allow seek for column with `NOT NULL` == false attribute.
                         * If a column may contain NULL-s, the comparator installed
                         * by Tarantool is prepared to seek using a NULL value.
@@ -1259,8 +1257,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,  /* Complete information about t
                         * FYI: entries in an index are ordered as follows:
                         *      NULL, ... NULL, min_value, ...
                         */
-                       if ((j >= 0 && pIdx->pTable->def->fields[j].is_nullable)
-                           || j == XN_EXPR) {
+                       if (pIdx->pTable->def->fields[j].is_nullable) {
                                assert(pLoop->nSkip == 0);
                                bSeekPastNull = 1;
                                nExtraReg = 1;
@@ -1299,17 +1296,15 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,        /* Complete information about t
                                assert((bRev & ~1) == 0);
                                pLevel->iLikeRepCntr <<= 1;
                                pLevel->iLikeRepCntr |=
-                                       bRev ^ (sql_index_column_sort_order(pIdx, nEq) ==
+                                       bRev ^ (pIdx->def->key_def->
+                                                 parts[nEq].sort_order ==
                                                SORT_ORDER_DESC);
                        }
 #endif
                        if (pRangeStart == 0) {
-                               j = pIdx->aiColumn[nEq];
-                               if ((j >= 0 &&
-                                    pIdx->pTable->def->fields[j].is_nullable)||
-                                   j == XN_EXPR) {
+                               j = pIdx->def->key_def->parts[nEq].fieldno;
+                               if (pIdx->pTable->def->fields[j].is_nullable)
                                        bSeekPastNull = 1;
-                               }
                        }
                }
                assert(pRangeEnd == 0
@@ -1320,7 +1315,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,  /* Complete information about t
                 * start and end terms (pRangeStart and pRangeEnd).
                 */
                if ((nEq < nIdxCol &&
-                    bRev == (sql_index_column_sort_order(pIdx, nEq) ==
+                    bRev == (pIdx->def->key_def->parts[nEq].sort_order ==
                              SORT_ORDER_ASC)) ||
                    (bRev && nIdxCol == nEq)) {
                        SWAP(pRangeEnd, pRangeStart);
@@ -1386,9 +1381,10 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t
                }
                struct Index *pk = sqlite3PrimaryKeyIndex(pIdx->pTable);
                assert(pk);
-               int nPkCol = index_column_count(pk);
+               int nPkCol = pk->def->key_def->part_count;
+               uint32_t zero_fieldno = pk->def->key_def->parts[0].fieldno;
                char affinity =
-                       pIdx->pTable->def->fields[pk->aiColumn[0]].affinity;
+                       pIdx->pTable->def->fields[zero_fieldno].affinity;
                if (nPkCol == 1 && affinity == AFFINITY_INTEGER) {
                        /* Right now INTEGER PRIMARY KEY is the only option to
                         * get Tarantool's INTEGER column type. Need special handling
@@ -1397,7 +1393,8 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,  /* Complete information about t
                         */
                        int limit = pRangeStart == NULL ? nEq : nEq + 1;
                        for (int i = 0; i < limit; i++) {
-                               if (pIdx->aiColumn[i] == pk->aiColumn[0]) {
+                               if (pIdx->def->key_def->parts[i].fieldno ==
+                                   zero_fieldno) {
                                        /* Here: we know for sure that table has INTEGER
                                           PRIMARY KEY, single column, and Index we're
                                           trying to use for scan contains this column. */
@@ -1506,10 +1503,10 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,        /* Complete information about t
                        /* pIdx is a covering index.  No need to access the main table. */
                }  else if (iCur != iIdxCur) {
                        Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
-                       int nPkCol = index_column_count(pPk);
+                       int nPkCol = pPk->def->key_def->part_count;
                        int iKeyReg = sqlite3GetTempRange(pParse, nPkCol);
                        for (j = 0; j < nPkCol; j++) {
-                               k = pPk->aiColumn[j];
+                               k = pPk->def->key_def->parts[j].fieldno;
                                sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k,
                                                  iKeyReg + j);
                        }
@@ -1614,7 +1611,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,  /* Complete information about t
                 */
                if ((pWInfo->wctrlFlags & WHERE_DUPLICATES_OK) == 0) {
                        Index *pPk = sqlite3PrimaryKeyIndex(pTab);
-                       int nPkCol = index_column_count(pPk);
+                       int nPkCol = pPk->def->key_def->part_count;
                        regRowset = pParse->nTab++;
                        sqlite3VdbeAddOp2(v, OP_OpenTEphemeral,
                                          regRowset, nPkCol);
@@ -1718,13 +1715,16 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,        /* Complete information about t
                                                int iSet =
                                                    ((ii == pOrWc->nTerm - 1) ? -1 : ii);
                                                Index *pPk = sqlite3PrimaryKeyIndex (pTab);
-                                               int nPk = index_column_count(pPk);
+                                               int nPk = pPk->def->key_def->part_count;
                                                int iPk;
 
                                                /* Read the PK into an array of temp registers. */
                                                r = sqlite3GetTempRange(pParse, nPk);
                                                for (iPk = 0; iPk < nPk; iPk++) {
-                                                       int iCol = pPk->aiColumn[iPk];
+                                                       int iCol = pPk->def->
+                                                               key_def->
+                                                               parts[iPk].
+                                                               fieldno;
                                                        sqlite3ExprCodeGetColumnToReg
                                                                (pParse, pTab->def,
                                                                 iCol, iCur,
diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c
index aa6d4524d..40e4e2577 100644
--- a/src/box/sql/whereexpr.c
+++ b/src/box/sql/whereexpr.c
@@ -903,7 +903,6 @@ exprMightBeIndexed(SrcList * pFrom, /* The FROM clause */
                   int *piColumn        /* Write the referenced table column number here */
     )
 {
-       Index *pIdx;
        int i;
        int iCur;
 
@@ -930,20 +929,6 @@ exprMightBeIndexed(SrcList * pFrom,        /* The FROM clause */
        for (i = 0; mPrereq > 1; i++, mPrereq >>= 1) {
        }
        iCur = pFrom->a[i].iCursor;
-       for (pIdx = pFrom->a[i].pTab->pIndex; pIdx; pIdx = pIdx->pNext) {
-               if (pIdx->aColExpr == 0)
-                       continue;
-               for (i = 0; i < pIdx->nColumn; i++) {
-                       if (pIdx->aiColumn[i] != XN_EXPR)
-                               continue;
-                       if (sqlite3ExprCompare
-                           (pExpr, pIdx->aColExpr->a[i].pExpr, iCur) == 0) {
-                               *piCur = iCur;
-                               *piColumn = XN_EXPR;
-                               return 1;
-                       }
-               }
-       }
        return 0;
 }
 
-- </font></pre></body></html>