-C Additional\stesting\sof\sthe\sATTACH\scommand\swith\sbug\sfixes\sfor\sthe\snew\sproblems\nthat\sthe\stests\sfound.\s(CVS\s998)
-D 2003-06-03T01:47:11
+C Avoid\scorrupting\sindices\swhen\sdoing\sa\sREPLACE\son\sa\stable\swith\san\nINTEGER\sPRIMARY\sKEY\sthat\salso\shas\sanother\sindex.\s\sTicket\s#334.\s(CVS\s999)
+D 2003-06-04T12:23:31
F Makefile.in 1ff85c27d4350c74118341024e8a4fb2a04a3a43
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/func.c 33bbce6acaf9578ac99aa1f689968ccaf2ce43a2
F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
-F src/insert.c e34301f41a69cf59c4d75962b2ca5e1af427b5f0
+F src/insert.c 6a61c6d1ef17396d0e87e555806653fddab0b084
F src/main.c 945f9b6855007b28a6c910584d1ca5adff92d821
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c 080238f03015057879cdf53bc4af9e497f2ba724
F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
F test/in.test 22de8a3eb27265aab723adc513bea0e76bef70c6
F test/index.test 90ef4c426865f15937858bd433cc82b9c11af913
-F test/insert.test 5697ba098e4d8a6f0151f281b7e39dec9c439e05
+F test/insert.test e73709f2fee30e003ce131e7ca66ad3dcfac662a
F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f
F test/intpkey.test 39f49fd993350f7f3ab255e5cfbf9a09d8f8800e
F test/ioerr.test 5dbaf09f96b56ee01cf3edd762b96eb4ad2c9ca4
F www/sqlite.tcl 4bd1729e320f5fa9125f0022b281fbe839192125
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P daf7b94017f03638da1ef65830f3762be030b93c
-R 64dc9487d2ea82a1f70ee389c18ab473
+P 3e8889d7ce5e99fc855526fc1bb62ddbe282bfc5
+R 9165bb0816719b739dc59ff58a777b66
U drh
-Z 95bab4cd51ed3d170690377c2faf1c26
+Z 94bfab46c8d22deaac737964000d29aa
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.86 2003/06/01 01:10:33 drh Exp $
+** $Id: insert.c,v 1.87 2003/06/04 12:23:31 drh Exp $
*/
#include "sqliteInt.h"
/* If we have an INTEGER PRIMARY KEY, make sure the primary key
** of the new record does not previously exist. Except, if this
** is an UPDATE and the primary key is not changing, that is OK.
- ** Also, if the conflict resolution policy is REPLACE, then we
- ** can skip this test.
*/
- if( /* (recnoChng || !isUpdate) && pTab->iPKey>=0 */ recnoChng ){
+ if( recnoChng ){
onError = pTab->keyConf;
if( overrideError!=OE_Default ){
onError = overrideError;
onError = OE_Abort;
}
- if( onError!=OE_Replace ){
- if( isUpdate ){
- sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
- sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
- jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
+ if( isUpdate ){
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
+ jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
+ switch( onError ){
+ default: {
+ onError = OE_Abort;
+ /* Fall thru into the next case */
}
- sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
- jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
- switch( onError ){
- default: {
- onError = OE_Abort;
- /* Fall thru into the next case */
- }
- case OE_Rollback:
- case OE_Abort:
- case OE_Fail: {
- sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
- sqliteVdbeChangeP3(v, -1, "PRIMARY KEY must be unique", P3_STATIC);
- break;
- }
- case OE_Ignore: {
- sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
- sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
- break;
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
+ sqliteVdbeChangeP3(v, -1, "PRIMARY KEY must be unique", P3_STATIC);
+ break;
+ }
+ case OE_Replace: {
+ sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
+ if( isUpdate ){
+ sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
}
+ seenReplace = 1;
+ break;
}
- contAddr = sqliteVdbeCurrentAddr(v);
- sqliteVdbeChangeP2(v, jumpInst2, contAddr);
- if( isUpdate ){
- sqliteVdbeChangeP2(v, jumpInst1, contAddr);
- sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
- sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ case OE_Ignore: {
+ assert( seenReplace==0 );
+ sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
}
}
+ contAddr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeChangeP2(v, jumpInst2, contAddr);
+ if( isUpdate ){
+ sqliteVdbeChangeP2(v, jumpInst1, contAddr);
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ }
}
/* Test all UNIQUE constraints by creating entries for each UNIQUE
}else if( onError==OE_Default ){
onError = OE_Abort;
}
+ if( seenReplace ){
+ if( onError==OE_Ignore ) onError = OE_Replace;
+ else if( onError==OE_Fail ) onError = OE_Abort;
+ }
+
/* Check to see if the new index entry will be unique */
sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);