1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Experimental change to the handling of foreign key constraint violations when applying a changeset: all foreign keys, immediate and deferred, are deferred until the end of the transaction (or sub-transaction) opened by the sqlite3changeset_apply(). A single call to the conflict-handler (if any) is made if any FK constraint violations are still present in the database at this point. The conflict-handler may choose to rollback the changeset, or to apply it, constraint violations and all.

FossilOrigin-Name: 1d44e5d3c2b1dc958442f9114a960b256e002ed3
This commit is contained in:
dan
2013-07-03 19:53:05 +00:00
parent 35e2858e98
commit cb3e4b797e
16 changed files with 391 additions and 136 deletions

View File

@@ -878,7 +878,7 @@ case OP_Halt: {
p->rc = rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
assert( rc==SQLITE_OK || db->nDeferredCons>0 );
assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
goto vdbe_return;
@@ -2737,6 +2737,7 @@ case OP_Savepoint: {
pNew->pNext = db->pSavepoint;
db->pSavepoint = pNew;
pNew->nDeferredCons = db->nDeferredCons;
pNew->nDeferredImmCons = db->nDeferredImmCons;
}
}
}else{
@@ -2824,6 +2825,7 @@ case OP_Savepoint: {
}
}else{
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
if( !isTransaction ){
@@ -2978,6 +2980,7 @@ case OP_Transaction: {
** counter. If the statement transaction needs to be rolled back,
** the value of this counter needs to be restored too. */
p->nStmtDefCons = db->nDeferredCons;
p->nStmtDefImmCons = db->nDeferredImmCons;
}
}
break;
@@ -5319,7 +5322,9 @@ case OP_Param: { /* out2-prerelease */
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
if( pOp->p1 ){
if( db->flags & SQLITE_DeferForeignKeys ){
db->nDeferredImmCons += pOp->p2;
}else if( pOp->p1 ){
db->nDeferredCons += pOp->p2;
}else{
p->nFkConstraint += pOp->p2;
@@ -5340,9 +5345,9 @@ case OP_FkCounter: {
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
if( db->nDeferredCons==0 ) pc = pOp->p2-1;
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}else{
if( p->nFkConstraint==0 ) pc = pOp->p2-1;
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}
break;
}