/ Check-in [ad90e762]
Login

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

Overview
Comment:Improved comments and variable names in infrastructure routines of UPDATE, DELETE, and INSERT.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-rowid
Files: files | file ages | folders
SHA1: ad90e762e51384ac7c311f08a641419f03f6d3f0
User & Date: drh 2013-10-31 15:37:49
Context
2013-10-31
17:38
Fix issues with quering from an auxiliary index that must refer back to the PRIMARY KEY index of a WITHOUT ROWID table. check-in: cff1f55c user: drh tags: omit-rowid
15:37
Improved comments and variable names in infrastructure routines of UPDATE, DELETE, and INSERT. check-in: ad90e762 user: drh tags: omit-rowid
12:13
Moving UPDATE towards the iDataCur/iIdxCur representation. Still not working for WITHOUT ROWID, though. check-in: deacbd21 user: drh tags: omit-rowid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   519    519   #endif
   520    520   #ifdef pTrigger
   521    521    #undef pTrigger
   522    522   #endif
   523    523   
   524    524   /*
   525    525   ** This routine generates VDBE code that causes a single row of a
   526         -** single table to be deleted.
          526  +** single table to be deleted.  Both the original table entry and
          527  +** all indices are removed.
   527    528   **
   528         -** The VDBE must be in a particular state when this routine is called.
   529         -** These are the requirements:
          529  +** Preconditions:
   530    530   **
   531         -**   1.  iDataCur is an open cursor on the btree that is the primary data
   532         -**       repository for the table.  This will be either the table itself,
          531  +**   1.  iDataCur is an open cursor on the btree that is the canonical data
          532  +**       store for the table.  (This will be either the table itself,
   533    533   **       in the case of a rowid table, or the PRIMARY KEY index in the case
   534         -**       of a WITHOUT ROWID table.
          534  +**       of a WITHOUT ROWID table.)
   535    535   **
   536    536   **   2.  Read/write cursors for all indices of pTab must be open as
   537    537   **       cursor number iIdxCur+i for the i-th index.
   538    538   **
   539    539   **   3.  The primary key for the row to be deleted must be stored in a
   540    540   **       sequence of nPk memory cells starting at iPk. 
   541         -**
   542         -** This routine generates code to remove both the table record and all 
   543         -** index entries that point to that record.
   544    541   */
   545    542   void sqlite3GenerateRowDelete(
   546    543     Parse *pParse,     /* Parsing context */
   547    544     Table *pTab,       /* Table containing the row to be deleted */
   548    545     Trigger *pTrigger, /* List of triggers to (potentially) fire */
   549    546     int iDataCur,      /* Cursor from which column data is extracted */
   550    547     int iIdxCur,       /* First index cursor */
................................................................................
   556    553     Vdbe *v = pParse->pVdbe;        /* Vdbe */
   557    554     int iOld = 0;                   /* First register in OLD.* array */
   558    555     int iLabel;                     /* Label resolved to end of generated code */
   559    556     u8 opSeek;                      /* Seek opcode */
   560    557   
   561    558     /* Vdbe is guaranteed to have been allocated by this stage. */
   562    559     assert( v );
   563         -  VdbeModuleComment((v, "BEGIN: GenerateRowDelete(%d,%d,%d,%d)",
          560  +  VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
   564    561                            iDataCur, iIdxCur, iPk, (int)nPk));
   565    562   
   566    563     /* Seek cursor iCur to the row to delete. If this row no longer exists 
   567    564     ** (this can happen if a trigger program has already deleted it), do
   568    565     ** not attempt to delete it or fire any DELETE triggers.  */
   569    566     iLabel = sqlite3VdbeMakeLabel(v);
   570    567     opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
................................................................................
   632    629         TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
   633    630     );
   634    631   
   635    632     /* Jump here if the row had already been deleted before any BEFORE
   636    633     ** trigger programs were invoked. Or if a trigger program throws a 
   637    634     ** RAISE(IGNORE) exception.  */
   638    635     sqlite3VdbeResolveLabel(v, iLabel);
   639         -  VdbeModuleComment((v, "END: GenerateRowDelete()"));
          636  +  VdbeModuleComment((v, "END: GenRowDel()"));
   640    637   }
   641    638   
   642    639   /*
   643    640   ** This routine generates VDBE code that causes the deletion of all
   644         -** index entries associated with a single row of a single table.
          641  +** index entries associated with a single row of a single table, pTab
   645    642   **
   646         -** The VDBE must be in a particular state when this routine is called.
   647         -** These are the requirements:
          643  +** Preconditions:
   648    644   **
   649         -**   1.  A read/write cursor "iDataCur" pointing to canonical storage
   650         -**       tree for the table pTab, which will be either the table itself
          645  +**   1.  A read/write cursor "iDataCur" must be open on the canonical storage
          646  +**       btree for the table pTab.  (This will be either the table itself
   651    647   **       for rowid tables or to the primary key index for WITHOUT ROWID
   652         -**       tables.
          648  +**       tables.)
   653    649   **
   654    650   **   2.  Read/write cursors for all indices of pTab must be open as
   655         -**       cursor number iIdxCur+i for the i-th index.
          651  +**       cursor number iIdxCur+i for the i-th index.  (The pTab->pIndex
          652  +**       index is the 0-th index.)
   656    653   **
   657         -**   3.  The "iDataCur" cursor must be pointing to the row that is to be
   658         -**       deleted.
          654  +**   3.  The "iDataCur" cursor must be already be positioned on the row
          655  +**       that is to be deleted.
   659    656   */
   660    657   void sqlite3GenerateRowIndexDelete(
   661    658     Parse *pParse,     /* Parsing and code generating context */
   662    659     Table *pTab,       /* Table containing the row to be deleted */
   663    660     int iDataCur,      /* Cursor of table holding data. */
   664    661     int iIdxCur,       /* First index cursor */
   665    662     int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
   666    663   ){
   667         -  int i;
   668         -  Index *pIdx;
   669         -  int r1;
   670         -  int iPartIdxLabel;
   671         -  Vdbe *v = pParse->pVdbe;
   672         -  Index *pPk;
          664  +  int i;             /* Index loop counter */
          665  +  int r1;            /* Register holding an index key */
          666  +  int iPartIdxLabel; /* Jump destination for skipping partial index entries */
          667  +  Index *pIdx;       /* Current index */
          668  +  Vdbe *v;           /* The prepared statement under construction */
          669  +  Index *pPk;        /* PRIMARY KEY index, or NULL for rowid tables */
   673    670   
          671  +  v = pParse->pVdbe;
   674    672     pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
   675    673     for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
          674  +    assert( iIdxCur+i!=iDataCur || pPk==pIdx );
   676    675       if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
   677    676       if( pIdx==pPk ) continue;
   678    677       r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
   679    678       sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
   680    679                         pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
   681    680       sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   682    681     }

