Skip to content

[GLUTEN-12753][CORE] Mark natively-handled PushedFilters with * for all file-source scans - #12626

Draft
felipepessoto wants to merge 3 commits into
apache:mainfrom
felipepessoto:vl-mark-pushedfilters-native-handled
Draft

[GLUTEN-12753][CORE] Mark natively-handled PushedFilters with * for all file-source scans#12626
felipepessoto wants to merge 3 commits into
apache:mainfrom
felipepessoto:vl-mark-pushedfilters-native-handled

Conversation

@felipepessoto

@felipepessoto felipepessoto commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #12753

What changes are proposed in this pull request?

Gluten's file-source scan transformers push every filter conjunct into the native scan via PushDownFilterToScan and evaluate them as exact row-level filters, so the paired FilterExecTransformer becomes a no-op (FilterExecTransformerBase.isNoop) and no separate post-scan Filter is needed. This is exactly the state Spark marks with a leading * in a scan's PushedFilters metadata — RowDataSourceScanExec's convention for a filter the source fully handles itself.

Gluten inherited FileSourceScanLike's rendering, which leaves PushedFilters unmarked, so its plan output under-reported what the native scan actually does. This PR marks each pushed-filter entry with * in the rendered plan string of FileSourceScanExecTransformerBase. Because metadata is a lazy val and cannot be super-overridden, the marking is applied to the rendered node string in both paths that print it:

  • simpleString (executedPlan.toString), and
  • verboseStringWithOperatorId (FormattedMode / plan-stability golden files).

Only FileSourceScanExecTransformer nodes are marked. AQE FormattedMode also prints an Initial Plan whose scans are vanilla FileSourceScanExec (Scan parquet); those are left unmarked, which matches runtime output and the semantics of * (the vanilla Initial-Plan scan still has a real Filter above it).

The change lives in the common gluten-substrait module (hence [CORE]). Golden plans are updated accordingly (TPC-H approved-plan, TPC-DS plan-stability, and gluten-tpch-plan-stability across the supported Spark versions): every offloaded FileSourceScanExecTransformer PushedFilters entry now carries *, while vanilla Initial-Plan scan entries stay unmarked. The goldens contain no DataSource V2 BatchScan PushedFilters, so no V2 golden is affected.

How was this patch tested?

  • gluten-substrait compiles against main (spark-3.5 / scala-2.12).
  • Golden plans regenerated deterministically and cross-checked: 0 vanilla Scan parquet nodes marked and 0 FileSourceScanExecTransformer nodes left unmarked across all 1672 golden files. The golden diff is purely the * toggling (no unrelated plan drift).
  • The updated PushedFilters rendering is exercised by the existing VeloxTPCHSuite golden-file checks and the TPC-DS / TPC-H plan-stability suites.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: GitHub Copilot CLI (Claude Opus 4.8)

Copilot AI lite review requested due to automatic review settings July 26, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions github-actions Bot added CORE works for Gluten Core VELOX labels Jul 26, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@felipepessoto felipepessoto changed the title [VL] Mark natively-handled PushedFilters with * for all file-source scans [GLUTEN-12753][CORE] Mark natively-handled PushedFilters with * for all file-source scans Aug 11, 2026
@felipepessoto
felipepessoto force-pushed the vl-mark-pushedfilters-native-handled branch from 92aee41 to 1bb3bd4 Compare August 11, 2026 20:56
Copilot AI review requested due to automatic review settings August 11, 2026 20:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@felipepessoto
felipepessoto force-pushed the vl-mark-pushedfilters-native-handled branch from 1bb3bd4 to 7f697b6 Compare August 11, 2026 21:35
Copilot AI review requested due to automatic review settings August 11, 2026 21:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI review requested due to automatic review settings August 11, 2026 22:08
@felipepessoto
felipepessoto force-pushed the vl-mark-pushedfilters-native-handled branch from 7f697b6 to 9375f7d Compare August 11, 2026 22:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@felipepessoto
felipepessoto marked this pull request as draft August 12, 2026 16:47
… all file-source scans

Gluten's file-source scan transformers push every filter conjunct into the native
scan via PushDownFilterToScan and evaluate them as exact row-level filters, so the
paired FilterExecTransformer becomes a no-op (FilterExecTransformerBase.isNoop) and
no separate post-scan Filter is needed. This is exactly the state Spark marks with
a leading `*` in a scan's `PushedFilters` metadata (RowDataSourceScanExec's
convention for a filter the source fully handles itself).

