]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The Index object now has nKeyCol and nColumn. nColumn is the total number
authordrh <drh@noemail.net>
Tue, 22 Oct 2013 18:01:40 +0000 (18:01 +0000)
committerdrh <drh@noemail.net>
Tue, 22 Oct 2013 18:01:40 +0000 (18:01 +0000)
of columns and nKeyCol is the number of key columns.  Currently these always
differ by one.  Refactor aiColumn[] to be of type i16 instead of int.

FossilOrigin-Name: a106ce86cd4afd1f81603826de77df1fb25e9ab5

14 files changed:
manifest
manifest.uuid
src/analyze.c
src/build.c
src/delete.c
src/expr.c
src/fkey.c
src/insert.c
src/pragma.c
src/sqliteInt.h
src/update.c
src/vdbeblob.c
src/vdbemem.c
src/where.c

index 0de9dc357366b231e79e9814bb753754569009c6..ecbd37a3e8b1701595847772b901145fc3ebd3ce 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sa\sprocedure\sto\shandle\sthe\smessy\sdetails\sof\sallocating\san\sIndex\sobject\nfrom\sthe\sheap.
-D 2013-10-22T14:28:02.309
+C The\sIndex\sobject\snow\shas\snKeyCol\sand\snColumn.\s\snColumn\sis\sthe\stotal\snumber\nof\scolumns\sand\snKeyCol\sis\sthe\snumber\sof\skey\scolumns.\s\sCurrently\sthese\salways\ndiffer\sby\sone.\s\sRefactor\saiColumn[]\sto\sbe\sof\stype\si16\sinstead\sof\sint.
+D 2013-10-22T18:01:40.210
 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 f1c5ed1fe128c3f106dcd95e97ee9ef94db7a3fa
+F src/analyze.c ee880a4c0deb1c4090a4bbff03adfbf934451f50
 F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -168,21 +168,21 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 509722ce305471b626d3401c0631a808fd33237b
 F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c 1c522019071838e71ab67366105d2e79860aaf4b
+F src/build.c c29b38fb05dcd6c17990b3d2f2e6cdd66b5c42b7
 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
-F src/delete.c 45788c5e48734f2af4acd75a876466e5b9838e34
-F src/expr.c e7338ccffdc391c53ba2d51c5eb6a2f5299e040e
+F src/delete.c c1547dbf732c9987d109b6f45729b4a70e14659e
+F src/expr.c 040c0d340c6eed1d7316407fcd8ea6d4a50dc9d9
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
-F src/fkey.c 5dc10cbaa355753903cd2a64da040f948997ebf8
+F src/fkey.c 628f81177299660a86e40359b3689b81f517e125
 F src/func.c 2c47b65e6e00e3e9374942f28254faf8adafe398
 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 9a3f578ffe37f18ef695a06764320db5dc1f0011
+F src/insert.c c9db86093430946d08186117dab197fddf621a75
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -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 64d3d1f8b4ed144ba85c061d00d96d6be8aa2fea
+F src/pragma.c ab815d27690d24e87c953355a765edb546c47708
 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
 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 bf4e57f30d67a0720fe7bc35926fdd0f0f07972f
+F src/sqliteInt.h b365e0f5ae7e22a433be5d1595f62a9db66d11cc
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -275,7 +275,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
 F src/trigger.c ba0a883cd536b7dfdd4df3733001f5372a4299da
-F src/update.c f5182157f5d0d0a97bc5f5e3c9bdba0dfbe08f08
+F src/update.c 2bb5a267796e6d0177ef5689487c3688de5c309e
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c f313bc97123a4dd4bfd3f50a00c4d44c08a5b1b7
@@ -284,15 +284,15 @@ F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
 F src/vdbeInt.h ff57f67aee1ba26a3a47e786533dab155ab6dad6
 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
 F src/vdbeaux.c 55f4858fe6abd84bd7311acbf30a75a28903ec25
-F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
-F src/vdbemem.c 649933bad3e922465b726eaf85c72a75acba2ab7
+F src/vdbeblob.c ef973d8d9f8170015343dd8824f795da675caa87
+F src/vdbemem.c 6087553f2c61c06c8e1ab3959a60e174d6240c98
 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
 F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
-F src/where.c a5253015dc9ad53e9b811affa062cac6fef47729
+F src/where.c 32b6e99b4343958f5ca641e3d62fe3da072f7128
 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 5ca0ea2e9b40a7fa133d2af8a2ecc676de7a8723
-R af47abc49940901bd05e026560bdb4b9
+P 45efc94f9a8169433ffcb4aa35760551c55df4c4
+R 01cd56332e89d0bc92e41f690b42402c
 U drh