Changes to src/insert.c.

  1119   1119    #undef pTrigger
  1120   1120   #endif
  1121   1121   #ifdef tmask
  1122   1122    #undef tmask
  1123   1123   #endif
  1124   1124   
  1125   1125   /*
  1126         -** Generate code to do constraint checks prior to an INSERT or an UPDATE.
  1127         -**
  1128         -** The input is a range of consecutive registers as follows:
  1129         -**
  1130         -**    1.  The rowid of the row after the update, or NULL
  1131         -**        for WITHOUT ROWID tables.
  1132         -**
  1133         -**    2.  The data in the first column of the entry after the update.
  1134         -**
  1135         -**    i.  Data from middle columns...
  1136         -**
  1137         -**    N.  The data in the last column of the entry after the update.
  1138         -**
  1139         -** The regRowid parameter is the index of the register containing (1).
  1140         -**
  1141         -** If isUpdate is true and pkChng is non-zero, then pkChng contains
  1142         -** the address of a range of registers containing the rowid or PRIMARY KEY
  1143         -** value before the update takes place. isUpdate is true for UPDATEs and
  1144         -** false for INSERTs. If isUpdate is false then a non-zero pkChng 
  1145         -** indicates that the rowid was explicitly specified as part of the
  1146         -** INSERT statement. If pkChng is false, it means that  the rowid is
  1147         -** computed automatically in an insert and is therefore guaranteed to
  1148         -** be unique. The pkChng parameter is always false for inserts
  1149         -** into a WITHOUT ROWID table.
  1150         -**
  1151         -** The code generated by this routine should store new index entries into
         1126  +** Generate code to do constraint checks prior to an INSERT or an UPDATE
         1127  +** on table pTab.
         1128  +**
         1129  +** The regNewData parameter is the first register in a range that contains
         1130  +** the data to be inserted or the data after the update.  There will be
         1131  +** pTab->nCol+1 registers in this range.  The first register (the one
         1132  +** that regNewData points to) will contain the new rowid, or NULL in the
         1133  +** case of a WITHOUT ROWID table.  The second register in the range will
         1134  +** contain the content of the first table column.  The third register will
         1135  +** contain the content of the second table column.  And so forth.
         1136  +**
         1137  +** For an UPDATE (isUpdate!=0), if pkChng is non-zero then it contains
         1138  +** the address of a range of registers containing the rowid and table
         1139  +** data from before the change.  In other words, pkChng is like 
         1140  +** regNewData except that it describes the row before the update rather
         1141  +** than afterwards.  If pkChng is zero, that means that the rowid does 
         1142  +** not change (for a normal rowid table) or the PRIMARY KEY does not
         1143  +** change (for a WITHOUT ROWID table) in which case the old data is
         1144  +** not needed.
         1145  +**
         1146  +** For an INSERT (isUpdate==0), pkChng is just a boolean that indicates
         1147  +** whether or not the rowid was explicitly specified as part of the
         1148  +** INSERT statement.  If pkChng is zero, it means that the either rowid
         1149  +** is computed automatically or that the table is a WITHOUT ROWID table
         1150  +** and has no rowid.  On an INSERT, pkChng will only be true if the
         1151  +** INSERT statement provides an integer value for either the rowid
         1152  +** column or its INTEGER PRIMARY KEY alias.
         1153  +**
         1154  +** The code generated by this routine will store new index entries into
  1152   1155   ** registers identified by aRegIdx[].  No index entry is created for
  1153   1156   ** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
  1154   1157   ** the same as the order of indices on the linked list of indices
  1155         -** attached to the table.
         1158  +** at pTab->pIndex.
         1159  +**
         1160  +** The caller must have already opened writeable cursors on the main
         1161  +** table and all applicable indices (that is to say, all indices for which
         1162  +** aRegIdx[] is not zero).  iDataCur is the cursor for the main table when
         1163  +** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
         1164  +** index when operating on a WITHOUT ROWID table.  iIdxCur is the cursor
         1165  +** for the first index in the pTab->pIndex list.  Cursors for other indices
         1166  +** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
  1156   1167   **
  1157   1168   ** This routine also generates code to check constraints.  NOT NULL,
  1158   1169   ** CHECK, and UNIQUE constraints are all checked.  If a constraint fails,
  1159   1170   ** then the appropriate action is performed.  There are five possible
  1160   1171   ** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
  1161   1172   **
  1162   1173   **  Constraint type  Action       What Happens
  1163   1174   **  ---------------  ----------   ----------------------------------------
  1164   1175   **  any              ROLLBACK     The current transaction is rolled back and
  1165         -**                                sqlite3_exec() returns immediately with a
         1176  +**                                sqlite3_step() returns immediately with a
  1166   1177   **                                return code of SQLITE_CONSTRAINT.
  1167   1178   **
  1168   1179   **  any              ABORT        Back out changes from the current command
  1169   1180   **                                only (do not do a complete rollback) then
  1170         -**                                cause sqlite3_exec() to return immediately
         1181  +**                                cause sqlite3_step() to return immediately
  1171   1182   **                                with SQLITE_CONSTRAINT.
  1172   1183   **
  1173         -**  any              FAIL         Sqlite3_exec() returns immediately with a
         1184  +**  any              FAIL         Sqlite3_step() returns immediately with a
  1174   1185   **                                return code of SQLITE_CONSTRAINT.  The
  1175   1186   **                                transaction is not rolled back and any
  1176         -**                                prior changes are retained.
         1187  +**                                changes to prior rows are retained.
  1177   1188   **
  1178         -**  any              IGNORE       The record number and data is popped from
  1179         -**                                the stack and there is an immediate jump
  1180         -**                                to label ignoreDest.
         1189  +**  any              IGNORE       The attempt in insert or update the current
         1190  +**                                row is skipped, without throwing an error.
         1191  +**                                Processing continues with the next row.
         1192  +**                                (There is an immediate jump to ignoreDest.)
  1181   1193   **
  1182   1194   **  NOT NULL         REPLACE      The NULL value is replace by the default
  1183   1195   **                                value for that column.  If the default value
  1184   1196   **                                is NULL, the action is the same as ABORT.
  1185   1197   **
  1186   1198   **  UNIQUE           REPLACE      The other row that conflicts with the row
  1187   1199   **                                being inserted is removed.
................................................................................
  1188   1200   **
  1189   1201   **  CHECK            REPLACE      Illegal.  The results in an exception.
  1190   1202   **
  1191   1203   ** Which action to take is determined by the overrideError parameter.
  1192   1204   ** Or if overrideError==OE_Default, then the pParse->onError parameter
  1193   1205   ** is used.  Or if pParse->onError==OE_Default then the onError value
  1194   1206   ** for the constraint is used.
  1195         -**
  1196         -** The calling routine must open a read/write cursor for pTab with
  1197         -** cursor number "baseCur".  All indices of pTab must also have open
  1198         -** read/write cursors with cursor number baseCur+i for the i-th cursor.
  1199         -** Except, if there is no possibility of a REPLACE action then
  1200         -** cursors do not need to be open for indices where aRegIdx[i]==0.
  1201   1207   */
  1202   1208   void sqlite3GenerateConstraintChecks(
  1203         -  Parse *pParse,      /* The parser context */
  1204         -  Table *pTab,        /* the table into which we are inserting */
  1205         -  int iDataCur,       /* Cursor of the canonical data tree */
  1206         -  int iIdxCur,        /* First index cursor */
  1207         -  int regRowid,       /* First register in a range holding values to insert */
  1208         -  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  1209         -  int pkChng,         /* Non-zero if the rowid or PRIMARY KEY changed */
  1210         -  int isUpdate,       /* True for UPDATE, False for INSERT */
  1211         -  int overrideError,  /* Override onError to this if not OE_Default */
  1212         -  int ignoreDest,     /* Jump to this label on an OE_Ignore resolution */
  1213         -  int *pbMayReplace   /* OUT: Set to true if constraint may cause a replace */
         1209  +  Parse *pParse,       /* The parser context */
         1210  +  Table *pTab,         /* The table being inserted or updated */
         1211  +  int iDataCur,        /* Canonical data cursor (main table or PK index) */
         1212  +  int iIdxCur,         /* First index cursor */
         1213  +  int regNewData,      /* First register in a range holding values to insert */
         1214  +  int *aRegIdx,        /* Register used by each index.  0 for unused indices */
         1215  +  int pkChng,          /* Non-zero if the rowid or PRIMARY KEY changed */
         1216  +  int isUpdate,        /* True for UPDATE, False for INSERT */
         1217  +  int overrideError,   /* Override onError to this if not OE_Default */
         1218  +  int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
         1219  +  int *pbMayReplace    /* OUT: Set to true if constraint may cause a replace */
  1214   1220   ){
  1215         -  int i;              /* loop counter */
  1216         -  Vdbe *v;            /* VDBE under constrution */
  1217         -  int nCol;           /* Number of columns */
  1218         -  int onError;        /* Conflict resolution strategy */
  1219         -  int j1;             /* Addresss of jump instruction */
  1220         -  int ix;             /* Index loop counter */
  1221         -  int regData;        /* Register containing first data column */
         1221  +  int i;               /* loop counter */
         1222  +  Vdbe *v;             /* VDBE under constrution */
         1223  +  int nCol;            /* Number of columns */
         1224  +  int onError;         /* Conflict resolution strategy */
         1225  +  int j1;              /* Addresss of jump instruction */
         1226  +  int ix;              /* Index loop counter */
  1222   1227     Index *pIdx;         /* Pointer to one of the indices */
  1223   1228     Index *pPk = 0;      /* The PRIMARY KEY index */
  1224   1229     sqlite3 *db;         /* Database connection */
  1225   1230     int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  1226         -  int regOldPk;        /* Previous rowid or PRIMARY KEY value */
         1231  +  int regOldData;      /* Previous rowid and table data */
  1227   1232     int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
  1228   1233   
  1229         -  regOldPk = (pkChng && isUpdate) ? pkChng : regRowid;
         1234  +  regOldData = (pkChng && isUpdate) ? pkChng : regNewData;
  1230   1235     db = pParse->db;
  1231   1236     v = sqlite3GetVdbe(pParse);
  1232   1237     assert( v!=0 );
  1233   1238     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1234   1239     nCol = pTab->nCol;
  1235         -  regData = regRowid + 1;
  1236         -
  1237         -  /* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
  1238         -  ** number for the PRIMARY KEY index */
         1240  +  
         1241  +  /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
         1242  +  ** normal rowid tables.  nPkField is the number of key fields in the 
         1243  +  ** pPk index or 1 for a rowid table.  In other words, nPkField is the
         1244  +  ** number of fields in the true primary key of the table. */
  1239   1245     if( HasRowid(pTab) ){
  1240   1246       pPk = 0;
  1241   1247       nPkField = 1;
  1242   1248     }else{
  1243   1249       pPk = sqlite3PrimaryKeyIndex(pTab);
  1244   1250       nPkField = pPk->nKeyCol;
  1245   1251     }
  1246   1252   
  1247   1253     /* Record that this module has started */
  1248   1254     VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
  1249         -                     iDataCur, iIdxCur, regRowid, pkChng, regOldPk));
         1255  +                     iDataCur, iIdxCur, regNewData, regOldData, pkChng));
  1250   1256   
  1251   1257     /* Test all NOT NULL constraints.
  1252   1258     */
  1253   1259     for(i=0; i<nCol; i++){
  1254   1260       if( i==pTab->iPKey ){
  1255   1261         continue;
  1256   1262       }
................................................................................
  1270   1276         case OE_Abort:
  1271   1277           sqlite3MayAbort(pParse);
  1272   1278           /* Fall through */
  1273   1279         case OE_Rollback:
  1274   1280         case OE_Fail: {
  1275   1281           char *zMsg;
  1276   1282           sqlite3VdbeAddOp3(v, OP_HaltIfNull,
  1277         -                          SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
         1283  +                          SQLITE_CONSTRAINT_NOTNULL, onError, regNewData+1+i);
  1278   1284           zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
  1279   1285                                 pTab->zName, pTab->aCol[i].zName);
  1280   1286           sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
  1281   1287           break;
  1282   1288         }
  1283   1289         case OE_Ignore: {
  1284         -        sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
         1290  +        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
  1285   1291           break;
  1286   1292         }
  1287   1293         default: {
  1288   1294           assert( onError==OE_Replace );
  1289         -        j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
  1290         -        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
         1295  +        j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
         1296  +        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
  1291   1297           sqlite3VdbeJumpHere(v, j1);
  1292   1298           break;
  1293   1299         }
  1294   1300       }
  1295   1301     }
  1296   1302   
  1297   1303     /* Test all CHECK constraints
  1298   1304     */
  1299   1305   #ifndef SQLITE_OMIT_CHECK
  1300   1306     if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
  1301   1307       ExprList *pCheck = pTab->pCheck;
  1302         -    pParse->ckBase = regData;
         1308  +    pParse->ckBase = regNewData+1;
  1303   1309       onError = overrideError!=OE_Default ? overrideError : OE_Abort;
  1304   1310       for(i=0; i<pCheck->nExpr; i++){
  1305   1311         int allOk = sqlite3VdbeMakeLabel(v);
  1306   1312         sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
  1307   1313         if( onError==OE_Ignore ){
  1308   1314           sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
  1309   1315         }else{
................................................................................
  1320   1326         sqlite3VdbeResolveLabel(v, allOk);
  1321   1327       }
  1322   1328     }
  1323   1329   #endif /* !defined(SQLITE_OMIT_CHECK) */
  1324   1330   
  1325   1331     /* If there is an INTEGER PRIMARY KEY, make sure the primary key
  1326   1332     ** of the new record does not previously exist.  Except, if this
  1327         -  ** is an UPDATE and the primary key is not changing, that is OK.
         1333  +  ** is an UPDATE and the primary key is not changing, then obviously
         1334  +  ** it is OK for the previous rowid to exist in that case.
  1328   1335     **
  1329   1336     ** This block only runs for tables that have a rowid.
  1330   1337     */
  1331   1338     if( pkChng && pPk==0 ){
  1332   1339       int addrRowidOk = sqlite3VdbeMakeLabel(v);
  1333   1340   
  1334   1341       onError = pTab->keyConf;
................................................................................
  1335   1342       if( overrideError!=OE_Default ){
  1336   1343         onError = overrideError;
  1337   1344       }else if( onError==OE_Default ){
  1338   1345         onError = OE_Abort;
  1339   1346       }
  1340   1347   
  1341   1348       if( isUpdate ){
  1342         -      sqlite3VdbeAddOp3(v, OP_Eq, regRowid, addrRowidOk, pkChng);
         1349  +      sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
  1343   1350       }
  1344         -    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regRowid);
         1351  +    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
  1345   1352       switch( onError ){
  1346   1353         default: {
  1347   1354           onError = OE_Abort;
  1348   1355           /* Fall thru into the next case */
  1349   1356         }
  1350   1357         case OE_Rollback:
  1351   1358         case OE_Abort:
................................................................................
  1380   1387           Trigger *pTrigger = 0;
  1381   1388           if( db->flags&SQLITE_RecTriggers ){
  1382   1389             pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
  1383   1390           }
  1384   1391           if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
  1385   1392             sqlite3MultiWrite(pParse);
  1386   1393             sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
  1387         -                                   regRowid, 1, 0, OE_Replace);
         1394  +                                   regNewData, 1, 0, OE_Replace);
  1388   1395           }else if( pTab->pIndex ){
  1389   1396             sqlite3MultiWrite(pParse);
  1390   1397             sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
  1391   1398           }
  1392   1399           seenReplace = 1;
  1393   1400           break;
  1394   1401         }
