szehon-ho opened a new pull request, #58145:
URL: https://github.com/apache/spark/pull/58145

   ### What changes were proposed in this pull request?
   
   Adds two optional methods to the `SupportsPushDownCatalystFilters` mix-in, 
both defaulting to `Nil`:
   
   - `additionalCatalystFilters`: filters the source inferred that the query 
did not state. Spark
     resolves their column names against the scan output and adds them to the 
logical `Filter`.
   - `fullyPushedFilters`: filters the source evaluates itself. An additional 
filter listed here is
     recorded on `DataSourceV2ScanRelation.pushedFilters` and dropped from 
`FilterExec`, so it stays
     available to the optimizer without being evaluated twice.
   
   `V2ScanRelationPushDown` resolves and appends the additional filters, and 
`DataSourceV2Strategy` is
   where a fully pushed filter is dropped from the physical `Filter`.
   
   ### Why are the changes needed?
   
   A source often knows a predicate the query did not state, and today it has 
no way to tell Spark.
   The common case is partitioning derived from a column: a table partitioned 
by a transform of a
   column (Iceberg partition transforms) or by a generated column derived from 
one (Delta generated
   columns) can translate `ts = '2026-01-01 10:00:00'` into a filter on the 
`days(ts)` partition
   column, and then read a single partition.
   
   Spark cannot see that. It estimates the scan from whole-table statistics, so 
a query reading one
   partition is costed as if it read everything, which affects join selection 
and other cost-based
   decisions. Reporting the inferred filter lets the optimizer size the scan 
from the partitions
   actually read. Keeping the filter on the logical `Filter` is what makes it 
visible to statistics
   estimation, while `fullyPushedFilters` avoids paying to evaluate it again.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. `SupportsPushDownCatalystFilters` lives in 
`org.apache.spark.sql.internal.connector`, both new
   methods have default implementations, and behavior is unchanged unless a 
source overrides them.
   
   ### How was this patch tested?
   
   New tests in `DataSourceV2Suite` cover the end-to-end behavior: an 
additional filter that is not
   fully pushed stays in `FilterExec`, and one that is fully pushed stays on 
the logical `Filter`, is
   recorded on the scan, and is dropped from `FilterExec`, with `checkAnswer` 
in both cases. The test
   source evaluates the filter it reports as fully pushed. New tests in 
`DataSourceV2StrategySuite`
   cover name resolution for nested columns (`s.tz`) and quoted dotted parts 
(`` `a.b`.`c.d` ``).
   
   Both suites pass: 101 tests, 0 failures.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Cursor (Claude Opus 4.5)


-- 
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