/ Check-in [141a38a7]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved comments on the constraint checking logic.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-rowid
Files: files | file ages | folders
SHA1: 141a38a7a636e3e4255b59c27df4a1b3d6f26e97
User & Date: drh 2013-10-29 16:14:35
Context
2013-10-29
20:47
Import the automatic comment generating changes from trunk. check-in: 8bb51da1 user: drh tags: omit-rowid
16:14
Improved comments on the constraint checking logic. check-in: 141a38a7 user: drh tags: omit-rowid
2013-10-28
22:39
Merge recent fixes from trunk. check-in: 9f8191d1 user: drh tags: omit-rowid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/insert.c.

  1178   1178   **
  1179   1179   ** If isUpdate is true and pkChng is non-zero, then pkChng contains
  1180   1180   ** the address of a range of registers containing the rowid or PRIMARY KEY
  1181   1181   ** value before the update takes place. isUpdate is true for UPDATEs and
  1182   1182   ** false for INSERTs. If isUpdate is false then a non-zero pkChng 
  1183   1183   ** indicates that the rowid was explicitly specified as part of the
  1184   1184   ** INSERT statement. If pkChng is false, it means that  the rowid is
  1185         -** computed automatically in an insert or that the rowid value is not 
  1186         -** modified by an update. The pkChng parameter is always false for inserts
         1185  +** computed automatically in an insert and is therefore guaranteed to
         1186  +** be unique. The pkChng parameter is always false for inserts
  1187   1187   ** into a WITHOUT ROWID table.
  1188   1188   **
  1189   1189   ** The code generated by this routine should store new index entries into
  1190   1190   ** registers identified by aRegIdx[].  No index entry is created for
  1191   1191   ** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
  1192   1192   ** the same as the order of indices on the linked list of indices
  1193   1193   ** attached to the table.
................................................................................
  1271   1271     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1272   1272     nCol = pTab->nCol;
  1273   1273     regData = regRowid + 1;
  1274   1274   
  1275   1275     /* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
  1276   1276     ** number for the PRIMARY KEY index */
  1277   1277     if( !HasRowid(pTab) ){
         1278  +    assert( pkChng==0 || isUpdate!=0 );
  1278   1279       pkCur = baseCur+1;
  1279   1280       pPk = pTab->pIndex;
  1280   1281       while( ALWAYS(pPk) && pPk->autoIndex!=2 ){
  1281   1282         pPk=pPk->pNext;
  1282   1283         pkCur++;
  1283   1284       }
  1284   1285     }
................................................................................
  1300   1301         onError = OE_Abort;
  1301   1302       }
  1302   1303       assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
  1303   1304           || onError==OE_Ignore || onError==OE_Replace );
  1304   1305       switch( onError ){
  1305   1306         case OE_Abort:
  1306   1307           sqlite3MayAbort(pParse);
         1308  +        /* Fall through */
  1307   1309         case OE_Rollback:
  1308   1310         case OE_Fail: {
  1309   1311           char *zMsg;
  1310   1312           sqlite3VdbeAddOp3(v, OP_HaltIfNull,
  1311   1313                             SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
  1312   1314           zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
  1313   1315                                 pTab->zName, pTab->aCol[i].zName);
................................................................................
  1352   1354                                 onError, zConsName, P4_DYNAMIC);
  1353   1355         }
  1354   1356         sqlite3VdbeResolveLabel(v, allOk);
  1355   1357       }
  1356   1358     }
  1357   1359   #endif /* !defined(SQLITE_OMIT_CHECK) */
  1358   1360   
  1359         -  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
         1361  +  /* If there is an INTEGER PRIMARY KEY, make sure the primary key
  1360   1362     ** of the new record does not previously exist.  Except, if this
  1361   1363     ** is an UPDATE and the primary key is not changing, that is OK.
  1362   1364     **
  1363   1365     ** This block only runs for tables that have a rowid.
  1364   1366     */
  1365   1367     if( pkChng && pkCur==0 ){
  1366   1368       int addrRowidOk = sqlite3VdbeMakeLabel(v);
................................................................................
  1442   1444     */
  1443   1445     for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
  1444   1446       int regIdx;
  1445   1447       int regR;
  1446   1448       int idxCur = baseCur+iCur+1;
  1447   1449       int addrUniqueOk = sqlite3VdbeMakeLabel(v);
  1448   1450   
  1449         -    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */
         1451  +    if( aRegIdx[iCur]==0 ) continue;  /* Skip indices that do not change */
  1450   1452   
  1451   1453       if( pIdx->pPartIdxWhere ){
  1452   1454         sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
  1453   1455         pParse->ckBase = regData;
  1454   1456         sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
  1455   1457                            SQLITE_JUMPIFNULL);
  1456   1458         pParse->ckBase = 0;
................................................................................
  1487   1489         else if( onError==OE_Fail ) onError = OE_Abort;
  1488   1490       }
  1489   1491       
  1490   1492       /* Check to see if the new index entry will be unique */
  1491   1493       regR = sqlite3GetTempReg(pParse);
  1492   1494       sqlite3VdbeAddOp4Int(v, OP_NoConflict, idxCur, addrUniqueOk,
  1493   1495                            regIdx, pIdx->nKeyCol);
         1496  +#if 0
         1497  +    if( !isUpdate ){
         1498  +      /* A pre-existing row is always a conflict on an insert */
         1499  +    }else
         1500  +#endif
  1494   1501       if( HasRowid(pTab) ){
  1495         -      /* Conflict only if the rowid of the existing entry with the matching
  1496         -      ** key is different from old-rowid */
         1502  +      /* Conflict only if the rowid of the existing index entry
         1503  +      ** is different from old-rowid */
  1497   1504         sqlite3VdbeAddOp2(v, OP_IdxRowid, idxCur, regR);
  1498   1505         sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldPk);
  1499   1506       }else if( pIdx->autoIndex==2 ){
  1500         -      /* If there is a matching entry on the PRIMARY KEY index ... */
         1507  +      /* For PRIMARY KEY index on a WITHOUT ROWID table, conflict only
         1508  +      ** if the PRIMARY KEY has changed.  If the PRIMARY KEY is unchanged,
         1509  +      ** then the matching entry is just the original row that is being
         1510  +      ** modified. */
  1501   1511         int addrPkConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
  1502   1512         for(i=0; i<pPk->nKeyCol-1; i++){
  1503   1513           sqlite3VdbeAddOp3(v, OP_Ne,
  1504   1514                             regOldPk+pPk->aiColumn[i], addrPkConflict, regIdx+i);
  1505   1515         }
  1506   1516         sqlite3VdbeAddOp3(v, OP_Eq,
  1507   1517                           regOldPk+pPk->aiColumn[i], addrUniqueOk, regIdx+i);
  1508   1518       }else{
         1519  +      /* For a UNIQUE index on a WITHOUT ROWID table, conflict only if the
         1520  +      ** PRIMARY KEY value of the match is different from the old PRIMARY KEY
         1521  +      ** value from before the update. */
  1509   1522         int addrConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol*2;
  1510   1523         assert( pIdx->nKeyCol + pPk->nKeyCol == pIdx->nColumn );
  1511   1524         for(i=0; i<pPk->nKeyCol-1; i++){
  1512   1525           sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR);
  1513   1526           sqlite3VdbeAddOp3(v, OP_Ne,
  1514   1527                             regOldPk+pPk->aiColumn[i], addrConflict, regR);
  1515   1528         }