-Z 079ab6bb649eb152e2879418f011e61b
+Z 6297f61b2d795cc46624c31a3c77d60c
index 09b2dcbc3482a64e22a70aee488c33a5fb4a1e8e..48d7ab4e297a891702bbc9051c139280987cd56c 100644 (file)
@@ -1 +1 @@
-45efc94f9a8169433ffcb4aa35760551c55df4c4
\ No newline at end of file
+a106ce86cd4afd1f81603826de77df1fb25e9ab5
\ No newline at end of file
index 30ea0f6065fd53cb227322651f9b7b76f1694b2e..89d666c05fef370972ad904f034baea9f821327c 100644 (file)
@@ -916,7 +916,7 @@ static void analyzeOneTable(
     if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
     if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
     VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
-    nCol = pIdx->nColumn;
+    nCol = pIdx->nKeyCol;
     aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
     if( aGotoChng==0 ) continue;
     pKey = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -1081,7 +1081,7 @@ static void analyzeOneTable(
                                       pIdx->aiColumn[0], regSample);
 #else
       for(i=0; i<nCol; i++){
-        int iCol = pIdx->aiColumn[i];
+        i16 iCol = pIdx->aiColumn[i];
         sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
       }
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
@@ -1337,7 +1337,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
   z = argv[2];
 
   if( pIndex ){
-    decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst, pIndex);
+    decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex);
     if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
   }else{
     Index fakeIdx;
@@ -1383,7 +1383,7 @@ static void initAvgEq(Index *pIdx){
     IndexSample *aSample = pIdx->aSample;
     IndexSample *pFinal = &aSample[pIdx->nSample-1];
     int iCol;
-    for(iCol=0; iCol<pIdx->nColumn; iCol++){
+    for(iCol=0; iCol<pIdx->nKeyCol; iCol++){
       int i;                    /* Used to iterate through samples */
       tRowcnt sumEq = 0;        /* Sum of the nEq values */
       tRowcnt nSum = 0;         /* Number of terms contributing to sumEq */
@@ -1466,8 +1466,8 @@ static int loadStatTbl(
     ** loaded from the stat4 table. In this case ignore stat3 data.  */
     if( pIdx==0 || pIdx->nSample ) continue;
     if( bStat3==0 ){
-      nIdxCol = pIdx->nColumn+1;
-      nAvgCol = pIdx->nColumn;
+      nIdxCol = pIdx->nKeyCol+1;
+      nAvgCol = pIdx->nKeyCol;
     }
     pIdx->nSampleCol = nIdxCol;
     nByte = sizeof(IndexSample) * nSample;
index acd4983502aa5f7fa348dba49734904f441fd7d5..58950330ceda59b98381b0fe206344e6e0046f0f 100644 (file)
@@ -1314,7 +1314,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){
     ** collation type was added. Correct this if it is the case.
     */
     for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
-      assert( pIdx->nColumn==1 );
+      assert( pIdx->nKeyCol==1 );
       if( pIdx->aiColumn[0]==i ){
         pIdx->azColl[0] = p->aCol[i].zColl;
       }
@@ -1524,12 +1524,13 @@ static void estimateTableWidth(Table *pTab){
 ** Estimate the average size of a row for an index.
 */
 static void estimateIndexWidth(Index *pIdx){
-  unsigned wIndex = 1;
+  unsigned wIndex = 0;
   int i;
   const Column *aCol = pIdx->pTable->aCol;
   for(i=0; i<pIdx->nColumn; i++){
-    assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]<pIdx->pTable->nCol );
-    wIndex += aCol[pIdx->aiColumn[i]].szEst;
+    i16 x = pIdx->aiColumn[i];
+    assert( x<pIdx->pTable->nCol );
+    wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
   }
   pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
 }
@@ -2524,7 +2525,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
 */
 Index *sqlite3AllocateIndexObject(
   sqlite3 *db,         /* Database connection */
-  int nCol,            /* Number of columns in the index */
+  i16 nCol,            /* Total number of columns in the index */
   int nExtra,          /* Number of bytes of extra space to alloc */
   char **ppExtra       /* Pointer to the "extra" space */
 ){
@@ -2534,16 +2535,17 @@ Index *sqlite3AllocateIndexObject(
   nByte = ROUND8(sizeof(Index)) +              /* Index structure  */
           ROUND8(sizeof(char*)*nCol) +         /* Index.azColl     */
           ROUND8(sizeof(tRowcnt)*(nCol+1) +    /* Index.aiRowEst   */
-                 sizeof(int)*nCol +            /* Index.aiColumn   */
+                 sizeof(i16)*nCol +            /* Index.aiColumn   */
                  sizeof(u8)*nCol);             /* Index.aSortOrder */
   p = sqlite3DbMallocZero(db, nByte + nExtra);
   if( p ){
     char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
     p->azColl = (char**)pExtra;      pExtra += ROUND8(sizeof(char*)*nCol);
     p->aiRowEst = (tRowcnt*)pExtra;  pExtra += sizeof(tRowcnt)*(nCol+1);
-    p->aiColumn = (int*)pExtra;      pExtra += sizeof(int)*nCol;
+    p->aiColumn = (i16*)pExtra;      pExtra += sizeof(i16)*nCol;
     p->aSortOrder = (u8*)pExtra;
     p->nColumn = nCol;
+    p->nKeyCol = nCol - 1;
     *ppExtra = ((char*)p) + nByte;
   }
   return p;
@@ -2763,7 +2765,7 @@ Index *sqlite3CreateIndex(
   ** Allocate the index structure. 
   */
   nName = sqlite3Strlen30(zName);
-  pIndex = sqlite3AllocateIndexObject(db, pList->nExpr,
+  pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + 1,
                                       nName + nExtra + 1, &zExtra);
   if( db->mallocFailed ){
     goto exit_create_index;
@@ -2774,7 +2776,6 @@ Index *sqlite3CreateIndex(
   zExtra += nName + 1;
   memcpy(pIndex->zName, zName, nName+1);
   pIndex->pTable = pTab;
-  pIndex->nColumn = pList->nExpr;
   pIndex->onError = (u8)onError;
   pIndex->uniqNotNull = onError==OE_Abort;
   pIndex->autoIndex = (u8)(pName==0);
@@ -2818,7 +2819,8 @@ Index *sqlite3CreateIndex(
       pParse->checkSchema = 1;
       goto exit_create_index;
     }
-    pIndex->aiColumn[i] = j;
+    assert( pTab->nCol<=0x7fff && j<=0x7fff );
+    pIndex->aiColumn[i] = (i16)j;
     if( pListItem->pExpr ){
       int nColl;
       assert( pListItem->pExpr->op==TK_COLLATE );
@@ -2841,6 +2843,8 @@ Index *sqlite3CreateIndex(
     pIndex->aSortOrder[i] = (u8)requestedSortOrder;
     if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
   }
+  pIndex->aiColumn[i] = -1;
+  pIndex->azColl[i] = "BINARY";
   sqlite3DefaultRowEst(pIndex);
   if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
 
@@ -2873,8 +2877,8 @@ Index *sqlite3CreateIndex(
       assert( pIdx->autoIndex );
       assert( pIndex->onError!=OE_None );
 
-      if( pIdx->nColumn!=pIndex->nColumn ) continue;
-      for(k=0; k<pIdx->nColumn; k++){
+      if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue;
+      for(k=0; k<pIdx->nKeyCol; k++){
         const char *z1;
         const char *z2;
         if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
@@ -2882,7 +2886,7 @@ Index *sqlite3CreateIndex(
         z2 = pIndex->azColl[k];
         if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
       }
-      if( k==pIdx->nColumn ){
+      if( k==pIdx->nKeyCol ){
         if( pIdx->onError!=pIndex->onError ){
           /* This constraint creates the same index as a previous
           ** constraint specified somewhere in the CREATE TABLE statement.
@@ -3051,12 +3055,12 @@ void sqlite3DefaultRowEst(Index *pIdx){
   a[0] = pIdx->pTable->nRowEst;
   if( a[0]<10 ) a[0] = 10;
   n = 10;
-  for(i=1; i<=pIdx->nColumn; i++){
+  for(i=1; i<=pIdx->nKeyCol; i++){
     a[i] = n;
     if( n>5 ) n--;
   }
   if( pIdx->onError!=OE_None ){
-    a[pIdx->nColumn] = 1;
+    a[pIdx->nKeyCol] = 1;
   }
 }
 
@@ -3764,8 +3768,8 @@ static int collationMatch(const char *zColl, Index *pIndex){
   assert( zColl!=0 );
   for(i=0; i<pIndex->nColumn; i++){
     const char *z = pIndex->azColl[i];
-    assert( z!=0 );
-    if( 0==sqlite3StrICmp(z, zColl) ){
+    assert( z!=0 || pIndex->aiColumn[i]<0 );
+    if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){
       return 1;
     }
   }
@@ -3895,7 +3899,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
 */
 KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
   int i;
-  int nCol = pIdx->nColumn;
+  int nCol = pIdx->nKeyCol;
   KeyInfo *pKey;
 
   pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
index 5eaae4fb8190ca1cf6cb267a916957d50960f548..38257a1af159909a4fa8a43053dce345bada0d12 100644 (file)
@@ -598,7 +598,7 @@ void sqlite3GenerateRowIndexDelete(
   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
     r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
-    sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
+    sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nKeyCol+1);
     sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   }
 }
@@ -645,11 +645,11 @@ int sqlite3GenerateIndexKey(
       *piPartIdxLabel = 0;
     }
   }
-  nCol = pIdx->nColumn;
+  nCol = pIdx->nKeyCol;
   regBase = sqlite3GetTempRange(pParse, nCol+1);
   sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
   for(j=0; j<nCol; j++){
-    int idx = pIdx->aiColumn[j];
+    i16 idx = pIdx->aiColumn[j];
     if( idx==pTab->iPKey ){
       sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
     }else{
index eb2f545639caa1d80818cb357c3ce121a24927db..58895562d1bb124dd368af6c1e4f100f38a31fba 100644 (file)
@@ -1532,8 +1532,8 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
     sqlite3 *db = pParse->db;              /* Database connection */
     Table *pTab;                           /* Table <table>. */
     Expr *pExpr;                           /* Expression <column> */
-    int iCol;                              /* Index of column <column> */
-    int iDb;                               /* Database idx for pTab */
+    i16 iCol;                              /* Index of column <column> */
+    i16 iDb;                               /* Database idx for pTab */
 
     assert( p );                        /* Because of isCandidateForInOpt(p) */
     assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
@@ -1541,7 +1541,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
     assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
     pTab = p->pSrc->a[0].pTab;
     pExpr = p->pEList->a[0].pExpr;
-    iCol = pExpr->iColumn;
+    iCol = (i16)pExpr->iColumn;
    
     /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -1579,7 +1579,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
       for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
         if( (pIdx->aiColumn[0]==iCol)
          && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
-         && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
+         && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
         ){
           int iAddr;
           char *pKey;
index 5c49ded876ddc7e1ca3d8662d24cdcceae0e0089..95f1d632cfc68d0ed3d29d24b21449c30ee86d8d 100644 (file)
@@ -225,7 +225,7 @@ int sqlite3FkLocateIndex(
   }
 
   for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
-    if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ 
+    if( pIdx->nKeyCol==nCol && pIdx->onError!=OE_None ){ 
       /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
       ** of columns. If each indexed column corresponds to a foreign key
       ** column of pFKey, then this index is a winner.  */
@@ -248,7 +248,7 @@ int sqlite3FkLocateIndex(
         ** the default collation sequences for each column. */
         int i, j;
         for(i=0; i<nCol; i++){
-          int iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
+          i16 iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
           char *zDfltColl;                  /* Def. collation for column */
           char *zIdxCol;                    /* Name of indexed column */
 
@@ -509,7 +509,7 @@ static void fkScanChildren(
     Expr *pLeft;                  /* Value from parent table row */
     Expr *pRight;                 /* Column ref to child table */
     Expr *pEq;                    /* Expression (pLeft = pRight) */
-    int iCol;                     /* Index of column in child table */ 
+    i16 iCol;                     /* Index of column in child table */ 
     const char *zCol;             /* Name of column in child table */
 
     pLeft = sqlite3Expr(db, TK_REGISTER, 0);
@@ -966,7 +966,7 @@ u32 sqlite3FkOldmask(
       Index *pIdx = 0;
       sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
       if( pIdx ){
-        for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+        for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
       }
     }
   }
index 2f5a386cad068897a6cf5cb95be3e188641df5d6..c662a52e70f5a10a78588d61580ba160c00e8df5 100644 (file)
@@ -67,12 +67,12 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
     int n;
     Table *pTab = pIdx->pTable;
     sqlite3 *db = sqlite3VdbeDb(v);
-    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
+    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nKeyCol+2);
     if( !pIdx->zColAff ){
       db->mallocFailed = 1;
       return 0;
     }
-    for(n=0; n<pIdx->nColumn; n++){
+    for(n=0; n<pIdx->nKeyCol; n++){
       pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
     }
     pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
@@ -1393,24 +1393,23 @@ void sqlite3GenerateConstraintChecks(
     }
 
     /* Create a key for accessing the index entry */
-    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
+    regIdx = sqlite3GetTempRange(pParse, pIdx->nKeyCol+1);
     for(i=0; i<pIdx->nColumn; i++){
-      int idx = pIdx->aiColumn[i];
-      if( idx==pTab->iPKey ){
+      i16 idx = pIdx->aiColumn[i];
+      if( idx<0 || idx==pTab->iPKey ){
         sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
       }else{
         sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
       }
     }
-    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
-    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
+    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[iCur]);
     sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
-    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
+    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
 
     /* Find out what action to take in case there is an indexing conflict */
     onError = pIdx->onError;
     if( onError==OE_None ){ 
-      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nKeyCol+1);
       sqlite3VdbeResolveLabel(v, addrSkipRow);
       continue;  /* pIdx is not a UNIQUE index */
     }
@@ -1430,7 +1429,7 @@ void sqlite3GenerateConstraintChecks(
     j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
                            regR, SQLITE_INT_TO_PTR(regIdx),
                            P4_INT32);
-    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nKeyCol+1);
 
     /* Generate code that executes if the new index entry is not unique */
     assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
@@ -1446,15 +1445,15 @@ void sqlite3GenerateConstraintChecks(
 
         sqlite3StrAccumInit(&errMsg, 0, 0, 200);
         errMsg.db = db;
-        zSep = pIdx->nColumn>1 ? "columns " : "column ";
-        for(j=0; j<pIdx->nColumn; j++){
+        zSep = pIdx->nKeyCol>1 ? "columns " : "column ";
+        for(j=0; j<pIdx->nKeyCol; j++){
           char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
           sqlite3StrAccumAppend(&errMsg, zSep, -1);
           zSep = ", ";
           sqlite3StrAccumAppend(&errMsg, zCol, -1);
         }
         sqlite3StrAccumAppend(&errMsg,
-            pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
+            pIdx->nKeyCol>1 ? " are not unique" : " is not unique", -1);
         zErr = sqlite3StrAccumFinish(&errMsg);
         sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
                               onError, zErr, 0);
@@ -1631,13 +1630,13 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
   int i;
   assert( pDest && pSrc );
   assert( pDest->pTable!=pSrc->pTable );
-  if( pDest->nColumn!=pSrc->nColumn ){
+  if( pDest->nKeyCol!=pSrc->nKeyCol ){
     return 0;   /* Different number of columns */
   }
   if( pDest->onError!=pSrc->onError ){
     return 0;   /* Different conflict resolution strategies */
   }
-  for(i=0; i<pSrc->nColumn; i++){
+  for(i=0; i<pSrc->nKeyCol; i++){
     if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
       return 0;   /* Different columns indexed */
     }
index a1f32c36d35723afb179198ad9b87df459ed71f3..b6f9ae191c849f1abc5b2f13e8cc8d1973d1b594 100644 (file)
@@ -1475,8 +1475,8 @@ void sqlite3Pragma(
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
-      for(i=0; i<pIdx->nColumn; i++){
-        int cnum = pIdx->aiColumn[i];
+      for(i=0; i<pIdx->nKeyCol; i++){
+        i16 cnum = pIdx->aiColumn[i];
         sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
         sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
         assert( pTab->nCol>cnum );
@@ -1872,7 +1872,7 @@ void sqlite3Pragma(
           };
           r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
           sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1);  /* increment entry count */
-          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
+          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nKeyCol+1);
           addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
           sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
           sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
index 11053b9af4644ee9d22d866e5f5f6394c1232b7d..4565e92a88660fede615b53f7a5dadab79987a82 100644 (file)
@@ -1577,7 +1577,7 @@ struct UnpackedRecord {
 */
 struct Index {
   char *zName;             /* Name of this index */
-  int *aiColumn;           /* Which columns are used by this index.  1st is 0 */
+  i16 *aiColumn;           /* Which columns are used by this index.  1st is 0 */
   tRowcnt *aiRowEst;       /* From ANALYZE: Est. rows selected by each column */
   Table *pTable;           /* The SQL table being indexed */
   char *zColAff;           /* String defining the affinity of each column */
@@ -1588,7 +1588,8 @@ struct Index {
   Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
   int tnum;                /* DB Page containing root of this index */
   LogEst szIdxRow;         /* Estimated average row size in bytes */
-  u16 nColumn;             /* Number of columns in table used by this index */
+  u16 nKeyCol;             /* Number of columns forming the key */
+  u16 nColumn;             /* Number of columns stored in the index */
   u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   unsigned autoIndex:2;    /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
   unsigned bUnordered:1;   /* Use this index for == or IN queries only */
@@ -2826,7 +2827,7 @@ void sqlite3SrcListShiftJoinType(SrcList*);
 void sqlite3SrcListAssignCursors(Parse*, SrcList*);
 void sqlite3IdListDelete(sqlite3*, IdList*);
 void sqlite3SrcListDelete(sqlite3*, SrcList*);
-Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**);
+Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
 Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                           Expr*, int, int);
 void sqlite3DropIndex(Parse*, SrcList*, int);
index 0f760a460933290c8e1ae07869bd63d117dc127b..9a4f374fa9e9707170cbcbccd4f9fc69c12c7a95 100644 (file)
@@ -250,7 +250,7 @@ void sqlite3Update(
       reg = ++pParse->nMem;
     }else{
       reg = 0;
-      for(i=0; i<pIdx->nColumn; i++){
+      for(i=0; i<pIdx->nKeyCol; i++){
         if( aXRef[pIdx->aiColumn[i]]>=0 ){
           reg = ++pParse->nMem;
           break;
index 2e8fd8ee7447e64646e3494b4c041d3a4abb0885..4953579c6dfc1969e31efcd4fb1e4accf8c2a044 100644 (file)
@@ -235,7 +235,7 @@ int sqlite3_blob_open(
 #endif
       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
         int j;
-        for(j=0; j<pIdx->nColumn; j++){
+        for(j=0; j<pIdx->nKeyCol; j++){
           if( pIdx->aiColumn[j]==iCol ){
             zFault = "indexed";
           }
index b549c4a31ac74cd536dcbbed2904dc1955db6977..cdaacac83f3904ea79377bd9cd7b60b408c76072 100644 (file)
@@ -1031,7 +1031,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
       Index *pIdx = p->pIdx;      /* Index being probed */
       int nByte;                  /* Bytes of space to allocate */
       int i;                      /* Counter variable */
-      int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */
+      int nCol = pIdx->nKeyCol+1; /* Number of index columns including rowid */
   
       nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
       pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
index d9f4a9c422060a7744a6a6c5c12252474e746026..b9036c9247c9d0ae9936cf77de008a24ff7ca918 100644 (file)
@@ -968,7 +968,7 @@ static WhereTerm *whereScanInit(
   if( pIdx && iColumn>=0 ){
     pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
     for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
-      if( NEVER(j>=pIdx->nColumn) ) return 0;
+      if( NEVER(j>=pIdx->nKeyCol) ) return 0;
     }
     pScan->zCollName = pIdx->azColl[j];
   }else{
@@ -1898,16 +1898,16 @@ static int isDistinctRedundant(
   */
   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
     if( pIdx->onError==OE_None ) continue;
-    for(i=0; i<pIdx->nColumn; i++){
-      int iCol = pIdx->aiColumn[i];
+    for(i=0; i<pIdx->nKeyCol; i++){
+      i16 iCol = pIdx->aiColumn[i];
       if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
         int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
-        if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
+        if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){
           break;
         }
       }
     }
-    if( i==pIdx->nColumn ){
+    if( i==pIdx->nKeyCol ){
       /* This index implies that the DISTINCT qualifier is redundant. */
       return 1;
     }
@@ -2005,7 +2005,7 @@ static void constructAutomaticIndex(
   Bitmask notReady,           /* Mask of cursors that are not available */
   WhereLevel *pLevel          /* Write new index here */
 ){
-  int nColumn;                /* Number of columns in the constructed index */
+  int nKeyCol;                /* Number of columns in the constructed index */
   WhereTerm *pTerm;           /* A single term of the WHERE clause */
   WhereTerm *pWCEnd;          /* End of pWC->a[] */
   Index *pIdx;                /* Object describing the transient index */
@@ -2033,7 +2033,7 @@ static void constructAutomaticIndex(
 
   /* Count the number of columns that will be added to the index
   ** and used to match WHERE clause constraints */
-  nColumn = 0;
+  nKeyCol = 0;
   pTable = pSrc->pTab;
   pWCEnd = &pWC->a[pWC->nTerm];
   pLoop = pLevel->pWLoop;
@@ -2051,14 +2051,14 @@ static void constructAutomaticIndex(
         sentWarning = 1;
       }
       if( (idxCols & cMask)==0 ){
-        if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
-        pLoop->aLTerm[nColumn++] = pTerm;
+        if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;
+        pLoop->aLTerm[nKeyCol++] = pTerm;
         idxCols |= cMask;
       }
     }
   }
-  assert( nColumn>0 );
-  pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
+  assert( nKeyCol>0 );
+  pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
   pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
                      | WHERE_AUTO_INDEX;
 
@@ -2075,15 +2075,15 @@ static void constructAutomaticIndex(
   testcase( pTable->nCol==BMS-1 );
   testcase( pTable->nCol==BMS-2 );
   for(i=0; i<mxBitCol; i++){
-    if( extraCols & MASKBIT(i) ) nColumn++;
+    if( extraCols & MASKBIT(i) ) nKeyCol++;
   }
   if( pSrc->colUsed & MASKBIT(BMS-1) ){
-    nColumn += pTable->nCol - BMS + 1;
+    nKeyCol += pTable->nCol - BMS + 1;
   }
   pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
 
   /* Construct the Index object to describe this index */
-  pIdx = sqlite3AllocateIndexObject(pParse->db, nColumn, 0, &zNotUsed);
+  pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
   if( pIdx==0 ) return;
   pLoop->u.btree.pIndex = pIdx;
   pIdx->zName = "auto-index";
@@ -2124,13 +2124,13 @@ static void constructAutomaticIndex(
       n++;
     }
   }
-  assert( n==nColumn );
+  assert( n==nKeyCol );
 
   /* Create the automatic index */
   pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
   assert( pLevel->iIdxCur>=0 );
   pLevel->iIdxCur = pParse->nTab++;
-  sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
+  sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1, 0,
                     (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
   VdbeComment((v, "for %s", pTable->zName));
 
@@ -2384,7 +2384,7 @@ static void whereKeyStats(
       iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
       iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
     }
-    aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1);
+    aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
     if( iLower>=iUpper ){
       iGap = 0;
     }else{
@@ -2484,7 +2484,7 @@ static int whereRangeScanEst(
     tRowcnt iLower;
     tRowcnt iUpper;
 
-    if( nEq==p->nColumn ){
+    if( nEq==p->nKeyCol ){
       aff = SQLITE_AFF_INTEGER;
     }else{
       aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
@@ -2602,7 +2602,7 @@ static int whereEqualScanEst(
   int bOk;
 
   assert( nEq>=1 );
-  assert( nEq<=(p->nColumn+1) );
+  assert( nEq<=(p->nKeyCol+1) );
   assert( p->aSample!=0 );
   assert( p->nSample>0 );
   assert( pBuilder->nRecValid<nEq );
@@ -2615,7 +2615,7 @@ static int whereEqualScanEst(
 
   /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
   ** below would return the same value.  */
-  if( nEq>p->nColumn ){
+  if( nEq>p->nKeyCol ){
     *pnRow = 1;
     return SQLITE_OK;
   }
@@ -3002,7 +3002,7 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
   int nEq = pLoop->u.btree.nEq;
   int i, j;
   Column *aCol = pTab->aCol;
-  int *aiColumn = pIndex->aiColumn;
+  i16 *aiColumn = pIndex->aiColumn;
   StrAccum txt;
 
   if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
@@ -3012,17 +3012,17 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
   txt.db = db;
   sqlite3StrAccumAppend(&txt, " (", 2);
   for(i=0; i<nEq; i++){
-    char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
+    char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName;
     explainAppendTerm(&txt, i, z, "=");
   }
 
   j = i;
   if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
-    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+    char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
     explainAppendTerm(&txt, i++, z, ">");
   }
   if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
-    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+    char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
     explainAppendTerm(&txt, i, z, "<");
   }
   sqlite3StrAccumAppend(&txt, ")", 1);
@@ -3406,7 +3406,7 @@ static Bitmask codeOneLoopStart(
     */
     if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
      && (pWInfo->bOBSat!=0)
-     && (pIdx->nColumn>nEq)
+     && (pIdx->nKeyCol>nEq)
     ){
       /* assert( pOrderBy->nExpr==1 ); */
       /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
@@ -3439,8 +3439,8 @@ static Bitmask codeOneLoopStart(
     ** a forward order scan on a descending index, interchange the 
     ** start and end terms (pRangeStart and pRangeEnd).
     */
-    if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
-     || (bRev && pIdx->nColumn==nEq)
+    if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+     || (bRev && pIdx->nKeyCol==nEq)
     ){
       SWAP(WhereTerm *, pRangeEnd, pRangeStart);
     }
@@ -4243,8 +4243,8 @@ static int whereLoopAddBtreeIndex(
   }
   if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
 
-  assert( pNew->u.btree.nEq<=pProbe->nColumn );
-  if( pNew->u.btree.nEq < pProbe->nColumn ){
+  assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
+  if( pNew->u.btree.nEq < pProbe->nKeyCol ){
     iCol = pProbe->aiColumn[pNew->u.btree.nEq];
     nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
     if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
@@ -4301,7 +4301,7 @@ static int whereLoopAddBtreeIndex(
       pNew->wsFlags |= WHERE_COLUMN_EQ;
       if( iCol<0  
        || (pProbe->onError!=OE_None && nInMul==0
-           && pNew->u.btree.nEq==pProbe->nColumn-1)
+           && pNew->u.btree.nEq==pProbe->nKeyCol-1)
       ){
         assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
         pNew->wsFlags |= WHERE_ONEROW;
@@ -4367,7 +4367,7 @@ static int whereLoopAddBtreeIndex(
     whereLoopOutputAdjust(pBuilder->pWC, pNew);
     rc = whereLoopInsert(pBuilder, pNew);
     if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
-     && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
+     && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0))
     ){
       whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
     }
@@ -4406,7 +4406,7 @@ static int indexMightHelpWithOrderBy(
     Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
     if( pExpr->op!=TK_COLUMN ) return 0;
     if( pExpr->iTable==iCursor ){
-      for(jj=0; jj<pIndex->nColumn; jj++){
+      for(jj=0; jj<pIndex->nKeyCol; jj++){
         if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
       }
     }
@@ -4421,7 +4421,7 @@ static int indexMightHelpWithOrderBy(
 static Bitmask columnsInIndex(Index *pIdx){
   Bitmask m = 0;
   int j;
-  for(j=pIdx->nColumn-1; j>=0; j--){
+  for(j=pIdx->nKeyCol-1; j>=0; j--){
     int x = pIdx->aiColumn[j];
     assert( x>=0 );
     testcase( x==BMS-1 );
@@ -4456,7 +4456,7 @@ static int whereLoopAddBtree(
   Index *pProbe;              /* An index we are evaluating */
   Index sPk;                  /* A fake index object for the primary key */
   tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
-  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
+  i16 aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
   SrcList *pTabList;          /* The FROM clause */
   struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
   WhereLoop *pNew;            /* Template WhereLoop object */
@@ -4486,7 +4486,7 @@ static int whereLoopAddBtree(
     ** indices to follow */
     Index *pFirst;                  /* First of real indices on the table */
     memset(&sPk, 0, sizeof(Index));
-    sPk.nColumn = 1;
+    sPk.nKeyCol = 1;
     sPk.aiColumn = &aiColumnPk;
     sPk.aiRowEst = aiRowEstPk;
     sPk.onError = OE_Replace;
@@ -4961,7 +4961,7 @@ static int wherePathSatisfiesOrderBy(
   u8 isOrderDistinct;   /* All prior WhereLoops are order-distinct */
   u8 distinctColumns;   /* True if the loop has UNIQUE NOT NULL columns */
   u8 isMatch;           /* iColumn matches a term of the ORDER BY clause */
-  u16 nColumn;          /* Number of columns in pIndex */
+  u16 nKeyCol;          /* Number of columns in pIndex */
   u16 nOrderBy;         /* Number terms in the ORDER BY clause */
   int iLoop;            /* Index of WhereLoop in pPath being processed */
   int i, j;             /* Loop counters */
@@ -5053,11 +5053,11 @@ static int wherePathSatisfiesOrderBy(
     if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
       if( pLoop->wsFlags & WHERE_IPK ){
         pIndex = 0;
-        nColumn = 0;
+        nKeyCol = 0;
       }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
         return 0;
       }else{
-        nColumn = pIndex->nColumn;
+        nKeyCol = pIndex->nKeyCol;
         isOrderDistinct = pIndex->onError!=OE_None;
       }
 
@@ -5066,7 +5066,7 @@ static int wherePathSatisfiesOrderBy(
       */
       rev = revSet = 0;
       distinctColumns = 0;
-      for(j=0; j<=nColumn; j++){
+      for(j=0; j<=nKeyCol; j++){
         u8 bOnce;   /* True to run the ORDER BY search loop */
 
         /* Skip over == and IS NULL terms */
@@ -5083,14 +5083,14 @@ static int wherePathSatisfiesOrderBy(
         /* Get the column number in the table (iColumn) and sort order
         ** (revIdx) for the j-th column of the index.
         */
-        if( j<nColumn ){
+        if( j<nKeyCol ){
           /* Normal index columns */
           iColumn = pIndex->aiColumn[j];
           revIdx = pIndex->aSortOrder[j];
           if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
         }else{
           /* The ROWID column at the end */
-          assert( j==nColumn );
+          assert( j==nKeyCol );
           iColumn = -1;
           revIdx = 0;
         }
@@ -5147,7 +5147,7 @@ static int wherePathSatisfiesOrderBy(
           }
         }else{
           /* No match found */
-          if( j==0 || j<nColumn ){
+          if( j==0 || j<nKeyCol ){
             testcase( isOrderDistinct!=0 );
             isOrderDistinct = 0;
           }
@@ -5513,14 +5513,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
       assert( ArraySize(pLoop->aLTermSpace)==4 );
       if( pIdx->onError==OE_None 
        || pIdx->pPartIdxWhere!=0 
-       || pIdx->nColumn>ArraySize(pLoop->aLTermSpace) 
+       || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
       ) continue;
-      for(j=0; j<pIdx->nColumn; j++){
+      for(j=0; j<pIdx->nKeyCol; j++){
         pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
         if( pTerm==0 ) break;
         pLoop->aLTerm[j] = pTerm;
       }
-      if( j!=pIdx->nColumn ) continue;
+      if( j!=pIdx->nKeyCol ) continue;
       pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
       if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
         pLoop->wsFlags |= WHERE_IDX_ONLY;
@@ -6112,14 +6112,14 @@ 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++){
+          for(j=0; j<pIdx->nKeyCol; j++){
             if( pOp->p2==pIdx->aiColumn[j] ){
               pOp->p2 = j;
               pOp->p1 = pLevel->iIdxCur;
               break;
             }
           }
-          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || j<pIdx->nColumn );
+          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || j<pIdx->nKeyCol );
         }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;
           pOp->opcode = OP_IdxRowid;