]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Basic DELETE operations now working on WITHOUT ROWID tables.
authordrh <drh@noemail.net>
Fri, 25 Oct 2013 14:46:15 +0000 (14:46 +0000)
committerdrh <drh@noemail.net>
Fri, 25 Oct 2013 14:46:15 +0000 (14:46 +0000)
FossilOrigin-Name: 9eafafa31c4a2bbcf48418743e0fcb17c374e9a6

manifest
manifest.uuid
src/analyze.c
src/build.c
src/delete.c
src/insert.c
src/pragma.c
src/select.c
src/sqliteInt.h
src/vdbe.c
src/where.c

index a44ff79d3969a9d7f482ca8774be78d450e18b83..13d1feecb881d6e82744500afc19d892ed9f9890 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sthe\sinterface\sto\sthe\ssqlite3GenerateRowDelete()\sutility\sso\sthat\sit\sis\nable\sto\shandle\sWITHOUT\sROWID\stables.\s\sThe\simplementation\sstill\sneeds\sto\sbe\s\ncompleted.
-D 2013-10-24T19:48:39.042
+C Basic\sDELETE\soperations\snow\sworking\son\sWITHOUT\sROWID\stables.
+D 2013-10-25T14:46:15.958
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -159,7 +159,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c ee880a4c0deb1c4090a4bbff03adfbf934451f50
+F src/analyze.c b6b115d69adaf0d2fa15001748b12735832fb296
 F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -168,12 +168,12 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 509722ce305471b626d3401c0631a808fd33237b
 F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c f99c6980a258e32e0e0068b04dd8eed6a4af9445
+F src/build.c 4d62e99fa36db1793cc1bed63e6775defdf8c587
 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
-F src/delete.c 3a750695133bf8646124b07cf8a51222110885a6
+F src/delete.c 8b9aa9c935fdd48a7a8ac0eff22c03cb29f12e96
 F src/expr.c 3180b6332072b263f845592e72e92971af562ab0
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 628f81177299660a86e40359b3689b81f517e125
@@ -182,7 +182,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c a188b1abcc80cb835a1a9b76e78190d1516d22bc
+F src/insert.c 71b3d1f551ab8e0ba59fdbaff3feef8d931a424e
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -212,18 +212,18 @@ F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
-F src/pragma.c d6eee7e1b6343996883e5c7e0f60bfad77be2180
+F src/pragma.c 5986f119f6350839a28936fce4e2d6a4c703922c
 F src/prepare.c f47ba2bba7ac5650881ab6c41f6d33a6de1a8d52
 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
 F src/resolve.c e729889b2c7a680ba4aa7296efa72c09369956d8
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
-F src/select.c dbcd2271470b5d074252ea75e2e50f3544638b49
+F src/select.c 8290456f2a516abaf8cbbed5e61944d3082e497e
 F src/shell.c 6f11f0e9ded63d48e306f2c6858c521e568a47bb
 F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h a0834a450cd990eadcb18b790557abfe6dc52270
+F src/sqliteInt.h 674cee6761771e7c1d6446671fcf7daf27b4c0f7
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -279,7 +279,7 @@ F src/update.c 2bb5a267796e6d0177ef5689487c3688de5c309e
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
-F src/vdbe.c cca2c5eb4eb85ff10955c766cc75b78b4cbb5b08
+F src/vdbe.c f7a2fb5d707db64f59ebb2d054485790350f84db
 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
 F src/vdbeInt.h ff57f67aee1ba26a3a47e786533dab155ab6dad6
 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
@@ -292,7 +292,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
-F src/where.c 04217a957c1423dd5f177b21b4ced319bf24b77c
+F src/where.c 512ddbf2884f5560a0ad5b076efc142ad7a07c7b
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1127,7 +1127,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 0e56ba69f0fcd12a5166c32f6e4eacdcc29fba04
-R 23965d1fb428e8ef205e9927049056c2
+P 85daf5174679630474b3bccf3d662d5d56bf00d5
+R 98e4cedace27c103667612897f7b7404
 U drh
-Z 7e96dccb2394803edfe091e61702bf27
+Z b296ee4a843fc7eab50d30ebcbf09f32
index 6c09c1517a0df925375977ab7f582c580fb670f4..ddaf3cea50a51cc5aeb575eaf2695c647be619cd 100644 (file)
@@ -1 +1 @@
-85daf5174679630474b3bccf3d662d5d56bf00d5
\ No newline at end of file
+9eafafa31c4a2bbcf48418743e0fcb17c374e9a6
\ No newline at end of file
index 89d666c05fef370972ad904f034baea9f821327c..d04e51da6e1c05b03b8751e7edd9aa2f9a714f6e 100644 (file)
@@ -244,8 +244,7 @@ static void openStatTable(
   /* Open the sqlite_stat[134] tables for writing. */
   for(i=0; aTable[i].zCols; i++){
     assert( i<ArraySize(aTable) );
-    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
-    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
+    sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
     sqlite3VdbeChangeP5(v, aCreateTbl[i]);
   }
 }
