xudong963 opened a new issue, #26131:
URL: https://github.com/apache/datafusion/issues/26131

   ### Is your feature request related to a problem or challenge?
   
   Follow-up to #25207 and #5830: simplify a disjunction using range 
constraints supplied by surrounding conjunctions.
   
   The motivating query is a `UNION ALL` of a primary table and a historical 
backfill table. The backfill branch explicitly restricts a timestamp column to 
two disjoint periods. A client applies a time range to the union, possibly 
followed by `ORDER BY ... LIMIT`. When the client range overlaps neither 
backfill period, the goal is to eliminate that branch during logical 
optimization, before calling its table provider's `scan()` method. This can 
avoid planning-time file listing or index access as well as execution-time 
reads.
   
   An integer-only example isolates the predicate shape:
   
   ```sql
   CREATE TABLE t AS
   SELECT * FROM (VALUES (1), (6), (11)) AS v(x);
   
   SET datafusion.explain.format = 'indent';
   
   EXPLAIN
   SELECT x
   FROM t
   WHERE x >= 10
     AND (
       (x >= 1 AND x < 3)
       OR
       (x >= 5 AND x < 7)
     );
   ```
   
   No value can satisfy this predicate, regardless of the table contents. Under 
the outer `x >= 10` condition, both disjuncts are impossible.
   
   #25207 handles contradictions among direct column comparisons in a 
conjunction. In the current [`simplify_predicates` 
implementation](https://github.com/apache/datafusion/blob/97c7593f609b277f65c086a7868a92c24ab5f8f2/datafusion/optimizer/src/simplify_expressions/simplify_predicates.rs),
 an `OR` expression falls into `other_predicates` and is retained without 
comparing its branches against the surrounding range constraints. This request 
is specifically for that contextual range reasoning.
   
   ### Describe the solution you'd like
   
   Recognize that the example's filter can never be true and produce an 
`EmptyRelation` with the correct output schema. In the corresponding `UNION 
ALL` query, propagate that empty relation and remove the impossible branch 
before physical planning invokes its provider.
   
   One possible approach is to collect supported range constraints from the 
outer conjunction and use them to simplify the remaining expression 
recursively. `ExprSimplifier::with_guarantees()` may provide reusable 
machinery. Conceptually:
   
   ```text
   P AND Q
       -> P AND simplify(Q, assuming ranges established by P)
   
   x >= 10 AND (first_interval OR second_interval)
       -> x >= 10 AND (FALSE OR FALSE)
       -> FALSE
   ```
   
   The predicates supplying the assumptions must be retained unless a separate 
proof establishes that they are redundant. Fully distributing arbitrary AND/OR 
expressions into DNF should not be necessary; analysis can have a work/depth 
budget and conservatively keep expressions it cannot prove.
   
   Useful regression coverage:
   
   - Both disjuncts contradict the outer range: produce an empty relation.
   - Only one disjunct contradicts it: retain the satisfiable branch.
   - The requested range falls in the gap between the two intervals.
   - Inclusive/exclusive endpoints, nullable columns, and timestamp 
precision/time zones.
   - An unsupported or potentially satisfiable disjunct must prevent 
incorrectly declaring the whole OR impossible.
   - A `UNION ALL` integration test with a mock provider confirms the 
eliminated branch's `scan()` is not called, including an outer sort/limit.
   
   This should preserve WHERE-clause semantics; replacing an expression that 
can be NULL with FALSE is not generally valid in projection expressions.
   
   ### Describe alternatives you've considered
   
   - Add a redundant enclosing interval alongside the exact OR predicate. This 
exposes a simple contradiction for requests outside the overall interval, but 
cannot identify requests that fall in the gap.
   - Split the disjoint periods into separate `UNION ALL` branches. This 
exposes direct conjunctions but changes the query structure and may increase 
planning overhead for overlapping requests.
   - Rely on partition/file pruning or physical empty-branch elimination. These 
can reduce reads, but may happen after the provider has already performed 
planning-time I/O.
   
   ### Additional context
   
   Source inspected at upstream `main` commit 
`97c7593f609b277f65c086a7868a92c24ab5f8f2`.
   
   The SQL above was executed locally on a `datafusion-cli 55.0.0` build and 
retained this logical plan:
   
   ```text
   Filter: t.x >= Int64(10) AND (t.x >= Int64(1) AND t.x < Int64(3) OR t.x >= 
Int64(5) AND t.x < Int64(7))
     TableScan: t projection=[x]
   ```
   
   That local build predates #25207; this output is not presented as a 
reproduction on current `main`. The proposed extension beyond #25207 is based 
on the source inspection linked above. I have not run the full current-main 
optimizer pipeline for this example.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to