Bug description
Description
Calculated column expressions containing OR are embedded into the WHERE clause without parentheses. Due to SQL operator precedence (AND binds tighter than OR), preceding filter conditions including time range filters are silently dropped.
This is the same class of bug fixed by #38183 for extras.where/extras.having, but on a different code path. PR #38183 wrapped adhoc SQL filter expressions in Grouping at helpers.py:3244. Calculated columns used as SIMPLE filters (e.g., IS TRUE, IN, =) go through a separate path - convert_tbl_column_to_sqla_col() → literal_column(expression) - and are not parenthesized.
Steps to Reproduce
-
Create a calculated column with an OR expression:
- Name:
is_active
- Expression:
status = 'active' OR status = 'pending'
-
Create a chart with a time range filter and add filter: is_active IS TRUE
-
Generated SQL:
WHERE __time >= '2026-01-01' AND __time < '2026-02-01' AND status = 'active' OR status = 'pending' IS TRUE
-
SQL parses this as:
WHERE (__time >= '2026-01-01' AND __time < '2026-02-01' AND status = 'active')
OR (status = 'pending' IS TRUE)
The time range filter is silently dropped from the second branch, and we will end up visualizing 'pending' data outside of the chosen time range.
Expected Behavior
WHERE __time >= '2026-01-01' AND __time < '2026-02-01' AND (status = 'active' OR status = 'pending') IS TRUE
Proposed Fix
Following the same pattern as #38183, wrap expression-based columns in Grouping when used in the filter path of get_sqla_query() (after sqla_col is finalized at ~line 3067):
if sqla_col is not None and (
(col_obj and col_obj.expression) or is_adhoc_column(flt_col)
):
sqla_col = Grouping(sqla_col)
This affects only WHERE/HAVING. Other keywords like SELECT, GROUP BY, and ORDER BY are unchanged. Affects all database backends.
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.9
Node version
16
Browser
Chrome
Additional context
No response
Checklist
Bug description
Description
Calculated column expressions containing
ORare embedded into theWHEREclause without parentheses. Due to SQL operator precedence (ANDbinds tighter thanOR), preceding filter conditions including time range filters are silently dropped.This is the same class of bug fixed by #38183 for
extras.where/extras.having, but on a different code path. PR #38183 wrapped adhoc SQL filter expressions inGroupingathelpers.py:3244. Calculated columns used as SIMPLE filters (e.g.,IS TRUE,IN,=) go through a separate path -convert_tbl_column_to_sqla_col()→literal_column(expression)- and are not parenthesized.Steps to Reproduce
Create a calculated column with an
ORexpression:is_activestatus = 'active' OR status = 'pending'Create a chart with a time range filter and add filter:
is_active IS TRUEGenerated SQL:
SQL parses this as:
The time range filter is silently dropped from the second branch, and we will end up visualizing 'pending' data outside of the chosen time range.
Expected Behavior
Proposed Fix
Following the same pattern as #38183, wrap expression-based columns in
Groupingwhen used in the filter path ofget_sqla_query()(aftersqla_colis finalized at ~line 3067):This affects only WHERE/HAVING. Other keywords like SELECT, GROUP BY, and ORDER BY are unchanged. Affects all database backends.
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.9
Node version
16
Browser
Chrome
Additional context
No response
Checklist