SQLite User Forum

Potential query optimiser bug
Login

Potential query optimiser bug

(1) By Josh (jleahy) on 2026-05-04 14:12:04 [link] [source]

I've found what I think is a bug in the SQLite query optimiser. If it is a bug, the my bisection shows it would have been introduced in 3.51.0 and is still present in 3.53.0.

This is a minimal reproducer:

CREATE TABLE t(n INTEGER, parent INTEGER);
CREATE INDEX idx ON t(parent);
INSERT INTO t VALUES (1,  NULL);
INSERT INTO t VALUES (10, NULL);

-- Reference (correct): prints 1.
SELECT count(*) FROM t b
 WHERE (b.parent IS NULL OR b.parent = 99)
   AND 5 <= +b.n;

-- Bug: should print 'match', prints nothing on 3.51.0+.
SELECT 'match' WHERE EXISTS (
  SELECT 1 FROM t b
   WHERE (b.parent IS NULL OR b.parent = 99)
     AND 5 <= +b.n
);

This wasn't discovered by an LLM fishing expedition, it was discovered in real-world usage (in a quite unpleasant way actually). However, for full disclosure, I utilised an LLM to minimise the issue and to perform the bisection.

I believe this was caused by the "Early detection of joins that return no rows due to one or more of the tables containing no rows" change in 3.51.0. It looks like this change introduced a number of bugs that were then later fixed, e.g.:

  • Fix incorrect results from nested EXISTS queries caused by the optimization in item 6b in the 3.51.0 release.
  • Fix multiple problems in the EXISTS-to-JOIN optimization that was added as part of optimization item 6b above.

That at least suggested to me that a bug in this area is possible (as opposed to me just failing to properly understand SQL, which admittedly remains a real possibility).

Interestingly the buggy query also gives no output if you swap "WHERE EXISTS" to "WHERE NOT EXISTS". Oddly the "+b.n" is actually required, it works properly if the second clause is simply "5 <= b.n". Presumably this unary plus is inhibiting some other code path that recognises simple range constraints even though it's actually a no-op.

(2) By Richard Hipp (drh) on 2026-05-04 18:44:00 in reply to 1 [link] [source]

Thanks for the bug report. This is the 8th bug that has resulted from the "Exists-to-Join" optimization that was added due to forum post 2025-06-27T09:10:26Z. Optimization is hard....

Please confirm that either of the following resolves your issue. After you confirm that the issue is resolved, we will cut release 3.53.1.

(3) By Josh (jleahy) on 2026-05-04 19:29:51 in reply to 2 [source]

Optimization is indeed hard.

Confirmed that both of these check-ins resolve both my reproducer as well as the original more complex issue that I was seeing.

Thank you.