]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change to five conflict resolution algorithms: ROLLBACK, ABORT, FAIL,
authordrh <drh@noemail.net>
Thu, 31 Jan 2002 15:54:21 +0000 (15:54 +0000)
committerdrh <drh@noemail.net>
Thu, 31 Jan 2002 15:54:21 +0000 (15:54 +0000)
IGNORE, and REPLACE.  This checkin is code only.  Documentation and
tests are still needed.  Also, ABORT is not fully implemented. (CVS 360)

FossilOrigin-Name: d0e7cf4a83e6abad7129bed356b7492dddaff474

17 files changed:
manifest
manifest.uuid
publish.sh
src/build.c
src/delete.c
src/insert.c
src/main.c
src/parse.y
src/sqliteInt.h
src/tokenize.c
src/update.c
src/vdbe.c
test/conflict.test
test/copy.test
test/notnull.test
www/download.tcl
www/lang.tcl

index 7ad25dbe367deb9663b07533ccbb383a9bd0d8e3..849134cdd30918397e27377d673d8ec6339d798b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Added\sON\sCONFLICT\ssupport\sto\sCOPY.\sUpdates\sto\sdocumentation.\sBug\sfixes.\s(CVS\s359)
-D 2002-01-30T16:17:24
+C Change\sto\sfive\sconflict\sresolution\salgorithms:\sROLLBACK,\sABORT,\sFAIL,\nIGNORE,\sand\sREPLACE.\s\sThis\scheckin\sis\scode\sonly.\s\sDocumentation\sand\ntests\sare\sstill\sneeded.\s\sAlso,\sABORT\sis\snot\sfully\simplemented.\s(CVS\s360)
+D 2002-01-31T15:54:21
 F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
 F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -16,40 +16,40 @@ F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
 F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
-F publish.sh 523db0d8a451df7a8300e193afaa4ac44e41f98c
+F publish.sh 60adffbe50226a1d7d1a2930e8b7eb31535c4fe4
 F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
 F src/btree.c c796e387da340cb628dc1e41f684fc20253f561e
 F src/btree.h 9ead7f54c270d8a554e59352ca7318fdaf411390
-F src/build.c 78571589a39d4b03b19b1300db8b23f1d3e1bab2
-F src/delete.c 4cdb6d2e94e2eb1b1aa79eefafd4669d43c249d6
+F src/build.c f725dc396d784f723950cf3d47a10f1a69b2f7b7
+F src/delete.c f8ad71be53cf18656b6573de65395852fe817f0c
 F src/expr.c a2a87dbd411a508ff89dffa90505ad42dac2f920
 F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
 F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
-F src/insert.c 37971598f1cbfc9de9bd1d269529e233003652b8
-F src/main.c 0205771a6c31a9858ff131fc1e797b589afb76bf
+F src/insert.c 42e89cb227ce744802622886db3572f78e72093f
+F src/main.c 637582b8b80a85b0308ca5bab8f2b42ebb002af8
 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
 F src/os.c c615faa4d23e742e0650e0751a6ad2a18438ad53
 F src/os.h 5405a5695bf16889d4fc6caf9d42043caa41c269
 F src/pager.c 1e80a3ba731e454df6bd2e58d32eeba7dd65121b
 F src/pager.h f78d064c780855ff70beacbeba0e2324471b26fe
-F src/parse.y e80f1cf6a280e3da0f49c9b60b14edc2f15912ec
+F src/parse.y 90e9fc913c60b26217f4210d48a4c5c4e78f16f2
 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
 F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
 F src/select.c fc11d5a8c2bae1b62d8028ffb111c773ad6bf161
 F src/shell.c c102dfe388c7618a668c944ff157c49cb48f28e3
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
-F src/sqliteInt.h 3bf0938d01e1cc57154c39c730d7e91d9bd60359
+F src/sqliteInt.h 70fd20107f4953312e76a9630a704c9405161040
 F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a
 F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
 F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
 F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
 F src/test3.c d6775f95fd91f5b3cf0e2382a28e5aaeb68f745b
-F src/tokenize.c 1199b96a82d5c41509b5e24fc9faa1852b7f3135
-F src/update.c c6215079d7604fd1cf785eff64ec0e03e97bd138
+F src/tokenize.c 01a09db6adf933e941db1b781789a0c175be6504
+F src/update.c 3fb7c1601bbd379e39881d6b731d3223b822188a
 F src/util.c 8f8973dd55a6ec63be9632fc5de86965c99d6327
-F src/vdbe.c 14667d889d9d9ebdc5f5f5d030312071f41b7873
+F src/vdbe.c 8e6f1bfff67639b7c3bd07822595fc2ef19f0f34
 F src/vdbe.h 5b1bd518126fc5a30e6ea13fe11de931b32c4b59
 F src/where.c 2dda39367f193194e4c7d2e0dcab31527d9d8aba
 F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe
@@ -57,8 +57,8 @@ F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
 F test/btree.test 6ab4dc5f595905a276ef588fad3c9236dc07a47b
 F test/btree2.test 08e9485619265cbaf5d11bd71f357cdc26bb87e0
 F test/btree3.test 9caa9e22491dd8cd8aa36d7ac3b48b089817c895
-F test/conflict.test 685725a37ec13e671ec57f48285c1c08bba21c99
-F test/copy.test 4079990fb84be696d29c43de9fa6492312f165f0
+F test/conflict.test 70d40d77bb83f326574488d3cde1d0f3c51a0949
+F test/copy.test 9ff0063c0b95b3d51b8d0c7fe0ff51dabaa66549
 F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
 F test/expr.test c8a495050dcec3f9e68538c3ef466726933302c1
 F test/func.test 51dbe3f8a4c28972751697423e6acc5d6b551df1
@@ -73,7 +73,7 @@ F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
 F test/main.test 1626345b5f630c5398eede500d9354813b76b0fd
 F test/malloc.test 70fdd0812e2a57eb746aaf015350f58bb8eee0b1
 F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
-F test/notnull.test 70856457c86fe50877f760e4057e99fdedd2997c
+F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30
 F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
 F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
 F test/quick.test 6f023c7a73fc413e6d65b7a1879c79764038dc05
@@ -110,19 +110,19 @@ F www/c_interface.tcl 82a026b1681757f13b3f62e035f3a31407c1d353
 F www/changes.tcl 3770ded78faa7a634b55fbf5316caa4cb150e5f9
 F www/conflict.tcl 3f70c01680b8d763bf3305eb67f6d85fdf83b497
 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
-F www/download.tcl 1ea61f9d89a2a5a9b2cee36b0d5cf97321bdefe0
+F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
 F www/faq.tcl 32cbc134879871604070d4cc3a32e73fb22a35f9
 F www/formatchng.tcl 2d9a35c787823b48d72a5c64bb5414a43e26d5ad
 F www/index.tcl 748614d8208c761ed3840e7958b8eed04de81822
