<div dir="ltr">As Alexander asked I've added table content checking in tests, fixed the causes of failing tests in Travis & fixed Nikita's remarks. Diff for the newer version is in the end.<br><br><div class="gmail_quote"><div dir="ltr">пт, 13 июл. 2018 г. в 5:15, 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">Nitpicking ffter module prefix (i.e. sql:) don’t use upper case for first word<br>
<br></blockquote><div> </div><div>Fixed.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> Patch is aimed on making our sql closer to ANSI sql.<br>
<br>
Nitpicking: write SQL in upper case - it is an abbreviation.<br>
<br></blockquote><div><br></div><div>Fixed.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> <br>
> With the patch applied only following commands can be used:<br>
> - "START TRANSACTION" to begin transaction.<br>
> - "COMMIT" to end transaction.<br>
> - "ROLLBACK" to rollback transaction without savepoints.<br>
> - "ROLLBACK TO .." to rollback transaction to savepoint.<br>
> <br>
> Closes #2164<br>
> ---<br>
> <br>
> diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c<br>
> index 990c419..1ec1538 100644<br>
> --- a/extra/mkkeywordhash.c<br>
> +++ b/extra/mkkeywordhash.c<br>
> @@ -120,7 +120,7 @@ static Keyword aKeywordTable[] = {<br>
>   { "ASC",                    "TK_ASC",         ALWAYS,           true  },<br>
>   { "AUTOINCREMENT",          "TK_AUTOINCR",    AUTOINCR,         false },<br>
>   { "BEFORE",                 "TK_BEFORE",      TRIGGER,          false },<br>
> -  { "BEGIN",                  "TK_BEGIN",       ALWAYS,           true  },<br>
> +  { "BEGIN",                  "TK_BEGIN",       TRIGGER,          true  },<br>
>   { "BETWEEN",                "TK_BETWEEN",     ALWAYS,           true  },<br>
>   { "BY",                     "TK_BY",          ALWAYS,           true  },<br>
>   { "CASCADE",                "TK_CASCADE",     FKEY,             false },<br>
> @@ -210,6 +210,7 @@ static Keyword aKeywordTable[] = {<br>
>   { "SAVEPOINT",              "TK_SAVEPOINT",   ALWAYS,           true  },<br>
>   { "SELECT",                 "TK_SELECT",      ALWAYS,           true  },<br>
>   { "SET",                    "TK_SET",         ALWAYS,           true  },<br>
> +  { "START",                  "TK_START",       ALWAYS,           true  },<br>
>   { "TABLE",                  "TK_TABLE",       ALWAYS,           true  },<br>
>   { "THEN",                   "TK_THEN",        ALWAYS,           true  },<br>
>   { "TO",                     "TK_TO",          ALWAYS,           true  },<br>
> @@ -274,7 +275,6 @@ static Keyword aKeywordTable[] = {<br>
>   { "SIGNAL",                 "TK_STANDARD",    RESERVED,         true  },<br>
>   { "SMALLINT",               "TK_ID",          RESERVED,         true  },<br>
>   { "SPECIFIC",               "TK_STANDARD",    RESERVED,         true  },<br>
> -  { "START",                  "TK_STANDARD",    RESERVED,         true  },<br>
>   { "SYSTEM",                 "TK_STANDARD",    RESERVED,         true  },<br>
>   { "SQL",                    "TK_STANDARD",    RESERVED,         true  },<br>
>   { "USER",                   "TK_STANDARD",    RESERVED,         true  },<br>
> diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c<br>
> index 3183e3d..42ab600 100644<br>
> --- a/src/box/sql/expr.c<br>
> +++ b/src/box/sql/expr.c<br>
> @@ -4835,11 +4835,13 @@ sqlite3ExprIfFalse(Parse * pParse, Expr * pExpr, int dest, int jumpIfNull)<br>
>        * Assert()s verify that the computation is correct.<br>
>        */<br>
> <br>
> -     op = ((pExpr->op + (TK_ISNULL & 1)) ^ 1) - (TK_ISNULL & 1);<br>
> +     if (pExpr->op >= TK_NE && pExpr->op <= TK_GE)<br>
> +             op = ((pExpr->op + (TK_NE & 1)) ^ 1) - (TK_NE & 1);<br>
> +     if (pExpr->op == TK_ISNULL || pExpr->op == TK_NOTNULL)<br>
> +             op = ((pExpr->op + (TK_ISNULL & 1)) ^ 1) - (TK_ISNULL & 1);<br>
<br>
Please, leave comment how this code work.<br>
It isn't even close to be obvious, really.<br></blockquote><div><br></div><div>Fixed.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> <br>
>       /*<br>
>        * Verify correct alignment of TK_ and OP_ constants.<br>
> -      * Tokens TK_ISNULL and TK_NE shoud have the same parity.<br>
>        */<br>
>       assert(pExpr->op != TK_NE || op == OP_Eq);<br>
>       assert(pExpr->op != TK_EQ || op == OP_Ne);<br>
> diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y<br>
> index b2940b7..e956dfc 100644<br>
> --- a/src/box/sql/parse.y<br>
> +++ b/src/box/sql/parse.y<br>
> @@ -147,13 +147,11 @@ cmdx ::= cmd.<br>
> ///////////////////// Begin and end transactions. ////////////////////////////<br>
> //<br>
> <br>
> -cmd ::= BEGIN trans_opt.  {sql_transaction_begin(pParse);}<br>
> +cmd ::= START TRANSACTION trans_opt.  {sql_transaction_begin(pParse);}<br>
> trans_opt ::= .<br>
> -trans_opt ::= TRANSACTION.<br>
> -trans_opt ::= TRANSACTION nm.<br>
> -cmd ::= COMMIT trans_opt.      {sql_transaction_commit(pParse);}<br>
> -cmd ::= END trans_opt.         {sql_transaction_commit(pParse);}<br>
> -cmd ::= ROLLBACK trans_opt.    {sql_transaction_rollback(pParse);}<br>
> +trans_opt ::= nm.<br>
<br>
What is the point of named transactions, if rollback and commit<br>
don’t use name? I mean, now we ofc can’t use its name, but<br>
what does ANSI say?<br></blockquote><div><br></div><div>Fixed it.</div><div>Ansi only asks for <transaction characteristics> after 'START TRANSACTION'.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +cmd ::= COMMIT.      {sql_transaction_commit(pParse);}<br>
> +cmd ::= ROLLBACK.    {sql_transaction_rollback(pParse);}<br>
> <br>
> savepoint_opt ::= SAVEPOINT.<br>
> savepoint_opt ::= .<br>
> @@ -163,7 +161,7 @@ cmd ::= SAVEPOINT nm(X). {<br>
> cmd ::= RELEASE savepoint_opt nm(X). {<br>
>   sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &X);<br>
> }<br>
> -cmd ::= ROLLBACK trans_opt TO savepoint_opt nm(X). {<br>
> +cmd ::= ROLLBACK TO savepoint_opt nm(X). {<br>
>   sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &X);<br>
> }<br>
> <br>
> diff --git a/test/sql-tap/analyze3.test.lua b/test/sql-tap/analyze3.test.lua<br>
> index 26f8793..5079962 100755<br>
> --- a/test/sql-tap/analyze3.test.lua<br>
> +++ b/test/sql-tap/analyze3.test.lua<br>
> @@ -340,7 +340,7 @@ test:do_execsql_test(<br>
>     "analyze3-1.3.1",<br>
>     [[<br>
>         CREATE TABLE t3(id INTEGER PRIMARY KEY, y TEXT, x INTEGER);<br>
> -        BEGIN;<br>
> +        START TRANSACTION;<br>
>           INSERT INTO t3 SELECT id, y, x FROM t1;<br>
>         COMMIT;<br>
>         CREATE INDEX i3 ON t3(x);<br>
> @@ -465,7 +465,7 @@ test:do_test(<br>
> --     function()<br>
> --         test:execsql([[<br>
> --             PRAGMA case_sensitive_like=off;<br>
> ---             BEGIN;<br>
> +--             START TRANSACTION;<br>
<br>
I guess, you can remove it at all. It makes no sense to add dead code.<br>
<br>
> --- a/test/sql-tap/in1.test.lua<br>
> +++ b/test/sql-tap/in1.test.lua<br>
> @@ -26,7 +26,7 @@ test:do_test(<br>
>     function()<br>
>         test:execsql [[<br>
>             CREATE TABLE t1(a PRIMARY KEY, b);<br>
> -            BEGIN;<br>
> +            START TRANSACTION;<br>
>         ]]<br>
>         -- for _ in X(0, "X!for", [=[["set i 1","$i<=10","incr i"]]=]) do<br>
>         local j = 1<br>
> @@ -1073,7 +1073,7 @@ test:do_execsql_test(<br>
> -- MUST_WORK_TEST<br>
> -- do_test in-13.14 {<br>
> --   execsql {<br>
> ---     BEGIN TRANSACTION;<br>
> +--     START TRANSACTION;<br>
<br>
The same is here and in other places.<br>
<br></blockquote><div><br></div><div>Fixed. </div><div><br></div><div><div>diff --git a/extra/lempar.c b/extra/lempar.c</div><div>index 00fd79c..d043e39 100644</div><div>--- a/extra/lempar.c</div><div>+++ b/extra/lempar.c</div><div>@@ -336,8 +336,8 @@ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){</div><div>   if( pParser ){</div><div> #ifdef YYTRACKMAXSTACKDEPTH</div><div>     pParser->yyhwm = 0;</div><div>-    pParser->is_fallback_failed = false;</div><div> #endif</div><div>+    pParser->is_fallback_failed = false;</div><div> #if YYSTACKDEPTH<=0</div><div>     pParser->yytos = NULL;</div><div>     pParser->yystack = NULL;</div><div>diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c</div><div>index 990c419..1ec1538 100644</div><div>--- a/extra/mkkeywordhash.c</div><div>+++ b/extra/mkkeywordhash.c</div><div>@@ -120,7 +120,7 @@ static Keyword aKeywordTable[] = {</div><div>   { "ASC",                    "TK_ASC",         ALWAYS,           true  },</div><div>   { "AUTOINCREMENT",          "TK_AUTOINCR",    AUTOINCR,         false },</div><div>   { "BEFORE",                 "TK_BEFORE",      TRIGGER,          false },</div><div>-  { "BEGIN",                  "TK_BEGIN",       ALWAYS,           true  },</div><div>+  { "BEGIN",                  "TK_BEGIN",       TRIGGER,          true  },</div><div>   { "BETWEEN",                "TK_BETWEEN",     ALWAYS,           true  },</div><div>   { "BY",                     "TK_BY",          ALWAYS,           true  },</div><div>   { "CASCADE",                "TK_CASCADE",     FKEY,             false },</div><div>@@ -210,6 +210,7 @@ static Keyword aKeywordTable[] = {</div><div>   { "SAVEPOINT",              "TK_SAVEPOINT",   ALWAYS,           true  },</div><div>   { "SELECT",                 "TK_SELECT",      ALWAYS,           true  },</div><div>   { "SET",                    "TK_SET",         ALWAYS,           true  },</div><div>+  { "START",                  "TK_START",       ALWAYS,           true  },</div><div>   { "TABLE",                  "TK_TABLE",       ALWAYS,           true  },</div><div>   { "THEN",                   "TK_THEN",        ALWAYS,           true  },</div><div>   { "TO",                     "TK_TO",          ALWAYS,           true  },</div><div>@@ -274,7 +275,6 @@ static Keyword aKeywordTable[] = {</div><div>   { "SIGNAL",                 "TK_STANDARD",    RESERVED,         true  },</div><div>   { "SMALLINT",               "TK_ID",          RESERVED,         true  },</div><div>   { "SPECIFIC",               "TK_STANDARD",    RESERVED,         true  },</div><div>-  { "START",                  "TK_STANDARD",    RESERVED,         true  },</div><div>   { "SYSTEM",                 "TK_STANDARD",    RESERVED,         true  },</div><div>   { "SQL",                    "TK_STANDARD",    RESERVED,         true  },</div><div>   { "USER",                   "TK_STANDARD",    RESERVED,         true  },</div><div>diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c</div><div>index b1650cf..b26728d 100644</div><div>--- a/src/box/sql/expr.c</div><div>+++ b/src/box/sql/expr.c</div><div>@@ -4826,23 +4826,32 @@ sqlite3ExprIfFalse(Parse * pParse, Expr * pExpr, int dest, int jumpIfNull)</div><div> <span style="white-space:pre-wrap">     </span> *       TK_EQ              OP_Ne</div><div> <span style="white-space:pre-wrap">   </span> *       TK_GT              OP_Le</div><div> <span style="white-space:pre-wrap">   </span> *       TK_LE              OP_Gt</div><div>-<span style="white-space:pre-wrap">    </span> *       TK_GE              OP_Lt</div><div> <span style="white-space:pre-wrap">   </span> *       TK_LT              OP_Ge</div><div>+<span style="white-space:pre-wrap">    </span> *       TK_GE              OP_Lt</div><div> <span style="white-space:pre-wrap">   </span> *        ...                ...</div><div> <span style="white-space:pre-wrap">   </span> *       TK_ISNULL          OP_NotNull</div><div> <span style="white-space:pre-wrap">        </span> *       TK_NOTNULL         OP_IsNull</div><div> <span style="white-space:pre-wrap"> </span> *</div><div>-<span style="white-space:pre-wrap">      </span> * For other values of pExpr->op, op is undefined and unused.</div><div>-<span style="white-space:pre-wrap">        </span> * The value of TK_ and OP_ constants are arranged such that we</div><div>-<span style="white-space:pre-wrap"> </span> * can compute the mapping above using the following expression.</div><div>+<span style="white-space:pre-wrap">        </span> * For other values of pExpr->op, op is undefined</div><div>+<span style="white-space:pre-wrap">    </span> * and unused. The value of TK_ and OP_ constants</div><div>+<span style="white-space:pre-wrap">       </span> * are arranged such that we can compute the mapping</div><div>+<span style="white-space:pre-wrap">    </span> * above using the following expression. The idea</div><div>+<span style="white-space:pre-wrap">       </span> * is that both for OP_'s and TK_'s the first elements</div><div>+<span style="white-space:pre-wrap">  </span> * in the given mapping ranges of codes and tokens are</div><div>+<span style="white-space:pre-wrap">  </span> * 'Not equal' and 'Is null'. Moreover the 'excluding'</div><div>+<span style="white-space:pre-wrap">  </span> * ones (like 'Greater than' and 'Lower than or Equal')</div><div>+<span style="white-space:pre-wrap"> </span> * are paired and follow one each other, hence have n</div><div>+<span style="white-space:pre-wrap">   </span> * and n + 1 numbers.</div><div> <span style="white-space:pre-wrap">  </span> * Assert()s verify that the computation is correct.</div><div> <span style="white-space:pre-wrap">   </span> */</div><div> </div><div>-<span style="white-space:pre-wrap">    </span>op = ((pExpr->op + (TK_ISNULL & 1)) ^ 1) - (TK_ISNULL & 1);</div><div>+<span style="white-space:pre-wrap">  </span>if (pExpr->op >= TK_NE && pExpr->op <= TK_GE)</div><div>+<span style="white-space:pre-wrap">               </span>op = ((pExpr->op + (TK_NE & 1)) ^ 1) - (TK_NE & 1);</div><div>+<span style="white-space:pre-wrap">  </span>if (pExpr->op == TK_ISNULL || pExpr->op == TK_NOTNULL)</div><div>+<span style="white-space:pre-wrap">            </span>op = ((pExpr->op + (TK_ISNULL & 1)) ^ 1) - (TK_ISNULL & 1);</div><div> </div><div> <span style="white-space:pre-wrap">        </span>/*</div><div> <span style="white-space:pre-wrap">     </span> * Verify correct alignment of TK_ and OP_ constants.</div><div>-<span style="white-space:pre-wrap">   </span> * Tokens TK_ISNULL and TK_NE shoud have the same parity.</div><div> <span style="white-space:pre-wrap">      </span> */</div><div> <span style="white-space:pre-wrap">    </span>assert(pExpr->op != TK_NE || op == OP_Eq);</div><div> <span style="white-space:pre-wrap">  </span>assert(pExpr->op != TK_EQ || op == OP_Ne);</div><div>diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y</div><div>index ac935fd..b4f11e5 100644</div><div>--- a/src/box/sql/parse.y</div><div>+++ b/src/box/sql/parse.y</div><div>@@ -147,13 +147,9 @@ cmdx ::= cmd.</div><div> ///////////////////// Begin and end transactions. ////////////////////////////</div><div> //</div><div> </div><div>-cmd ::= BEGIN trans_opt.  {sql_transaction_begin(pParse);}</div><div>-trans_opt ::= .</div><div>-trans_opt ::= TRANSACTION.</div><div>-trans_opt ::= TRANSACTION nm.</div><div>-cmd ::= COMMIT trans_opt.      {sql_transaction_commit(pParse);}</div><div>-cmd ::= END trans_opt.         {sql_transaction_commit(pParse);}</div><div>-cmd ::= ROLLBACK trans_opt.    {sql_transaction_rollback(pParse);}</div><div>+cmd ::= START TRANSACTION.  {sql_transaction_begin(pParse);}</div><div>+cmd ::= COMMIT.      {sql_transaction_commit(pParse);}</div><div>+cmd ::= ROLLBACK.    {sql_transaction_rollback(pParse);}</div><div> </div><div> savepoint_opt ::= SAVEPOINT.</div><div> savepoint_opt ::= .</div><div>@@ -163,7 +159,7 @@ cmd ::= SAVEPOINT nm(X). {</div><div> cmd ::= RELEASE savepoint_opt nm(X). {</div><div>   sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &X);</div><div> }</div><div>-cmd ::= ROLLBACK trans_opt TO savepoint_opt nm(X). {</div><div>+cmd ::= ROLLBACK TO savepoint_opt nm(X). {</div><div>   sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &X);</div><div> }</div><div>diff --git a/test/sql-tap/start-transaction.test.lua b/test/sql-tap/start-transaction.test.lua</div><div>new file mode 100755</div><div>index 0000000..eece4cd</div><div>--- /dev/null</div><div>+++ b/test/sql-tap/start-transaction.test.lua</div><div>@@ -0,0 +1,266 @@</div><div>+#!/usr/bin/env tarantool</div><div>+test = require("sqltester")</div><div>+test:plan(21)</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">   </span>"start-transaction-1.0",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>CREATE TABLE IF NOT EXISTS t(id int PRIMARY KEY);</div><div>+<span style="white-space:pre-wrap">               </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>BEGIN;</div><div>+<span style="white-space:pre-wrap">                  </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.0></div><div>+<span style="white-space:pre-wrap">                </span>1, "near \"BEGIN\": syntax error"</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.0></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.1",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.1></div><div>+</div><div>+<span style="white-space:pre-wrap">                </span>-- <start-transaction-1.1></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.2",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>CREATE TABLE IF NOT EXISTS t(id int primary key);</div><div>+<span style="white-space:pre-wrap">               </span>delete from t;</div><div>+<span style="white-space:pre-wrap">          </span>BEGIN TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.1></div><div>+<span style="white-space:pre-wrap">                </span>1, "near \"BEGIN\": syntax error"</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.1></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.3",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.3></div><div>+</div><div>+<span style="white-space:pre-wrap">                </span>-- <start-transaction-1.3></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.4",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.4></div><div>+<span style="white-space:pre-wrap">                </span>0</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.4></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.5",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.5></div><div>+<span style="white-space:pre-wrap">                </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.5></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.6",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>COMMIT TRANSACTION;</div><div>+<span style="white-space:pre-wrap">     </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.6></div><div>+<span style="white-space:pre-wrap">                </span>1, "keyword \"TRANSACTION\" is reserved"</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.6></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.7",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>COMMIT;</div><div>+<span style="white-space:pre-wrap">         </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.7></div><div>+<span style="white-space:pre-wrap">                </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.7></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.8",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>END;</div><div>+<span style="white-space:pre-wrap">    </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.8></div><div>+<span style="white-space:pre-wrap">                </span>1, "keyword \"END\" is reserved"</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.8></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.9",</div><div>+<span style="white-space:pre-wrap">      </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>COMMIT;</div><div>+<span style="white-space:pre-wrap">         </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.9></div><div>+<span style="white-space:pre-wrap">                </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.9></div><div>+<span style="white-space:pre-wrap">        </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.10",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>END TRANSACTION;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.10></div><div>+<span style="white-space:pre-wrap">               </span>1, "keyword \"END\" is reserved"</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.10></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.11",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>COMMIT;</div><div>+<span style="white-space:pre-wrap">         </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.11></div><div>+<span style="white-space:pre-wrap">               </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.11></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.12",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">               </span>ROLLBACK;</div><div>+<span style="white-space:pre-wrap">       </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.12></div><div>+<span style="white-space:pre-wrap">               </span>0</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.12></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.13",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.13></div><div>+</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.13></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.14",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">                       </span>ROLLBACK TRANSACTION;</div><div>+<span style="white-space:pre-wrap">           </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.14></div><div>+<span style="white-space:pre-wrap">               </span>1, "keyword \"TRANSACTION\" is reserved"</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.14></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.15",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>COMMIT;</div><div>+<span style="white-space:pre-wrap">         </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.15></div><div>+<span style="white-space:pre-wrap">               </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.15></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.16",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>SAVEPOINT s1;</div><div>+<span style="white-space:pre-wrap">                   </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">                       </span>ROLLBACK TO s1;</div><div>+<span style="white-space:pre-wrap">         </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.16></div><div>+<span style="white-space:pre-wrap">               </span>0</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.16></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.17",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.17></div><div>+<span style="white-space:pre-wrap">               </span>1</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.17></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre-wrap">        </span>"start-transaction-1.18",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>DELETE FROM t;</div><div>+<span style="white-space:pre-wrap">          </span>START TRANSACTION;</div><div>+<span style="white-space:pre-wrap">                      </span>INSERT INTO t VALUES (1);</div><div>+<span style="white-space:pre-wrap">                       </span>SAVEPOINT s1;</div><div>+<span style="white-space:pre-wrap">                   </span>INSERT INTO t VALUES (2);</div><div>+<span style="white-space:pre-wrap">                       </span>ROLLBACK TRANSACTION TO s1;</div><div>+<span style="white-space:pre-wrap">             </span>COMMIT;</div><div>+<span style="white-space:pre-wrap"> </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.18></div><div>+<span style="white-space:pre-wrap">               </span>1, "keyword \"TRANSACTION\" is reserved"</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.18></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.19",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>COMMIT;</div><div>+<span style="white-space:pre-wrap">         </span>SELECT * FROM t;</div><div>+<span style="white-space:pre-wrap">        </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start-transaction-1.19></div><div>+<span style="white-space:pre-wrap">               </span>1, 2</div><div>+<span style="white-space:pre-wrap">            </span>-- <start-transaction-1.19></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre-wrap"> </span>"start-transaction-1.20",</div><div>+<span style="white-space:pre-wrap">     </span>[[</div><div>+<span style="white-space:pre-wrap">              </span>drop table t;</div><div>+<span style="white-space:pre-wrap">   </span>]], {</div><div>+<span style="white-space:pre-wrap">           </span>-- <start0transaction-1.20></div><div>+</div><div>+<span style="white-space:pre-wrap">               </span>-- <start-transaction-1.20></div><div>+<span style="white-space:pre-wrap">       </span>})</div><div>+</div><div>+test:finish_test()</div></div></div></div>