From: dan Date: Wed, 17 Jun 2020 14:14:11 +0000 (+0000) Subject: Fix a problem with retrying constraint failures within sqlite3changeset_apply() calls... X-Git-Tag: version-3.33.0~115 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d237bfab14b5bfa2036f588ddd77662e837ca91;p=thirdparty%2Fsqlite.git Fix a problem with retrying constraint failures within sqlite3changeset_apply() calls with the SQLITE_CHANGESET_INVERT flag is set. FossilOrigin-Name: d73e857b833dfc29400049ca7f01ca465f980466e3aa67214c3c5e5573181419 --- diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index ceffdad4ba..c52ac457c0 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -172,8 +172,8 @@ proc compare_db {db1 db2} { set data1 [$db1 eval $sql] set data2 [$db2 eval $sql] if {$data1 != $data2} { - puts "$data1" - puts "$data2" + puts "$db1: $data1" + puts "$db2: $data2" error "table $tbl data mismatch" } } diff --git a/ext/session/sessioninvert.test b/ext/session/sessioninvert.test index 49205f6b26..b7c157d2e7 100644 --- a/ext/session/sessioninvert.test +++ b/ext/session/sessioninvert.test @@ -155,5 +155,29 @@ do_test 3.2 { compare_db db db2 } {} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 4.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(4, 'four'); +} + +do_invert_test 4.1 { + DELETE FROM t1; + INSERT INTO t1 VALUES(1, 'two'); + INSERT INTO t1 VALUES(2, 'five'); + INSERT INTO t1 VALUES(3, 'one'); + INSERT INTO t1 VALUES(4, 'three'); +} { + {UPDATE t1 0 X. {i 1 t two} {{} {} t one}} + {UPDATE t1 0 X. {i 2 t five} {{} {} t two}} + {UPDATE t1 0 X. {i 3 t one} {{} {} t three}} + {UPDATE t1 0 X. {i 4 t three} {{} {} t four}} +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 78cc5875cd..cb350ab2d4 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3479,6 +3479,7 @@ struct SessionApplyCtx { u8 *abPK; /* Boolean array - true if column is in PK */ int bStat1; /* True if table is sqlite_stat1 */ int bDeferConstraints; /* True to defer constraints */ + int bInvertConstraints; /* Invert when iterating constraints buffer */ SessionBuffer constraints; /* Deferred constraints are stored here */ SessionBuffer rebase; /* Rebase information (if any) here */ u8 bRebaseStarted; /* If table header is already in rebase */ @@ -4251,7 +4252,9 @@ static int sessionRetryConstraints( SessionBuffer cons = pApply->constraints; memset(&pApply->constraints, 0, sizeof(SessionBuffer)); - rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0); + rc = sessionChangesetStart( + &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints + ); if( rc==SQLITE_OK ){ size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); int rc2; @@ -4318,6 +4321,7 @@ static int sessionChangesetApply( pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); + sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); diff --git a/manifest b/manifest index 1c62e7fa0f..08766c3872 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,13 @@ B fd5abb1a7b5a55127d5c0d5ff448020d8bccab44e4f5afe1eb88fc19578af735 -C Add\snew\sfile\sdoc/wal-lock.md,\scontaining\snotes\son\swal-mode\sblocking\slocks. -D 2020-06-16T19:51:56.187 +C Fix\sa\sproblem\swith\sretrying\sconstraint\sfailures\swithin\ssqlite3changeset_apply()\scalls\swith\sthe\sSQLITE_CHANGESET_INVERT\sflag\sis\sset. +D 2020-06-17T14:14:11.666 F configure f594931bd7b23dad12db96b81e1dba43b41b30a4560d6eb008014e3d9f1617e8 x F configure.ac 13e4ecf89214c3aa0ba099a9e0178f13f03261ace627126737d8cee240ec5c1c F doc/wal-lock.md 781726aaba20bafeceb7ba9f91d5c98c6731691b30c954e37cf0b49a053d461d F ext/fts3/fts3.c ad3416827315a5bef8d0e23d8e90bf29940fbec23ee78aa0c5d3caed85072dec +F ext/session/session_common.tcl f613174665456b2d916ae8df3e5735092a1c1712f36f46840172e9a01e8cc53e +F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 +F ext/session/sqlite3session.c fc8c6c13dc0456943ff24abf574ced10418eec66a548c97d3eafbebe9fc5e908 F src/alter.c b8ffe4acd48b4fe793d01901f28fd4f3b037854a0e99f0c977738556c31b9d2b F src/btree.c f3a4479b0dba3a59a1d156d973be41fc1ccb3dbdb69151c4c62a791d86c9ffe2 F src/build.c 8245e69aa1a2f8b67e76203fdbaa9f88deccd89b5ed41f7097c202b920484fd0 @@ -29,7 +32,7 @@ F test/where.test f5e62453537e5b335b69f3b09f8a02ce3328289fad5d866e25371284b837d7 F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa F test/window1.test 9d7f4990e5b36d95af93b189da4aa75216c6690ce95cced3c8b6d3234be51c2c F test/without_rowid3.test 96426a6c9a2a5cf62bbe55ea1ad038eaaf4bf743f40a1ad517233b8e5a3d4339 -P f3bd689336fecaa1e2928b826c6aedb0178d322f4633ac429dd1ae6fbc08e7f1 -R 20b349aca00331020aae5b577df5847f +P c6b1d3a385751633d3ac1853e13d5e847185dd6432fb8b960a4080f61357c08c +R 1c31ce9492a1552b437bdc6502d1c44a U dan -Z 109a0399a3983dd11a4da8f364e04d14 +Z 7c6b85ada24210dbbf9cdb2233bd591e diff --git a/manifest.uuid b/manifest.uuid index 863cc43bb7..47d4d0968d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6b1d3a385751633d3ac1853e13d5e847185dd6432fb8b960a4080f61357c08c \ No newline at end of file +d73e857b833dfc29400049ca7f01ca465f980466e3aa67214c3c5e5573181419 \ No newline at end of file