/ Check-in [da2f62c5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further examples of using automatic deallocation to replace "delete" methods.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | malloc-enhancement
Files: files | file ages | folders
SHA1: da2f62c502dfd3b53940b08a971137048732ecea
User & Date: drh 2010-07-25 02:12:51
Context
2010-07-25
02:39
Fixes to prior checkins so that they compile and run even if SQLITE_MEMDEBUG is not defined. Closed-Leaf check-in: 548bf3f7 user: drh tags: malloc-enhancement
02:12
Further examples of using automatic deallocation to replace "delete" methods. check-in: da2f62c5 user: drh tags: malloc-enhancement
2010-07-24
19:08
Additional malloc sanity changes. Use sqlite3MemLink() on Index.zColAff and Table.zColAff as a proof of concept. check-in: e5ecb159 user: drh tags: malloc-enhancement
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

   771    771     pNew->nRef = 1;
   772    772     pNew->nCol = pTab->nCol;
   773    773     assert( pNew->nCol>0 );
   774    774     nAlloc = (((pNew->nCol-1)/8)*8)+8;
   775    775     assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
   776    776     pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
   777    777     pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
          778  +  sqlite3MemLink(pNew, pNew->zName);
   778    779     if( !pNew->aCol || !pNew->zName ){
   779    780       db->mallocFailed = 1;
   780    781       goto exit_begin_add_column;
   781    782     }
   782    783     memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
   783    784     for(i=0; i<pNew->nCol; i++){
   784    785       Column *pCol = &pNew->aCol[i];

Changes to src/analyze.c.

   482    482       }
   483    483       pIndex->aiRowEst[i] = v;
   484    484       if( *z==' ' ) z++;
   485    485     }
   486    486     return 0;
   487    487   }
   488    488   
   489         -/*
   490         -** If the Index.aSample variable is not NULL, delete the aSample[] array
   491         -** and its contents.
   492         -*/
   493         -void sqlite3DeleteIndexSamples(Index *pIdx){
   494         -#ifdef SQLITE_ENABLE_STAT2
   495         -  if( pIdx->aSample ){
   496         -    int j;
   497         -    for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
   498         -      IndexSample *p = &pIdx->aSample[j];
   499         -      if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
   500         -        sqlite3_free(p->u.z);
   501         -      }
   502         -    }
   503         -    sqlite3DbFree(0, pIdx->aSample);
   504         -    pIdx->aSample = 0;
   505         -  }
   506         -#else
   507         -  UNUSED_PARAMETER(pIdx);
   508         -#endif
   509         -}
   510         -
   511    489   /*
   512    490   ** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
   513    491   ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
   514    492   ** arrays. The contents of sqlite_stat2 are used to populate the
   515    493   ** Index.aSample[] arrays.
   516    494   **
   517    495   ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
................................................................................
   538    516     assert( db->aDb[iDb].pBt!=0 );
   539    517     assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
   540    518   
   541    519     /* Clear any prior statistics */
   542    520     for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
   543    521       Index *pIdx = sqliteHashData(i);
   544    522       sqlite3DefaultRowEst(pIdx);
   545         -    sqlite3DeleteIndexSamples(pIdx);
          523  +    if( pIdx->aSample ){
          524  +      sqlite3MemUnlink(pIdx, pIdx->aSample);
          525  +      sqlite3DbFree(db, pIdx->aSample);
          526  +      pIdx->aSample = 0;
          527  +    }
   546    528     }
   547    529   
   548    530     /* Check to make sure the sqlite_stat1 table exists */
   549    531     sInfo.db = db;
   550    532     sInfo.zDatabase = db->aDb[iDb].zName;
   551    533     if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
   552    534       return SQLITE_ERROR;