index 5fd6272daba8ad540473b729808f4f28965e7f76..1a85396ca9f349b76bf6bcc4b898a7670f51100c 100644 (file)
@@ -642,8 +642,7 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
 void sqlite3OpenMasterTable(Parse *p, int iDb){
   Vdbe *v = sqlite3GetVdbe(p);
   sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
-  sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
-  sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32);  /* 5 column table */
+  sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
   if( p->nTab==0 ){
     p->nTab = 1;
   }
index b80db6f6b29d7ac9b86fd06241d9c549c067f3ef..35d06aafe817ddc4efc83a0db2b908a3f7a9c536 100644 (file)
@@ -352,18 +352,70 @@ void sqlite3DeleteFrom(
   ){
     assert( !isView );
     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
-    sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
-                      pTab->zName, P4_STATIC);
+    if( HasRowid(pTab) ){
+      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+                        pTab->zName, P4_STATIC);
+    }
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
       assert( pIdx->pSchema==pTab->pSchema );
       sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
     }
   }else
 #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
-  /* The usual case: There is a WHERE clause so we have to scan through
-  ** the table and pick which records to delete.
-  */
-  {
+  if( !HasRowid(pTab) ){
+    /* There is a WHERE clause on a WITHOUT ROWID table.  
+    */
+    Index *pPk;      /* The PRIMARY KEY index on the table */
+    int iPk;         /* First of nPk memory cells holding PRIMARY KEY value */
+    int iEph;        /* Ephemeral table holding all primary key values */
+    int iKey;        /* Key value inserting into iEph */
+    i16 nPk;         /* Number of components of the PRIMARY KEY */
+
+    pPk = sqlite3PrimaryKeyIndex(pTab);
+    assert( pPk!=0 );
+    nPk = pPk->nKeyCol;
+    iPk = pParse->nMem+1;
+    pParse->nMem += nPk;
+    iKey = ++pParse->nMem;
+    iEph = pParse->nTab++;
+
+    sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iEph, nPk, 0, 
+                      (char*)sqlite3IndexKeyinfo(pParse, pPk),
+                      P4_KEYINFO_HANDOFF);
+    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
+    if( pWInfo==0 ) goto delete_from_cleanup;
+    for(i=0; i<nPk; i++){
+      sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, pPk->aiColumn[i], iPk+i);
+    }
+    sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+                      sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+    sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey);
+    sqlite3WhereEnd(pWInfo);
+
+    /* Open cursors for all indices of the table.
+    */
+    sqlite3OpenTableAndIndices(pParse, pTab, iCur, iCur, OP_OpenWrite);
+
+    /* Loop over the primary keys to be deleted. */
+    addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph);
+    sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk);
+
+    /* Delete the row */
+    sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iCur, iPk, 0,
+                             1, OE_Default);
+
+    /* End of the delete loop */
+    sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1);
+    sqlite3VdbeJumpHere(v, addr);
+
+    /* Close the cursors open on the table and its indexes. */
+    for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+      sqlite3VdbeAddOp2(v, OP_Close, pIdx==pPk ? iCur : iCur + i, pIdx->tnum);
+    }
+  }else{
+    /* There is a WHERE clause on a rowid table.  Run a loop that extracts
+    ** all rowids to be deleted into a RowSet.
+    */
     int iRowSet = ++pParse->nMem;   /* Register for rowset of rows to delete */
     int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
     int regRowid;                   /* Actual register containing rowids */
@@ -392,7 +444,7 @@ void sqlite3DeleteFrom(
     ** only effect this statement has is to fire the INSTEAD OF 
     ** triggers.  */
     if( !isView ){
-      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
+      sqlite3OpenTableAndIndices(pParse, pTab, iCur, -1, OP_OpenWrite);
     }
 
     addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
@@ -475,10 +527,7 @@ delete_from_cleanup:
 **       cursor number iCur+i for the i-th index.
 **
 **   3.  The primary key for the row to be deleted must be stored in a
-**       sequence of memory cells starting at iPk.  If nPk==0 then the
-**       primary key is a rowid an uses just one memory cell.  If nPk>0
-**       then a WITHOUT ROWID table is being used and there are nPk elements
-**       of the primary key.
+**       sequence of memory cells starting at iPk. 
 **
 ** This routine generates code to remove both the table record and all 
 ** index entries that point to that record.
@@ -496,6 +545,7 @@ void sqlite3GenerateRowDelete(
   Vdbe *v = pParse->pVdbe;        /* Vdbe */
   int iOld = 0;                   /* First register in OLD.* array */
   int iLabel;                     /* Label resolved to end of generated code */
+  u8 opSeek;                      /* Seek opcode */
 
   /* Vdbe is guaranteed to have been allocated by this stage. */
   assert( v );
@@ -504,7 +554,8 @@ void sqlite3GenerateRowDelete(
   ** (this can happen if a trigger program has already deleted it), do
   ** not attempt to delete it or fire any DELETE triggers.  */
   iLabel = sqlite3VdbeMakeLabel(v);
-  sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iPk);
+  opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+  sqlite3VdbeAddOp4Int(v, opSeek, iCur, iLabel, iPk, nPk);
  
   /* If there are any triggers to fire, allocate a range of registers to
   ** use for the old.* references in the triggers.  */
@@ -539,7 +590,7 @@ void sqlite3GenerateRowDelete(
     ** the BEFORE triggers coded above have already removed the row
     ** being deleted. Do not attempt to delete the row a second time, and 
     ** do not fire AFTER triggers.  */
-    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iPk);
+    sqlite3VdbeAddOp4Int(v, opSeek, iCur, iLabel, iPk, nPk);
 
     /* Do FK processing. This call checks that any FK constraints that
     ** refer to this table (i.e. constraints attached to other tables) 
@@ -600,28 +651,22 @@ void sqlite3GenerateRowIndexDelete(
   int iCur,          /* Cursor number for the table */
   int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
 ){
-  int i, iPk = 0;
+  int i;
   Index *pIdx;
   int r1;
   int iPartIdxLabel;
   Vdbe *v = pParse->pVdbe;
   Index *pPk;
 
-  pPk = sqlite3PrimaryKeyIndex(pTab);
+  pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
-    if( pIdx==pPk ){ iPk = iCur+i; continue; }
+    if( pIdx==pPk ) continue;
     r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 1, &iPartIdxLabel);
     sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1,
                       pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
     sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   }
-  if( iPk ){
-    r1 = sqlite3GenerateIndexKey(pParse, pPk, iCur, 0, 1, &iPartIdxLabel);
-    sqlite3VdbeAddOp3(v, OP_IdxDelete, iPk, r1,
-                      pPk->uniqNotNull ? pPk->nKeyCol : pPk->nColumn);
-    sqlite3VdbeResolveLabel(v, iPartIdxLabel);
-  }
 }
 
 /*
@@ -677,7 +722,7 @@ int sqlite3GenerateIndexKey(
       sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+j);
     }else{
       sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
-      sqlite3ColumnDefault(v, pTab, idx, -1);
+      sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
     }
   }
   if( regOut ){
index 29eb264b3aa3bea9c5a2c8ec088678aef6f847a4..c3d3af72358f44ab27e7a61730e5dacebb8eba50 100644 (file)
@@ -36,8 +36,7 @@ void sqlite3OpenTable(
   assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
   sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
   if( HasRowid(pTab) ){
-    sqlite3VdbeAddOp4(v, opcode, iCur, pTab->tnum, iDb,
-                      SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
+    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
     VdbeComment((v, "%s", pTab->zName));
   }else if( opcode==OP_OpenRead ){
     Index *pPk = sqlite3PrimaryKeyIndex(pTab);
@@ -825,7 +824,7 @@ void sqlite3Insert(
     int nIdx;
 
     baseCur = pParse->nTab - withoutRowid;
-    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
+    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, -1, OP_OpenWrite);
     aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
     if( aRegIdx==0 ){
       goto insert_cleanup;
@@ -1411,7 +1410,7 @@ void sqlite3GenerateConstraintChecks(
     }
 
     /* Create a key for accessing the index entry */
