]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Construct secondary indices on WITHOUT ROWID tables.
authordrh <drh@noemail.net>
Wed, 23 Oct 2013 22:23:03 +0000 (22:23 +0000)
committerdrh <drh@noemail.net>
Wed, 23 Oct 2013 22:23:03 +0000 (22:23 +0000)
FossilOrigin-Name: 2c028ddc85cb45746cad6ab0cefd99134fbd50d7

manifest
manifest.uuid
src/build.c
src/delete.c
src/pragma.c
src/sqliteInt.h
src/where.c

index e5b4e806267fc945cf494a6f1ebc6abbb2945614..e5466cac3a20a63802691747f7471c8c49d89de8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Report\san\serror\swhen\strying\sto\sresolve\scolumn\sname\s"rowid"\sin\sa\nWITHOUT\sROWID\stable.
-D 2013-10-23T17:39:41.217
+C Construct\ssecondary\sindices\son\sWITHOUT\sROWID\stables.
+D 2013-10-23T22:23:03.281
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -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 029e1709651df95c75477c334be7bc1ea9332e6d
+F src/build.c 6970691b8d22c6eb2c1ab0078e4d25c939acfdad
 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
-F src/delete.c c1547dbf732c9987d109b6f45729b4a70e14659e
+F src/delete.c 5dcd957b7af5b67b4cce125dd2b580248678db8a
 F src/expr.c 3180b6332072b263f845592e72e92971af562ab0
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 628f81177299660a86e40359b3689b81f517e125
@@ -212,7 +212,7 @@ F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
-F src/pragma.c ab815d27690d24e87c953355a765edb546c47708
+F src/pragma.c 575a4462366b371076dd14bd93df21f325a10995
 F src/prepare.c f47ba2bba7ac5650881ab6c41f6d33a6de1a8d52
 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
@@ -223,7 +223,7 @@ 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 dc7c57e1d792cda4af5a21bc9566a9afe63f977f
+F src/sqliteInt.h 62dee86c51c7b2dc73b0f2cbdfa332a4b79f9bcf
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -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 f9e7662714d776a929683d813a2496fbca8b9087
+F src/where.c 13add0a866a75adb345abfa2ad25585322d472f3
 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 579815fff1737552d2077255862b8f4fd220927c
-R d63ce5fb7a4f24abe25c071303585c0a
+P 36bcc9cb885523fba2f3b0d152de9e08073668c1
+R 5319af9bbb603de112b9787a2a60f8ed
 U drh
-Z 3ecb7889d41fd9bb93bb233d04c44ce3
+Z 289de8cc66e2b52514de0b537df4236c
index 8767ec035bd17c46628cabe85a7f9af2b207da28..aa82b4848ca31e7dbbbcc2594e023db827485eb8 100644 (file)
@@ -1 +1 @@
-36bcc9cb885523fba2f3b0d152de9e08073668c1
\ No newline at end of file
+2c028ddc85cb45746cad6ab0cefd99134fbd50d7
\ No newline at end of file
index 1f6315ec5eaea49cf81c985a0ce9f5d36e498373..0062dd5370387544af5d77e732ad19dc3e243f86 100644 (file)
@@ -748,6 +748,27 @@ int sqlite3CheckObjectName(Parse *pParse, const char *zName){
   return SQLITE_OK;
 }
 
