mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Improved comments on the constraint checking logic.
FossilOrigin-Name: 141a38a7a636e3e4255b59c27df4a1b3d6f26e97
This commit is contained in:
27
src/insert.c
27
src/insert.c
@@ -1182,8 +1182,8 @@ static int sqlite3PrimaryKeyRegisters(Parse *pParse, Index *pPk, int regFirst){
|
||||
** false for INSERTs. If isUpdate is false then a non-zero pkChng
|
||||
** indicates that the rowid was explicitly specified as part of the
|
||||
** INSERT statement. If pkChng is false, it means that the rowid is
|
||||
** computed automatically in an insert or that the rowid value is not
|
||||
** modified by an update. The pkChng parameter is always false for inserts
|
||||
** computed automatically in an insert and is therefore guaranteed to
|
||||
** be unique. The pkChng parameter is always false for inserts
|
||||
** into a WITHOUT ROWID table.
|
||||
**
|
||||
** The code generated by this routine should store new index entries into
|
||||
@@ -1275,6 +1275,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
/* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
|
||||
** number for the PRIMARY KEY index */
|
||||
if( !HasRowid(pTab) ){
|
||||
assert( pkChng==0 || isUpdate!=0 );
|
||||
pkCur = baseCur+1;
|
||||
pPk = pTab->pIndex;
|
||||
while( ALWAYS(pPk) && pPk->autoIndex!=2 ){
|
||||
@@ -1304,6 +1305,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
switch( onError ){
|
||||
case OE_Abort:
|
||||
sqlite3MayAbort(pParse);
|
||||
/* Fall through */
|
||||
case OE_Rollback:
|
||||
case OE_Fail: {
|
||||
char *zMsg;
|
||||
@@ -1356,7 +1358,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_CHECK) */
|
||||
|
||||
/* If we have an INTEGER PRIMARY KEY, make sure the primary key
|
||||
/* If there is an INTEGER PRIMARY KEY, make sure the primary key
|
||||
** of the new record does not previously exist. Except, if this
|
||||
** is an UPDATE and the primary key is not changing, that is OK.
|
||||
**
|
||||
@@ -1446,7 +1448,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
int idxCur = baseCur+iCur+1;
|
||||
int addrUniqueOk = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
|
||||
if( aRegIdx[iCur]==0 ) continue; /* Skip indices that do not change */
|
||||
|
||||
if( pIdx->pPartIdxWhere ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
|
||||
@@ -1491,13 +1493,21 @@ void sqlite3GenerateConstraintChecks(
|
||||
regR = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp4Int(v, OP_NoConflict, idxCur, addrUniqueOk,
|
||||
regIdx, pIdx->nKeyCol);
|
||||
#if 0
|
||||
if( !isUpdate ){
|
||||
/* A pre-existing row is always a conflict on an insert */
|
||||
}else
|
||||
#endif
|
||||
if( HasRowid(pTab) ){
|
||||
/* Conflict only if the rowid of the existing entry with the matching
|
||||
** key is different from old-rowid */
|
||||
/* Conflict only if the rowid of the existing index entry
|
||||
** is different from old-rowid */
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, idxCur, regR);
|
||||
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldPk);
|
||||
}else if( pIdx->autoIndex==2 ){
|
||||
/* If there is a matching entry on the PRIMARY KEY index ... */
|
||||
/* For PRIMARY KEY index on a WITHOUT ROWID table, conflict only
|
||||
** if the PRIMARY KEY has changed. If the PRIMARY KEY is unchanged,
|
||||
** then the matching entry is just the original row that is being
|
||||
** modified. */
|
||||
int addrPkConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
|
||||
for(i=0; i<pPk->nKeyCol-1; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Ne,
|
||||
@@ -1506,6 +1516,9 @@ void sqlite3GenerateConstraintChecks(
|
||||
sqlite3VdbeAddOp3(v, OP_Eq,
|
||||
regOldPk+pPk->aiColumn[i], addrUniqueOk, regIdx+i);
|
||||
}else{
|
||||
/* For a UNIQUE index on a WITHOUT ROWID table, conflict only if the
|
||||
** PRIMARY KEY value of the match is different from the old PRIMARY KEY
|
||||
** value from before the update. */
|
||||
int addrConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol*2;
|
||||
assert( pIdx->nKeyCol + pPk->nKeyCol == pIdx->nColumn );
|
||||
for(i=0; i<pPk->nKeyCol-1; i++){
|
||||
|
||||
Reference in New Issue
Block a user