mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
If an AFTER DELETE trigger fires when a conflict row is deleted by REPLACE
conflict resolution, make sure the conflict really has been resolved and that the trigger did not recreate the row before continuing. Ticket [a8a4847a2d96f5de] FossilOrigin-Name: eea1e7aa57e74c4329003f4550168e2aed9e33d2301a3ba84b10781a9cebbc1b
This commit is contained in:
@@ -1582,6 +1582,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
sqlite3MultiWrite(pParse);
|
||||
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
|
||||
regNewData, 1, 0, OE_Replace, 1, -1);
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
||||
sqlite3RowidConstraint(pParse, OE_Abort, pTab);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
assert( HasRowid(pTab) );
|
||||
@@ -1829,16 +1831,23 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
default: {
|
||||
Trigger *pTrigger = 0;
|
||||
int bRetryConstraintCheck = 0;
|
||||
assert( onError==OE_Replace );
|
||||
if( db->flags&SQLITE_RecTriggers ){
|
||||
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
|
||||
}
|
||||
if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
|
||||
sqlite3MultiWrite(pParse);
|
||||
bRetryConstraintCheck = 1;
|
||||
}
|
||||
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
|
||||
regR, nPkField, 0, OE_Replace,
|
||||
(pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
|
||||
if( bRetryConstraintCheck ){
|
||||
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
|
||||
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
|
||||
sqlite3UniqueConstraint(pParse, OE_Abort, pIdx);
|
||||
}
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user