+/*
+** Return the PRIMARY KEY index of a table
+*/
+Index *sqlite3PrimaryKeyIndex(Table *pTab){
+  Index *p;
+  for(p=pTab->pIndex; p && p->autoIndex!=2; p=p->pNext){}
+  return p;
+}
+
+/*
+** Return the column of index pIdx that corresponds to table
+** column iCol.  Return -1 if not found.
+*/
+i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
+  int i;
+  for(i=0; i<pIdx->nColumn; i++){
+    if( iCol==pIdx->aiColumn[i] ) return i;
+  }
+  return -1;
+}
+
 /*
 ** Begin constructing a new table representation in memory.  This is
 ** the first of several action routines that get called in response
@@ -1610,8 +1631,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
     if( pPk==0 ) return;
     pTab->iPKey = -1;
+  }else{
+    pPk = sqlite3PrimaryKeyIndex(pTab);
   }
-  for(pPk=pTab->pIndex; pPk && pPk->autoIndex<2; pPk=pPk->pNext){}
   assert( pPk!=0 );
   nPk = pPk->nKeyCol;
 
@@ -2600,12 +2622,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
     tnum = memRootPage;
   }else{
     tnum = pIndex->tnum;
-    sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
   }
   pKey = sqlite3IndexKeyinfo(pParse, pIndex);
-  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
-                    (char *)pKey, P4_KEYINFO_HANDOFF);
-  sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
 
   /* Open the sorter cursor if we are to use one. */
   iSorter = pParse->nTab++;
@@ -2613,7 +2631,16 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
 
   /* Open the table. Loop through all rows of the table, inserting index
   ** records into the sorter. */
-  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+  if( HasRowid(pTab) ){
+    sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+  }else{
+    Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+    assert( pPk!=0 );
+    assert( pPk->tnum=pTab->tnum );
+    sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pPk->tnum, iDb,
+                     (char*)sqlite3IndexKeyinfo(pParse, pPk),
+                     P4_KEYINFO_HANDOFF);
+  }
   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
   regRecord = sqlite3GetTempReg(pParse);
 
@@ -2622,6 +2649,11 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
   sqlite3VdbeJumpHere(v, addr1);
