/ Check-in [2f58c8c9]
Login

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

Overview
Comment:Fix a memory leak caused by duplicate entries in the sqlite_stat1 table.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2f58c8c9722fffc486610f9e6b08178d53a56b64
User & Date: dan 2015-04-20 15:13:08
Context
2015-04-20
18:58
Many new configuration options for fuzzershell. check-in: 41c95439 user: drh tags: trunk
15:13
Fix a memory leak caused by duplicate entries in the sqlite_stat1 table. check-in: 2f58c8c9 user: dan tags: trunk
13:59
Fix an obscure memory leak in sqlite3Stat4ProbeFree() check-in: c72abbe2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

  1515   1515       pIndex = sqlite3PrimaryKeyIndex(pTable);
  1516   1516     }else{
  1517   1517       pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  1518   1518     }
  1519   1519     z = argv[2];
  1520   1520   
  1521   1521     if( pIndex ){
         1522  +    tRowcnt *aiRowEst = 0;
  1522   1523       int nCol = pIndex->nKeyCol+1;
  1523   1524   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1524         -    tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
  1525         -        sizeof(tRowcnt) * nCol
  1526         -    );
  1527         -    if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
  1528         -#else
  1529         -    tRowcnt * const aiRowEst = 0;
         1525  +    /* Index.aiRowEst may already be set here if there are duplicate 
         1526  +    ** sqlite_stat1 entries for this index. In that case just clobber
         1527  +    ** the old data with the new instead of allocating a new array.  */
         1528  +    if( pIndex->aiRowEst==0 ){
         1529  +      pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
         1530  +      if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
         1531  +    }
         1532  +    aiRowEst = pIndex->aiRowEst;
  1530   1533   #endif
  1531   1534       pIndex->bUnordered = 0;
  1532   1535       decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
  1533   1536       if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  1534   1537     }else{
  1535   1538       Index fakeIdx;
  1536   1539       fakeIdx.szIdxRow = pTable->szTabRow;

Changes to test/analyze3.test.

    12     12   # This file implements regression tests for SQLite library. This file 
    13     13   # implements tests for range and LIKE constraints that use bound variables
    14     14   # instead of literal constant arguments.
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
           19  +set testprefix analyze3
    19     20   
    20     21   ifcapable !stat4&&!stat3 {
    21     22     finish_test
    22     23     return
    23     24   }
    24     25   
    25     26   #----------------------------------------------------------------------
................................................................................
    41     42   #               within sqlite3Reprepare() are handled correctly.
    42     43   #
    43     44   # analyze3-5.*: Check that the query plans of applicable statements are
    44     45   #               invalidated if the values of SQL parameter are modified
    45     46   #               using the clear_bindings() or transfer_bindings() APIs.
    46     47   # 
    47     48   # analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
           49  +#
           50  +# analyze3-7.*: Test that some memory leaks discovered by fuzz testing 
           51  +#               have been fixed.
    48     52   #
    49     53   
    50     54   proc getvar {varname} { uplevel #0 set $varname }
    51     55   db function var getvar
    52     56   
    53     57   proc eqp {sql {db db}} {
    54     58     uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
................................................................................
   670    674     DROP TABLE IF EXISTS t1;
   671    675     CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
   672    676     INSERT INTO t1 VALUES(1,1,'0000');
   673    677     CREATE INDEX t0b ON t1(b);
   674    678     ANALYZE;
   675    679     SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
   676    680   } {}
          681  +
          682  +# At one point duplicate stat1 entries were causing a memory leak.
          683  +#
          684  +reset_db
          685  +do_execsql_test 7.2 {
          686  +  CREATE TABLE t1(a,b,c);
          687  +  CREATE INDEX t1a ON t1(a);
          688  +  ANALYZE;
          689  +  SELECT * FROM sqlite_stat1;
          690  +  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
          691  +  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
          692  +  ANALYZE sqlite_master;
          693  +}
   677    694   
   678    695   finish_test