From: dan Date: Sat, 15 Apr 2017 14:16:04 +0000 (+0000) Subject: Fix memory leaks in the code on this branch. Make use of the X-Git-Tag: version-3.22.0~147^2~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79610f5d090160c0df4d80f3badd9b50f8e959e2;p=thirdparty%2Fsqlite.git Fix memory leaks in the code on this branch. Make use of the sqlite3_index_constraint.usage field. Do not try to handle ORDER BY terms with explicit COLLATE clauses - they don't get passed to the vtab layer anyway. FossilOrigin-Name: 0cd75a872c89958a7f418720a0e8c6f638f8284c488f666015c19136feae6be8 --- diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 3cd110c367..153159fbbf 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -39,7 +39,6 @@ struct IdxConstraint { 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 DESC */ IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ @@ -111,25 +110,6 @@ struct IdxHash { 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. */ @@ -166,48 +146,6 @@ static void *idxMalloc(int *pRc, int nByte){ 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. */ @@ -426,14 +364,14 @@ static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ /* Add the constraints to the IdxScan object */ for(i=0; inConstraint; 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{ @@ -442,20 +380,17 @@ static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ 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; @@ -813,7 +748,6 @@ static int idxFindCompatible( static int idxCreateFromCons( sqlite3expert *p, - IdxTable *pTab, IdxScan *pScan, IdxConstraint *pEq, IdxConstraint *pTail @@ -821,6 +755,7 @@ static int idxCreateFromCons( 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; @@ -882,22 +817,16 @@ static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ 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; } @@ -905,18 +834,15 @@ static int idxCreateFromWhere( /* 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); } } } @@ -931,30 +857,12 @@ static int idxCreateFromWhere( 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; @@ -1004,6 +912,18 @@ static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ } } +/* +** 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 @@ -1126,6 +1046,7 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ } } } + idxFinalize(&rc, pSchema); return rc; } @@ -1296,7 +1217,9 @@ void sqlite3_expert_destroy(sqlite3expert *p){ 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); } } diff --git a/manifest b/manifest index 89f2ca08db..6db1d15746 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -43,7 +43,7 @@ F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef 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 @@ -488,7 +488,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 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 @@ -1578,7 +1578,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 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 diff --git a/manifest.uuid b/manifest.uuid index 7b25e887aa..de896ff6d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bb6585004090dbf92dd5e9abdf0fd2c921e64b5b3121c4fb7446db764ab59e5 \ No newline at end of file +0cd75a872c89958a7f418720a0e8c6f638f8284c488f666015c19136feae6be8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index df7582832a..d49c3d42f2 100644 --- a/src/where.c +++ b/src/where.c @@ -3120,27 +3120,17 @@ static int whereLoopAddVirtualOne( struct BestIndexCtx { WhereClause *pWC; sqlite3_index_info *pIdxInfo; - ExprList *pOrderBy; Parse *pParse; }; const char *sqlite3_vtab_collation(sqlite3 *db, int iCons){ struct BestIndexCtx *p = (struct BestIndexCtx*)db->pVtabWC; const char *zRet = 0; - if( p && iCons>=0 ){ - if( iConspIdxInfo->nConstraint ){ - int iTerm = p->pIdxInfo->aConstraint[iCons].iTermOffset; - Expr *pX = p->pWC->a[iTerm].pExpr; - CollSeq *pC = sqlite3BinaryCompareCollSeq(p->pParse,pX->pLeft,pX->pRight); - zRet = (pC ? pC->zName : "BINARY"); - }else{ - iCons -= p->pIdxInfo->nConstraint; - if( iConspIdxInfo->nOrderBy ){ - Expr *pX = p->pOrderBy->a[iCons].pExpr; - CollSeq *pC = sqlite3ExprCollSeq(p->pParse, pX); - zRet = (pC ? pC->zName : "BINARY"); - } - } + if( p && iCons>=0 && iConspIdxInfo->nConstraint ){ + int iTerm = p->pIdxInfo->aConstraint[iCons].iTermOffset; + Expr *pX = p->pWC->a[iTerm].pExpr; + CollSeq *pC = sqlite3BinaryCompareCollSeq(p->pParse,pX->pLeft,pX->pRight); + zRet = (pC ? pC->zName : "BINARY"); } return zRet; } @@ -3212,7 +3202,6 @@ static int whereLoopAddVirtual( bic.pWC = pWC; bic.pIdxInfo = p; bic.pParse = pParse; - bic.pOrderBy = pBuilder->pOrderBy; pSaved = pParse->db->pVtabWC; pParse->db->pVtabWC = (void*)&bic;