Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improved comments on the constraint checking logic. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | omit-rowid |
Files: | files | file ages | folders |
SHA1: |
141a38a7a636e3e4255b59c27df4a1b3 |
User & Date: | drh 2013-10-29 16:14:35.997 |
Context
2013-10-29
| ||
20:47 | Import the automatic comment generating changes from trunk. (check-in: 8bb51da130 user: drh tags: omit-rowid) | |
16:14 | Improved comments on the constraint checking logic. (check-in: 141a38a7a6 user: drh tags: omit-rowid) | |
2013-10-28
| ||
22:39 | Merge recent fixes from trunk. (check-in: 9f8191d1d8 user: drh tags: omit-rowid) | |
Changes
Changes to src/insert.c.
︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 | ** ** If isUpdate is true and pkChng is non-zero, then pkChng contains ** the address of a range of registers containing the rowid or PRIMARY KEY ** value before the update takes place. isUpdate is true for UPDATEs and ** 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 | | | | 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 | ** ** If isUpdate is true and pkChng is non-zero, then pkChng contains ** the address of a range of registers containing the rowid or PRIMARY KEY ** value before the update takes place. isUpdate is true for UPDATEs and ** 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 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 ** registers identified by aRegIdx[]. No index entry is created for ** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is ** the same as the order of indices on the linked list of indices ** attached to the table. |
︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 | assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; regData = regRowid + 1; /* For WITHOUT ROWID tables, we'll need to know the Index and the cursor ** number for the PRIMARY KEY index */ if( !HasRowid(pTab) ){ pkCur = baseCur+1; pPk = pTab->pIndex; while( ALWAYS(pPk) && pPk->autoIndex!=2 ){ pPk=pPk->pNext; pkCur++; } } | > | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 | assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; regData = regRowid + 1; /* 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 ){ pPk=pPk->pNext; pkCur++; } } |
︙ | ︙ | |||
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 | onError = OE_Abort; } assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Abort: sqlite3MayAbort(pParse); case OE_Rollback: case OE_Fail: { char *zMsg; sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, regData+i); zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); | > | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | onError = OE_Abort; } assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Abort: sqlite3MayAbort(pParse); /* Fall through */ case OE_Rollback: case OE_Fail: { char *zMsg; sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, regData+i); zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); |
︙ | ︙ | |||
1352 1353 1354 1355 1356 1357 1358 | onError, zConsName, P4_DYNAMIC); } sqlite3VdbeResolveLabel(v, allOk); } } #endif /* !defined(SQLITE_OMIT_CHECK) */ | | | 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | onError, zConsName, P4_DYNAMIC); } sqlite3VdbeResolveLabel(v, allOk); } } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* 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. ** ** This block only runs for tables that have a rowid. */ if( pkChng && pkCur==0 ){ int addrRowidOk = sqlite3VdbeMakeLabel(v); |
︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 | */ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; int regR; int idxCur = baseCur+iCur+1; int addrUniqueOk = sqlite3VdbeMakeLabel(v); | | | 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 | */ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; int regR; int idxCur = baseCur+iCur+1; int addrUniqueOk = sqlite3VdbeMakeLabel(v); if( aRegIdx[iCur]==0 ) continue; /* Skip indices that do not change */ if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]); pParse->ckBase = regData; sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk, SQLITE_JUMPIFNULL); pParse->ckBase = 0; |
︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 1494 | else if( onError==OE_Fail ) onError = OE_Abort; } /* Check to see if the new index entry will be unique */ regR = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4Int(v, OP_NoConflict, idxCur, addrUniqueOk, regIdx, pIdx->nKeyCol); if( HasRowid(pTab) ){ | > > > > > | | | > > > > > > | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | else if( onError==OE_Fail ) onError = OE_Abort; } /* Check to see if the new index entry will be unique */ 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 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 ){ /* 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, regOldPk+pPk->aiColumn[i], addrPkConflict, regIdx+i); } 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++){ sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR); sqlite3VdbeAddOp3(v, OP_Ne, regOldPk+pPk->aiColumn[i], addrConflict, regR); } |
︙ | ︙ |