Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -773,10 +773,11 @@ assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + sqlite3MemLink(pNew, pNew->zName); if( !pNew->aCol || !pNew->zName ){ db->mallocFailed = 1; goto exit_begin_add_column; } memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); Index: src/analyze.c ================================================================== --- src/analyze.c +++ src/analyze.c @@ -484,32 +484,10 @@ if( *z==' ' ) z++; } return 0; } -/* -** If the Index.aSample variable is not NULL, delete the aSample[] array -** and its contents. -*/ -void sqlite3DeleteIndexSamples(Index *pIdx){ -#ifdef SQLITE_ENABLE_STAT2 - if( pIdx->aSample ){ - int j; - for(j=0; jaSample[j]; - if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ - sqlite3_free(p->u.z); - } - } - sqlite3DbFree(0, pIdx->aSample); - pIdx->aSample = 0; - } -#else - UNUSED_PARAMETER(pIdx); -#endif -} - /* ** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] ** arrays. The contents of sqlite_stat2 are used to populate the ** Index.aSample[] arrays. @@ -540,11 +518,15 @@ /* Clear any prior statistics */ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); - sqlite3DeleteIndexSamples(pIdx); + if( pIdx->aSample ){ + sqlite3MemUnlink(pIdx, pIdx->aSample); + sqlite3DbFree(db, pIdx->aSample); + pIdx->aSample = 0; + } } /* Check to make sure the sqlite_stat1 table exists */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zName; @@ -586,24 +568,24 @@ Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase); if( pIdx ){ int iSample = sqlite3_column_int(pStmt, 1); if( iSample=0 ){ int eType = sqlite3_column_type(pStmt, 2); + IndexSample *aSample = pIdx->aSample; - if( pIdx->aSample==0 ){ + if( aSample==0 ){ static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES; - pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz); - if( pIdx->aSample==0 ){ + pIdx->aSample = aSample = sqlite3DbMallocZeroChild(0, sz, pIdx); + if( aSample==0 ){ db->mallocFailed = 1; break; } - memset(pIdx->aSample, 0, sz); } - - assert( pIdx->aSample ); + + assert( aSample ); { - IndexSample *pSample = &pIdx->aSample[iSample]; + IndexSample *pSample = &aSample[iSample]; pSample->eType = (u8)eType; if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ pSample->u.r = sqlite3_column_double(pStmt, 2); }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ const char *z = (const char *)( @@ -617,13 +599,14 @@ } pSample->nByte = (u8)n; if( n < 1){ pSample->u.z = 0; }else{ - pSample->u.z = sqlite3Malloc(n); - if( pSample->u.z ){ - memcpy(pSample->u.z, z, n); + char *zSample; + pSample->u.z = zSample = sqlite3DbMallocRawChild(0,n,aSample); + if( zSample ){ + memcpy(zSample, z, n); }else{ db->mallocFailed = 1; break; } } Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -344,13 +344,10 @@ /* ** Reclaim the memory used by an index */ static void freeIndex(sqlite3 *db, Index *p){ -#ifndef SQLITE_OMIT_ANALYZE - sqlite3DeleteIndexSamples(p); -#endif sqlite3DbFree(db, p); } /* ** Remove the given index from the index hash table, and free @@ -475,13 +472,10 @@ assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ sqlite3DbFree(db, pCol->zName); sqlite3ExprDelete(db, pCol->pDflt); - sqlite3DbFree(db, pCol->zDflt); - sqlite3DbFree(db, pCol->zType); - sqlite3DbFree(db, pCol->zColl); } sqlite3DbFree(db, pTable->aCol); } pTable->aCol = 0; pTable->nCol = 0; @@ -520,11 +514,10 @@ sqlite3FkDelete(db, pTable); /* Delete the Table structure itself. */ sqliteResetColumnNames(db, pTable); - sqlite3DbFree(db, pTable->zName); sqlite3SelectDelete(db, pTable->pSelect); #ifndef SQLITE_OMIT_CHECK sqlite3ExprDelete(db, pTable->pCheck); #endif sqlite3VtabClear(db, pTable); @@ -809,10 +802,11 @@ pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; } pTable->zName = zName; + sqlite3MemLink(pTable, zName); pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; @@ -941,11 +935,11 @@ return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; - aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); + aNew = sqlite3DbRealloc(db, p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); if( aNew==0 ){ sqlite3DbFree(db, z); return; } p->aCol = aNew; @@ -1052,10 +1046,11 @@ p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; assert( pCol->zType==0 ); pCol->zType = sqlite3NameFromToken(pParse->db, pType); + sqlite3MemLink(p->aCol, pCol->zType); pCol->affinity = sqlite3AffinityType(pCol->zType); } /* ** The expression is the default value for the most recently added column @@ -1082,13 +1077,13 @@ ** tokens that point to volatile memory. The 'span' of the expression ** is required by pragma table_info. */ sqlite3ExprDelete(db, pCol->pDflt); pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE); - sqlite3DbFree(db, pCol->zDflt); pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart, (int)(pSpan->zEnd - pSpan->zStart)); + sqlite3MemLink(p->aCol, pCol->zDflt); } } sqlite3ExprDelete(db, pSpan->pExpr); } @@ -1207,10 +1202,11 @@ if( !zColl ) return; if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; p->aCol[i].zColl = zColl; + sqlite3MemLink(p->aCol, zColl); /* If the column is declared as " PRIMARY KEY COLLATE ", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. */ Index: src/insert.c ================================================================== --- src/insert.c +++ src/insert.c @@ -65,16 +65,15 @@ ** up. */ int n; Table *pTab = pIdx->pTable; sqlite3 *db = sqlite3VdbeDb(v); - pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2); + pIdx->zColAff = (char *)sqlite3DbMallocRawChild(0, pIdx->nColumn+2, pIdx); if( !pIdx->zColAff ){ db->mallocFailed = 1; return 0; } - sqlite3MemLink(pIdx, pIdx->zColAff); for(n=0; nnColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; } pIdx->zColAff[n++] = SQLITE_AFF_NONE; pIdx->zColAff[n] = 0; @@ -108,16 +107,15 @@ if( !pTab->zColAff ){ char *zColAff; int i; sqlite3 *db = sqlite3VdbeDb(v); - zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); + zColAff = (char *)sqlite3DbMallocRawChild(0, pTab->nCol+1, pTab); if( !zColAff ){ db->mallocFailed = 1; return; } - sqlite3MemLink(pTab, zColAff); for(i=0; inCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } zColAff[pTab->nCol] = '\0'; Index: src/malloc.c ================================================================== --- src/malloc.c +++ src/malloc.c @@ -652,20 +652,35 @@ } return p; } /* -** Allocate and zero memory. If the allocation fails, make +** Allocate and zero memory. If the allocation fails, set ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, int n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ memset(p, 0, n); } return p; } + +/* +** Allocate and zero memory child memory. If the allocation fails, set +** the mallocFailed flag in the connection pointer. +*/ +void *sqlite3DbMallocZeroChild(sqlite3 *db, int n, void *pParent){ + void *p = sqlite3DbMallocRaw(db, n); + if( p ){ + memset(p, 0, n); + sqlite3MemLink(pParent, p); + } + return p; +} + + /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. ** @@ -720,10 +735,19 @@ finish_emalloc_raw: memset(p, 0, sizeof(EMemHdr)); setValidEMem(p); return (void*)&p[1]; } + +/* +** A convenience wrapper around sqlite3DbMallocRaw() and sqlite3MemLink(). +*/ +void *sqlite3DbMallocRawChild(sqlite3 *db, int n, void *pParent){ + void *p = sqlite3DbMallocRaw(db, n); + sqlite3MemLink(pParent, p); + return p; +} /* ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. ** Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -1266,15 +1266,17 @@ sNC.pSrcList = pSelect->pSrc; a = pSelect->pEList->a; for(i=0, pCol=aCol; izType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); + sqlite3MemLink(aCol, pCol->zType); pCol->affinity = sqlite3ExprAffinity(p); if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE; pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ pCol->zColl = sqlite3DbStrDup(db, pColl->zName); + sqlite3MemLink(aCol, pCol->zColl); } } } /* @@ -3095,10 +3097,11 @@ sqlite3WalkSelect(pWalker, pSel); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); + sqlite3MemLink(pTab, pTab->zName); while( pSel->pPrior ){ pSel = pSel->pPrior; } selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); pTab->iPKey = -1; pTab->tabFlags |= TF_Ephemeral; #endif Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -2485,10 +2485,12 @@ void sqlite3MallocEnd(void); void *sqlite3Malloc(int); void *sqlite3MallocZero(int); void *sqlite3DbMallocZero(sqlite3*, int); void *sqlite3DbMallocRaw(sqlite3*, int); +void *sqlite3DbMallocZeroChild(sqlite3*, int, void *pParent); +void *sqlite3DbMallocRawChild(sqlite3*, int, void *pParent); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, int); void *sqlite3Realloc(void*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); @@ -2908,11 +2910,10 @@ void sqlite3Analyze(Parse*, Token*, Token*); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); int sqlite3AnalysisLoad(sqlite3*,int iDB); -void sqlite3DeleteIndexSamples(Index*); void sqlite3DefaultRowEst(Index*); void sqlite3RegisterLikeFunctions(sqlite3*, int); int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); void sqlite3MinimumFileFormat(Parse*, int, int); void sqlite3SchemaFree(void *);