From: drh Date: Mon, 4 Nov 2013 15:23:25 +0000 (+0000) Subject: Correctly handle changing counting when inserting and deleting on X-Git-Tag: version-3.8.2~137^2~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6546af1480cf7e8484b0e655f5421bdb5ed8d9d6;p=thirdparty%2Fsqlite.git Correctly handle changing counting when inserting and deleting on WITHOUT ROWID tables. Add more FOREIGN KEY test cases. FossilOrigin-Name: d072bcd0a8692d590c13c2bf458454c10c12a3e2 --- diff --git a/manifest b/manifest index 64a0c82308..a055d7d345 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\shandle\sself-referential\sforeign\skeys\son\sWITHOUT\sROWID\stables. -D 2013-11-04T13:56:00.182 +C Correctly\shandle\schanging\scounting\swhen\sinserting\sand\sdeleting\son\nWITHOUT\sROWID\stables.\s\sAdd\smore\sFOREIGN\sKEY\stest\scases. +D 2013-11-04T15:23:25.268 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 605be39dc72a56768a55ee7245d92774ed7ae343 +F src/delete.c f4e0dc7b804fc0eb1a040e3e6ac7aaf341834e39 F src/expr.c ecc2b98eb75fe5533cfdfcca6b04cfe5f0c6001f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 24bbd27a963c8e022a79579964885cc638567c88 @@ -182,7 +182,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 62c2997b6884e2f7ba8daa486f663ae885c4b479 +F src/insert.c faa58c9978001f67b3fcb4e0fb588c7852c05483 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -279,7 +279,7 @@ F src/update.c 94d63d3e06b09df3618655a841dc95d5b9466dc6 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 3492f312ed979b146296289ecbd8851a7891a830 +F src/vdbe.c 8bab888622f007944e24da09680c3517800a7a91 F src/vdbe.h c18a2dd91c838601b867a214e43c5f66d5d001ba F src/vdbeInt.h f2fa3ceccceeb757773921fb08af7c6e9f3caa1c F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1078,7 +1078,7 @@ F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b F test/without_rowid1.test de6f9e6ea36a7e4b087e44084abed3c0456f7dfe F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 -F test/without_rowid3.test a755f3eef1e0d20e1bb9c9da00ebfa889d7b0bd7 +F test/without_rowid3.test 8ad27697fbe319d0e858b790c0ec53abf4f8617b F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1130,7 +1130,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1315d9109c7105f4a62bb2d43ca6948d41245129 -R 64353718434772b548f438b0d879d511 +P af128862ab6008df9dda1ee90f93f9efd629e259 +R 4ec154138cf082ccfc3c655c3c0bf739 U drh -Z 7428ec81c08443a72ec23535cca14f03 +Z 13548943f156687a0863838255585229 diff --git a/manifest.uuid b/manifest.uuid index 55191530be..2720e2400a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af128862ab6008df9dda1ee90f93f9efd629e259 \ No newline at end of file +d072bcd0a8692d590c13c2bf458454c10c12a3e2 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 522b378e87..21bbb02819 100644 --- a/src/delete.c +++ b/src/delete.c @@ -393,6 +393,9 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey); + if( db->flags & SQLITE_CountRows ){ + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + } sqlite3WhereEnd(pWInfo); /* Open cursors for all indices of the table. diff --git a/src/insert.c b/src/insert.c index d49c199f44..3cc88f96f6 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1627,9 +1627,12 @@ void sqlite3CompleteInsertion( sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); - if( useSeekResult ){ - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + pik_flags = 0; + if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; + if( pIdx->autoIndex==2 && !HasRowid(pTab) && pParse->nested==0 ){ + pik_flags |= OPFLAG_NCHANGE; } + if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; regData = regNewData + 1; diff --git a/src/vdbe.c b/src/vdbe.c index 12f3639655..05b0b98e3d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4580,6 +4580,7 @@ case OP_IdxInsert: { /* in2 */ pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); pCrsr = pC->pCursor; + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( ALWAYS(pCrsr!=0) ){ assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); @@ -4600,7 +4601,7 @@ case OP_IdxInsert: { /* in2 */ break; } -/* Opcode: IdxDelete P1 P2 P3 * * +/* Opcode: IdxDelete P1 P2 P3 * P5 ** Synopsis: key=r[P2@P3] ** ** The content of P3 registers starting at register P2 form @@ -4619,6 +4620,7 @@ case OP_IdxDelete: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( ALWAYS(pCrsr!=0) ){ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; diff --git a/test/without_rowid3.test b/test/without_rowid3.test index f2e1040ead..550f318ccb 100644 --- a/test/without_rowid3.test +++ b/test/without_rowid3.test @@ -1391,6 +1391,91 @@ foreach {tn zSchema} { } {1 {foreign key constraint failed}} } +# Additional tests cases using multi-column self-referential +# FOREIGN KEY constraints. +# +drop_all_tables +do_execsql_test without_rowid3-16.4.1.1 { + PRAGMA foreign_keys=ON; + CREATE TABLE t1(a,b,c,d,e,f, + UNIQUE (a,b), + PRIMARY KEY (e,c), + FOREIGN KEY (d,f) REFERENCES t1(e,c) + ) WITHOUT rowid; + INSERT INTO t1 VALUES(1,2,3,5,5,3); + INSERT INTO t1 VALUES(2,3,4,6,6,4); + INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5); + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_execsql_test without_rowid3-16.4.1.2 { + UPDATE t1 SET c=99, f=99 WHERE a=1; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_execsql_test without_rowid3-16.4.1.3 { + UPDATE t1 SET e=876, d=876 WHERE a=2; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_test without_rowid3-16.4.1.4 { + catchsql { + UPDATE t1 SET c=11, e=22 WHERE a=1; + } +} {1 {foreign key constraint failed}} + +do_test without_rowid3-16.4.1.5 { + catchsql { + UPDATE t1 SET d=11, f=22 WHERE a=1; + } +} {1 {foreign key constraint failed}} + +do_execsql_test without_rowid3-16.4.1.6 { + DELETE FROM t1 WHERE a=1; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_execsql_test without_rowid3-16.4.2.1 { + DROP TABLE t1; + CREATE TABLE t1(a,b,c,d,e,f, + PRIMARY KEY (a,b), + UNIQUE (e,c), + FOREIGN KEY (d,f) REFERENCES t1(e,c) + ) WITHOUT rowid; + INSERT INTO t1 VALUES(1,2,3,5,5,3); + INSERT INTO t1 VALUES(2,3,4,6,6,4); + INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5); + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_execsql_test without_rowid3-16.4.2.2 { + UPDATE t1 SET c=99, f=99 WHERE a=1; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_execsql_test without_rowid3-16.4.2.3 { + UPDATE t1 SET e=876, d=876 WHERE a=2; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} + +do_test without_rowid3-16.4.2.4 { + catchsql { + UPDATE t1 SET c=11, e=22 WHERE a=1; + } +} {1 {foreign key constraint failed}} + +do_test without_rowid3-16.4.2.5 { + catchsql { + UPDATE t1 SET d=11, f=22 WHERE a=1; + } +} {1 {foreign key constraint failed}} + +do_execsql_test without_rowid3-16.4.2.6 { + DELETE FROM t1 WHERE a=1; + SELECT *, '|' FROM t1 ORDER BY a, b; +} {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} + + #------------------------------------------------------------------------- # This next block of tests, without_rowid3-17.*, tests that if "PRAGMA count_changes" # is turned on statements that violate immediate FK constraints return