................................................................................
   584    566         while( sqlite3_step(pStmt)==SQLITE_ROW ){
   585    567           char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
   586    568           Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
   587    569           if( pIdx ){
   588    570             int iSample = sqlite3_column_int(pStmt, 1);
   589    571             if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
   590    572               int eType = sqlite3_column_type(pStmt, 2);
          573  +            IndexSample *aSample = pIdx->aSample;
   591    574   
   592         -            if( pIdx->aSample==0 ){
          575  +            if( aSample==0 ){
   593    576                 static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
   594         -              pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz);
   595         -              if( pIdx->aSample==0 ){
          577  +              pIdx->aSample = aSample = sqlite3DbMallocZeroChild(0, sz, pIdx);
          578  +              if( aSample==0 ){
   596    579                   db->mallocFailed = 1;
   597    580                   break;
   598    581                 }
   599         -	      memset(pIdx->aSample, 0, sz);
   600    582               }
   601         -
   602         -            assert( pIdx->aSample );
          583  +  
          584  +            assert( aSample );
   603    585               {
   604         -              IndexSample *pSample = &pIdx->aSample[iSample];
          586  +              IndexSample *pSample = &aSample[iSample];
   605    587                 pSample->eType = (u8)eType;
   606    588                 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
   607    589                   pSample->u.r = sqlite3_column_double(pStmt, 2);
   608    590                 }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
   609    591                   const char *z = (const char *)(
   610    592                       (eType==SQLITE_BLOB) ?
   611    593                       sqlite3_column_blob(pStmt, 2):
................................................................................
   615    597                   if( n>24 ){
   616    598                     n = 24;
   617    599                   }
   618    600                   pSample->nByte = (u8)n;
   619    601                   if( n < 1){
   620    602                     pSample->u.z = 0;
   621    603                   }else{
   622         -                  pSample->u.z = sqlite3Malloc(n);
   623         -                  if( pSample->u.z ){
   624         -                    memcpy(pSample->u.z, z, n);
          604  +                  char *zSample;
          605  +                  pSample->u.z = zSample = sqlite3DbMallocRawChild(0,n,aSample);
          606  +                  if( zSample ){
          607  +                    memcpy(zSample, z, n);
   625    608                     }else{
   626    609                       db->mallocFailed = 1;
   627    610                       break;
   628    611                     }
   629    612                   }
   630    613                 }
   631    614               }

Changes to src/build.c.

   342    342     return p;
   343    343   }
   344    344   
   345    345   /*
   346    346   ** Reclaim the memory used by an index
   347    347   */
   348    348   static void freeIndex(sqlite3 *db, Index *p){
   349         -#ifndef SQLITE_OMIT_ANALYZE
   350         -  sqlite3DeleteIndexSamples(p);
   351         -#endif
   352    349     sqlite3DbFree(db, p);
   353    350   }
   354    351   
   355    352   /*
   356    353   ** Remove the given index from the index hash table, and free
   357    354   ** its memory structures.
   358    355   **
................................................................................
   473    470     int i;
   474    471     Column *pCol;
   475    472     assert( pTable!=0 );
   476    473     if( (pCol = pTable->aCol)!=0 ){
   477    474       for(i=0; i<pTable->nCol; i++, pCol++){
   478    475         sqlite3DbFree(db, pCol->zName);
   479    476         sqlite3ExprDelete(db, pCol->pDflt);
   480         -      sqlite3DbFree(db, pCol->zDflt);
   481         -      sqlite3DbFree(db, pCol->zType);
   482         -      sqlite3DbFree(db, pCol->zColl);
   483    477       }
   484    478       sqlite3DbFree(db, pTable->aCol);
   485    479     }
   486    480     pTable->aCol = 0;
   487    481     pTable->nCol = 0;
   488    482   }
   489    483   
................................................................................
   518    512   
   519    513     /* Delete any foreign keys attached to this table. */
   520    514     sqlite3FkDelete(db, pTable);
   521    515   
   522    516     /* Delete the Table structure itself.
   523    517     */
   524    518     sqliteResetColumnNames(db, pTable);
   525         -  sqlite3DbFree(db, pTable->zName);
   526    519     sqlite3SelectDelete(db, pTable->pSelect);
   527    520   #ifndef SQLITE_OMIT_CHECK
   528    521     sqlite3ExprDelete(db, pTable->pCheck);
   529    522   #endif
   530    523     sqlite3VtabClear(db, pTable);
   531    524     sqlite3DbFree(db, pTable);
   532    525   }
................................................................................
   807    800     if( pTable==0 ){
   808    801       db->mallocFailed = 1;
   809    802       pParse->rc = SQLITE_NOMEM;
   810    803       pParse->nErr++;
   811    804       goto begin_table_error;
   812    805     }
   813    806     pTable->zName = zName;
          807  +  sqlite3MemLink(pTable, zName);
   814    808     pTable->iPKey = -1;
   815    809     pTable->pSchema = db->aDb[iDb].pSchema;
   816    810     pTable->nRef = 1;
   817    811     assert( pParse->pNewTable==0 );
   818    812     pParse->pNewTable = pTable;
   819    813   
   820    814     /* If this is the magic sqlite_sequence table used by autoincrement,
................................................................................
   939    933         sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
   940    934         sqlite3DbFree(db, z);
   941    935         return;
   942    936       }
   943    937     }
   944    938     if( (p->nCol & 0x7)==0 ){
   945    939       Column *aNew;
   946         -    aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
          940  +    aNew = sqlite3DbRealloc(db, p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
   947    941       if( aNew==0 ){
   948    942         sqlite3DbFree(db, z);
   949    943         return;
   950    944       }
   951    945       p->aCol = aNew;
   952    946     }
   953    947     pCol = &p->aCol[p->nCol];
................................................................................
  1050   1044     Column *pCol;
  1051   1045   
  1052   1046     p = pParse->pNewTable;
  1053   1047     if( p==0 || NEVER(p->nCol<1) ) return;
  1054   1048     pCol = &p->aCol[p->nCol-1];
  1055   1049     assert( pCol->zType==0 );
  1056   1050     pCol->zType = sqlite3NameFromToken(pParse->db, pType);
         1051  +  sqlite3MemLink(p->aCol, pCol->zType);
  1057   1052     pCol->affinity = sqlite3AffinityType(pCol->zType);
  1058   1053   }
  1059   1054   
  1060   1055   /*
  1061   1056   ** The expression is the default value for the most recently added column
  1062   1057   ** of the table currently under construction.
  1063   1058   **
................................................................................
  1080   1075       }else{
  1081   1076         /* A copy of pExpr is used instead of the original, as pExpr contains
  1082   1077         ** tokens that point to volatile memory. The 'span' of the expression
  1083   1078         ** is required by pragma table_info.
  1084   1079         */
  1085   1080         sqlite3ExprDelete(db, pCol->pDflt);
  1086   1081         pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
  1087         -      sqlite3DbFree(db, pCol->zDflt);
  1088   1082         pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
  1089   1083                                        (int)(pSpan->zEnd - pSpan->zStart));
         1084  +      sqlite3MemLink(p->aCol, pCol->zDflt);
  1090   1085       }
  1091   1086     }
  1092   1087     sqlite3ExprDelete(db, pSpan->pExpr);
  1093   1088   }
  1094   1089   
  1095   1090   /*
  1096   1091   ** Designate the PRIMARY KEY for the table.  pList is a list of names 
................................................................................
  1205   1200     db = pParse->db;
  1206   1201     zColl = sqlite3NameFromToken(db, pToken);
  1207   1202     if( !zColl ) return;
  1208   1203   
  1209   1204     if( sqlite3LocateCollSeq(pParse, zColl) ){
  1210   1205       Index *pIdx;
  1211   1206       p->aCol[i].zColl = zColl;
         1207  +    sqlite3MemLink(p->aCol, zColl);
  1212   1208     
  1213   1209       /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
  1214   1210       ** then an index may have been created on this column before the
  1215   1211       ** collation type was added. Correct this if it is the case.
  1216   1212       */
  1217   1213       for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
  1218   1214         assert( pIdx->nColumn==1 );

Changes to src/insert.c.

    63     63       ** The column affinity string will eventually be deleted by
    64     64       ** sqliteDeleteIndex() when the Index structure itself is cleaned
    65     65       ** up.
    66     66       */
    67     67       int n;
    68     68       Table *pTab = pIdx->pTable;
    69     69       sqlite3 *db = sqlite3VdbeDb(v);
    70         -    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
           70  +    pIdx->zColAff = (char *)sqlite3DbMallocRawChild(0, pIdx->nColumn+2, pIdx);
    71     71       if( !pIdx->zColAff ){
    72     72         db->mallocFailed = 1;
    73     73         return 0;
    74     74       }
    75         -    sqlite3MemLink(pIdx, pIdx->zColAff);
    76     75       for(n=0; n<pIdx->nColumn; n++){
    77     76         pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
    78     77       }
    79     78       pIdx->zColAff[n++] = SQLITE_AFF_NONE;
    80     79       pIdx->zColAff[n] = 0;
    81     80     }
    82     81    
................................................................................
   106    105     ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
   107    106     */
   108    107     if( !pTab->zColAff ){
   109    108       char *zColAff;
   110    109       int i;
   111    110       sqlite3 *db = sqlite3VdbeDb(v);
   112    111   
   113         -    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
          112  +    zColAff = (char *)sqlite3DbMallocRawChild(0, pTab->nCol+1, pTab);
   114    113       if( !zColAff ){
   115    114         db->mallocFailed = 1;
   116    115         return;
   117    116       }
   118         -    sqlite3MemLink(pTab, zColAff);
   119    117       for(i=0; i<pTab->nCol; i++){
   120    118         zColAff[i] = pTab->aCol[i].affinity;
   121    119       }
   122    120       zColAff[pTab->nCol] = '\0';
   123    121   
   124    122       pTab->zColAff = zColAff;
   125    123     }

