Skip to content

fix: WHERE filter pushdown silently corrupts OR/CASE queries#154

Closed
jxom wants to merge 1 commit intomainfrom
fix/where-filter-pushdown
Closed

fix: WHERE filter pushdown silently corrupts OR/CASE queries#154
jxom wants to merge 1 commit intomainfrom
fix/where-filter-pushdown

Conversation

@jxom
Copy link
Copy Markdown
Member

@jxom jxom commented Mar 31, 2026

Audit Finding

WHERE Filter Pushdown Silently Corrupts Queries with OR/CASE Expressions by Forcing AND Restrictions on CTE (Severity: High)

Problem

extract_raw_column_predicates used visit_expressions to walk the entire AST, which extracted predicates from inside OR branches and CASE arms. These were then pushed down as AND restrictions on the CTE, silently changing query semantics.

For example:

SELECT * FROM Transfer WHERE block_num > 100 OR address = '0xABC'

Would incorrectly push block_num > 100 as an AND filter on the CTE, filtering out rows that matched address = '0xABC' but had block_num <= 100.

Fix

Replace visit_expressions with explicit WHERE clause extraction that only processes top-level AND conjuncts via flatten_and_conjuncts(). Complex expressions (OR, CASE, nested subexpressions) remain as single opaque conjuncts and are never decomposed for pushdown.

Tests Added

  • test_extract_raw_predicates_skips_or_expressions — pure OR not pushed down
  • test_extract_raw_predicates_skips_or_mixed_with_and — only safe AND conjuncts pushed down
  • test_extract_raw_predicates_skips_case_expressions — CASE not pushed down

The extract_raw_column_predicates function used visit_expressions to walk
the entire AST tree, which incorrectly extracted predicates from inside OR
branches and CASE arms as AND restrictions on the CTE. This silently
changed query semantics.

For example, WHERE block_num > 100 OR address = '0xABC' would push down
block_num > 100 as an AND restriction, filtering out rows that matched
address = '0xABC' but had block_num <= 100.

Fix: Replace visit_expressions with explicit WHERE clause extraction that
only processes top-level AND conjuncts via flatten_and_conjuncts(). Complex
expressions (OR, CASE, etc.) remain as single opaque conjuncts and are not
decomposed for pushdown.

Audit finding: WHERE Filter Pushdown Silently Corrupts Queries with
OR/CASE Expressions by Forcing AND Restrictions on CTE (High)

Amp-Thread-ID: https://ampcode.com/threads/T-019d4584-cd22-77c3-8001-677b460e61c6
Co-authored-by: Amp <amp@ampcode.com>
@jxom jxom closed this Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant