mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Do not check immediate foreign key constraints until the end of the statement. This matches the postgres behaviour.
FossilOrigin-Name: 1a32149cc3c722058f4ed4c81edadeb6ce5bc9e4
This commit is contained in:
@@ -321,6 +321,7 @@ static Op *opIterNext(VdbeOpIter *p){
|
||||
** * OP_Destroy
|
||||
** * OP_VUpdate
|
||||
** * OP_VRename
|
||||
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
|
||||
**
|
||||
** Then check that the value of Parse.mayAbort is true if an
|
||||
** ABORT may be thrown, or false otherwise. Return true if it does
|
||||
@@ -339,6 +340,9 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
while( (pOp = opIterNext(&sIter))!=0 ){
|
||||
int opcode = pOp->opcode;
|
||||
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
|| (opcode==OP_FkCounter && pOp->p1==1 && pOp->p2==0)
|
||||
#endif
|
||||
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
|
||||
&& (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
|
||||
){
|
||||
@@ -1944,10 +1948,11 @@ void sqlite3VdbeMutexArrayEnter(Vdbe *p){
|
||||
** an error message to it. Then return SQLITE_ERROR.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
int sqlite3VdbeCheckDeferred(Vdbe *p){
|
||||
int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
|
||||
sqlite3 *db = p->db;
|
||||
if( db->nDeferredCons ){
|
||||
if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
|
||||
p->rc = SQLITE_CONSTRAINT;
|
||||
p->errorAction = OE_Abort;
|
||||
sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -2029,6 +2034,11 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for immediate foreign key violations. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
sqlite3VdbeCheckFk(p, 0);
|
||||
}
|
||||
|
||||
/* If the auto-commit flag is set and this is the only active writer
|
||||
** VM, then we do either a commit or rollback of the current transaction.
|
||||
@@ -2041,7 +2051,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
&& db->writeVdbeCnt==(p->readOnly==0)
|
||||
){
|
||||
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
|
||||
if( sqlite3VdbeCheckDeferred(p) ){
|
||||
if( sqlite3VdbeCheckFk(p, 1) ){
|
||||
sqlite3BtreeMutexArrayLeave(&p->aMutex);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user