]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix memory leaks in the code on this branch. Make use of the
authordan <dan@noemail.net>
Sat, 15 Apr 2017 14:16:04 +0000 (14:16 +0000)
committerdan <dan@noemail.net>
Sat, 15 Apr 2017 14:16:04 +0000 (14:16 +0000)
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

ext/expert/sqlite3expert.c
manifest
manifest.uuid
src/where.c

index 3cd110c3677a4402d4c5ffd8111a254dd98264d7..153159fbbf96175d4ff44baaa5e21842f6692f06 100644 (file)
@@ -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 <expr> 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; 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{
@@ -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);
   }
 }
index 89f2ca08db0d50a19490239b0add8a65d988912a..6db1d157469cd668d4be2dde45d5f89dd0dcaba6 100644 (file)
--- 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
index 7b25e887aa5a402ceba520ae4de6f78b2455f6a7..de896ff6d41edcd4b18341b8eaff3366c949586b 100644 (file)
@@ -1 +1 @@
-3bb6585004090dbf92dd5e9abdf0fd2c921e64b5b3121c4fb7446db764ab59e5
\ No newline at end of file
+0cd75a872c89958a7f418720a0e8c6f638f8284c488f666015c19136feae6be8
\ No newline at end of file
index df7582832ac7a5e3075c3605ca8b41bdbcdcf654..d49c3d42f2f6520883f7d3bde3fcc19a2d4ebdc0 100644 (file)
@@ -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( iCons<p->pIdxInfo->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( iCons<p->pIdxInfo->nOrderBy ){
-        Expr *pX = p->pOrderBy->a[iCons].pExpr;
-        CollSeq *pC = sqlite3ExprCollSeq(p->pParse, pX);
-        zRet = (pC ? pC->zName : "BINARY");
-      }
-    }
+  if( p && iCons>=0 && iCons<p->pIdxInfo->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;