Changes to src/malloc.c.

   650    650     if( p ){
   651    651       memset(p, 0, n);
   652    652     }
   653    653     return p;
   654    654   }
   655    655   
   656    656   /*
   657         -** Allocate and zero memory.  If the allocation fails, make
          657  +** Allocate and zero memory.  If the allocation fails, set
   658    658   ** the mallocFailed flag in the connection pointer.
   659    659   */
   660    660   void *sqlite3DbMallocZero(sqlite3 *db, int n){
   661    661     void *p = sqlite3DbMallocRaw(db, n);
   662    662     if( p ){
   663    663       memset(p, 0, n);
   664    664     }
   665    665     return p;
   666    666   }
          667  +
          668  +/*
          669  +** Allocate and zero memory child memory.  If the allocation fails, set
          670  +** the mallocFailed flag in the connection pointer.
          671  +*/
          672  +void *sqlite3DbMallocZeroChild(sqlite3 *db, int n, void *pParent){
          673  +  void *p = sqlite3DbMallocRaw(db, n);
          674  +  if( p ){
          675  +    memset(p, 0, n);
          676  +    sqlite3MemLink(pParent, p);
          677  +  }
          678  +  return p;
          679  +}
          680  +
          681  +
   667    682   
   668    683   /*
   669    684   ** Allocate and zero memory.  If the allocation fails, make
   670    685   ** the mallocFailed flag in the connection pointer.
   671    686   **
   672    687   ** If db!=0 and db->mallocFailed is true (indicating a prior malloc
   673    688   ** failure on the same database connection) then always return 0.
................................................................................
   718    733               ((db && db->lookaside.bEnabled) ? MEMTYPE_DB : MEMTYPE_HEAP));
   719    734   
   720    735   finish_emalloc_raw:
   721    736     memset(p, 0, sizeof(EMemHdr));
   722    737     setValidEMem(p);
   723    738     return (void*)&p[1];
   724    739   }
          740  +
          741  +/*
          742  +** A convenience wrapper around sqlite3DbMallocRaw() and sqlite3MemLink().
          743  +*/
          744  +void *sqlite3DbMallocRawChild(sqlite3 *db, int n, void *pParent){
          745  +  void *p = sqlite3DbMallocRaw(db, n);
          746  +  sqlite3MemLink(pParent, p);
          747  +  return p;
          748  +}
   725    749   
   726    750   /*
   727    751   ** Resize the block of memory pointed to by p to n bytes. If the
   728    752   ** resize fails, set the mallocFailed flag in the connection object.
   729    753   **
   730    754   ** The pOld memory block must not be linked into an allocation hierarchy
   731    755   ** as a child.  It is OK for the allocation to be the root of a hierarchy

Changes to src/select.c.

  1264   1264     if( db->mallocFailed ) return;
  1265   1265     memset(&sNC, 0, sizeof(sNC));
  1266   1266     sNC.pSrcList = pSelect->pSrc;
  1267   1267     a = pSelect->pEList->a;
  1268   1268     for(i=0, pCol=aCol; i<nCol; i++, pCol++){
  1269   1269       p = a[i].pExpr;
  1270   1270       pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
         1271  +    sqlite3MemLink(aCol, pCol->zType);
  1271   1272       pCol->affinity = sqlite3ExprAffinity(p);
  1272   1273       if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
  1273   1274       pColl = sqlite3ExprCollSeq(pParse, p);
  1274   1275       if( pColl ){
  1275   1276         pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
         1277  +      sqlite3MemLink(aCol, pCol->zColl);
  1276   1278       }
  1277   1279     }
  1278   1280   }
  1279   1281   
  1280   1282   /*
  1281   1283   ** Given a SELECT statement, generate a Table structure that describes
  1282   1284   ** the result set of that SELECT.
................................................................................
  3093   3095         assert( pSel!=0 );
  3094   3096         assert( pFrom->pTab==0 );
  3095   3097         sqlite3WalkSelect(pWalker, pSel);
  3096   3098         pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
  3097   3099         if( pTab==0 ) return WRC_Abort;
  3098   3100         pTab->nRef = 1;
  3099   3101         pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
         3102  +      sqlite3MemLink(pTab, pTab->zName);
  3100   3103         while( pSel->pPrior ){ pSel = pSel->pPrior; }
  3101   3104         selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
  3102   3105         pTab->iPKey = -1;
  3103   3106         pTab->tabFlags |= TF_Ephemeral;
  3104   3107   #endif
  3105   3108       }else{
  3106   3109         /* An ordinary table or view name in the FROM clause */

