diff options
Diffstat (limited to 'ext/session')
-rw-r--r-- | ext/session/session_common.tcl | 4 | ||||
-rw-r--r-- | ext/session/sessioninvert.test | 24 | ||||
-rw-r--r-- | ext/session/sqlite3session.c | 6 |
3 files changed, 31 insertions, 3 deletions
diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index ceffdad4b..c52ac457c 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 49205f6b2..b7c157d2e 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 78cc5875c..cb350ab2d 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); |