<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">ср, 4 апр. 2018 г. в 19:11, n.pettik <<a href="mailto:korablev@tarantool.org">korablev@tarantool.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">Now, patch looks way better. Keep fixing minor remarks.<div>Also, it is better to push your changes, so that I can check</div><div>Travis status (i.e. make sure that all tests have passed).</div><div><br></div><div><br><div><blockquote type="cite"><div>On 4 Apr 2018, at 18:46, Hollow111 <<a href="mailto:hollow653@gmail.com" target="_blank">hollow653@gmail.com</a>> wrote:</div><br class="gmail-m_-687465658851464753Apple-interchange-newline"><div><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">ср, 4 апр. 2018 г. в 17:06, n.pettik <<a href="mailto:korablev@tarantool.org" target="_blank">korablev@tarantool.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Please, don’t hurry when working on patch.<br>
Consider carefully each fix and comment: there is no any deadline.<br>
<br>
You don’t have to send second patch version.<br>
This patch is pretty small, so you can answer to this letter and<br>
pin your changes. For example: you won’t change tests (since they are OK),<br>
so don’t include them in provided diff.<br>
<br>
> On 4 Apr 2018, at 00:37, N.Tatunov <<a href="mailto:hollow653@gmail.com" target="_blank">hollow653@gmail.com</a>> wrote:<br>
><br>
> Currently dropping an index leads to removal of<br>
> all the entries containing the certain index name<br>
> in "_sql_statN" tables. Thus far analyze routine was fixed<br>
> so it seems that the indexes from the different tables but<br>
> with the same names should work more properly.<br>
><br>
> Closes: #3264<br>
> ---<br>
><br>
> Branch: <a href="https://github.com/tarantool/tarantool/tree/N_Tatunov/gh-3264-stat-table-entries-removal" rel="noreferrer" target="_blank">https://github.com/tarantool/tarantool/tree/N_Tatunov/gh-3264-stat-table-entries-removal</a><br>
> Issue: <a href="https://github.com/tarantool/tarantool/issues/3264" rel="noreferrer" target="_blank">https://github.com/tarantool/tarantool/issues/3264</a><br>
><br>
> src/box/sql/build.c                    |  41 ++++++-----<br>
> test/sql/sql-statN-index-drop.result   | 127 +++++++++++++++++++++++++++++++++<br>
> test/sql/sql-statN-index-drop.test.lua |  54 ++++++++++++++<br>
> 3 files changed, 206 insertions(+), 16 deletions(-)<br>
> create mode 100644 test/sql/sql-statN-index-drop.result<br>
> create mode 100644 test/sql/sql-statN-index-drop.test.lua<br>
><br>
> diff --git a/src/box/sql/build.c b/src/box/sql/build.c<br>
> index 5e3ed0f..44d7548 100644<br>
> --- a/src/box/sql/build.c<br>
> +++ b/src/box/sql/build.c<br>
> @@ -2207,25 +2207,34 @@ sqliteViewResetAll(sqlite3 * db)<br>
> #endif                                /* SQLITE_OMIT_VIEW */<br>
><br>
> /*<br>
> - * Remove entries from the sqlite_statN tables (for N in (1,2,3))<br>
> + * Remove entries from the _sql_statN tables (for N in (1, 4))<br>
>  * after a DROP INDEX or DROP TABLE command.<br>
>  */<br>
<br>
Comment prior to function starts from /**.<br>
Your provide short description (it is already there),<br>
describe arguments and return value with @param and @retval tags.<br>
You can find more information by searching ‘doxygen comments’.<br>
<br>
> static void<br>
> -sqlite3ClearStatTables(Parse * pParse,       /* The parsing context */<br>
> -                    const char *zType,       /* "idx" or "tbl" */<br>
> -                    const char *zName        /* Name of index or table */<br>
> +sql_clear_stat_tables(Parse * pParse,        /* The parsing context */<br>
<br>
pParse and zType are examples of Hungarian notation:<br>
you don’t need ‘p’ and ‘z’ prefixes. Moreover, you can remove comment<br>
right after arguments, since args will be described above within oxygen comment.<br>
<br>
> +                    const char *zType,           /* "idx" or "tbl" */<br>
> +               const char *table_name,  /* Name of the table*/<br>
> +                    const char *idx_name     /* Name of the index*/<br>
>     )<br>
> {<br>
> -     int i;<br>
> -     for (i = 1; i <= 4; i++) {<br>
> -             char zTab[24];<br>
> -             sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i);<br>
> -             if (sqlite3FindTable(pParse->db, zTab)) {<br>
> -                     sqlite3NestedParse(pParse,<br>
> -                                        "DELETE FROM \"%s\" WHERE \"%s\"=%Q",<br>
> -                                        zTab, zType, zName);<br>
> -             }<br>
> -     }<br>
> +    int i, j;<br>
<br>
You don’t need to declare vars beforehand:<br>
it is is required in obsolete C standards (such as KR or C89).<br>
However, we are using *modern* C99:<br>
for (int i = 0; …)  - is OK.<br>
<br>
> +    if(strcmp(zType, "idx") == 0)<br>
<br>
As you suggest, you can get rid of this ’type’. Instead, just<br>
check index name on nullability.<br>
<br>
> +        for(i = 1, j = 1; i <= 2; i++, j++) {<br>
<br>
This cycle-for is completely unreadable. Don’t make things to be complicated:<br>
it is better to use *less* beautiful, but more obvious and clear approach.<br>
Don’t be afraid of changing code: this function is declared as static,<br>
so it is not available for public usage.<br>
<br>
I would like to suggest you to get rid of cycle and snprintf,<br>
but add two almost the same calls of sqlite3NestedParse().<br>
It will result in plain and readable code:<br>
sqlite3NestedParse(…, ” … WHERE tbl = stat1”);<br>
sqlite3NestedParse(…, ” … WHERE tbl = stat4”);<br>
<br>
> +            char zTab[24];<br>
> +            sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i * j);<br>
> +            sqlite3NestedParse(pParse,<br>
> +                        "DELETE FROM \"%s\" WHERE (\"idx\"=%Q AND "<br>
> +                        "\"tbl\"=%Q)",<br>
> +                        zTab, idx_name, table_name);<br>
> +        }<br>
> +    else<br>
> +        for(i = 1, j = 1; i <= 2; i++, j++) {<br>
> +            char zTab[24];<br>
> +            sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i * j);<br>
> +            sqlite3NestedParse(pParse,<br>
> +                        "DELETE FROM \"%s\" WHERE \"tbl\"=%Q",<br>
> +                        zTab, table_name);<br>
> +        }<br>
> }<br>
><br>
> /*<br>
> @@ -2415,7 +2424,7 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)<br>
>        */<br>
><br>
>       sqlite3BeginWriteOperation(pParse, 1);<br>
> -     sqlite3ClearStatTables(pParse, "tbl", pTab->zName);<br>
> +    sql_clear_stat_tables(pParse, "tbl", pTab->zName, NULL);<br>
>       sqlite3FkDropTable(pParse, pName, pTab);<br>
>       sqlite3CodeDropTable(pParse, pTab, isView);<br>
><br>
> @@ -3417,7 +3426,7 @@ sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)<br>
>        * But firstly, delete statistics since schema<br>
>        * changes after DDL.<br>
>        */<br>
> -     sqlite3ClearStatTables(pParse, "idx", pIndex->zName);<br>
> +    sql_clear_stat_tables(pParse, "idx", pIndex->pTable->zName, pIndex->zName);<br>
>       int record_reg = ++pParse->nMem;<br>
>       int space_id_reg = ++pParse->nMem;<br>
>       sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_PAGENO_TO_SPACEID(pIndex->tnum),<br>
> diff --git a/test/sql/sql-statN-index-drop.result b/test/sql/sql-statN-index-drop.result<br>
> new file mode 100644<br>
> index 0000000..c7e476f<br>
> --- /dev/null<br>
> +++ b/test/sql/sql-statN-index-drop.result<br>
> @@ -0,0 +1,127 @@<br>
> +test_run = require('test_run').new()<br>
> +---<br>
> +...<br>
> +-- Initializing some things.<br>
> +box.sql.execute("CREATE TABLE t1(id PRIMARY KEY, a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE TABLE t2(id PRIMARY KEY, a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE INDEX i1 ON t1(a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE INDEX i1 ON t2(a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("INSERT INTO t1 VALUES(1, 2);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("INSERT INTO t2 VALUES(1, 2);")<br>
> +---<br>
> +...<br>
> +-- Analyze.<br>
> +box.sql.execute("ANALYZE;")<br>
> +---<br>
> +...<br>
> +-- Checking the data.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T1', 'T1', '1', '0', '0', !!binary kQE=]<br>
> +  - ['T2', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T2', 'T2', '1', '0', '0', !!binary kQE=]<br>
> +...<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1 1']<br>
> +  - ['T1', 'T1', '1 1']<br>
> +  - ['T2', 'I1', '1 1']<br>
> +  - ['T2', 'T2', '1 1']<br>
> +...<br>
> +-- Dropping an index.<br>
> +box.sql.execute("DROP INDEX i1 ON t1;")<br>
> +---<br>
> +...<br>
> +-- Checking the DROP INDEX results.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +---<br>
> +- - ['T1', 'T1', '1', '0', '0', !!binary kQE=]<br>
> +  - ['T2', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T2', 'T2', '1', '0', '0', !!binary kQE=]<br>
> +...<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +---<br>
> +- - ['T1', 'T1', '1 1']<br>
> +  - ['T2', 'I1', '1 1']<br>
> +  - ['T2', 'T2', '1 1']<br>
> +...<br>
> +--Cleaning up.<br>
> +box.sql.execute("DROP TABLE t1;")<br>
> +---<br>
> +...<br>
> +box.sql.execute("DROP TABLE t2;")<br>
> +---<br>
> +...<br>
> +-- Same test but dropping an INDEX ON t2.<br>
> +box.sql.execute("CREATE TABLE t1(id PRIMARY KEY, a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE TABLE t2(id PRIMARY KEY, a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE INDEX i1 ON t1(a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("CREATE INDEX i1 ON t2(a);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("INSERT INTO t1 VALUES(1, 2);")<br>
> +---<br>
> +...<br>
> +box.sql.execute("INSERT INTO t2 VALUES(1, 2);")<br>
> +---<br>
> +...<br>
> +-- Analyze.<br>
> +box.sql.execute("ANALYZE;")<br>
> +---<br>
> +...<br>
> +-- Checking the data.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T1', 'T1', '1', '0', '0', !!binary kQE=]<br>
> +  - ['T2', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T2', 'T2', '1', '0', '0', !!binary kQE=]<br>
> +...<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1 1']<br>
> +  - ['T1', 'T1', '1 1']<br>
> +  - ['T2', 'I1', '1 1']<br>
> +  - ['T2', 'T2', '1 1']<br>
> +...<br>
> +-- Dropping an index.<br>
> +box.sql.execute("DROP INDEX i1 ON t2;")<br>
> +---<br>
> +...<br>
> +-- Checking the DROP INDEX results.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1', '0', '0', !!binary kQI=]<br>
> +  - ['T1', 'T1', '1', '0', '0', !!binary kQE=]<br>
> +  - ['T2', 'T2', '1', '0', '0', !!binary kQE=]<br>
> +...<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +---<br>
> +- - ['T1', 'I1', '1 1']<br>
> +  - ['T1', 'T1', '1 1']<br>
> +  - ['T2', 'T2', '1 1']<br>
> +...<br>
> +--Cleaning up.<br>
> +box.sql.execute("DROP TABLE t1;")<br>
> +---<br>
> +...<br>
> +box.sql.execute("DROP TABLE t2;")<br>
> +---<br>
> +...<br>
> diff --git a/test/sql/sql-statN-index-drop.test.lua b/test/sql/sql-statN-index-drop.test.lua<br>
> new file mode 100644<br>
> index 0000000..bf4a752<br>
> --- /dev/null<br>
> +++ b/test/sql/sql-statN-index-drop.test.lua<br>
> @@ -0,0 +1,54 @@<br>
> +test_run = require('test_run').new()<br>
> +<br>
> +-- Initializing some things.<br>
> +box.sql.execute("CREATE TABLE t1(id PRIMARY KEY, a);")<br>
> +box.sql.execute("CREATE TABLE t2(id PRIMARY KEY, a);")<br>
> +box.sql.execute("CREATE INDEX i1 ON t1(a);")<br>
> +box.sql.execute("CREATE INDEX i1 ON t2(a);")<br>
> +box.sql.execute("INSERT INTO t1 VALUES(1, 2);")<br>
> +box.sql.execute("INSERT INTO t2 VALUES(1, 2);")<br>
> +<br>
> +-- Analyze.<br>
> +box.sql.execute("ANALYZE;")<br>
> +<br>
> +-- Checking the data.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +<br>
> +-- Dropping an index.<br>
> +box.sql.execute("DROP INDEX i1 ON t1;")<br>
> +<br>
> +-- Checking the DROP INDEX results.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +<br>
> +--Cleaning up.<br>
> +box.sql.execute("DROP TABLE t1;")<br>
> +box.sql.execute("DROP TABLE t2;")<br>
> +<br>
> +-- Same test but dropping an INDEX ON t2.<br>
> +<br>
> +box.sql.execute("CREATE TABLE t1(id PRIMARY KEY, a);")<br>
> +box.sql.execute("CREATE TABLE t2(id PRIMARY KEY, a);")<br>
> +box.sql.execute("CREATE INDEX i1 ON t1(a);")<br>
> +box.sql.execute("CREATE INDEX i1 ON t2(a);")<br>
> +box.sql.execute("INSERT INTO t1 VALUES(1, 2);")<br>
> +box.sql.execute("INSERT INTO t2 VALUES(1, 2);")<br>
> +<br>
> +-- Analyze.<br>
> +box.sql.execute("ANALYZE;")<br>
> +<br>
> +-- Checking the data.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +<br>
> +-- Dropping an index.<br>
> +box.sql.execute("DROP INDEX i1 ON t2;")<br>
> +<br>
> +-- Checking the DROP INDEX results.<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat4\";")<br>
> +box.sql.execute("SELECT * FROM \"_sql_stat1\";")<br>
> +<br>
> +--Cleaning up.<br>
> +box.sql.execute("DROP TABLE t1;")<br>
> +box.sql.execute("DROP TABLE t2;")<br>
> --<br>
> 2.7.4<br>
><br>
><br>
<br></blockquote><div>Suggested changes were applied so this is diff:<br><br><div> </div><div>diff --git a/src/box/sql/build.c b/src/box/sql/build.c</div><div>index 44d7548..16ae042 100644</div><div>--- a/src/box/sql/build.c</div><div>+++ b/src/box/sql/build.c</div><div>@@ -2206,34 +2206,35 @@ sqliteViewResetAll(sqlite3 * db)</div><div> #define sqliteViewResetAll(A,B)</div><div> #endif<span style="white-space:pre-wrap">                              </span>/* SQLITE_OMIT_VIEW */</div><div> </div><div>-/*</div><div>+/**</div><div>  * Remove entries from the _sql_statN tables (for N in (1, 4))</div><div>  * after a DROP INDEX or DROP TABLE command.</div><div>+ * </div><div>+ * @param table_name table to be dropped or</div><div>+ *                   the table that contains index to be dropped</div><div>+ * @param idx_name index to be dropped</div></div></div></div></div></blockquote><div><br></div><div>Nitpicking: put dot at the end of comments and</div><div>start sentences from capital letter.</div><div>(This is just advice. You may skip most ’nitpicking’ comments.)</div><div><br></div><div>Moreover, you forget to describe first arg:</div><div>even despite the fact that it is obviously ’The parsing context'. </div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><div>  */</div><div> static void</div><div>-sql_clear_stat_tables(Parse * pParse,<span style="white-space:pre-wrap">   </span>/* The parsing context */</div><div>-<span style="white-space:pre-wrap">               </span>       const char *zType,<span style="white-space:pre-wrap">   </span>    /* "idx" or "tbl" */</div><div>-               const char *table_name,  /* Name of the table*/</div><div>-<span style="white-space:pre-wrap">           </span>       const char *idx_name<span style="white-space:pre-wrap"> </span>/* Name of the index*/</div><div>-    )</div><div>+sql_clear_stat_tables(Parse *parse,</div><div>+               const char *table_name,</div><div>+<span style="white-space:pre-wrap">          </span>       const char *idx_name)</div></div></div></div></div></blockquote><div><br></div><div>You don’t need to place each arg at new line.</div><div>The only restriction is 80 chars per line.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><div> {</div><div>-    int i, j;</div><div>-    if(strcmp(zType, "idx") == 0)</div><div>-        for(i = 1, j = 1; i <= 2; i++, j++) {</div><div>-            char zTab[24];</div><div>-            sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i * j);</div><div>-            sqlite3NestedParse(pParse,</div><div>-                        "DELETE FROM \"%s\" WHERE (\"idx\"=%Q AND "</div><div>-                        "\"tbl\"=%Q)",</div><div>-                        zTab, idx_name, table_name);</div><div>-        }</div><div>-    else</div><div>-        for(i = 1, j = 1; i <= 2; i++, j++) {</div><div>-            char zTab[24];</div><div>-            sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i * j);</div><div>-            sqlite3NestedParse(pParse,</div><div>-                        "DELETE FROM \"%s\" WHERE \"tbl\"=%Q",</div><div>-                        zTab, table_name);</div><div>+    if(idx_name) {</div></div></div></div></div></blockquote><div><br></div><div>It is better to use explicit == NULL check.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><div>+        sqlite3NestedParse(parse,</div><div>+                    "DELETE FROM \"_sql_stat1\" WHERE (\"idx\"=%Q AND "</div><div>+                    "\"tbl\"=%Q)",</div><div>+                    idx_name, table_name);</div><div>+        sqlite3NestedParse(parse,</div><div>+                    "DELETE FROM \"_sql_stat4\" WHERE (\"idx\"=%Q AND "</div><div>+                    "\"tbl\"=%Q)",</div><div>+                    idx_name, table_name);</div><div>+    } else {</div><div>+        sqlite3NestedParse(parse,</div><div>+                    "DELETE FROM \"_sql_stat1\" WHERE \"tbl\"=%Q",</div><div>+                    table_name);</div><div>+        sqlite3NestedParse(parse,</div><div>+                    "DELETE FROM \"_sql_stat4\" WHERE \"tbl\"=%Q",</div><div>+                    table_name);</div><div>         }</div><div> }</div><div> </div><div>@@ -2424,7 +2425,7 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)</div><div> <span style="white-space:pre-wrap">        </span> */</div><div> </div><div> <span style="white-space:pre-wrap">   </span>sqlite3BeginWriteOperation(pParse, 1);</div><div>-    sql_clear_stat_tables(pParse, "tbl", pTab->zName, NULL);</div><div>+    sql_clear_stat_tables(pParse, pTab->zName, NULL);</div><div> <span style="white-space:pre-wrap">    </span>sqlite3FkDropTable(pParse, pName, pTab);</div><div> <span style="white-space:pre-wrap">       </span>sqlite3CodeDropTable(pParse, pTab, isView);</div><div> </div><div>@@ -3426,7 +3427,7 @@ sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)</div><div> <span style="white-space:pre-wrap">       </span> * But firstly, delete statistics since schema</div><div> <span style="white-space:pre-wrap"> </span> * changes after DDL.</div><div> <span style="white-space:pre-wrap">  </span> */</div><div>-    sql_clear_stat_tables(pParse, "idx", pIndex->pTable->zName, pIndex->zName);</div><div>+    sql_clear_stat_tables(pParse, pIndex->pTable->zName, pIndex->zName);</div><div> <span style="white-space:pre-wrap">     </span>int record_reg = ++pParse->nMem;</div><div> <span style="white-space:pre-wrap">    </span>int space_id_reg = ++pParse->nMem;</div><div> <span style="white-space:pre-wrap">  </span>sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_PAGENO_TO_SPACEID(pIndex->tnum),</div><div>diff --git a/test/xlog/checkpoint_daemon.result b/test/xlog/checkpoint_daemon.result</div><div>index d5ed666..1c28336 100644</div><div>--- a/test/xlog/checkpoint_daemon.result</div><div>+++ b/test/xlog/checkpoint_daemon.result</div><div>@@ -96,11 +96,11 @@ fiber.sleep(3 * PERIOD)</div><div> -- check that it's not first snapshot</div><div> test_run:grep_log("default", "saving snapshot", 400) == nil</div><div> ---</div><div>-- true</div><div>+- false</div><div> ...</div><div> test_run:grep_log("default", "making snapshot", 400) ~= nil</div><div> ---</div><div>-- true</div><div>+- false</div></div></div></div></div></blockquote><div><br></div><div>I guess, this diff doesn’t belong to the patch.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><div> ...</div><div> -- restore default options</div><div> box.cfg{checkpoint_interval = 3600 * 4, checkpoint_count = 4 }</div> </div></div></div>
</div></blockquote></div><br></div></div></blockquote><div>Diff after the changes:<br><br><div>diff --git a/src/box/sql/build.c b/src/box/sql/build.c</div><div>index 16ae042..958927e 100644</div><div>--- a/src/box/sql/build.c</div><div>+++ b/src/box/sql/build.c</div><div>@@ -2210,16 +2210,17 @@ sqliteViewResetAll(sqlite3 * db)</div><div>  * Remove entries from the _sql_statN tables (for N in (1, 4))</div><div>  * after a DROP INDEX or DROP TABLE command.</div><div>  * </div><div>- * @param table_name table to be dropped or</div><div>- *                   the table that contains index to be dropped</div><div>- * @param idx_name index to be dropped</div><div>+ * @param parse      The parsing context.</div><div>+ * @param table_name The table to be dropped or</div><div>+ *                   the table that contains index to be dropped.</div><div>+ * @param idx_name   Index to be dropped.</div><div>  */</div><div> static void</div><div>-sql_clear_stat_tables(Parse *parse,</div><div>-               const char *table_name,</div><div>-<span style="white-space:pre">          </span>       const char *idx_name)</div><div>+sql_clear_stat_tables(Parse *parse, const char *table_name, </div><div>+                      const char *idx_name</div><div>+                     )</div><div> {</div><div>-    if(idx_name) {</div><div>+    if(idx_name != NULL) {</div><div>         sqlite3NestedParse(parse,</div><div>                     "DELETE FROM \"_sql_stat1\" WHERE (\"idx\"=%Q AND "</div><div>                     "\"tbl\"=%Q)",</div> </div></div></div>