diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 86778d65f0..2ff0bc56fe 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -667,14 +667,14 @@ static void sessionAppendUpdate( u8 *pCsr = p->aRecord; sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); for(i=0; ipConflict = pSelect; + res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); + pIter->pConflict = 0; + sqlite3_reset(pSelect); + }else{ + /* No other row with the new.* primary key. */ + rc = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ){ + res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); + } + } + + return rc; +} + int sqlite3changeset_apply( sqlite3 *db, int nChangeset, @@ -1479,6 +1527,8 @@ int sqlite3changeset_apply( sqlite3_stmt *pSelect = 0; /* SELECT statement */ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3changeset_start(&pIter, nChangeset, pChangeset); while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ int op; @@ -1494,6 +1544,13 @@ int sqlite3changeset_apply( sqlite3_finalize(pInsert); sqlite3_finalize(pSelect); pSelect = pUpdate = pInsert = pDelete = 0; + + if( (rc = sessionSelectRow(db, zTab, nCol, azCol, abPK, &pSelect)) + || (rc = sessionUpdateRow(db, zTab, nCol, azCol, abPK, &pUpdate)) + || (rc = sessionDeleteRow(db, zTab, nCol, azCol, abPK, &pDelete)) + ){ + break; + } } if( op==SQLITE_DELETE ){ @@ -1559,7 +1616,7 @@ int sqlite3changeset_apply( if( rc==SQLITE_OK ){ if( pOld ) sqlite3_bind_value(pUpdate, i*3+1, pOld); sqlite3_bind_int(pUpdate, i*3+2, !!pNew); - if( pNew ) sqlite3_bind_value(pUpdate, i*3+3, pOld); + if( pNew ) sqlite3_bind_value(pUpdate, i*3+3, pNew); } } if( rc==SQLITE_OK ) rc = sqlite3_bind_int(pUpdate, nCol*3+1, 0); @@ -1592,7 +1649,32 @@ int sqlite3changeset_apply( } } }else if( rc==SQLITE_CONSTRAINT ){ - assert(0); + /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if + ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT + ** otherwise. */ + int bPKChange = 0; + + /* Check if the PK has been modified. */ + rc = SQLITE_OK; + for(i=0; ipConflict = pSelect; - res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); - pIter->pConflict = 0; - sqlite3_reset(pSelect); - }else{ - rc = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ){ - res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); - } - } + rc = sessionConstraintConflict( + db, pIter, abPK, pSelect, xConflict, pCtx + ); } } } diff --git a/manifest b/manifest index b3938bacd9..38e0a86e95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3changeset_apply()\sfunction.\sDoes\snot\syet\shandle\sall\scases. -D 2011-03-11T19:05:52 +C Fix\ssome\sissues\swith\sUPDATE\schanges\sin\sthe\ssession\smodule. +D 2011-03-12T17:22:46 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -98,7 +98,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 724a064f0d9a909c12dfb668b42ce007378f352e +F ext/session/sqlite3session.c af63d87b8787c19b4a4b681f77331a9cc13d67af F ext/session/sqlite3session.h 3246613b20857e58f7419e4e26dbe9161677aff0 F ext/session/test_session.c 1b4f278d0ae164e2d02c11f5e1f2df3a2567ba41 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -639,7 +639,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c -F test/session1.test 6a2e0db809e44879cec5314a6fd238ad768d9723 +F test/session1.test 6ec522f3491fbdbf8a5b6c27f50b9e35f24e3dba F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 75d5dff725dbb66d67d56ad042926f1daae56dbe -R 7203b6a6763bad83d70ecbe2db2167c5 +P 2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 +R 222ffce3b378b2ba18950183bb251367 U dan -Z 77d8992b93ad5a2a0231fb47a635b3cb +Z b642b18410bb67d03067201d5612ecd6 diff --git a/manifest.uuid b/manifest.uuid index f741e56cff..b6d1059b89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 \ No newline at end of file +57862efe718fdc93401998f9058511292a0e1a50 \ No newline at end of file diff --git a/test/session1.test b/test/session1.test index 737d796ba3..5706b77bc5 100644 --- a/test/session1.test +++ b/test/session1.test @@ -259,22 +259,29 @@ do_execsql_test 3.3.1 { CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c)); INSERT INTO t4 VALUES(1, 2, 3); INSERT INTO t4 VALUES(4, 5, 6); + INSERT INTO t4 VALUES(7, 8, 9); + INSERT INTO t4 VALUES(10, 11, 12); } do_db2_test 3.3.2 { - CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c)); + CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c)); INSERT INTO t4 VALUES(0, 2, 3); INSERT INTO t4 VALUES(4, 5, 7); + INSERT INTO t4 VALUES(7, 8, 9); + INSERT INTO t4 VALUES(10, 11, 12); } - -do_conflict_test 3.2.3 -tables t4 -sql { +do_conflict_test 3.3.3 -tables t4 -sql { UPDATE t4 SET a = -1 WHERE b = 2; + UPDATE t4 SET a = -1 WHERE b = 5; + UPDATE t4 SET a = NULL WHERE c = 9; + UPDATE t4 SET a = 'x' WHERE b = 11; } -conflicts { - {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 i 2 i 3} {i 0 i 2 i 3}} + {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} + {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} + {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } -do_db2_test 3.3.4 { - SELECT * FROM t4 -} {0 2 3 4 5 7} +do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} +do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} catch { db2 close }