SQLite

Check-in [1a6328f2]
Login

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

Overview
Comment:Fix the Bloom-filter optimization so that it does not use IS NULL or IS NOT NULL constraints from the WHERE clause when operating on a LEFT JOIN. Forum thread 031e262a89b6a9d2.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2
User & Date: drh 2022-03-25 01:23:37
Context
2022-03-28
13:22
Performance optimization in the memsys5 memory allocator. (check-in: 94913323 user: drh tags: trunk)
2022-03-25
20:39
Sync w/trunk (check-in: 8402e5e7 user: larrybr tags: cli_extension)
01:31
Fix the Bloom-filter optimization so that it does not use IS NULL or IS NOT NULL constraints from the WHERE clause when operating on a LEFT JOIN. Forum thread 031e262a89b6a9d2. (check-in: 8246bfbc user: drh tags: branch-3.38)
01:23
Fix the Bloom-filter optimization so that it does not use IS NULL or IS NOT NULL constraints from the WHERE clause when operating on a LEFT JOIN. Forum thread 031e262a89b6a9d2. (check-in: 1a6328f2 user: drh tags: trunk)
2022-03-24
14:01
The "PRAGMA writable_schema=ON" flag should not allow OOM errors to pass while parsing the schema. dbsqlfuzz 9cc49e1a53e1cef8e3a1496a88c683aa20483163. (check-in: a7abb725 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/where.c.

2592
2593
2594
2595
2596
2597
2598
2599








2600

2601
2602
2603
2604
2605
2606
2607
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
      if( pLoop->maskSelf==pTerm->prereqAll ){
        /* If there are extra terms in the WHERE clause not used by an index
        ** that depend only on the table being scanned, and that will tend to
        ** cause many rows to be omitted, then mark that table as
        ** "self-culling". */








        pLoop->wsFlags |= WHERE_SELFCULL;

      }
      if( pTerm->truthProb<=0 ){
        /* If a truth probability is specified using the likelihood() hints,
        ** then use the probability provided by the application. */
        pLoop->nOut += pTerm->truthProb;
      }else{
        /* In the absence of explicit truth probabilities, use heuristics to







|
>
>
>
>
>
>
>
>
|
>







2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
      if( pLoop->maskSelf==pTerm->prereqAll ){
        /* If there are extra terms in the WHERE clause not used by an index
        ** that depend only on the table being scanned, and that will tend to
        ** cause many rows to be omitted, then mark that table as
        ** "self-culling".
        **
        ** 2022-03-24:  Self-culling only applies if either the extra terms
        ** are straight comparison operators that are non-true with NULL
        ** operand, or if the loop is not a LEFT JOIN.
        */
        if( (pTerm->eOperator & 0x3f)!=0
         || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
        ){
          pLoop->wsFlags |= WHERE_SELFCULL;
        }
      }
      if( pTerm->truthProb<=0 ){
        /* If a truth probability is specified using the likelihood() hints,
        ** then use the probability provided by the application. */
        pLoop->nOut += pTerm->truthProb;
      }else{
        /* In the absence of explicit truth probabilities, use heuristics to

Changes to test/join5.test.

297
298
299
300
301
302
303







304
305
306
307
308
309
310

  ANALYZE;
}

do_eqp_test 7.4 {
  SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
} {







  QUERY PLAN
  |--SCAN t3
  |--BLOOM FILTER ON t4 (x=?)
  `--SEARCH t4 USING INDEX t4xz (x=?)
} 

reset_db







>
>
>
>
>
>
>







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

  ANALYZE;
}

do_eqp_test 7.4 {
  SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
} {
  QUERY PLAN
  |--SCAN t3
  `--SEARCH t4 USING INDEX t4xz (x=?)
} 
do_eqp_test 7.4b {
  SELECT * FROM t3 CROSS JOIN t4 ON (t4.x = t3.x) WHERE (+t4.y = ? OR t4.z = ?);
} {
  QUERY PLAN
  |--SCAN t3
  |--BLOOM FILTER ON t4 (x=?)
  `--SEARCH t4 USING INDEX t4xz (x=?)
} 

reset_db
355
356
357
358
359
360
361
362


363

























364
  DELETE FROM t1;
  INSERT INTO t1 VALUES(0),(0);
  CREATE VIEW v1 AS SELECT * FROM t1 NATURAL JOIN t1 WHERE (x BETWEEN 0 AND 10) OR true;
  CREATE VIEW v2 AS SELECT * FROM v1 NATURAL JOIN v1;
  CREATE VIEW v3 AS SELECT * FROM v2, v1 USING (x) GROUP BY x;
  SELECT x FROM v3; 
} {0}





























finish_test








>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  DELETE FROM t1;
  INSERT INTO t1 VALUES(0),(0);
  CREATE VIEW v1 AS SELECT * FROM t1 NATURAL JOIN t1 WHERE (x BETWEEN 0 AND 10) OR true;
  CREATE VIEW v2 AS SELECT * FROM v1 NATURAL JOIN v1;
  CREATE VIEW v3 AS SELECT * FROM v2, v1 USING (x) GROUP BY x;
  SELECT x FROM v3; 
} {0}

# 2022-03-24 https://sqlite.org/forum/forumpost/031e262a89b6a9d2
# Bloom-filter on a LEFT JOIN with NULL-based WHERE constraints.
#
reset_db
do_execsql_test 11.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
  CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<8)
  INSERT INTO t1(a,b) SELECT x, 10*x FROM c;
  INSERT INTO t2(c,d) SELECT b*2, 100*a FROM t1;
  ANALYZE;
  DELETE FROM sqlite_stat1;
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES
    ('t1',NULL,150105),('t2',NULL,98747);
  ANALYZE sqlite_schema;
} {}
do_execsql_test 11.2 {
  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d IS NULL;
} {4}
do_execsql_test 11.3 {
  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d=100;
} {1}
do_execsql_test 11.4 {
  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d>=300;
} {2}



finish_test