Changes to src/sqliteInt.h.

  2483   2483   
  2484   2484   int sqlite3MallocInit(void);
  2485   2485   void sqlite3MallocEnd(void);
  2486   2486   void *sqlite3Malloc(int);
  2487   2487   void *sqlite3MallocZero(int);
  2488   2488   void *sqlite3DbMallocZero(sqlite3*, int);
  2489   2489   void *sqlite3DbMallocRaw(sqlite3*, int);
         2490  +void *sqlite3DbMallocZeroChild(sqlite3*, int, void *pParent);
         2491  +void *sqlite3DbMallocRawChild(sqlite3*, int, void *pParent);
  2490   2492   char *sqlite3DbStrDup(sqlite3*,const char*);
  2491   2493   char *sqlite3DbStrNDup(sqlite3*,const char*, int);
  2492   2494   void *sqlite3Realloc(void*, int);
  2493   2495   void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
  2494   2496   void *sqlite3DbRealloc(sqlite3 *, void *, int);
  2495   2497   void sqlite3DbFree(sqlite3*, void*);
  2496   2498   void sqlite3MemLink(void *pParent, void *pChild);
................................................................................
  2906   2908   CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
  2907   2909   char sqlite3AffinityType(const char*);
  2908   2910   void sqlite3Analyze(Parse*, Token*, Token*);
  2909   2911   int sqlite3InvokeBusyHandler(BusyHandler*);
  2910   2912   int sqlite3FindDb(sqlite3*, Token*);
  2911   2913   int sqlite3FindDbName(sqlite3 *, const char *);
  2912   2914   int sqlite3AnalysisLoad(sqlite3*,int iDB);
  2913         -void sqlite3DeleteIndexSamples(Index*);
  2914   2915   void sqlite3DefaultRowEst(Index*);
  2915   2916   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  2916   2917   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  2917   2918   void sqlite3MinimumFileFormat(Parse*, int, int);
  2918   2919   void sqlite3SchemaFree(void *);
  2919   2920   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  2920   2921   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);