SQLite

Check-in [17152bf1a2]
Login

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

Overview
Comment:Fix a vdbe stack leak that could occur where one side of a WHERE clause inequality evaluated to SQL null. (CVS 4045)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 17152bf1a268e130f0c43046bb438b617a747ff5
User & Date: danielk1977 2007-06-02 07:54:38.000
Context
2007-06-07
10:55
Add the SQLITE_MAX_COMPOUND_SELECT compile-time parameter for limiting the number of terms in a compound select statement. Set the default limit to 100. (CVS 4046) (check-in: 0d71ad4591 user: drh tags: trunk)
2007-06-02
07:54
Fix a vdbe stack leak that could occur where one side of a WHERE clause inequality evaluated to SQL null. (CVS 4045) (check-in: 17152bf1a2 user: danielk1977 tags: trunk)
2007-05-31
08:20
Extend out-of-memory testing with fuzzily generated sql some. One fix for a problem found by the same. (CVS 4044) (check-in: d2282e64f1 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.249 2007/05/29 12:11:30 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.250 2007/06/02 07:54:38 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
        Expr *pX;
        int k = pIdx->aiColumn[j];
        pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx);
        assert( pTerm!=0 );
        pX = pTerm->pExpr;
        assert( (pTerm->flags & TERM_CODED)==0 );
        sqlite3ExprCode(pParse, pX->pRight);
        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), nxt);
        topEq = pTerm->eOperator & (WO_LE|WO_GE);
        disableTerm(pLevel, pTerm);
        testOp = OP_IdxGE;
      }else{
        testOp = nEq>0 ? OP_IdxGE : OP_Noop;
        topEq = 1;
      }







|







2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
        Expr *pX;
        int k = pIdx->aiColumn[j];
        pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx);
        assert( pTerm!=0 );
        pX = pTerm->pExpr;
        assert( (pTerm->flags & TERM_CODED)==0 );
        sqlite3ExprCode(pParse, pX->pRight);
        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq*2+1), nxt);
        topEq = pTerm->eOperator & (WO_LE|WO_GE);
        disableTerm(pLevel, pTerm);
        testOp = OP_IdxGE;
      }else{
        testOp = nEq>0 ? OP_IdxGE : OP_Noop;
        topEq = 1;
      }
Changes to test/where4.test.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the use of indices in WHERE clauses.
# This file was created when support for optimizing IS NULL phrases
# was added.  And so the principle purpose of this file is to test
# that IS NULL phrases are correctly optimized.  But you can never
# have too many tests, so some other tests are thrown in as well.
#
# $Id: where4.test,v 1.3 2007/03/28 14:30:09 drh Exp $

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

# Build some test data
#
do_test where4-1.0 {







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the use of indices in WHERE clauses.
# This file was created when support for optimizing IS NULL phrases
# was added.  And so the principle purpose of this file is to test
# that IS NULL phrases are correctly optimized.  But you can never
# have too many tests, so some other tests are thrown in as well.
#
# $Id: where4.test,v 1.4 2007/06/02 07:54:38 danielk1977 Exp $

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

# Build some test data
#
do_test where4-1.0 {
225
226
227
228
229
230
231
232
































233
  }
  execsql {
    SELECT * FROM t6 WHERE y=NULL AND z IN ('hello');
  }
} {}

integrity_check {where4-99.0}

































finish_test








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

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  }
  execsql {
    SELECT * FROM t6 WHERE y=NULL AND z IN ('hello');
  }
} {}

integrity_check {where4-99.0}

do_test where4-7.1 {
  execsql {
    BEGIN;
    CREATE TABLE t8(a, b, c, d);
    CREATE INDEX t8_i ON t8(a, b, c);
    CREATE TABLE t7(i);

    INSERT INTO t7 VALUES(1);
    INSERT INTO t7 SELECT i*2 FROM t7;
    INSERT INTO t7 SELECT i*2 FROM t7;
    INSERT INTO t7 SELECT i*2 FROM t7;
    INSERT INTO t7 SELECT i*2 FROM t7;
    INSERT INTO t7 SELECT i*2 FROM t7;
    INSERT INTO t7 SELECT i*2 FROM t7;

    COMMIT;
  }
} {}

# At one point the sub-select inside the aggregate sum() function in the
# following query was leaking a couple of stack entries. This query 
# runs the SELECT in a loop enough times that an assert() fails. Or rather,
# did fail before the bug was fixed.
#
do_test where4-7.2 {
  execsql {
    SELECT sum((
      SELECT d FROM t8 WHERE a = i AND b = i AND c < NULL
    )) FROM t7;
  }
} {{}}

finish_test