mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Fixes to the logic for constraint check reordering during upsert.
Improved comments on constraint check bytecode. Add an assert that prevents the same label from being resolved more than once. FossilOrigin-Name: 1ddbb0ff5586ef5ca987e4309979f24f95eea883ed68937094a2db2d61e75657
This commit is contained in:
28
src/insert.c
28
src/insert.c
@@ -1507,7 +1507,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
|
||||
/* Check to see if the new rowid already exists in the table. Skip
|
||||
** the following conflict logic if it does not. */
|
||||
VdbeNoopComment((v, "constraint checks for ROWID"));
|
||||
VdbeNoopComment((v, "uniqueness check for ROWID"));
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
||||
VdbeCoverage(v);
|
||||
|
||||
@@ -1603,17 +1603,21 @@ void sqlite3GenerateConstraintChecks(
|
||||
int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
|
||||
|
||||
if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
|
||||
VdbeNoopComment((v, "constraint checks for %s", pIdx->zName));
|
||||
if( pUpIdx==pIdx ){
|
||||
addrUniqueOk = sAddr.upsertBtm;
|
||||
upsertBypass = sqlite3VdbeGoto(v, 0);
|
||||
VdbeComment((v, "Skip upsert subroutine"));
|
||||
sqlite3VdbeResolveLabel(v, sAddr.upsertTop);
|
||||
}else{
|
||||
addrUniqueOk = sqlite3VdbeMakeLabel(v);
|
||||
}
|
||||
VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
|
||||
if( bAffinityDone==0 ){
|
||||
sqlite3TableAffinity(v, pTab, regNewData+1);
|
||||
bAffinityDone = 1;
|
||||
}
|
||||
iThisCur = iIdxCur+ix;
|
||||
if( pUpIdx==pIdx ){
|
||||
addrUniqueOk = sAddr.upsertBtm;
|
||||
}else{
|
||||
addrUniqueOk = sqlite3VdbeMakeLabel(v);
|
||||
}
|
||||
|
||||
|
||||
/* Skip partial indices for which the WHERE clause is not true */
|
||||
if( pIdx->pPartIdxWhere ){
|
||||
@@ -1683,9 +1687,6 @@ void sqlite3GenerateConstraintChecks(
|
||||
}else{
|
||||
onError = OE_Update; /* DO UPDATE */
|
||||
}
|
||||
upsertBypass = sqlite3VdbeGoto(v, 0);
|
||||
VdbeComment((v, "Upsert bypass"));
|
||||
sqlite3VdbeResolveLabel(v, sAddr.upsertTop);
|
||||
}
|
||||
|
||||
/* Collision detection may be omitted if all of the following are true:
|
||||
@@ -1802,10 +1803,13 @@ void sqlite3GenerateConstraintChecks(
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, addrUniqueOk);
|
||||
if( pUpIdx==pIdx ){
|
||||
sqlite3VdbeJumpHere(v, upsertBypass);
|
||||
}else{
|
||||
sqlite3VdbeResolveLabel(v, addrUniqueOk);
|
||||
}
|
||||
sqlite3ExprCachePop(pParse);
|
||||
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
|
||||
if( pUpIdx==pIdx ) sqlite3VdbeJumpHere(v, upsertBypass);
|
||||
|
||||
}
|
||||
reorderConstraintChecks(v, &sAddr);
|
||||
|
||||
Reference in New Issue
Block a user