mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Change to five conflict resolution algorithms: ROLLBACK, ABORT, FAIL,
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
This commit is contained in:
40
manifest
40
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
|
||||
|
@ -1 +1 @@
|
||||
cf1538d71c9ce12d5e59f367e03642cbcaf6b717
|
||||
d0e7cf4a83e6abad7129bed356b7492dddaff474
|
46
publish.sh
46
publish.sh
@ -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
|
||||
|
122
src/build.c
122
src/build.c
@ -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.
|
||||
*/
|
||||
|
12
src/delete.c
12
src/delete.c
@ -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.
|
||||
|
69
src/insert.c
69
src/insert.c
@ -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: {
|
||||
|
@ -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);
|
||||
|
35
src/parse.y
35
src/parse.y
@ -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 /////////////////////////////
|
||||
|
@ -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*);
|
||||
|
@ -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 },
|
||||
|
12
src/update.c
12
src/update.c
@ -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.
|
||||
|
17
src/vdbe.c
17
src/vdbe.c
@ -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;
|
||||
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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 "
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user