[GLUTEN-12538][VL] Fall back to row-based Delta stats when the stats plan cannot be offloaded#12539
Draft
felipepessoto wants to merge 1 commit into
Draft
[GLUTEN-12538][VL] Fall back to row-based Delta stats when the stats plan cannot be offloaded#12539felipepessoto wants to merge 1 commit into
felipepessoto wants to merge 1 commit into
Conversation
felipepessoto
force-pushed
the
delta-stats-fallback
branch
from
July 17, 2026 05:52
6cb6a6d to
cbcb8b4
Compare
…plan cannot be offloaded GlutenDeltaJobStatsTracker collects Delta write statistics by building a local Velox aggregation plan and assuming it is always offloaded to a WholeStageTransformer. When the stats plan references a type/expression Velox cannot offload (for example an aggregate over TIMESTAMP_NTZ), the offload rules reject it and leave a vanilla ProjectExec, so the unconditional cast threw `ClassCastException: ProjectExec cannot be cast to WholeStageTransformer` and failed the whole write. The decision is now made on the executor in newTaskInstance(), where the native plan is actually built. tryBuildOffloadedStatsPlan builds the aggregation plan, runs the offload rules, and returns the offloaded TransformSupport only when the WHOLE plan was offloaded -- every node except the StatisticsInputNode leaf is a TransformSupport (a root WholeStageTransformer is not sufficient, since ColumnarCollapseTransformStages can wrap an offloaded parent above a vanilla child). Otherwise it returns None and statistics are collected the row-based way through the existing GlutenDeltaJobStatsFallbackTracker. Native resources are allocated only on the accepted path. Add DeltaTimestampNtzStatsWriteSuite covering top-level and struct-nested TIMESTAMP_NTZ columns: the native write succeeds and Delta min/max statistics are still produced via the fallback. Generated-by: GitHub Copilot CLI (Claude Opus 4.8) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 66a9e40f-3ac8-45be-8fee-a606a22fa098
felipepessoto
force-pushed
the
delta-stats-fallback
branch
from
July 17, 2026 23:27
cbcb8b4 to
8106751
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes are proposed in this pull request?
Fixes #12538.
GlutenDeltaJobStatsTrackercollects Delta write statistics by building a local Velox aggregation plan and assuming it is always offloaded to aWholeStageTransformer. When the statistics plan references a type or expression Velox cannot offload — for example an aggregate over aTIMESTAMP_NTZcolumn — the offload rules reject it and leave a vanillaProjectExec, so the unconditional cast threw:failing the whole write.
This PR makes the Delta stats path fall back to row-based statistics collection when the plan cannot be fully offloaded, as suggested by rui-mo and zhztheplayer in 12388:
newTaskInstance(), where the native plan is actually built.tryBuildOffloadedStatsPlanbuilds the aggregation plan, runs the offload rules, and returns the offloadedTransformSupportonly when the whole plan was offloaded — every node except theStatisticsInputNodeleaf is aTransformSupport. A rootWholeStageTransformeralone is not sufficient, becauseColumnarCollapseTransformStagescan wrap an offloaded parent above a vanilla child.Noneand statistics are collected the row-based way through the existingGlutenDeltaJobStatsFallbackTracker. Native resources (the single-thread executor andNativePlanEvaluator) are allocated only on the accepted path.Both the Delta 3.3 (
src-delta33) and Delta 4.0+ (src-delta40) variants are updated.How was this patch tested?
Added
DeltaTimestampNtzStatsWriteSuite(bothsrc-delta33andsrc-delta40), which writes a Delta table with a top-level and a struct-nestedTIMESTAMP_NTZcolumn through the native write path with statistics collection enabled. Without the fix the write throws theClassCastExceptionabove; with it the write succeeds, the data reads back correctly, and DeltaminValues/maxValuesstatistics are still produced for theTIMESTAMP_NTZcolumn via the fallback.Compiles for
-Pspark-4.1(delta40) and-Pspark-3.5(delta33).Was this patch authored or co-authored using generative AI tooling?
Generated-by: GitHub Copilot CLI (Claude Opus 4.8)