-F www/lang.tcl f04d74017e627f6f133438234bd20fbe585ca4cf
+F www/lang.tcl 7ad595247fd81f394012a0cfd84ccd6241b9e59a
 F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
 F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
 F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 9bbddb8e013b47547164f71f2d7abd995f8d7385
-R ad077c176de250ed6687e2b5636281f6
+P cf1538d71c9ce12d5e59f367e03642cbcaf6b717
+R b0c9c7a017538a09b4eca555b386a82f
 U drh
-Z 1ba7e7bec405961a534e04fc39ece2b3
+Z b508e059fe2aafe83b423b2a1e04f6ed
index 022d213837b49d15a3ec3a4ba4d5b9ecc2e18a10..89c4ee85eabb5741fabbeb95b403fd37b132785a 100644 (file)
@@ -1 +1 @@
-cf1538d71c9ce12d5e59f367e03642cbcaf6b717
\ No newline at end of file
+d0e7cf4a83e6abad7129bed356b7492dddaff474
\ No newline at end of file
index b0bb8883276e03e2ec859084df60caddf043958b..02448a0ed7c2e50daee6495cdc006b6ec1711584 100644 (file)
@@ -28,7 +28,9 @@ gzip sqlite.bin
 # under Linux
 #
 make target_source
+rm sqlite_source.zip
 cd tsrc
+zip ../sqlite_source.zip *
 rm shell.c
 TCLDIR=/home/drh/tcltk/8.2linux
 TCLSTUBLIB=$TCLDIR/libtclstub8.2g.a
@@ -36,9 +38,14 @@ OPTS='-DUSE_TCL_STUBS=1 -DNDEBUG=1'
 gcc -fPIC $OPTS -O2 -I. -I$TCLDIR -shared *.c $TCLSTUBLIB -o tclsqlite.so
 strip tclsqlite.so
 mv tclsqlite.so ..
+rm tclsqlite.c
+gcc -fPIC -DNDEBUG=1 -O2 -I. -shared *.c -o sqlite.so
+strip sqlite.so
+mv sqlite.so ..
 cd ..
-rm -f tclsqlite.so.gz
+rm -f tclsqlite.so.gz sqlite.so.gz
 gzip tclsqlite.so
+gzip sqlite.so
 
 # Build the tclsqlite.dll shared library that can be imported into tclsh
 # or wish on windows.
@@ -69,9 +76,43 @@ i386-mingw32-dllwrap \
      -dllname tclsqlite.dll -lmsvcrt *.o $TCLSTUBLIB
 i386-mingw32-strip tclsqlite.dll
 mv tclsqlite.dll ..
+rm tclsqlite.o
+cat >sqlite.def <<\END_OF_FILE
+EXPORTS
+sqlite_open
+sqlite_close
+sqlite_exec
+sqlite_last_insert_rowid
+sqlite_error_string
+sqlite_interrupt
+sqlite_complete
+sqlite_busy_handler
+sqlite_busy_timeout
+sqlite_get_table
+sqlite_free_table
+sqlite_mprintf
+sqlite_vmprintf
+sqlite_exec_printf
+sqlite_exec_vprintf
+sqlite_get_table_printf
+sqlite_get_table_vprintf
+sqliteMalloc
+sqliteFree
+sqliteRealloc
+END_OF_FILE
+i386-mingw32-dllwrap \
+     --def sqlite.def -v --export-all \
+     --driver-name i386-mingw32-gcc \
+     --dlltool-name i386-mingw32-dlltool \
+     --as i386-mingw32-as \
+     --target i386-mingw32 \
+     -dllname sqlite.dll -lmsvcrt *.o
+i386-mingw32-strip sqlite.dll
+mv sqlite.dll sqlite.def ..
 cd ..
-rm -f tclsqlite.zip
+rm -f tclsqlite.zip sqlitedll.zip
 zip tclsqlite.zip tclsqlite.dll
+zip sqlitedll.zip sqlite.dll sqlite.def
 
 # Build the sqlite.exe executable for windows.
 #
@@ -103,3 +144,4 @@ cp $srcdir/../historical/* .
 rm -rf doc
 make doc
 ln sqlite.bin.gz sqlite.zip sqlite*.tar.gz tclsqlite.so.gz tclsqlite.zip doc
+ln sqlitedll.zip sqlite.so.gz sqlite_source.zip doc
index 7f6ec3f3a9c6a0eb91ef75c12536be822adebbfb..fa8d92a0a663220a7dd8a98ab27c3092a8ad39be 100644 (file)
@@ -25,7 +25,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.69 2002/01/30 16:17:24 drh Exp $
+** $Id: build.c,v 1.70 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -422,7 +422,7 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
       rc = sqliteBtreeBeginTrans(db->pBeTemp);
       if( rc!=SQLITE_OK ){
         sqliteSetNString(&pParse->zErrMsg, "unable to get a write lock on "
-          "the temporary datbase file", 0);
+          "the temporary database file", 0);
         pParse->nErr++;
         return;
       }
@@ -474,11 +474,7 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
   if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable);
   pParse->pNewTable = pTable;
   if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-      sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-      pParse->schemaVerified = 1;
-    }
+    sqliteBeginWriteOperation(pParse);
     if( !isTemp ){
       sqliteVdbeAddOp(v, OP_SetCookie, db->file_format, 1);
       sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
@@ -738,9 +734,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
       sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
       sqliteVdbeAddOp(v, OP_Close, 0, 0);
     }
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-    }
+    sqliteEndWriteOperation(pParse);
   }
 }
 
@@ -802,11 +796,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
       { OP_Close,      0, 0,        0},
     };
     Index *pIdx;
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-      sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-      pParse->schemaVerified = 1;
-    }
+    sqliteBeginWriteOperation(pParse);
     if( !pTable->isTemp ){
       base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
       sqliteVdbeChangeP3(v, base+2, pTable->zName, P3_STATIC);
@@ -817,9 +807,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
     for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
       sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp);
     }
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-    }
+    sqliteEndWriteOperation(pParse);
   }
 
   /* Move the table (and all its indices) to the pending DROP queue.
@@ -1057,11 +1045,7 @@ void sqliteCreateIndex(
     v = sqliteGetVdbe(pParse);
     if( v==0 ) goto exit_create_index;
     if( pTable!=0 ){
-      if( (db->flags & SQLITE_InTrans)==0 ){
-        sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-        sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-        pParse->schemaVerified = 1;
-      }
+      sqliteBeginWriteOperation(pParse);
       if( !isTemp ){
         sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
         sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
@@ -1118,9 +1102,7 @@ void sqliteCreateIndex(
         sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
         sqliteVdbeAddOp(v, OP_Close, 0, 0);
       }
-      if( (db->flags & SQLITE_InTrans)==0 ){
-        sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-      }
+      sqliteEndWriteOperation(pParse);
     }
   }
 
@@ -1173,11 +1155,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
     int base;
     Table *pTab = pIndex->pTable;
 
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-      sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-      pParse->schemaVerified = 1;
-    }
+    sqliteBeginWriteOperation(pParse);
     if( !pTab->isTemp ){
       base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
       sqliteVdbeChangeP3(v, base+2, pIndex->zName, P3_STATIC);
@@ -1185,9 +1163,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
       sqliteVdbeChangeP1(v, base+10, db->next_cookie);
     }
     sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pTab->isTemp);
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-    }
+    sqliteEndWriteOperation(pParse);
   }
 
   /* Move the index onto the pending DROP queue.  Or, if the index was
@@ -1337,7 +1313,7 @@ void sqliteCopy(
 ){
   Table *pTab;
   char *zTab;
-  int i, j;
+  int i;
   Vdbe *v;
   int addr, end;
   Index *pIdx;
@@ -1362,11 +1338,7 @@ void sqliteCopy(
   v = sqliteGetVdbe(pParse);
   if( v ){
     int openOp;
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-      sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-      pParse->schemaVerified = 1;
-    }
+    sqliteBeginWriteOperation(pParse);
     addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0);
     sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
     sqliteVdbeDequoteP3(v, addr);
@@ -1411,9 +1383,7 @@ void sqliteCopy(
     sqliteVdbeAddOp(v, OP_Goto, 0, addr);
     sqliteVdbeResolveLabel(v, end);
     sqliteVdbeAddOp(v, OP_Noop, 0, 0);
-    if( (db->flags & SQLITE_InTrans)==0 ){
-      sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-    }
+    sqliteEndWriteOperation(pParse);
     if( db->flags & SQLITE_CountRows ){
       sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
       sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
@@ -1450,11 +1420,7 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
   }
   v = sqliteGetVdbe(pParse);
   if( v==0 ) goto vacuum_cleanup;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-    pParse->schemaVerified = 1;
-  }
+  sqliteBeginWriteOperation(pParse);
   if( zName ){
     sqliteVdbeAddOp(v, OP_Reorganize, 0, 0);
     sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
@@ -1472,9 +1438,7 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
       }
     }
   }
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-  }
+  sqliteEndWriteOperation(pParse);
 
 vacuum_cleanup:
   sqliteFree(zName);
@@ -1484,20 +1448,15 @@ vacuum_cleanup:
 /*
 ** Begin a transaction
 */