-    regIdx = sqlite3GetTempRange(pParse, pIdx->nKeyCol+1);
+    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
     for(i=0; i<pIdx->nColumn; i++){
       i16 idx = pIdx->aiColumn[i];
       if( idx<0 || idx==pTab->iPKey ){
@@ -1444,9 +1443,7 @@ void sqlite3GenerateConstraintChecks(
     /* Check to see if the new index entry will be unique */
     regR = sqlite3GetTempReg(pParse);
     sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
-    j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
-                           regR, SQLITE_INT_TO_PTR(regIdx),
-                           P4_INT32);
+    j3 = sqlite3VdbeAddOp4Int(v, OP_IsUnique, baseCur+iCur+1, 0, regR, regIdx);
     sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nKeyCol+1);
 
     /* Generate code that executes if the new index entry is not unique */
@@ -1582,6 +1579,7 @@ int sqlite3OpenTableAndIndices(
   Parse *pParse,   /* Parsing context */
   Table *pTab,     /* Table to be opened */
   int baseCur,     /* Cursor number assigned to the table */
+  int pkCur,       /* Cursor number for the primary key */
   int op           /* OP_OpenRead or OP_OpenWrite */
 ){
   int i;
@@ -1596,14 +1594,13 @@ int sqlite3OpenTableAndIndices(
   sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
   for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
     KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+    int iCur = (pkCur>=0 && pIdx->autoIndex==2) ? pkCur : i+baseCur;
     assert( pIdx->pSchema==pTab->pSchema );
-    sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
+    sqlite3VdbeAddOp4(v, op, iCur, pIdx->tnum, iDb,
                       (char*)pKey, P4_KEYINFO_HANDOFF);
     VdbeComment((v, "%s", pIdx->zName));
   }
-  if( pParse->nTab<baseCur+i ){
-    pParse->nTab = baseCur+i;
-  }
+  if( pParse->nTab<=i+baseCur ) pParse->nTab = i+baseCur;
   return i-1;
 }
 
index ee85445654fd97e01c2cf321b0deb0754f4f1b0b..d64bcf633f38f80ae3b2c83712b3888c2d95e647 100644 (file)
@@ -1847,7 +1847,7 @@ void sqlite3Pragma(
         sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
         sqlite3VdbeJumpHere(v, addr);
         sqlite3ExprCacheClear(pParse);
-        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
+        sqlite3OpenTableAndIndices(pParse, pTab, 1, -1, OP_OpenRead);
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
           sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
         }
index 3382c26b5d305299264c936020252a0feee61148..c54837ba1dee7d51807c1663ab3e9787339aa054 100644 (file)
@@ -4656,8 +4656,7 @@ int sqlite3Select(
         }
 
         /* Open a read-only cursor, execute the OP_Count, close the cursor. */
-        sqlite3VdbeAddOp4(v, OP_OpenRead, iCsr, iRoot, iDb, 
-              SQLITE_INT_TO_PTR(1), P4_INT32);
+        sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
         if( pKeyInfo ){
           sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
         }
index 99730e4d2a0b4d683b5a90c3b7e3ad7cac2baf61..c99cdb2070b71aed9f6173736ce73f6a57e60d44 100644 (file)
@@ -2920,7 +2920,7 @@ int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                      int*,int,int,int,int,int*);
 void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
