SQLite

Check-in [2f58c8c972]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2f58c8c9722fffc486610f9e6b08178d53a56b64
User & Date: dan 2015-04-20 15:13:08.018
Context
2015-04-20
18:58
Many new configuration options for fuzzershell. (check-in: 41c9543916 user: drh tags: trunk)
15:13
Fix a memory leak caused by duplicate entries in the sqlite_stat1 table. (check-in: 2f58c8c972 user: dan tags: trunk)
13:59
Fix an obscure memory leak in sqlite3Stat4ProbeFree() (check-in: c72abbe2c1 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/analyze.c.
1515
1516
1517
1518
1519
1520
1521

1522
1523



1524
1525
1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536
    pIndex = sqlite3PrimaryKeyIndex(pTable);
  }else{
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }
  z = argv[2];

  if( pIndex ){

    int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4



    tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
        sizeof(tRowcnt) * nCol
    );
    if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
#else

    tRowcnt * const aiRowEst = 0;
#endif
    pIndex->bUnordered = 0;
    decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
    if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  }else{
    Index fakeIdx;
    fakeIdx.szIdxRow = pTable->szTabRow;







>


>
>
>
|
|
<
|
<
>
|







1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529

1530

1531
1532
1533
1534
1535
1536
1537
1538
1539
    pIndex = sqlite3PrimaryKeyIndex(pTable);
  }else{
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }
  z = argv[2];

  if( pIndex ){
    tRowcnt *aiRowEst = 0;
    int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    /* Index.aiRowEst may already be set here if there are duplicate 
    ** sqlite_stat1 entries for this index. In that case just clobber
    ** the old data with the new instead of allocating a new array.  */
    if( pIndex->aiRowEst==0 ){
      pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);

      if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;

    }
    aiRowEst = pIndex->aiRowEst;
#endif
    pIndex->bUnordered = 0;
    decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
    if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  }else{
    Index fakeIdx;
    fakeIdx.szIdxRow = pTable->szTabRow;
Changes to test/analyze3.test.
12
13
14
15
16
17
18

19
20
21
22
23
24
25
# This file implements regression tests for SQLite library. This file 
# implements tests for range and LIKE constraints that use bound variables
# instead of literal constant arguments.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


ifcapable !stat4&&!stat3 {
  finish_test
  return
}

#----------------------------------------------------------------------







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file implements regression tests for SQLite library. This file 
# implements tests for range and LIKE constraints that use bound variables
# instead of literal constant arguments.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix analyze3

ifcapable !stat4&&!stat3 {
  finish_test
  return
}

#----------------------------------------------------------------------
41
42
43
44
45
46
47



48
49
50
51
52
53
54
#               within sqlite3Reprepare() are handled correctly.
#
# analyze3-5.*: Check that the query plans of applicable statements are
#               invalidated if the values of SQL parameter are modified
#               using the clear_bindings() or transfer_bindings() APIs.
# 
# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.



#

proc getvar {varname} { uplevel #0 set $varname }
db function var getvar

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db







>
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#               within sqlite3Reprepare() are handled correctly.
#
# analyze3-5.*: Check that the query plans of applicable statements are
#               invalidated if the values of SQL parameter are modified
#               using the clear_bindings() or transfer_bindings() APIs.
# 
# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
#
# analyze3-7.*: Test that some memory leaks discovered by fuzz testing 
#               have been fixed.
#

proc getvar {varname} { uplevel #0 set $varname }
db function var getvar

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
670
671
672
673
674
675
676
677













678
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1,1,'0000');
  CREATE INDEX t0b ON t1(b);
  ANALYZE;
  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
} {}














finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1,1,'0000');
  CREATE INDEX t0b ON t1(b);
  ANALYZE;
  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
} {}

# At one point duplicate stat1 entries were causing a memory leak.
#
reset_db
do_execsql_test 7.2 {
  CREATE TABLE t1(a,b,c);
  CREATE INDEX t1a ON t1(a);
  ANALYZE;
  SELECT * FROM sqlite_stat1;
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
  ANALYZE sqlite_master;
}

finish_test