+  if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
+  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
+                    (char *)pKey, P4_KEYINFO_HANDOFF);
+  sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+
   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
   if( pIndex->onError!=OE_None ){
     int j2 = sqlite3VdbeCurrentAddr(v) + 3;
@@ -2724,7 +2756,9 @@ Index *sqlite3CreateIndex(
   struct ExprList_item *pListItem; /* For looping over pList */
   const Column *pTabCol;           /* A column in the table */
   int nExtra = 0;                  /* Space allocated for zExtra[] */
+  int nExtraCol;                   /* Number of extra columns needed */
   char *zExtra;                    /* Extra space after the Index object */
+  Index *pPk = 0;      /* PRIMARY KEY index for WITHOUT ROWID tables */
 
   assert( pParse->nErr==0 );      /* Never called with prior errors */
   if( db->mallocFailed || IN_DECLARE_VTAB ){
@@ -2776,6 +2810,7 @@ Index *sqlite3CreateIndex(
            pTab->zName);
       goto exit_create_index;
     }
+    if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab);
   }else{
     assert( pName==0 );
     assert( pStart==0 );
@@ -2893,7 +2928,8 @@ Index *sqlite3CreateIndex(
   ** Allocate the index structure. 
   */
   nName = sqlite3Strlen30(zName);
-  pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + 1,
+  nExtraCol = pPk ? pPk->nKeyCol : 1;
+  pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
                                       nName + nExtra + 1, &zExtra);
   if( db->mallocFailed ){
     goto exit_create_index;
@@ -2971,8 +3007,16 @@ Index *sqlite3CreateIndex(
     pIndex->aSortOrder[i] = (u8)requestedSortOrder;
     if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
   }
-  pIndex->aiColumn[i] = -1;
-  pIndex->azColl[i] = "BINARY";
+  if( pPk ){
+    for(j=0; j<pPk->nKeyCol; j++, i++){
+      pIndex->aiColumn[i] = pPk->aiColumn[j];
+      pIndex->azColl[i] = pPk->azColl[j];
+      pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+    }
+  }else{
+    pIndex->aiColumn[i] = -1;
+    pIndex->azColl[i] = "BINARY";
+  }
   sqlite3DefaultRowEst(pIndex);
   if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
 
index 38257a1af159909a4fa8a43053dce345bada0d12..1a38f79e70c8df414a0e0b97bfcfd5aff0cb3b93 100644 (file)
@@ -634,6 +634,7 @@ int sqlite3GenerateIndexKey(
   Table *pTab = pIdx->pTable;
   int regBase;
   int nCol;
+  Index *pPk;
 
   if( piPartIdxLabel ){
     if( pIdx->pPartIdxWhere ){
@@ -645,13 +646,14 @@ int sqlite3GenerateIndexKey(
       *piPartIdxLabel = 0;
     }
   }
-  nCol = pIdx->nKeyCol;
-  regBase = sqlite3GetTempRange(pParse, nCol+1);
-  sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
+  nCol = pIdx->nColumn;
+  regBase = sqlite3GetTempRange(pParse, nCol);
+  pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
   for(j=0; j<nCol; j++){
     i16 idx = pIdx->aiColumn[j];
-    if( idx==pTab->iPKey ){
-      sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
+    if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
+    if( idx<0 || idx==pTab->iPKey ){
+      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+j);
     }else{
       sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
       sqlite3ColumnDefault(v, pTab, idx, -1);
@@ -666,9 +668,9 @@ int sqlite3GenerateIndexKey(
     }else{
       zAff = sqlite3IndexAffinityStr(v, pIdx);
     }
-    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
+    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
     sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
   }
-  sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
+  sqlite3ReleaseTempRange(pParse, regBase, nCol);
   return regBase;
 }
index b6f9ae191c849f1abc5b2f13e8cc8d1973d1b594..21f1e1a720a2e3048ef7b3f9efb47edca4ee5f31 100644 (file)
@@ -1391,8 +1391,7 @@ void sqlite3Pragma(
       int i, k;
       int nHidden = 0;
       Column *pCol;
-      Index *pPk;
-      for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
+      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
       sqlite3VdbeSetNumCols(v, 6);
       pParse->nMem = 6;
       sqlite3CodeVerifySchema(pParse, iDb);
index 0522171ca5981dcac7ba5d57119c7def89484f40..fec5f230b8ec2c475a60cdb54dc6e1afd1f87b6f 100644 (file)
@@ -2774,6 +2774,8 @@ void sqlite3BeginParse(Parse*,int);
 void sqlite3CommitInternalChanges(sqlite3*);
 Table *sqlite3ResultSetOfSelect(Parse*,Select*);
 void sqlite3OpenMasterTable(Parse *, int);
+Index *sqlite3PrimaryKeyIndex(Table*);
+i16 sqlite3ColumnOfIndex(Index*, i16);
 void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
 void sqlite3AddColumn(Parse*,Token*);
 void sqlite3AddNotNull(Parse*, int);
index bccb980b7a20ab1bd06d57067b6062613f71bf4b..b293de4790c66fc01e69d112d2776c46df06f25f 100644 (file)
@@ -2125,6 +2125,8 @@ static void constructAutomaticIndex(
     }
   }
   assert( n==nKeyCol );
+  pIdx->aiColumn[n] = -1;
+  pIdx->azColl[n] = "BINARY";
 
   /* Create the automatic index */
   pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -6113,7 +6115,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
       pIdx = pLevel->u.pCovidx;
     }
     if( pIdx && !db->mallocFailed ){
-      int k, j, last;
+      int k, last;
       VdbeOp *pOp;
 
       last = sqlite3VdbeCurrentAddr(v);
@@ -6122,14 +6124,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
       for(; k<last; k++, pOp++){
         if( pOp->p1!=pLevel->iTabCur ) continue;
         if( pOp->opcode==OP_Column ){
-          for(j=0; j<pIdx->nColumn; j++){
-            if( pOp->p2==pIdx->aiColumn[j] ){
-              pOp->p2 = j;
-              pOp->p1 = pLevel->iIdxCur;
-              break;
-            }
+          i16 x = sqlite3ColumnOfIndex(pIdx, pOp->p2);
+          if( x>=0 ){
+            pOp->p2 = x;
+            pOp->p1 = pLevel->iIdxCur;
           }
-          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || j<pIdx->nColumn );
+          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
         }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;
           pOp->opcode = OP_IdxRowid;