diff options
author | drh <drh@noemail.net> | 2013-10-22 18:01:40 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-10-22 18:01:40 +0000 |
commit | bbbdc83b52cc704f1dcc8f1456ad9f1445e3b384 (patch) | |
tree | e0d925d89395420a1982cb5d3e6297484ae43cbe /src | |
parent | 77e57dfbc8f40ecfdab70be2514165d5c74e914c (diff) | |
download | sqlite-bbbdc83b52cc704f1dcc8f1456ad9f1445e3b384.tar.gz sqlite-bbbdc83b52cc704f1dcc8f1456ad9f1445e3b384.zip |
The Index object now has nKeyCol and nColumn. nColumn is the total number
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
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze.c | 12 | ||||
-rw-r--r-- | src/build.c | 40 | ||||
-rw-r--r-- | src/delete.c | 6 | ||||
-rw-r--r-- | src/expr.c | 8 | ||||
-rw-r--r-- | src/fkey.c | 8 | ||||
-rw-r--r-- | src/insert.c | 29 | ||||
-rw-r--r-- | src/pragma.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 7 | ||||
-rw-r--r-- | src/update.c | 2 | ||||
-rw-r--r-- | src/vdbeblob.c | 2 | ||||
-rw-r--r-- | src/vdbemem.c | 2 | ||||
-rw-r--r-- | src/where.c | 94 |
12 files changed, 110 insertions, 106 deletions
diff --git a/src/analyze.c b/src/analyze.c index 30ea0f606..89d666c05 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -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; diff --git a/src/build.c b/src/build.c index acd498350..58950330c 100644 --- a/src/build.c +++ b/src/build.c @@ -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); diff --git a/src/delete.c b/src/delete.c index 5eaae4fb8..38257a1af 100644 --- a/src/delete.c +++ b/src/delete.c @@ -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{ diff --git a/src/expr.c b/src/expr.c index eb2f54563..58895562d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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; diff --git a/src/fkey.c b/src/fkey.c index 5c49ded87..95f1d632c 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -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]); } } } diff --git a/src/insert.c b/src/insert.c index 2f5a386ca..c662a52e7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -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 */ } diff --git a/src/pragma.c b/src/pragma.c index a1f32c36d..b6f9ae191 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 11053b9af..4565e92a8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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); diff --git a/src/update.c b/src/update.c index 0f760a460..9a4f374fa 100644 --- a/src/update.c +++ b/src/update.c @@ -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; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 2e8fd8ee7..4953579c6 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -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"; } diff --git a/src/vdbemem.c b/src/vdbemem.c index b549c4a31..cdaacac83 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -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); diff --git a/src/where.c b/src/where.c index d9f4a9c42..b9036c924 100644 --- a/src/where.c +++ b/src/where.c @@ -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; |