-void sqliteBeginTransaction(Parse *pParse){
+void sqliteBeginTransaction(Parse *pParse, int onError){
   sqlite *db;
-  Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
   if( pParse->nErr || sqlite_malloc_failed ) return;
   if( db->flags & SQLITE_InTrans ) return;
-  v = sqliteGetVdbe(pParse);
-  if( v ){
-    sqliteVdbeAddOp(v, OP_Transaction, 1, 0);
-    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-    pParse->schemaVerified = 1;
-  }
+  sqliteBeginWriteOperation(pParse);
   db->flags |= SQLITE_InTrans;
+  db->onError = onError;
 }
 
 /*
@@ -1505,16 +1464,13 @@ void sqliteBeginTransaction(Parse *pParse){
 */
 void sqliteCommitTransaction(Parse *pParse){
   sqlite *db;
-  Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
   if( pParse->nErr || sqlite_malloc_failed ) return;
   if( (db->flags & SQLITE_InTrans)==0 ) return;
-  v = sqliteGetVdbe(pParse);
-  if( v ){
-    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-  }
   db->flags &= ~SQLITE_InTrans;
+  sqliteEndWriteOperation(pParse);
+  db->onError = OE_Default;
 }
 
 /*
@@ -1532,8 +1488,46 @@ void sqliteRollbackTransaction(Parse *pParse){
     sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
   }
   db->flags &= ~SQLITE_InTrans;
+  db->onError = OE_Default;
 }
 
+/*
+** Generate VDBE code that prepares for doing an operation that
+** might change the database.  If we are in the middle of a transaction,
+** then this sets a checkpoint.  If we are not in a transaction, then
+** start a transaction.
+*/
+void sqliteBeginWriteOperation(Parse *pParse){
+  Vdbe *v;
+  v = sqliteGetVdbe(pParse);
+  if( v==0 ) return;
+  if( pParse->db->flags & SQLITE_InTrans ){
+    /* sqliteVdbeAddOp(v, OP_CheckPoint, 0, 0); */
+  }else{
+    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
+    sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);
+    pParse->schemaVerified = 1;
+  }
+}
+
+/*
+** Generate code that concludes an operation that may have changed
+** the database.  This is a companion function to BeginWriteOperation().
+** If a transaction was started, then commit it.  If a checkpoint was
+** started then commit that.
+*/
+void sqliteEndWriteOperation(Parse *pParse){
+  Vdbe *v;
+  v = sqliteGetVdbe(pParse);
+  if( v==0 ) return;
+  if( pParse->db->flags & SQLITE_InTrans ){
+    /* Do Nothing */
+  }else{
+    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
+  }
+}
+
+
 /*
 ** Interpret the given string as a boolean value.
 */
index 15e2ea3f9d475b399982c4589ce978cbb33dac83..3898fdfcf1b5936dd14ca284382c2fa0c5b680cf 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.25 2002/01/29 23:07:02 drh Exp $
+** $Id: delete.c,v 1.26 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -82,11 +82,7 @@ void sqliteDeleteFrom(
   */
   v = sqliteGetVdbe(pParse);
   if( v==0 ) goto delete_from_cleanup;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-    pParse->schemaVerified = 1;
-  }
+  sqliteBeginWriteOperation(pParse);
 
   /* Initialize the counter of the number of rows deleted, if
   ** we are counting rows.
@@ -156,9 +152,7 @@ void sqliteDeleteFrom(
     sqliteVdbeResolveLabel(v, end);
     sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
   }
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-  }
+  sqliteEndWriteOperation(pParse);
 
   /*
   ** Return the number of rows that were deleted.
index ff7661387d2e2c0c8e34a3b784dc707c06458124..5632c76b470fc7b6c61d3cd6f59a46d0fc3e896e 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.38 2002/01/30 16:17:24 drh Exp $
+** $Id: insert.c,v 1.39 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -79,11 +79,7 @@ void sqliteInsert(
   */
   v = sqliteGetVdbe(pParse);
   if( v==0 ) goto insert_cleanup;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-    pParse->schemaVerified = 1;