................................................................................
  1402   1409     }
  1403   1410   
  1404   1411     /* Test all UNIQUE constraints by creating entries for each UNIQUE
  1405   1412     ** index and making sure that duplicate entries do not already exist.
  1406   1413     ** Compute the revised record entries for indices as we go.
  1407   1414     */
  1408   1415     for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
  1409         -    int regIdx;
  1410         -    int regR;
  1411         -    int iThisCur = iIdxCur+ix;
  1412         -    int addrUniqueOk = sqlite3VdbeMakeLabel(v);
         1416  +    int regIdx;          /* Range of registers hold conent for pIdx */
         1417  +    int regR;            /* Range of registers holding conflicting PK */
         1418  +    int iThisCur;        /* Cursor for this UNIQUE index */
         1419  +    int addrUniqueOk;    /* Jump here if the UNIQUE constraint is satisfied */
  1413   1420   
  1414   1421       if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
         1422  +    iThisCur = iIdxCur+ix;
         1423  +    addrUniqueOk = sqlite3VdbeMakeLabel(v);
  1415   1424   
  1416   1425       if( pIdx->pPartIdxWhere ){
  1417   1426         sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
  1418         -      pParse->ckBase = regData;
         1427  +      pParse->ckBase = regNewData+1;
  1419   1428         sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
  1420   1429                            SQLITE_JUMPIFNULL);
  1421   1430         pParse->ckBase = 0;
  1422   1431       }
  1423   1432   
  1424         -    /* Create a key for accessing the index entry */
         1433  +    /* Create a record for this index entry as it should appear after
         1434  +    ** the insert or update. */
  1425   1435       regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
  1426   1436       for(i=0; i<pIdx->nColumn; i++){
  1427         -      i16 iField = pIdx->aiColumn[i];
         1437  +      int iField = pIdx->aiColumn[i];
  1428   1438         if( iField<0 || iField==pTab->iPKey ){
  1429         -        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
         1439  +        iField = regNewData;
  1430   1440         }else{
  1431         -        sqlite3VdbeAddOp2(v, OP_SCopy, regData+iField, regIdx+i);
         1441  +        iField += regNewData + 1;
  1432   1442         }
         1443  +      sqlite3VdbeAddOp2(v, OP_SCopy, iField, regIdx+i);
  1433   1444       }
  1434   1445       sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
  1435   1446       sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
  1436   1447       VdbeComment((v, "for %s", pIdx->zName));
  1437   1448       sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
  1438   1449   
  1439         -    /* Find out what action to take in case there is an indexing conflict */
         1450  +    /* Find out what action to take in case there is a uniqueness conflict */
  1440   1451       onError = pIdx->onError;
  1441   1452       if( onError==OE_None ){ 
  1442   1453         sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
  1443   1454         sqlite3VdbeResolveLabel(v, addrUniqueOk);
  1444   1455         continue;  /* pIdx is not a UNIQUE index */
  1445   1456       }
  1446   1457       if( overrideError!=OE_Default ){
................................................................................
  1454   1465       }
  1455   1466       
  1456   1467       /* Check to see if the new index entry will be unique */
  1457   1468       regR = sqlite3GetTempRange(pParse, nPkField);
  1458   1469       sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
  1459   1470                            regIdx, pIdx->nKeyCol);
  1460   1471       if( HasRowid(pTab) ){
         1472  +      sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
  1461   1473         /* Conflict only if the rowid of the existing index entry
  1462   1474         ** is different from old-rowid */
  1463         -      sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
  1464         -      sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldPk);
         1475  +      sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
  1465   1476       }else{
  1466   1477         /* Extract the PRIMARY KEY from the end of the index entry and
  1467   1478         ** store it in register regR..regR+nPk-1 */
  1468   1479         for(i=0; i<pPk->nKeyCol; i++){
  1469   1480           int x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
  1470   1481           sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
  1471   1482           VdbeComment((v, "%s.%s", pTab->zName,
................................................................................
  1474   1485         if( pIdx->autoIndex==2 ){
  1475   1486           /* For a PRIMARY KEY index on a WITHOUT ROWID table, always conflict
  1476   1487           ** on an INSERT.  On an UPDATE, only conflict if the PRIMARY KEY
  1477   1488           ** has changed. */
  1478   1489           if( isUpdate ){
  1479   1490             int addrPkConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
  1480   1491             for(i=0; i<pPk->nKeyCol-1; i++){
  1481         -            sqlite3VdbeAddOp3(v, OP_Ne, regOldPk+pPk->aiColumn[i]+1,
         1492  +            sqlite3VdbeAddOp3(v, OP_Ne, regOldData+pPk->aiColumn[i]+1,
  1482   1493                                 addrPkConflict, regIdx+i);
  1483   1494             }
  1484         -          sqlite3VdbeAddOp3(v, OP_Eq, regOldPk+pPk->aiColumn[i]+1,
         1495  +          sqlite3VdbeAddOp3(v, OP_Eq, regOldData+pPk->aiColumn[i]+1,
  1485   1496                               addrUniqueOk, regIdx+i);
  1486   1497           }
  1487   1498         }else{
  1488   1499           /* For a UNIQUE index on a WITHOUT ROWID table, conflict only if the
  1489   1500           ** PRIMARY KEY value of the match is different from the old PRIMARY KEY
  1490   1501           ** value from before the update. */
  1491   1502           int addrConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
  1492   1503           assert( pIdx->nKeyCol + pPk->nKeyCol == pIdx->nColumn );
  1493   1504           for(i=0; i<pPk->nKeyCol-1; i++){
  1494   1505             sqlite3VdbeAddOp3(v, OP_Ne,
  1495         -                            regOldPk+pPk->aiColumn[i], addrConflict, regR+i);
         1506  +                           regOldData+pPk->aiColumn[i]+1, addrConflict, regR+i);
  1496   1507           }
  1497   1508           sqlite3VdbeAddOp3(v, OP_Eq,
  1498         -                          regOldPk+pPk->aiColumn[i], addrUniqueOk, regR+i);
         1509  +                          regOldData+pPk->aiColumn[i]+1, addrUniqueOk, regR+i);
  1499   1510         }
  1500   1511       }
  1501   1512       sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
  1502   1513   
  1503   1514       /* Generate code that executes if the new index entry is not unique */
  1504   1515       assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
  1505   1516           || onError==OE_Ignore || onError==OE_Replace );
................................................................................
  1556   1567     }
  1557   1568     VdbeModuleComment((v, "END: GenCnstCks()"));
  1558   1569   }
  1559   1570   
  1560   1571   /*
  1561   1572   ** This routine generates code to finish the INSERT or UPDATE operation
  1562   1573   ** that was started by a prior call to sqlite3GenerateConstraintChecks.
  1563         -** A consecutive range of registers starting at regRowid contains the
         1574  +** A consecutive range of registers starting at regNewData contains the
  1564   1575   ** rowid and the content to be inserted.
  1565   1576   **
  1566   1577   ** The arguments to this routine should be the same as the first six
  1567   1578   ** arguments to sqlite3GenerateConstraintChecks.
  1568   1579   */
  1569   1580   void sqlite3CompleteInsertion(
  1570   1581     Parse *pParse,      /* The parser context */
  1571   1582     Table *pTab,        /* the table into which we are inserting */
  1572   1583     int iDataCur,       /* Cursor of the canonical data source */
  1573   1584     int iIdxCur,        /* First index cursor */
  1574         -  int regRowid,       /* Range of content */
         1585  +  int regNewData,     /* Range of content */
  1575   1586     int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  1576   1587     int isUpdate,       /* True for UPDATE, False for INSERT */
  1577   1588     int appendBias,     /* True if this is likely to be an append */
  1578   1589     int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
  1579   1590   ){
  1580         -  int i;
  1581         -  Vdbe *v;
  1582         -  Index *pIdx;
  1583         -  u8 pik_flags;
  1584         -  int regData;
  1585         -  int regRec;
         1591  +  Vdbe *v;            /* Prepared statements under construction */
         1592  +  Index *pIdx;        /* An index being inserted or updated */
         1593  +  u8 pik_flags;       /* flag values passed to the btree insert */
         1594  +  int regData;        /* Content registers (after the rowid) */
         1595  +  int regRec;         /* Register holding assemblied record for the table */
         1596  +  int i;              /* Loop counter */
  1586   1597   
  1587   1598     v = sqlite3GetVdbe(pParse);
  1588   1599     assert( v!=0 );
  1589   1600     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1590   1601     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
  1591   1602       if( aRegIdx[i]==0 ) continue;
  1592   1603       if( pIdx->pPartIdxWhere ){
................................................................................
  1594   1605       }
  1595   1606       sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
  1596   1607       if( useSeekResult ){
  1597   1608         sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  1598   1609       }
  1599   1610     }
  1600   1611     if( !HasRowid(pTab) ) return;
  1601         -  regData = regRowid + 1;
         1612  +  regData = regNewData + 1;
  1602   1613     regRec = sqlite3GetTempReg(pParse);
  1603   1614     sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
  1604   1615     sqlite3TableAffinityStr(v, pTab);
  1605   1616     sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
  1606   1617     if( pParse->nested ){
  1607   1618       pik_flags = 0;
  1608   1619     }else{
................................................................................
  1611   1622     }
  1612   1623     if( appendBias ){
  1613   1624       pik_flags |= OPFLAG_APPEND;
  1614   1625     }
  1615   1626     if( useSeekResult ){
  1616   1627       pik_flags |= OPFLAG_USESEEKRESULT;
  1617   1628     }
  1618         -  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regRowid);
         1629  +  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
  1619   1630     if( !pParse->nested ){
  1620   1631       sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
  1621   1632     }
  1622   1633     sqlite3VdbeChangeP5(v, pik_flags);
  1623   1634   }
  1624   1635   
  1625   1636   /*

Changes to src/pragma.c.

  1913   1913             sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
  1914   1914             jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
  1915   1915             sqlite3VdbeAddOp0(v, OP_Halt);
  1916   1916             sqlite3VdbeJumpHere(v, jmp4);
  1917   1917             sqlite3VdbeJumpHere(v, jmp2);
  1918   1918             sqlite3VdbeResolveLabel(v, jmp3);
  1919   1919           }
  1920         -        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
         1920  +        sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
  1921   1921           sqlite3VdbeJumpHere(v, loopTop-1);
  1922   1922   #ifndef SQLITE_OMIT_BTREECOUNT
  1923   1923           sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, 
  1924   1924                        "wrong # of entries in index ", P4_STATIC);
  1925   1925           for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
  1926   1926             if( pPk==pIdx ) continue;
  1927   1927             addr = sqlite3VdbeCurrentAddr(v);

Changes to test/without_rowid1.test.

    55     55   } {1 {columns c, a are not unique}}
    56     56   
    57     57   # REPLACE INTO works, however.
    58     58   #
    59     59   do_execsql_test without_rowid1-1.22 {
    60     60     REPLACE INTO t1 VALUES('dynamic','phone','flipper','harvard');
    61     61     SELECT *, '|' FROM t1 ORDER BY c, a;
    62         -} {}
           62  +} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic phone flipper harvard | journal sherman gamma patriot |}
    63     63   
    64     64   finish_test