diff options
author | drh <drh@noemail.net> | 2019-10-16 14:56:03 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-10-16 14:56:03 +0000 |
commit | 2da8d6fe7428fb9f82b5224b7adb9c65098e459c (patch) | |
tree | e0fa6a062edffd9cd959ee1b75080a190a2e54a3 /src | |
parent | 4ec3e820a00c5372972a0f1b143b2797b21ffb9f (diff) | |
download | sqlite-2da8d6fe7428fb9f82b5224b7adb9c65098e459c.tar.gz sqlite-2da8d6fe7428fb9f82b5224b7adb9c65098e459c.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/insert.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/src/insert.c b/src/insert.c index d9078b89d..690845a7d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -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; } |