-  }
+  sqliteBeginWriteOperation(pParse);
 
   /* Figure out how many columns of data are supplied.  If the data
   ** is coming from a SELECT statement, then this step has to generate
@@ -270,9 +266,7 @@ void sqliteInsert(
   for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
     sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
   }
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-  }
+  sqliteEndWriteOperation(pParse);
 
   /*
   ** Return the number of rows inserted.
@@ -312,8 +306,8 @@ insert_cleanup:
 **    N.  The data in the last column of the entry after the update.
 **
 ** The old recno shown as entry (1) above is omitted unless both isUpdate
-** and recnoChng are both 1.  isUpdate is true for UPDATEs and false for
-** INSERTs and recnoChng is ture if the record number is being changed.
+** and recnoChng are 1.  isUpdate is true for UPDATEs and false for
+** INSERTs and recnoChng is true if the record number is being changed.
 **
 ** The code generated by this routine pushes additional entries onto
 ** the stack which are the keys for new index entries for the new record.
@@ -323,18 +317,25 @@ insert_cleanup:
 **
 ** This routine also generates code to check constraints.  NOT NULL,
 ** CHECK, and UNIQUE constraints are all checked.  If a constraint fails,
-** then the appropriate action is performed.  The default action is to
-** execute OP_Halt to abort the transaction and cause sqlite_exec() to
-** return SQLITE_CONSTRAINT.  This is the so-called "ABORT" action.
-** Other actions are REPLACE and IGNORE.  The following table summarizes
-** what happens.
+** then the appropriate action is performed.  There are five possible
+** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
 **
 **  Constraint type  Action       What Happens
 **  ---------------  ----------   ----------------------------------------
-**  any              ABORT        The current transaction is rolled back and
+**  any              ROLLBACK     The current transaction is rolled back and
 **                                sqlite_exec() returns immediately with a
 **                                return code of SQLITE_CONSTRAINT.
 **
+**  any              ABORT        Back out changes from the current command
+**                                only (do not do a complete rollback) then
+**                                cause sqlite_exec() to return immediately
+**                                with SQLITE_CONSTRAINT.
+**
+**  any              FAIL         Sqlite_exec() returns immediately with a
+**                                return code of SQLITE_CONSTRAINT.  The
+**                                transaction is not rolled back and any
+**                                prior changes are retained.
+**
 **  any              IGNORE       The record number and data is popped from
 **                                the stack and there is an immediate jump
 **                                to label ignoreDest.
@@ -348,9 +349,10 @@ insert_cleanup:
 **
 **  CHECK            REPLACE      Illegal.  The results in an exception.
 **
-** The action to take is determined by the constraint itself if
-** overrideError is OE_Default.  Otherwise, overrideError determines
-** which action to use.
+** Which action to take is determined by the overrideError parameter.
+** Or if overrideError==OE_Default, then the pParse->onError parameter
+** is used.  Or if pParse->onError==OE_Default then the onError value
+** for the constraint is used.
 **
 ** The calling routine must an open read/write cursor for pTab with
 ** cursor number "base".  All indices of pTab must also have open
@@ -390,6 +392,9 @@ void sqliteGenerateConstraintChecks(
   v = sqliteGetVdbe(pParse);
   assert( v!=0 );
   nCol = pTab->nCol;
+  if( overrideError==OE_Default ){
+    overrideError = pParse->db->onError;
+  }
 
   /* Test all NOT NULL constraints.
   */
