]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Added tests for the in-memory database backend. Also updated some comments
authordrh <drh@noemail.net>
Sun, 20 Apr 2003 17:29:23 +0000 (17:29 +0000)
committerdrh <drh@noemail.net>
Sun, 20 Apr 2003 17:29:23 +0000 (17:29 +0000)
in other modules. (CVS 924)

FossilOrigin-Name: fb89adf4d1325c5ea471759ebfd8df7faa4f9a80

manifest
manifest.uuid
src/btree_rb.c
src/insert.c
src/update.c
src/where.c
test/memdb.test [new file with mode: 0644]

index 97c1bcd18f0cefe5c23a7a700bd5ee2a0a6d2f0f..5e04a0ed37c237b4a80cbb1b41e5d6f15ae455ae 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Align\sconfig\svars\scontrolling\sin-memory\sDB\swith\scode\s(CVS\s923)
-D 2003-04-20T11:46:35
+C Added\stests\sfor\sthe\sin-memory\sdatabase\sbackend.\s\sAlso\supdated\ssome\scomments\nin\sother\smodules.\s(CVS\s924)
+D 2003-04-20T17:29:24
 F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -23,7 +23,7 @@ F src/attach.c 7ebc7487de43e357a64226f8abef81f2669f2183
 F src/auth.c 2dd558dba4d8ffbed25fe1644e9af242f389f3e9
 F src/btree.c b9487cceb9ea78af9cbae9def34114902f511736
 F src/btree.h 529c98cb0715c62214544fbbe50b946f99a85540
-F src/btree_rb.c 0c4a10b52ae565071635863cc28c5b69fa5517fc
+F src/btree_rb.c 97375d44bc2cf93b6312acd0f3276177c20e77bb
 F src/build.c 66f8ca2457dfdcc6c45e1606696f337418a8c556
 F src/copy.c 8699e571994934c78f70761a1458d7b9e9e75073
 F src/delete.c af65b26d9d13abbf63fdc4e97b88d26c700b04bb
@@ -32,7 +32,7 @@ F src/expr.c 3c0ff6b7b34d483ea03fb86c66f28b929542c782
 F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
-F src/insert.c 45d27e3e8447bff4025db2f0dc3bb4e318e602f4
+F src/insert.c ae9ffb52b0c4218e3f00f611acfc600fd082dac4
 F src/main.c d6a7f78ec5269c7ced3380908a7ff04508aa2f8e
 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
 F src/os.c 7274951ed6894f383cb889342267ded07caf339b
@@ -56,12 +56,12 @@ F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
 F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 F src/tokenize.c a88cfb6f698d047e14d5064fa6c4ecb709bf8fa4
 F src/trigger.c 45b67f6c4338245288e4662c6a5b802ae3a66e5d
-F src/update.c 7f1aa8912876a682a692676f8adb215ddffad295
+F src/update.c 803c13ad967850fb18443394e0a5c2b0f0d7ce6f
 F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c
 F src/vacuum.c e24781e38db36d1c9f578b6b3613bf0989ebd63c
 F src/vdbe.c d453e8c95c9fac5a5e067c5c58243b3ae75699fc
 F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
-F src/where.c 89eca003346418093138159d79ca833ed9f2401b
+F src/where.c c0709e5cf402f30026b597dce9dc3e74f1d07f8e
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test b311c83e370e6b22b79a8279317039440ce64862
 F test/auth.test 8128cd750830cba01b7fd0fba8ddfa1722ea6291
@@ -91,6 +91,7 @@ F test/limit.test 9ffb965a0f5bf7152187ef3d8d1249b96e5620bf
 F test/lock.test 388a3a10962d2d571c0c1821cc35bf069ee73473
 F test/main.test 8108ac48302027bbe4296c30b913adbe6d5d984b
 F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd
+F test/memdb.test 2ad45c3c3215822c588c0c823137821abd96bded
 F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90
 F test/minmax.test b54ac3bc45460a4976b08ef363e05c032418726e
 F test/misc1.test 865c907df58195364eaf2e69426e9674bc8d1a8c
