char *zColl; /* Collation sequence */
int bRange; /* True for range, false for eq */
int iCol; /* Constrained table column */
- i64 depmask; /* Dependency mask */
int bFlag; /* Used by idxFindCompatible() */
int bDesc; /* True if ORDER BY <expr> DESC */
IdxConstraint *pNext; /* Next constraint in pEq or pRange list */
IdxHashEntry *aHash[IDX_HASH_SIZE];
};
-/*
-** A hash table for storing a set of 64-bit values. Methods are:
-**
-** idxHash64Init()
-** idxHash64Clear()
-** idxHash64Add()
-*/
-typedef struct IdxHash64Entry IdxHash64Entry;
-typedef struct IdxHash64 IdxHash64;
-struct IdxHash64Entry {
- u64 iVal;
- IdxHash64Entry *pNext; /* Next entry in hash table */
- IdxHash64Entry *pHashNext; /* Next entry in same hash bucket */
-};
-struct IdxHash64 {
- IdxHash64Entry *pFirst; /* Most recently added entry in hash table */
- IdxHash64Entry *aHash[IDX_HASH_SIZE];
-};
-
/*
** sqlite3expert object.
*/
return pRet;
}
-/*
-** Initialize an IdxHash64 hash table.
-*/
-static void idxHash64Init(IdxHash64 *pHash){
- memset(pHash, 0, sizeof(IdxHash64));
-}
-
-/*
-** Reset an IdxHash64 hash table.
-*/
-static void idxHash64Clear(IdxHash64 *pHash){
- IdxHash64Entry *pEntry;
- IdxHash64Entry *pNext;
- for(pEntry=pHash->pFirst; pEntry; pEntry=pNext){
- pNext = pEntry->pNext;
- sqlite3_free(pEntry);
- }
- memset(pHash, 0, sizeof(IdxHash64));
-}
-
-/*
-** Add iVal to the IdxHash64 hash table passed as the second argument. This
-** function is a no-op if iVal is already present in the hash table.
-*/
-static void idxHash64Add(int *pRc, IdxHash64 *pHash, u64 iVal){
- int iHash = (int)((iVal*7) % IDX_HASH_SIZE);
- IdxHash64Entry *pEntry;
- assert( iHash>=0 );
-
- for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
- if( pEntry->iVal==iVal ) return;
- }
- pEntry = idxMalloc(pRc, sizeof(IdxHash64Entry));
- if( pEntry ){
- pEntry->iVal = iVal;
- pEntry->pHashNext = pHash->aHash[iHash];
- pHash->aHash[iHash] = pEntry;
- pEntry->pNext = pHash->pFirst;
- pHash->pFirst = pEntry;
- }
-}
-
/*
** Initialize an IdxHash hash table.
*/
/* Add the constraints to the IdxScan object */
for(i=0; i<pIdxInfo->nConstraint; i++){
- int op = pIdxInfo->aConstraint[i].op;
- if( op&opmask ){
+ struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
+ if( pCons->usable && (pCons->op & opmask) ){
IdxConstraint *pNew;
const char *zColl = sqlite3_vtab_collation(dbv, i);
pNew = idxNewConstraint(&rc, zColl);
if( pNew ){
- pNew->iCol = pIdxInfo->aConstraint[i].iColumn;
- if( op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ pNew->iCol = pCons->iColumn;
+ if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
pNew->pNext = pScan->pEq;
pScan->pEq = pNew;
}else{
pScan->pRange = pNew;
}
}
- if( pIdxInfo->aConstraint[i].usable ){
- n++;
- pIdxInfo->aConstraintUsage[i].argvIndex = n;
- }
+ n++;
+ pIdxInfo->aConstraintUsage[i].argvIndex = n;
}
}
/* Add the ORDER BY to the IdxScan object */
for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
- IdxConstraint *pNew;
- const char *zColl = sqlite3_vtab_collation(dbv, i+pIdxInfo->nConstraint);
- pNew = idxNewConstraint(&rc, zColl);
+ int iCol = pIdxInfo->aOrderBy[i].iColumn;
+ IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
if( pNew ){
- pNew->iCol = pIdxInfo->aOrderBy[i].iColumn;
+ pNew->iCol = iCol;
pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
pNew->pNext = pScan->pOrder;
pNew->pLink = pScan->pOrder;
static int idxCreateFromCons(
sqlite3expert *p,
- IdxTable *pTab,
IdxScan *pScan,
IdxConstraint *pEq,
IdxConstraint *pTail
sqlite3 *dbm = p->dbm;
int rc = SQLITE_OK;
if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
+ IdxTable *pTab = pScan->pTab;
char *zCols = 0;
char *zIdx = 0;
IdxConstraint *pCons;
static int idxCreateFromWhere(
sqlite3expert *p,
- IdxTable *pTab,
- i64 mask, /* Consider only these constraints */
IdxScan *pScan, /* Create indexes for this scan */
- IdxConstraint *pEq, /* == constraints for inclusion */
IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */
){
- IdxConstraint *p1 = pEq;
+ IdxConstraint *p1 = 0;
IdxConstraint *pCon;
int rc;
- /* Gather up all the == constraints that match the mask. */
+ /* Gather up all the == constraints. */
for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
- if( (mask & pCon->depmask)==pCon->depmask
- && idxFindConstraint(p1, pCon)==0
- && idxFindConstraint(pTail, pCon)==0
- ){
+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
pCon->pLink = p1;
p1 = pCon;
}
/* Create an index using the == constraints collected above. And the
** range constraint/ORDER BY terms passed in by the caller, if any. */
- rc = idxCreateFromCons(p, pTab, pScan, p1, pTail);
+ rc = idxCreateFromCons(p, pScan, p1, pTail);
/* If no range/ORDER BY passed by the caller, create a version of the
- ** index for each range constraint that matches the mask. */
+ ** index for each range constraint. */
if( pTail==0 ){
for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
assert( pCon->pLink==0 );
- if( (mask & pCon->depmask)==pCon->depmask
- && idxFindConstraint(pEq, pCon)==0
- && idxFindConstraint(pTail, pCon)==0
- ){
- rc = idxCreateFromCons(p, pTab, pScan, p1, pCon);
+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
+ rc = idxCreateFromCons(p, pScan, p1, pCon);
}
}
}
static int idxCreateCandidates(sqlite3expert *p, char **pzErr){
int rc = SQLITE_OK;
IdxScan *pIter;
- IdxHash64 hMask;
- idxHash64Init(&hMask);
for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
- IdxHash64Entry *pEntry;
- IdxConstraint *pCons;
- IdxTable *pTab = pIter->pTab;
-
- idxHash64Add(&rc, &hMask, 0);
- for(pCons=pIter->pEq; pCons; pCons=pCons->pNext){
- for(pEntry=hMask.pFirst; pEntry; pEntry=pEntry->pNext){
- idxHash64Add(&rc, &hMask, pEntry->iVal | (u64)pCons->depmask);
- }
- }
-
- for(pEntry=hMask.pFirst; rc==SQLITE_OK && pEntry; pEntry=pEntry->pNext){
- i64 mask = (i64)pEntry->iVal;
- rc = idxCreateFromWhere(p, pTab, mask, pIter, 0, 0);
- if( rc==SQLITE_OK && pIter->pOrder ){
- rc = idxCreateFromWhere(p, pTab, mask, pIter, 0, pIter->pOrder);
- }
+ rc = idxCreateFromWhere(p, pIter, 0);
+ if( rc==SQLITE_OK && pIter->pOrder ){
+ rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
}
-
- idxHash64Clear(&hMask);
}
return rc;
}
}
+/*
+** Free the linked list of IdxTable objects starting at pTab.
+*/
+static void idxTableFree(IdxTable *pTab){
+ IdxTable *pIter;
+ IdxTable *pNext;
+ for(pIter=pTab; pIter; pIter=pNext){
+ pNext = pIter->pNext;
+ sqlite3_free(pIter);
+ }
+}
+
/*
** This function is called after candidate indexes have been created. It
}
}
}
+ idxFinalize(&rc, pSchema);
return rc;
}
sqlite3_close(p->dbv);
idxScanFree(p->pScan, 0);
idxStatementFree(p->pStatement, 0);
+ idxTableFree(p->pTable);
idxHashClear(&p->hIdx);
+ sqlite3_free(p->zCandidates);
sqlite3_free(p);
}
}
-C Modify\sthe\scode\sin\sext/expert/\sto\suse\sthe\svtab\sinterface\sinstead\sof\nsqlite3_whereinfo_hook().\sRemove\ssqlite3_whereinfo_hook().
-D 2017-04-14T19:41:37.126
+C Fix\smemory\sleaks\sin\sthe\scode\son\sthis\sbranch.\sMake\suse\sof\sthe\nsqlite3_index_constraint.usage\sfield.\sDo\snot\stry\sto\shandle\sORDER\sBY\sterms\swith\nexplicit\sCOLLATE\sclauses\s-\sthey\sdon't\sget\spassed\sto\sthe\svtab\slayer\sanyway.
+D 2017-04-15T14:16:04.093
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
F ext/expert/README.md 9f15075ec5ad772808eff55ef044c31140fd1146aa0a3c47eafd155e71851b01
F ext/expert/expert.c 6349cf8d26c847f5f0fa7e25772b614c67f60f3c850dca0d75d55eb27cf3f69b
F ext/expert/expert1.test cd630eda18a2508eade4c39a1eafe32e7437a33973391e5dddfc7fd0f3163684
-F ext/expert/sqlite3expert.c 9473b011d7e0be5b52157f3b1fc153d7e5f7d2b43af110180843e7a03972439f
+F ext/expert/sqlite3expert.c d4a0a45be58874b4cf54316e5d776726489967140399b1e77a17dbb66558cb38
F ext/expert/sqlite3expert.h b1c9eedeb647fd734c4206ae6851635284cfbfa5fb688eff74c3265c9f949b4d
F ext/expert/test_expert.c bad0611732d07180d586bd589cbb7713dc3ab0338c52bff29680eb2007678c05
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
-F src/where.c 64f2c18c72e06bc935c64a53fd5cea6446ffedeba87c45905408bea124c201b6
+F src/where.c 7b4d39ffdb82a6c5abd8678c66a4cd16d8bdba3bbe158a9e2f181a78e05b07ef
F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df
F src/wherecode.c 943e32e9dccd0af802e0683ae11071c8bd808364e5908a5fb66758bd404c8681
F src/whereexpr.c e913aaa7b73ffcce66abcea5f197e2c538d48b5df78d0b7bba8ff4d73cc2e745
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 5fcd840cf9b6a5c3ee4ef1e8f92f6c30f96a7899a3d774ee9be8a816916f2c3b
-R 754b00e271f01cdc7a8ee810736e1b12
+P 3bb6585004090dbf92dd5e9abdf0fd2c921e64b5b3121c4fb7446db764ab59e5
+R 039cfbfa3ee0c0fcda94663d31b151d9
U dan
-Z bc14af8147812d1c0312a546deaaf0cc
+Z 80d209b7df04543ba8ed8a1a58dd2c4a