@@ -402,6 +407,8 @@ void sqliteGenerateConstraintChecks(
     if( onError==OE_None ) continue;
     if( overrideError!=OE_Default ){
       onError = overrideError;
+    }else if( onError==OE_Default ){
+      onError = OE_Abort;
     }
     if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){
       onError = OE_Abort;
@@ -409,8 +416,10 @@ void sqliteGenerateConstraintChecks(
     sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1);
     addr = sqliteVdbeAddOp(v, OP_NotNull, 0, 0);
     switch( onError ){
-      case OE_Abort: {
-        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, 0);
+      case OE_Rollback:
+      case OE_Abort:
+      case OE_Fail: {
+        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
         break;
       }
       case OE_Ignore: {
@@ -441,10 +450,14 @@ void sqliteGenerateConstraintChecks(
     onError = pTab->keyConf;
     if( overrideError!=OE_Default ){
       onError = overrideError;
+    }else if( onError==OE_Default ){
+      onError = OE_Abort;
     }
     switch( onError ){
-      case OE_Abort: {
-        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, 0);
+      case OE_Rollback:
+      case OE_Abort:
+      case OE_Fail: {
+        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
         break;
       }
       case OE_Ignore: {
@@ -479,12 +492,16 @@ void sqliteGenerateConstraintChecks(
     if( onError==OE_None ) continue;
     if( overrideError!=OE_Default ){
       onError = overrideError;
+    }else if( onError==OE_Default ){
+      onError = OE_Abort;
     }
     sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
     jumpInst = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
     switch( onError ){
-      case OE_Abort: {
-        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, 0);
+      case OE_Rollback:
+      case OE_Abort:
+      case OE_Fail: {
+        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
         break;
       }
       case OE_Ignore: {
index 6d5f46f65cdc8834105abc4a1ce1be1be8313561..5fa0cfe148c708e1a564846941a4a21626432688 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.56 2002/01/16 21:00:27 drh Exp $
+** $Id: main.c,v 1.57 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -276,6 +276,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
   sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
   sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);
   db->nextRowid = sqliteRandomInteger();
+  db->onError = OE_Default;
   
   /* Open the backend database driver */
   rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
index c225cfb90a7d0ca1588b8e7449bd50c9d946e78e..ceaf764f8b05896028c26568ac618846ff7bba51 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.44 2002/01/30 16:17:24 drh Exp $
+** @(#) $Id: parse.y,v 1.45 2002/01/31 15:54:22 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -56,7 +56,7 @@ explain ::= EXPLAIN.    {pParse->explain = 1;}
 
 ///////////////////// Begin and end transactions. ////////////////////////////
 //
-cmd ::= BEGIN trans_opt.       {sqliteBeginTransaction(pParse);}
+cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
 trans_opt ::= .
 trans_opt ::= TRANSACTION.
 trans_opt ::= TRANSACTION ids.
@@ -106,6 +106,7 @@ id(A) ::= KEY(X).        {A = X;}
 id(A) ::= ABORT(X).      {A = X;}
 id(A) ::= IGNORE(X).     {A = X;}
 id(A) ::= REPLACE(X).    {A = X;}
+id(A) ::= FAIL(X).       {A = X;}
 id(A) ::= CONFLICT(X).   {A = X;}
 
 // And "ids" is an identifer-or-string.
@@ -166,15 +167,17 @@ tcons ::= CHECK expr onconf.
 // default behavior when there is a constraint conflict.
 //
 %type onconf {int}
-%type onconf_u {int}
-%type confresolve {int}
-onconf(A) ::= confresolve(X).                { A = X; }
-onconf(A) ::= onconf_u(X).                   { A = X; }
-onconf_u(A) ::= ON CONFLICT confresolve(X).  { A = X; }
-onconf_u(A) ::= .                            { A = OE_Default; }
-confresolve(A) ::= ABORT.                    { A = OE_Abort; }
-confresolve(A) ::= IGNORE.                   { A = OE_Ignore; }
-confresolve(A) ::= REPLACE.                  { A = OE_Replace; }
+%type orconf {int}
+%type resolvetype {int}
+onconf(A) ::= .                              { A = OE_Default; }
+onconf(A) ::= ON CONFLICT resolvetype(X).    { A = X; }
+orconf(A) ::= .                              { A = OE_Default; }
+orconf(A) ::= OR resolvetype(X).             { A = X; }
+resolvetype(A) ::= ROLLBACK.                 { A = OE_Rollback; }
+resolvetype(A) ::= ABORT.                    { A = OE_Abort; }
+resolvetype(A) ::= FAIL.                     { A = OE_Fail; }
+resolvetype(A) ::= IGNORE.                   { A = OE_Ignore; }
+resolvetype(A) ::= REPLACE.                  { A = OE_Replace; }
 
 ////////////////////////// The DROP TABLE /////////////////////////////////////
 //
@@ -313,7 +316,7 @@ where_opt(A) ::= WHERE expr(X).       {A = X;}
 
 ////////////////////////// The UPDATE command ////////////////////////////////
 //
-cmd ::= UPDATE onconf_u(R) ids(X) SET setlist(Y) where_opt(Z).
+cmd ::= UPDATE orconf(R) ids(X) SET setlist(Y) where_opt(Z).
     {sqliteUpdate(pParse,&X,Y,Z,R);}
 
 setlist(A) ::= setlist(Z) COMMA ids(X) EQ expr(Y).
@@ -322,9 +325,9 @@ setlist(A) ::= ids(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
 
 ////////////////////////// The INSERT command /////////////////////////////////
 //
-cmd ::= INSERT onconf(R) INTO ids(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.
+cmd ::= INSERT orconf(R) INTO ids(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.
                {sqliteInsert(pParse, &X, Y, 0, F, R);}
-cmd ::= INSERT onconf(R) INTO ids(X) inscollist_opt(F) select(S).
+cmd ::= INSERT orconf(R) INTO ids(X) inscollist_opt(F) select(S).
                {sqliteInsert(pParse, &X, 0, S, F, R);}
 
 
@@ -548,9 +551,9 @@ cmd ::= DROP INDEX ids(X).      {sqliteDropIndex(pParse, &X);}
 
 ///////////////////////////// The COPY command ///////////////////////////////
 //
-cmd ::= COPY onconf_u(R) ids(X) FROM ids(Y) USING DELIMITERS STRING(Z).
+cmd ::= COPY orconf(R) ids(X) FROM ids(Y) USING DELIMITERS STRING(Z).
     {sqliteCopy(pParse,&X,&Y,&Z,R);}
-cmd ::= COPY onconf_u(R) ids(X) FROM ids(Y).
+cmd ::= COPY orconf(R) ids(X) FROM ids(Y).
     {sqliteCopy(pParse,&X,&Y,0,R);}
 
 ///////////////////////////// The VACUUM command /////////////////////////////
index e0d81d9897957824d6eea023ea0ad7cdf66f7dd9..eb4630efb5ecfdd2fba550f3f5c04a215c819fd2 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.82 2002/01/30 16:17:24 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.83 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -183,6 +183,7 @@ struct sqlite {
   Hash idxDrop;                 /* Uncommitted DROP INDEXs */
   int lastRowid;                /* ROWID of most recent insert */
   int nextRowid;                /* Next generated rowID */
+  int onError;                  /* Default conflict algorithm */
 };
 
 /*
@@ -237,19 +238,31 @@ struct Table {
 };
 
 /*
-** SQLite supports three different ways to resolve a UNIQUE contraint
-** error.  (1) It can abort the transaction return SQLITE_CONSTRAINT.
-** (2) It can decide to not do the INSERT or UPDATE that was causing
-** the constraint violation. (3) It can delete existing records from
-** the table so that the pending INSERT or UPDATE will work without
-** a constraint error.  The following there symbolic values are used
-** to record which type of action to take.
+** SQLite supports 4 or 5 different ways to resolve a contraint
+** error.  (Only 4 are implemented as of this writing.  The fifth method
+** "ABORT" is planned.)  ROLLBACK processing means that a constraint violation
+** causes the operation in proces to fail and for the current transaction
+** to be rolled back.  ABORT processing means the operation in process
+** fails and any prior changes from that one operation are backed out,
+** but the transaction is not rolled back.  FAIL processing means that
+** the operation in progress stops and returns an error code.  But prior
+** changes due to the same operation are not backed out and no rollback
+** occurs.  IGNORE means that the particular row that caused the constraint
+** error is not inserted or updated.  Processing continues and no error
+** is returned.  REPLACE means that preexisting database rows that caused
+** a UNIQUE constraint violation are removed so that the new insert or
+** update can proceed.  Processing continues and no error is reported.
+** 
+** The following there symbolic values are used to record which type
+** of action to take.
 */
-#define OE_None    0   /* There is no constraint to check */
-#define OE_Abort   1   /* Abort and rollback. */
-#define OE_Ignore  2   /* Ignore the error. Do not do the INSERT or UPDATE */
-#define OE_Replace 3   /* Delete existing record, then do INSERT or UPDATE */
-#define OE_Default 9   /* Do whatever the default action is */
+#define OE_None     0   /* There is no constraint to check */
+#define OE_Rollback 1   /* Fail the operation and rollback the transaction */
+#define OE_Abort    2   /* Back out changes but do no rollback transaction */
+#define OE_Fail     3   /* Stop the operation but leave all prior changes */
+#define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
+#define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */
+#define OE_Default  9   /* Do whatever the default action is */
 
 /*
 ** Each SQL index is represented in memory by an
@@ -542,7 +555,7 @@ void sqliteParseInfoReset(Parse*);
 Vdbe *sqliteGetVdbe(Parse*);
 int sqliteRandomByte(void);
 int sqliteRandomInteger(void);
-void sqliteBeginTransaction(Parse*);
+void sqliteBeginTransaction(Parse*, int);
 void sqliteCommitTransaction(Parse*);
 void sqliteRollbackTransaction(Parse*);
 char *sqlite_mprintf(const char *, ...);
@@ -551,3 +564,5 @@ void sqliteGenerateRowDelete(Vdbe*, Table*, int);
 void sqliteGenerateRowIndexDelete(Vdbe*, Table*, int, char*);
 void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
 void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int);
+void sqliteBeginWriteOperation(Parse*);
+void sqliteEndWriteOperation(Parse*);
index 0a8d0b6913b4aa193faa8f70a2f0b15fb75295f6..49922eaab3665ba04e766b0591c017104e3a0ac6 100644 (file)
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.33 2002/01/29 18:41:25 drh Exp $
+** $Id: tokenize.c,v 1.34 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -62,6 +62,7 @@ static Keyword aKeywordTable[] = {
   { "END",               0, TK_END,              0 },
   { "EXCEPT",            0, TK_EXCEPT,           0 },
   { "EXPLAIN",           0, TK_EXPLAIN,          0 },
+  { "FAIL",              0, TK_FAIL,             0 },
   { "FROM",              0, TK_FROM,             0 },
   { "GLOB",              0, TK_GLOB,             0 },
   { "GROUP",             0, TK_GROUP,            0 },
index 51f648ec2c04bde8669db8e3bed02958f240a16c..4b3a71111ec1bf9be45e1c498d86d328f9454d2b 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.31 2002/01/30 16:17:24 drh Exp $
+** $Id: update.c,v 1.32 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -161,11 +161,7 @@ void sqliteUpdate(
   */
   v = sqliteGetVdbe(pParse);
   if( v==0 ) goto update_cleanup;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
-    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
-    pParse->schemaVerified = 1;
-  }
+  sqliteBeginWriteOperation(pParse);
 
   /* Begin the database scan
   */
@@ -282,9 +278,7 @@ void sqliteUpdate(
   sqliteVdbeAddOp(v, OP_Goto, 0, addr);
   sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
   sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-  }
+  sqliteEndWriteOperation(pParse);
 
   /*
   ** Return the number of rows that were changed.
index 3949413c4b715bebeee8605822cdb5452f333ad9..acc6d33455f5cc2100101bd6370c730fe858d481 100644 (file)
@@ -30,7 +30,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.112 2002/01/30 16:17:24 drh Exp $
+** $Id: vdbe.c,v 1.113 2002/01/31 15:54:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1072,6 +1072,7 @@ int sqliteVdbeExec(
   sqlite *db = p->db;        /* The database */
   char **zStack;             /* Text stack */
   Stack *aStack;             /* Additional stack information */
+  int rollbackOnError = 1;   /* Do a ROLLBACK if an error is encountered */
   char zBuf[100];            /* Space to sprintf() an integer */
 
 
@@ -1149,14 +1150,20 @@ case OP_Goto: {
   break;
 }
 
-/* Opcode:  Halt P1 * *
+/* Opcode:  Halt P1 P2 *
 **
 ** Exit immediately.  All open cursors, Lists, Sorts, etc are closed
 ** automatically.
 **
 ** P1 is the result code returned by sqlite_exec().  For a normal
 ** halt, this should be SQLITE_OK (0).  For errors, it can be some
-** other value.
+** other value.  If P1!=0 then P2 will determine whether or not to
+** rollback the current transaction.  Do not rollback if P2==OE_Fail.
+** Do the rollback if P2==OE_Rollback.  If P2==OE_Abort, then back
+** out all changes that have occurred during this execution of the
+** VDBE, but do not rollback the transaction.  (This last case has
+** not yet been implemented.  OE_Abort works like OE_Rollback for
+** now.  In the future that may change.)
 **
 ** There is an implied "Halt 0 0 0" instruction inserted at the very end of
 ** every program.  So a jump past the last instruction of the program
@@ -1165,6 +1172,7 @@ case OP_Goto: {
 case OP_Halt: {
   if( pOp->p1!=SQLITE_OK ){
     rc = pOp->p1;
+    rollbackOnError = pOp->p2!=OE_Fail;
     goto abort_due_to_error;
   }else{
     pc = p->nOp-1;
@@ -4458,12 +4466,13 @@ default: {
 
 cleanup:
   Cleanup(p);
-  if( rc!=SQLITE_OK ){
+  if( rc!=SQLITE_OK && rollbackOnError ){
     closeAllCursors(p);
     sqliteBtreeRollback(pBt);
     if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp);
     sqliteRollbackInternalChanges(db);
     db->flags &= ~SQLITE_InTrans;
+    db->onError = OE_Default;
   }
   return rc;
 
index 0ae48f18797d768f93d1adc5ede7cd0ffaecc934..0c91c769d312b273150566d7d3c5b96d7fc19cd3 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the conflict resolution extension
 # to SQLite.
 #
-# $Id: conflict.test,v 1.3 2002/01/30 16:17:25 drh Exp $
+# $Id: conflict.test,v 1.4 2002/01/31 15:54:23 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -36,37 +36,37 @@ do_test conflict-1.2 {
 } {1 {constraint failed}}
 do_test conflict-1.3 {
   catchsql {
-    INSERT ON CONFLICT IGNORE INTO t1 VALUES(1,2,4);
+    INSERT OR IGNORE INTO t1 VALUES(1,2,4);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 3}
 do_test conflict-1.4 {
   catchsql {
-    INSERT ON CONFLICT REPLACE INTO t1 VALUES(1,2,4);
+    INSERT OR REPLACE INTO t1 VALUES(1,2,4);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 4}
 do_test conflict-1.5 {
   catchsql {
-    INSERT ON CONFLICT ABORT INTO t1 VALUES(1,2,5);
+    INSERT OR ABORT INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}}
 do_test conflict-1.6 {
   catchsql {
-    INSERT IGNORE INTO t1 VALUES(1,2,5);
+    INSERT OR IGNORE INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 4}
 do_test conflict-1.7 {
   catchsql {
-    INSERT REPLACE INTO t1 VALUES(1,2,5);
+    INSERT OR REPLACE INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 5}
 do_test conflict-1.8 {
   catchsql {
-    INSERT ON CONFLICT ABORT INTO t1 VALUES(1,2,6);
+    INSERT OR ABORT INTO t1 VALUES(1,2,6);
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}}
@@ -89,13 +89,13 @@ do_test conflict-1.9 {
 } 8
 do_test conflict-1.10 {
   catchsql {
-    INSERT IGNORE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
+    INSERT OR IGNORE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {5 21}}
 do_test conflict-1.11 {
   catchsql {
-    INSERT REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
+    INSERT OR REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {14 24}}
@@ -103,7 +103,7 @@ do_test conflict-1.11 {
 ###### Fix me!
 do_test conflict-1.12 {
   catchsql {
-    INSERT REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c DESC;
+    INSERT OR REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c DESC;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {14 24}}
@@ -121,7 +121,7 @@ do_test conflict-1.13 {
 } {1 2 3 1 3 4 2 3 5}
 do_test conflict-1.14 {
   catchsql {
-    UPDATE ON CONFLICT ABORT t1 SET b=3 WHERE b=2;
+    UPDATE OR ABORT t1 SET b=3 WHERE b=2;
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}};
@@ -133,13 +133,13 @@ do_test conflict-1.15 {
 } {1 {constraint failed}};
 do_test conflict-1.16 {
   catchsql {
-    UPDATE ON CONFLICT IGNORE t1 SET b=3 WHERE b=2;
+    UPDATE OR IGNORE t1 SET b=3 WHERE b=2;
     SELECT * FROM t1 ORDER BY c;
   }
 } {0 {1 2 3 1 3 4 2 3 5}}
 do_test conflict-1.17 {
   catchsql {
-    UPDATE ON CONFLICT REPLACE t1 SET b=3 WHERE b=2;
+    UPDATE OR REPLACE t1 SET b=3 WHERE b=2;
     SELECT * FROM t1 ORDER BY c;
   }
 } {0 {1 3 3 2 3 5}}
@@ -163,37 +163,37 @@ do_test conflict-2.2 {
 } {1 {constraint failed}}
 do_test conflict-2.3 {
   catchsql { 
-    INSERT ON CONFLICT IGNORE INTO t1 VALUES(1,2,4);
+    INSERT OR IGNORE INTO t1 VALUES(1,2,4);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 3}
 do_test conflict-2.4 {
   catchsql {
-    INSERT ON CONFLICT REPLACE INTO t1 VALUES(1,2,4);
+    INSERT OR REPLACE INTO t1 VALUES(1,2,4);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 4}
 do_test conflict-2.5 {
   catchsql {
-    INSERT ON CONFLICT ABORT INTO t1 VALUES(1,2,5);
+    INSERT OR ABORT INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}}
 do_test conflict-2.6 {
   catchsql {
-    INSERT IGNORE INTO t1 VALUES(1,2,5);
+    INSERT OR IGNORE INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 4}
 do_test conflict-2.7 {
   catchsql {
-    INSERT REPLACE INTO t1 VALUES(1,2,5);
+    INSERT OR REPLACE INTO t1 VALUES(1,2,5);
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 5}
 do_test conflict-2.8 {
   catchsql {
-    INSERT ON CONFLICT ABORT INTO t1 VALUES(1,2,6);
+    INSERT OR ABORT INTO t1 VALUES(1,2,6);
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}}
@@ -216,13 +216,13 @@ do_test conflict-2.9 {
 } 8
 do_test conflict-2.10 {
   catchsql {
-    INSERT IGNORE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
+    INSERT OR IGNORE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {5 21}}
 do_test conflict-2.11 {
   catchsql {
-    INSERT REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
+    INSERT OR REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {14 24}}
@@ -230,7 +230,7 @@ do_test conflict-2.11 {
 ###### Fix me!
 do_test conflict-2.12 {
   catchsql {
-    INSERT REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c DESC;
+    INSERT OR REPLACE INTO t1 SELECT a,b,c FROM t2 ORDER BY c DESC;
     SELECT c FROM t1 ORDER BY c;
   }
 } {0 {14 24}}
@@ -248,7 +248,7 @@ do_test conflict-2.13 {
 } {1 2 3 2 3 4 3 3 5}
 do_test conflict-2.14 {
   catchsql {
-    UPDATE ON CONFLICT ABORT t1 SET a=2, b=3 WHERE b=2;
+    UPDATE OR ABORT t1 SET a=2, b=3 WHERE b=2;
     SELECT c FROM t1 ORDER BY c;
   }
 } {1 {constraint failed}};
@@ -260,13 +260,13 @@ do_test conflict-2.15 {
 } {1 {constraint failed}};
 do_test conflict-2.16 {
   catchsql {
-    UPDATE ON CONFLICT IGNORE t1 SET a=2, b=3 WHERE b=2;
+    UPDATE OR IGNORE t1 SET a=2, b=3 WHERE b=2;
     SELECT * FROM t1 ORDER BY c;
   }
 } {0 {1 2 3 2 3 4 3 3 5}}
 do_test conflict-2.17 {
   catchsql {
-    UPDATE ON CONFLICT REPLACE t1 SET a=2, b=3 WHERE b=2;
+    UPDATE OR REPLACE t1 SET a=2, b=3 WHERE b=2;
     SELECT * FROM t1 ORDER BY c;
   }
 } {0 {2 3 3 3 3 5}}
index 057217effc0a35602c0c16a77b224a8d4388ee27..db0aa2b31d7e422452a93d137834d534523663f7 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the COPY statement.
 #
-# $Id: copy.test,v 1.7 2002/01/30 16:17:25 drh Exp $
+# $Id: copy.test,v 1.8 2002/01/31 15:54:23 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -194,7 +194,7 @@ do_test copy-5.3 {
   puts $fd "33|22|44"
   close $fd
   catchsql {
-    COPY ON CONFLICT IGNORE t1 FROM 'data6.txt' USING DELIMITERS '|';
+    COPY OR IGNORE t1 FROM 'data6.txt' USING DELIMITERS '|';
     SELECT * FROM t1;
   }
 } {0 {11 22 33 22 33 11}}
@@ -203,7 +203,7 @@ do_test copy-5.4 {
   puts $fd "33|22|44"
   close $fd
   catchsql {
-    COPY ON CONFLICT REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
+    COPY OR REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
     SELECT * FROM t1;
   }
 } {0 {22 33 11 33 22 44}}
index 014fb97b38bcf85e43d25488612d6b33d431f22b..2ae67b40ac5bff37fd472cdf3292731aabce4550 100644 (file)
@@ -12,7 +12,7 @@
 #
 # This file implements tests for the NOT NULL constraint.
 #
-# $Id: notnull.test,v 1.1 2002/01/30 04:32:01 drh Exp $
+# $Id: notnull.test,v 1.2 2002/01/31 15:54:23 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -22,9 +22,9 @@ do_test notnull-1.0 {
     CREATE TABLE t1 (
       a NOT NULL,
       b NOT NULL DEFAULT 5,
-      c NOT NULL REPLACE DEFAULT 6,
-      d NOT NULL IGNORE DEFAULT 7,
-      e NOT NULL ABORT DEFAULT 8
+      c NOT NULL ON CONFLICT REPLACE DEFAULT 6,
+      d NOT NULL ON CONFLICT IGNORE DEFAULT 7,
+      e NOT NULL ON CONFLICT ABORT DEFAULT 8
     );
     SELECT * FROM t1;
   }
@@ -46,21 +46,21 @@ do_test notnull-1.2 {
 do_test notnull-1.3 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR IGNORE INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-1.4 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR REPLACE INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-1.5 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR ABORT INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
@@ -74,21 +74,21 @@ do_test notnull-1.6 {
 do_test notnull-1.7 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR IGNORE INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
 do_test notnull-1.8 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR REPLACE INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
 do_test notnull-1.9 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR ABORT INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
@@ -102,14 +102,14 @@ do_test notnull-1.10 {
 do_test notnull-1.11 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
+    INSERT OR IGNORE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-1.12 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
+    INSERT OR REPLACE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
@@ -123,35 +123,35 @@ do_test notnull-1.13 {
 do_test notnull-1.14 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR IGNORE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-1.15 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR REPLACE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 2 6 4 5}}
 do_test notnull-1.16 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR ABORT INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-1.17 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,d,e) VALUES(1,2,3,null,5);
+    INSERT OR ABORT INTO t1(a,b,c,d,e) VALUES(1,2,3,null,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-1.18 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,e) VALUES(1,2,3,5);
+    INSERT OR ABORT INTO t1(a,b,c,e) VALUES(1,2,3,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 2 3 7 5}}
@@ -172,7 +172,7 @@ do_test notnull-1.20 {
 do_test notnull-1.21 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(e,d,c,b,a) VALUES(1,2,3,null,5);
+    INSERT OR REPLACE INTO t1(e,d,c,b,a) VALUES(1,2,3,null,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {5 5 3 2 1}}
@@ -189,7 +189,7 @@ do_test notnull-2.2 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT REPLACE t1 SET a=null;
+    UPDATE OR REPLACE t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {1 {constraint failed}}
@@ -197,7 +197,7 @@ do_test notnull-2.3 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT IGNORE t1 SET a=null;
+    UPDATE OR IGNORE t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 2 3 4 5}}
@@ -205,7 +205,7 @@ do_test notnull-2.4 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT ABORT t1 SET a=null;
+    UPDATE OR ABORT t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {1 {constraint failed}}
@@ -221,7 +221,7 @@ do_test notnull-2.6 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT REPLACE t1 SET b=null, d=e, e=d;
+    UPDATE OR REPLACE t1 SET b=null, d=e, e=d;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 5 3 5 4}}
@@ -229,7 +229,7 @@ do_test notnull-2.7 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT IGNORE t1 SET b=null, d=e, e=d;
+    UPDATE OR IGNORE t1 SET b=null, d=e, e=d;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 2 3 4 5}}
@@ -285,21 +285,21 @@ do_test notnull-3.2 {
 do_test notnull-3.3 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR IGNORE INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-3.4 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR REPLACE INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-3.5 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(b,c,d,e) VALUES(2,3,4,5);
+    INSERT OR ABORT INTO t1(b,c,d,e) VALUES(2,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
@@ -313,21 +313,21 @@ do_test notnull-3.6 {
 do_test notnull-3.7 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR IGNORE INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
 do_test notnull-3.8 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR REPLACE INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
 do_test notnull-3.9 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,c,d,e) VALUES(1,3,4,5);
+    INSERT OR ABORT INTO t1(a,c,d,e) VALUES(1,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
@@ -341,14 +341,14 @@ do_test notnull-3.10 {
 do_test notnull-3.11 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
+    INSERT OR IGNORE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-3.12 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
+    INSERT OR REPLACE INTO t1(a,b,c,d,e) VALUES(1,null,3,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 5 3 4 5}}
@@ -362,35 +362,35 @@ do_test notnull-3.13 {
 do_test notnull-3.14 {
   catchsql {
     DELETE FROM t1;
-    INSERT IGNORE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR IGNORE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {}}
 do_test notnull-3.15 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR REPLACE INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 2 6 4 5}}
 do_test notnull-3.16 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
+    INSERT OR ABORT INTO t1(a,b,c,d,e) VALUES(1,2,null,4,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-3.17 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,d,e) VALUES(1,2,3,null,5);
+    INSERT OR ABORT INTO t1(a,b,c,d,e) VALUES(1,2,3,null,5);
     SELECT * FROM t1 order by a;
   }
 } {1 {constraint failed}}
 do_test notnull-3.18 {
   catchsql {
     DELETE FROM t1;
-    INSERT ABORT INTO t1(a,b,c,e) VALUES(1,2,3,5);
+    INSERT OR ABORT INTO t1(a,b,c,e) VALUES(1,2,3,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {1 2 3 7 5}}
@@ -411,7 +411,7 @@ do_test notnull-3.20 {
 do_test notnull-3.21 {
   catchsql {
     DELETE FROM t1;
-    INSERT REPLACE INTO t1(e,d,c,b,a) VALUES(1,2,3,null,5);
+    INSERT OR REPLACE INTO t1(e,d,c,b,a) VALUES(1,2,3,null,5);
     SELECT * FROM t1 order by a;
   }
 } {0 {5 5 3 2 1}}
@@ -428,7 +428,7 @@ do_test notnull-4.2 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT REPLACE t1 SET a=null;
+    UPDATE OR REPLACE t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {1 {constraint failed}}
@@ -436,7 +436,7 @@ do_test notnull-4.3 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT IGNORE t1 SET a=null;
+    UPDATE OR IGNORE t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 2 3 4 5}}
@@ -444,7 +444,7 @@ do_test notnull-4.4 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT ABORT t1 SET a=null;
+    UPDATE OR ABORT t1 SET a=null;
     SELECT * FROM t1 ORDER BY a;
   }
 } {1 {constraint failed}}
@@ -460,7 +460,7 @@ do_test notnull-4.6 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT REPLACE t1 SET b=null, d=e, e=d;
+    UPDATE OR REPLACE t1 SET b=null, d=e, e=d;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 5 3 5 4}}
@@ -468,7 +468,7 @@ do_test notnull-4.7 {
   catchsql {
     DELETE FROM t1;
     INSERT INTO t1 VALUES(1,2,3,4,5);
-    UPDATE ON CONFLICT IGNORE t1 SET b=null, d=e, e=d;
+    UPDATE OR IGNORE t1 SET b=null, d=e, e=d;
     SELECT * FROM t1 ORDER BY a;
   }
 } {0 {1 2 3 4 5}}
index 105b8c12430e781454eeac7159c4e671b2287b23..b8a7fddd697d8a397116ac8874adc5b3fca1f602 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this TCL script to generate HTML for the download.html file.
 #
-set rcsid {$Id: download.tcl,v 1.2 2001/11/24 13:23:05 drh Exp $}
+set rcsid {$Id: download.tcl,v 1.3 2002/01/31 15:54:23 drh Exp $}
 
 puts {<html>
 <head><title>SQLite Download Page</title></head>
@@ -41,6 +41,11 @@ Product tclsqlite.so.gz {
   See <a href="tclsqlite.html">the documentation</a> for details.
 }
 
+Product sqlite.so.gz {
+  A precompiled shared-library for Linux.  This is the same as
+  <b>tclsqlite.so.gz</b> but without the TCL bindings.
+}
+
 puts {<h2>Precompiled Binaries For Windows</h2>}
 
 Product sqlite.zip {
@@ -52,9 +57,21 @@ Product tclsqlite.zip {
   tclsh or wish to get SQLite database access from Tcl/Tk.
   See <a href="tclsqlite.html">the documentation</a> for details.
 }
+Product sqlitedll.zip {
+  This is a DLL of the SQLite library without the TCL bindings.
+  The only external dependency is MSVCRT.DLL.
+}
 
 puts {<h2>Source Code</h2>}
 
+Product {sqlite_source.zip} {
+  This ZIP archive contains pure C source code for the SQLite library.
+  Unlike the tarballs below, all of the preprocessing has already been
+  done on these C source code, so you can just hand the files directly to
+  your favorite C compiler.  This file is provided as a service to
+  MS-Windows users who lack the build support infrastructure of Unix.
+}
+
 foreach name [lsort -dict -decreasing [glob -nocomplain sqlite-*.tar.gz]] {
   regexp {sqlite-(.*)\.tar\.gz} $name match vers
   Product $name "
index a766eabd66b4b22724576d9764ae140371f60ed2..2bb0104248a27659b3091b4729d5b9475e575885 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: lang.tcl,v 1.19 2002/01/30 16:17:25 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.20 2002/01/31 15:54:23 drh Exp $}
 
 puts {<html>
 <head>
@@ -333,6 +333,11 @@ default algorithm specified in the CREATE TABLE statement.
 See the section titled
 <a href="#conflict">ON CONFLICT</a> for additional information.</p>
 
+<p>CHECK constraints are ignored in the current implementation.
+Support for CHECK constraints may be added in the future.  As of
+version 2.3.0, NOT NULL, PRIMARY KEY, and UNIQUE constraints all
+work.</p>
+
 <p>There are no arbitrary limits on the number
 of columns or on the number of constraints in a table.
 The total amount of data in a single row is limited to about