@@ -162,7 +163,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P d983accf4a702158f03742fb11959d0fd035a4b4
-R 9c9140e8f7e38e6951b9567de707f4f1
-U paul
-Z e6994638a8674e314247f6f23259eed8
+P 921656db9e3df865aea6b1abe1bc40b1acbeeb47
+R 33f3fc945956a6408c6cd1e1bd368307
+U drh
+Z 30e6aaf687d966a7606c8c8a04b291ba
index 002ffaad39c4e0305b63811d9f24bb6a80d9b7e5..df54ff70e3904d8e9956315cce3109b0b37bc721 100644 (file)
@@ -1 +1 @@
-921656db9e3df865aea6b1abe1bc40b1acbeeb47
\ No newline at end of file
+fb89adf4d1325c5ea471759ebfd8df7faa4f9a80
\ No newline at end of file
index 93db50dd94363f58378f08c118d7540d8ceced35..1a0db6d7e47c27b9919ff3b68c089e59b29e32bd 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree_rb.c,v 1.5 2003/04/20 11:41:04 paul Exp $
+** $Id: btree_rb.c,v 1.6 2003/04/20 17:29:24 drh Exp $
 **
 ** This file implements an in-core database using Red-Black balanced
 ** binary trees.
@@ -1184,26 +1184,23 @@ static int memBtreeBeginTrans(Btree* tree)
   return SQLITE_OK;
 }
 
-static int memBtreeCommit(Btree* tree)
-{
-  /* Just delete pTransRollback and pCheckRollback */
-  BtRollbackOp *pOp, *pTmp;
-  pOp = tree->pCheckRollback;
-  while( pOp ){
-    pTmp = pOp->pNext;
-    sqliteFree(pOp->pData);
-    sqliteFree(pOp->pKey);
-    sqliteFree(pOp);
-    pOp = pTmp;
-  }
-  pOp = tree->pTransRollback;
+/*
+** Delete a linked list of BtRollbackOp structures.
+*/
+static void deleteRollbackList(BtRollbackOp *pOp){
   while( pOp ){
-    pTmp = pOp->pNext;
+    BtRollbackOp *pTmp = pOp->pNext;
     sqliteFree(pOp->pData);
     sqliteFree(pOp->pKey);
     sqliteFree(pOp);
     pOp = pTmp;
   }
+}
+
+static int memBtreeCommit(Btree* tree){
+  /* Just delete pTransRollback and pCheckRollback */
+  deleteRollbackList(tree->pCheckRollback);
+  deleteRollbackList(tree->pTransRollback);
   tree->pTransRollback = 0;
   tree->pCheckRollback = 0;
   tree->pCheckRollbackTail = 0;
index 116c646be1cfd52b0d5855bfd7a6e79815b770ac..f7773314c88ad88b9d912b0f99796320d0f5c700 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.79 2003/04/15 19:22:23 drh Exp $
+** $Id: insert.c,v 1.80 2003/04/20 17:29:24 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -401,11 +401,10 @@ void sqliteInsert(
     }
     sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
     sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
-    sqliteVdbeAddOp(v, OP_Rewind, newIdx, 0);
 
     /* Fire BEFORE triggers */
-    if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, newIdx, -1, 
-        onError, endOfLoop) ){
+    if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, 
+        newIdx, -1, onError, endOfLoop) ){
       goto insert_cleanup;
     }
   }
@@ -560,7 +559,7 @@ insert_cleanup:
 ** When this routine is called, the stack contains (from bottom to top)
 ** the following values:
 **
-**    1.  The recno of the row to be updated before it is updated.  This
+**    1.  The recno of the row to be updated before the update.  This
 **        value is omitted unless we are doing an UPDATE that involves a
 **        change to the record number.
 **