-int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
+int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, int);
 void sqlite3BeginWriteOperation(Parse*, int, int);
 void sqlite3MultiWrite(Parse*);
 void sqlite3MayAbort(Parse*);
index 3b35aa8b58358305c89221dd32bb7f032d4438ea..d9f01837ee559e14ea0ef8f5108798527882de8d 100644 (file)
@@ -3681,6 +3681,7 @@ case OP_Found: {        /* jump, in3 */
       break;
     }
     alreadyExists = (res==0);
+    pC->nullRow = 1-alreadyExists;
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
   }
@@ -3781,15 +3782,14 @@ case OP_IsUnique: {        /* jump, in3 */
 
 /* Opcode: NotExists P1 P2 P3 * *
 **
-** Use the content of register P3 as an integer key.  If a record 
-** with that key does not exist in table of P1, then jump to P2. 
-** If the record does exist, then fall through.  The cursor is left 
-** pointing to the record if it exists.
+** P1 is the index of a cursor open on an SQL table btree (with integer
+** keys).  P3 is an integer rowid.  If P1 does not contain a record with
+** rowid P3 then jump immediately to P2.  If P1 does contain a record
+** with rowid P3 then leave the cursor pointing at that record and fall
+** through to the next instruction.
 **
-** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and that P1 is a table whereas
-** NotFound assumes key is a blob constructed from MakeRecord and
-** P1 is an index.
+** The OP_NotFound opcode performs the same operation on index btrees
+** (with arbitrary multi-value keys).
 **
 ** See also: Found, NotFound, IsUnique
 */
index af654e984b34ecbf745ff6dbb75f3d9b80b5448b..dcc034cff12c19d25dfc8d506f7b75d596231331 100644 (file)
@@ -3565,8 +3565,8 @@ static Bitmask codeOneLoopStart(
         k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
       }
-      sqlite3VdbeAddOp4(v, OP_NotFound, iCur, addrCont, iRowidReg, 
-                        SQLITE_INT_TO_PTR(pPk->nKeyCol), P4_INT32);
+      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
+                           iRowidReg, pPk->nKeyCol);
     }
 
     /* Record the instruction used to terminate the loop. Disable 
@@ -4603,7 +4603,7 @@ static int whereLoopAddBtree(
       if( b
        || ( m==0
          && pProbe->bUnordered==0
-         && pProbe->szIdxRow<pTab->szTabRow
+         && (!HasRowid(pTab) || pProbe->szIdxRow<pTab->szTabRow)
          && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
          && sqlite3GlobalConfig.bUseCis
          && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)