/ Check-in [2f58c8c9]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 Unified Diffs Show Whitespace Changes 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
..
41
42
43
44
45
46
47



48
49
50
51
52
53
54
...
670
671
672
673
674
675
676
677













678
# 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
}

#----------------------------------------------------------------------
................................................................................
#               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
................................................................................
  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







>







 







>
>
>







 








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

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
# 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
}

#----------------------------------------------------------------------
................................................................................
#               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
................................................................................
  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