@@ -763,10 +762,12 @@ void sqliteGenerateConstraintChecks(
   ** index and making sure that duplicate entries do not already exist.
   ** Add the new records to the indices as we go.
   */
-  extra = 0;
-  for(extra=(-1), iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
-    if( aIdxUsed && aIdxUsed[iCur]==0 ) continue;
-    extra++;    
+  extra = -1;
+  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
+    if( aIdxUsed && aIdxUsed[iCur]==0 ) continue;  /* Skip unused indices */
+    extra++;
+
+    /* Create a key for accessing the index entry */
     sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1);
     for(i=0; i<pIdx->nColumn; i++){
       int idx = pIdx->aiColumn[i];
@@ -778,16 +779,22 @@ void sqliteGenerateConstraintChecks(
     }
     jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
     if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
+
+    /* Find out what action to take in case there is an indexing conflict */
     onError = pIdx->onError;
-    if( onError==OE_None ) continue;
+    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
     if( overrideError!=OE_Default ){
       onError = overrideError;
     }else if( onError==OE_Default ){
       onError = pParse->db->onError;
       if( onError==OE_Default ) onError = OE_Abort;
     }
+
+    /* Check to see if the new index entry will be unique */
     sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
     jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
+
+    /* Generate code that executes if the new index entry is not unique */
     switch( onError ){
       case OE_Rollback:
       case OE_Abort:
index 53dd62ebf3abe21713c9ebf5bec1a39aff723279..b77e1bb0ce75e9cd1b22c99aee744fb7674e6597 100644 (file)
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.60 2003/04/17 22:57:54 drh Exp $
+** $Id: update.c,v 1.61 2003/04/20 17:29:24 drh Exp $
 */
 #include "sqliteInt.h"
 
 /*
 ** Process an UPDATE statement.
+**
+**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+**          \_______/ \________/     \______/       \________________/
+*            onError   pTabList      pChanges             pWhere
 */
 void sqliteUpdate(
   Parse *pParse,         /* The parser context */
@@ -37,7 +41,7 @@ void sqliteUpdate(
   int base;              /* Index of first available table cursor */
   sqlite *db;            /* The database structure */
   Index **apIdx = 0;     /* An array of indices that need updating too */
-  char *aIdxUsed = 0;    /* aIdxUsed[i] if the i-th index is used */
+  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                          ** an expression for the i-th column of the table.
                          ** aXRef[i]==-1 if the i-th column is not changed. */
@@ -56,10 +60,7 @@ void sqliteUpdate(
   db = pParse->db;
   assert( pTabList->nSrc==1 );
 
-  /* Locate the table which we want to update.  This table has to be
-  ** put in an SrcList structure because some of the subroutines we
-  ** will be calling are designed to work with multiple tables and expect
-  ** an SrcList* parameter instead of just a Table* parameter.
+  /* Locate the table which we want to update. 
   */
   pTab = sqliteSrcListLookup(pParse, pTabList);
   if( pTab==0 ) goto update_cleanup;
@@ -80,7 +81,9 @@ void sqliteUpdate(
   if( aXRef==0 ) goto update_cleanup;
   for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
 
-  /* If there are FOR EACH ROW triggers, allocate temp tables */
+  /* If there are FOR EACH ROW triggers, allocate cursors for the
+  ** special OLD and NEW tables
+  */
   if( row_triggers_exist ){
     newIdx = pParse->nTab++;
     oldIdx = pParse->nTab++;
index 7d87ccd8a1cc0d9c0ead62ee9e4f6b64a3ea3648..6e6fc289f83bd252b2a9897b919343b23443ea0f 100644 (file)
 **
 *************************************************************************
 ** This module contains C code that generates VDBE code used to process
-** the WHERE clause of SQL statements.  Also found here are subroutines
-** to generate VDBE code to evaluate expressions.
+** the WHERE clause of SQL statements.
 **
-** $Id: where.c,v 1.75 2003/04/19 16:34:05 drh Exp $
+** $Id: where.c,v 1.76 2003/04/20 17:29:24 drh Exp $
 */
 #include "sqliteInt.h"
 
diff --git a/test/memdb.test b/test/memdb.test
new file mode 100644 (file)
index 0000000..cf1058a
--- /dev/null
@@ -0,0 +1,363 @@
+# 2001 September 15
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this script is in-memory database backend.
+#
+# $Id: memdb.test,v 1.1 2003/04/20 17:29:25 drh Exp $
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# In the following sequence of tests, compute the MD5 sum of the content
+# of a table, make lots of modifications to that table, then do a rollback.
+# Verify that after the rollback, the MD5 checksum is unchanged.
+#
+# These tests were browed from trans.tcl.
+#
+do_test memdb-1.1 {
+  db close
+  sqlite db :memory:
+  # sqlite db test.db
+  execsql {
+    BEGIN;
+    CREATE TABLE t3(x TEXT);
+    INSERT INTO t3 VALUES(randstr(10,400));
+    INSERT INTO t3 VALUES(randstr(10,400));
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
+    COMMIT;
+    SELECT count(*) FROM t3;
+  }
+} {1024}
+
+# The following procedure computes a "signature" for table "t3".  If
+# T3 changes in any way, the signature should change.  
+#
+# This is used to test ROLLBACK.  We gather a signature for t3, then
+# make lots of changes to t3, then rollback and take another signature.
+# The two signatures should be the same.
+#
+proc signature {} {
+  return [db eval {SELECT count(*), md5sum(x) FROM t3}]
+}
+
+# Do rollbacks.  Make sure the signature does not change.
+#
+set limit 10
+for {set i 2} {$i<=$limit} {incr i} {
+  set ::sig [signature]
+  set cnt [lindex $::sig 0]
+  set ::journal_format [expr {($i%3)+1}]
+  if {$i%2==0} {
+    execsql {PRAGMA synchronous=FULL}
+  } else {
+    execsql {PRAGMA synchronous=NORMAL}
+  }
+  do_test memdb-1.$i.1-$cnt {
+     execsql {
+       BEGIN;
+       DELETE FROM t3 WHERE random()%10!=0;
+       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
+       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
+       ROLLBACK;
+     }
+     signature
+  } $sig
+  do_test memdb-1.$i.2-$cnt {
+     execsql {
+       BEGIN;
+       DELETE FROM t3 WHERE random()%10!=0;
+       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
+       DELETE FROM t3 WHERE random()%10!=0;
+       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
+       ROLLBACK;
+     }
+     signature
+  } $sig
+  if {$i<$limit} {
+    do_test memdb-1.$i.9-$cnt {
+       execsql {
+         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
+       }
+    } {}
+  }
+  set ::pager_old_format 0
+}
+
+do_test memdb-2.1 {
+  execsql {
+    PRAGMA integrity_check
+  }
+} {ok ok}
+
+do_test memdb-3.1 {
+  execsql {
+    CREATE TABLE t4(a,b,c,d);
+    BEGIN;
+    INSERT INTO t4 VALUES(1,2,3,4);
+    SELECT * FROM t4;
+  }
+} {1 2 3 4}
+do_test memdb-3.2 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type='table';
+  }
+} {t3 t4}
+do_test memdb-3.3 {
+  execsql {
+    DROP TABLE t4;
+    SELECT name FROM sqlite_master WHERE type='table';
+  }
+} {t3}
+do_test memdb-3.4 {
+  execsql {
+    ROLLBACK;
+    SELECT name FROM sqlite_master WHERE type='table';
+  }
+} {t3 t4}
+
+# Create tables for the first group of tests.
+#
+do_test memdb-4.0 {
+  execsql {
+    CREATE TABLE t1(a, b, c, UNIQUE(a,b));
+    CREATE TABLE t2(x);
+    SELECT c FROM t1 ORDER BY c;
+  }
+} {}
+
+# Six columns of configuration data as follows:
+#
+#   i      The reference number of the test
+#   conf   The conflict resolution algorithm on the BEGIN statement
+#   cmd    An INSERT or REPLACE command to execute against table t1
+#   t0     True if there is an error from $cmd
+#   t1     Content of "c" column of t1 assuming no error in $cmd
+#   t2     Content of "x" column of t2
+#
+foreach {i conf cmd t0 t1 t2} {
+  1 {}       INSERT                  1 {}  1
+  2 {}       {INSERT OR IGNORE}      0 3   1
+  3 {}       {INSERT OR REPLACE}     0 4   1
+  4 {}       REPLACE                 0 4   1
+  5 {}       {INSERT OR FAIL}        1 {}  1
+  6 {}       {INSERT OR ABORT}       1 {}  1
+  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
+  8 IGNORE   INSERT                  0 3   1
+  9 IGNORE   {INSERT OR IGNORE}      0 3   1
+ 10 IGNORE   {INSERT OR REPLACE}     0 4   1
+ 11 IGNORE   REPLACE                 0 4   1
+ 12 IGNORE   {INSERT OR FAIL}        1 {}  1
+ 13 IGNORE   {INSERT OR ABORT}       1 {}  1
+ 14 IGNORE   {INSERT OR ROLLBACK}    1 {}  {}
+ 15 REPLACE  INSERT                  0 4   1
+ 16 FAIL     INSERT                  1 {}  1
+ 17 ABORT    INSERT                  1 {}  1
+ 18 ROLLBACK INSERT                  1 {}  {}
+} {
+  do_test memdb-4.$i {
+    if {$conf!=""} {set conf "ON CONFLICT $conf"}
+    set r0 [catch {execsql [subst {
+      DELETE FROM t1;
+      DELETE FROM t2;
+      INSERT INTO t1 VALUES(1,2,3);
+      BEGIN $conf;
+      INSERT INTO t2 VALUES(1); 
+      $cmd INTO t1 VALUES(1,2,4);
+    }]} r1]
+    catch {execsql {COMMIT}}
+    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
+    set r2 [execsql {SELECT x FROM t2}]
+    list $r0 $r1 $r2
+  } [list $t0 $t1 $t2]
+}
+
+do_test memdb-5.0 {
+  execsql {
+    DROP TABLE t2;
+    DROP TABLE t3;
+    CREATE TABLE t2(a,b,c);
+    INSERT INTO t2 VALUES(1,2,1);
+    INSERT INTO t2 VALUES(2,3,2);
+    INSERT INTO t2 VALUES(3,4,1);
+    INSERT INTO t2 VALUES(4,5,4);
+    SELECT c FROM t2 ORDER BY b;
+    CREATE TABLE t3(x);
+    INSERT INTO t3 VALUES(1);
+  }
+} {1 2 1 4}
+
+# Six columns of configuration data as follows:
+#
+#   i      The reference number of the test
+#   conf1  The conflict resolution algorithm on the UNIQUE constraint
+#   conf2  The conflict resolution algorithm on the BEGIN statement
+#   cmd    An UPDATE command to execute against table t1
+#   t0     True if there is an error from $cmd
+#   t1     Content of "b" column of t1 assuming no error in $cmd
+#   t2     Content of "x" column of t3
+#
+foreach {i conf1 conf2 cmd t0 t1 t2} {
+  1 {}       {}       UPDATE                  1 {6 7 8 9}  1
+  2 REPLACE  {}       UPDATE                  0 {7 6 9}    1
+  3 IGNORE   {}       UPDATE                  0 {6 7 3 9}  1
+  4 FAIL     {}       UPDATE                  1 {6 7 3 4}  1
+  5 ABORT    {}       UPDATE                  1 {1 2 3 4}  1
+  6 ROLLBACK {}       UPDATE                  1 {1 2 3 4}  0
+  7 REPLACE  {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
+  8 IGNORE   {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
+  9 FAIL     {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
+ 10 ABORT    {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
+ 11 ROLLBACK {}       {UPDATE OR IGNORE}      0 {6 7 3 9}   1
+ 12 {}       {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
+ 13 {}       {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
+ 14 {}       {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1
+ 15 {}       {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1
+ 16 {}       {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0
+ 17 {}       IGNORE   UPDATE                  0 {6 7 3 9}  1
+ 18 {}       REPLACE  UPDATE                  0 {7 6 9}    1
+ 19 {}       FAIL     UPDATE                  1 {6 7 3 4}  1
+ 20 {}       ABORT    UPDATE                  1 {1 2 3 4}  1
+ 21 {}       ROLLBACK UPDATE                  1 {1 2 3 4}  0
+ 22 REPLACE  FAIL     UPDATE                  0 {7 6 9}    1
+ 23 IGNORE   ROLLBACK UPDATE                  0 {6 7 3 9}  1
+} {
+  if {$t0} {set t1 {uniqueness constraint failed}}
+  do_test memdb-5.$i {
+    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
+    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
+    set r0 [catch {execsql [subst {
+      DROP TABLE t1;
+      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
+      INSERT INTO t1 SELECT * FROM t2;
+      UPDATE t3 SET x=0;
+      BEGIN $conf2;
+      $cmd t3 SET x=1;
+      $cmd t1 SET b=b*2;
+      $cmd t1 SET a=c+5;
+    }]} r1]
+    catch {execsql {COMMIT}}
+    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
+    set r2 [execsql {SELECT x FROM t3}]
+    list $r0 $r1 $r2
+  } [list $t0 $t1 $t2]
+}
+
+do_test memdb-6.1 {
+  execsql {
+    SELECT * FROM t2;
+  }
+} {1 2 1 2 3 2 3 4 1 4 5 4}
+do_test memdb-6.2 {
+  execsql {
+    BEGIN;
+    DROP TABLE t2;
+    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
+  }
+} {t1 t3 t4}
+do_test memdb-6.3 {
+  execsql {
+    ROLLBACK;
+    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
+  }
+} {t1 t2 t3 t4}
+do_test memdb-6.4 {
+  execsql {
+    SELECT * FROM t2;
+  }
+} {1 2 1 2 3 2 3 4 1 4 5 4}
+do_test memdb-6.5 {
+  execsql {
+    SELECT a FROM t2 UNION SELECT b FROM t2 ORDER BY 1;
+  }
+} {1 2 3 4 5}
+do_test memdb-6.6 {
+  execsql {
+    CREATE INDEX i2 ON t2(c);
+    SELECT a FROM t2 ORDER BY c;
+  }
+} {1 3 2 4}
+do_test memdb-6.6 {
+  execsql {
+    SELECT a FROM t2 ORDER BY c DESC;
+  }
+} {4 2 3 1}
+do_test memdb-6.7 {
+  execsql {
+    BEGIN;
+    CREATE TABLE t5(x,y);
+    INSERT INTO t5 VALUES(1,2);
+    SELECT * FROM t5;
+  }
+} {1 2}
+do_test memdb-6.8 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
+  }
+} {t1 t2 t3 t4 t5}
+do_test memdb-6.9 {
+  execsql {
+    ROLLBACK;
+    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
+  }
+} {t1 t2 t3 t4}
+do_test memdb-6.10 {
+  execsql {
+    CREATE TABLE t5(x PRIMARY KEY, y UNIQUE);
+    SELECT * FROM t5;
+  }
+} {}
+do_test memdb-6.11 {
+  execsql {
+    SELECT * FROM t5 ORDER BY y DESC;
+  }
+} {}
+do_test memdb-6.12 {
+  execsql {
+    INSERT INTO t5 VALUES(1,2);
+    INSERT INTO t5 VALUES(3,4);
+    REPLACE INTO t5 VALUES(1,4);
+    SELECT rowid,* FROM t5;
+  }
+} {3 1 4}
+do_test memdb-6.13 {
+  execsql {
+    DELETE FROM t5 WHERE x>5;
+    SELECT * FROM t5;
+  }
+} {1 4}
+do_test memdb-6.14 {
+  execsql {
+    DELETE FROM t5 WHERE y<3;
+    SELECT * FROM t5;
+  }
+} {1 4}
+do_test memdb-6.15 {
+  execsql {
+    DELETE FROM t5 WHERE x>0;
+    SELECT * FROM t5;
+  }
+} {}
+
+
+
+
+
+
+finish_test