Gluten inherited FileSourceScanLike's rendering, which leaves `PushedFilters`
unmarked, so its plan output under-reported what the native scan actually does.
Mark each pushed-filter entry with `*` in the rendered plan string of
FileSourceScanExecTransformerBase. `metadata` is a lazy val and cannot be
super-overridden, so the marking is applied to the rendered node string in both
paths that print it:
  - simpleString (executedPlan.toString), and
  - verboseStringWithOperatorId (FormattedMode / plan-stability golden files).

The mark is gated on the backend actually accepting Gluten's full filter pushdown
(SparkPlanExecApi.supportPushDownFilterToScan). ClickHouse deliberately declines it
for Parquet to keep vanilla-Spark best-effort semantics, and there
BasicScanExecTransformer.filterExprs() silently drops filters the backend cannot
evaluate, leaving a real (non-no-op) FilterExecTransformer above the scan -- marking
those would be a false claim. Velox does not override the default (true), so its
rendering is unaffected.

Only FileSourceScanExecTransformer nodes are marked. AQE FormattedMode also prints
an Initial Plan whose scans are vanilla FileSourceScanExec (`Scan parquet`); those
are left unmarked, matching runtime output and the semantics of `*` (the vanilla
Initial-Plan scan still has a real Filter above it).

The change lives in the common gluten-substrait module (hence [CORE]). Golden plans
updated accordingly (TPC-H approved-plan, TPC-DS plan-stability, and
gluten-tpch-plan-stability across the supported Spark versions): every offloaded
FileSourceScanExecTransformer PushedFilters entry now carries `*`, while vanilla
Initial-Plan scan entries stay unmarked. The goldens contain no DataSourceV2
BatchScan PushedFilters, so no V2 golden is affected.

Add FileSourceScanExecTransformerPushedFiltersSuite covering the rendering helpers
directly: entry marking, column names containing spaces, commas nested inside an
entry (e.g. `In(id, [1,2,3])`), empty/non-list values, that only the PushedFilters
list is rewritten, and that an unbalanced list degrades to unchanged text rather
than being corrupted. It needs no native library, so it runs in the regular JVM
test job.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 02286396-395f-41db-ad89-ad69a192cded
@felipepessoto
felipepessoto force-pushed the vl-mark-pushedfilters-native-handled branch from 9375f7d to 0299776 Compare August 14, 2026 20:46
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Removed known failures related to Delta CDC tests from the list.
@github-actions github-actions Bot added the INFRA label Aug 15, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

…al-char columns

Delta's CDF filter-pushdown tests over a column-mapping table
(DeltaCDC{Id,Name}ColumnMappingSuite / SQL variants, "filters with special
characters in name should be pushed down") assert:

  PushedFilters: [*IsNotNull(id with space), *LessThan(id with space,5)]

Vanilla Delta serves a CDF read through a single PrunedFilteredScan
(DeltaCDFRelation), whose V1 PushedFilters are translated with nested-predicate
pushdown DISABLED, so a column name is rendered verbatim (unquoted). Gluten
offloads the CDF read to a parquet-backed scan, where Spark translates the same
filters with nested pushdown ENABLED and back-quotes any name that needs quoting:

  PushedFilters: [*IsNotNull(`id with space`), *LessThan(`id with space`,5)]

The `*` (added for all Gluten file scans in the prior commits) was already
correct; only the display-only back-quoting differed. Drop it for CDF scans to
match vanilla Delta. Scope is limited to CDF scans (relation.location is
CdcAddFileIndex / TahoeRemoveFileIndex / TahoeChangeFileIndex): a regular Delta
read is a parquet scan in vanilla Spark too and legitimately keeps the quoting.

`metadata` is a lazy val and cannot be super-overridden, so both rewrites (`*`
marking in the base, back-quote removal here) are applied to the rendered plan
string. Factor the list-locating logic in FileSourceScanExecTransformerBase into a
reusable `rewritePushedFiltersList` so DeltaScanTransformer layers the CDF
un-quoting over the base `*`-marking in simpleString / verboseStringWithOperatorId.
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@felipepessoto
felipepessoto marked this pull request as ready for review August 15, 2026 08:47
Copilot AI review requested due to automatic review settings August 15, 2026 08:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@felipepessoto felipepessoto reopened this Aug 15, 2026
@felipepessoto
felipepessoto marked this pull request as draft August 15, 2026 19:33
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native-handled PushedFilters are not marked with * in file-source scan plans

2 participants