Vivek1106-04 opened a new pull request, #59100:
URL: https://github.com/apache/spark/pull/59100

   ### What changes were proposed in this pull request?
   
   Spark Connect's `withColumns` and `withColumnsRenamed` try eager analysis 
first and fall back to a lazily resolved plan (`UnresolvedStarWithColumns` / 
`UnresolvedStarWithColumnsRenames`) when it fails (SPARK-53505).
   
   This PR plans Declarative Pipelines flow relations without that eager 
analysis:
   
   - `SparkConnectPlanner.transformRelationWithoutEagerAnalysis` transforms a 
relation with the eager analysis of `withColumns` / `withColumnsRenamed` 
disabled, and `handlePipelineCommand` hands it to `PipelinesHandler` instead of 
`transformRelation`. `PipelinesHandler` uses it only in `defineFlow`.
   - Both call sites now go through a shared `tryEagerAnalysis` helper, which 
returns the lazy plan directly when eager analysis is disabled and otherwise 
behaves exactly as before.
   
   Nothing changes outside pipelines, and no configuration is added.
   
   ### Why are the changes needed?
   
   `FlowAnalysis` discovers a flow's dependencies by matching 
`UnresolvedRelation`s in the flow's plan. `PipelinesHandler.defineFlow` runs 
the flow relation through the planner at `DefineFlow` time:
   
   - **First run (clean catalog):** the upstream table does not exist, eager 
analysis fails, the fallback keeps the `UnresolvedRelation`, and the dependency 
is recorded.
   - **Every later run:** the upstream table now exists, eager analysis 
succeeds and consumes the `UnresolvedRelation` against the *stale catalog 
table*. `FlowAnalysis` records no dependency, and the downstream flow is 
scheduled concurrently with its own upstream.
   
   Result from the JIRA repro: on the second run `b = 
spark.read.table("a").withColumn(...)` starts before `a` and ends up with **0 
rows**, while the equivalent `select(...)` flow `c` is correct. The bug passes 
every first-run smoke test and only shows up on scheduled re-runs.
   
   ### Does this PR introduce _any_ user-facing change?
   
   Yes, a bug fix. Pipeline flows that use `withColumn(s)` / 
`withColumnRenamed` / `withColumnsRenamed` on another pipeline dataset now keep 
their dependency on that dataset across runs, so they wait for it instead of 
reading a stale or empty table. Non-pipeline Spark Connect queries are 
unaffected.
   
   ### How was this patch tested?
   
   Added `SPARK-59663: withColumns and withColumnsRenamed keep the dependency 
on an internal dataset that already exists in the catalog` to 
`PythonPipelineSuite`. It pre-creates `spark_catalog.default.src` (simulating a 
previous run), defines `src` plus a `withColumn` flow and a `withColumnRenamed` 
flow on it, and asserts each flow's inputs are `{src}`.
   
   - Without the fix, the test fails for both flows (each verified separately): 
`Set() did not equal Set(spark_catalog.default.src)`.
   - With the fix, `PythonPipelineSuite`, `SparkConnectPlannerSuite`, 
`SparkConnectProtoSuite` and `PipelinesHandlerSuite` pass (222 tests).
   
   ```
   build/sbt 'connect/testOnly *PythonPipelineSuite *SparkConnectPlannerSuite 
*SparkConnectProtoSuite *PipelinesHandlerSuite'
   ```
   
   Note: if user code explicitly analyzes a DataFrame *outside* the flow 
function (e.g. `df.columns`), the resulting plan can come from the session plan 
cache. That path already fails on a clean catalog, and the existing test 
`reading internal datasets outside query function that trigger eager analysis 
or execution will fail` covers it as unsupported, so it is left out of scope 
here.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Claude Opus 5.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