cloud-fan commented on code in PR #58606:
URL: https://github.com/apache/spark/pull/58606#discussion_r3995050250


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveIdentifierClause.scala:
##########
@@ -69,14 +79,26 @@ class ResolveIdentifierClause(earlyBatches: 
Seq[RuleExecutor[LogicalPlan]#Batch]
           referredTempVars.get ++= collectTemporaryVariablesInLogicalPlan(p)
         }
 
-        executor.execute(p.planBuilder.apply(
+        val resolvedPlan = executor.execute(p.planBuilder.apply(
           IdentifierResolution.evalIdentifierExpr(p.identifierExpr), 
p.children))
+        // Only record the variables when the identifier names something 
inside a view body. When it

Review Comment:
   **Nit (P3):** This explanation is narrower than the implementation: the 
general `apply0` path records any non-`Command` IDENTIFIER result, including a 
standalone SELECT, not only a view body. Related new comments also say an ALTER 
target would always be rejected, although a temporary ALTER skips that 
validator and would instead persist the wrong dependency, and `AnalysisContext` 
says the set is exported to view metadata without the documented legacy 
persisted-view exception. Could these comments distinguish generic recording 
from temporary-view consumption, default persisted-view rejection, and 
temporary-target metadata ownership?



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -270,6 +281,8 @@ object AnalysisContext {
       resolutionPathEntries = function.functionStoredResolutionPath
         .map(CatalogManager.deserializePathEntriesOrFail(
           _, "SQL function", function.name.unquotedString)),
+      // See the same reset in `withAnalysisContext(viewDesc)`.
+      referredTempVariableNamesUnderIdentifier = mutable.LinkedHashSet.empty,

Review Comment:
   **Non-blocking (P2):** `withAnalysisContext(function)` replaces the caller's 
`referredTempVariableNamesUnderIdentifier` set. If a temporary view selects 
from a temporary SQL function whose body reads a relation through 
`IDENTIFIER(variable)`, the inner analysis records the variable here, then 
restoring `originContext` discards it. View creation succeeds, but the stored 
view has no referred-variable entry, so every later read fails when 
view-context resolution rejects the missing name. Please preserve or merge the 
caller's accumulator across function expansion and add the composed 
function-in-view regression; this does not require persisting the variable in 
`SQLFunction` metadata itself.



##########
sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala:
##########
@@ -84,7 +84,8 @@ case class CreateViewCommand(
     viewType: ViewType,
     viewSchemaMode: ViewSchemaMode = SchemaUnsupported,
     isAnalyzed: Boolean = false,
-    referredTempFunctions: Seq[String] = Seq.empty)
+    referredTempFunctions: Seq[String] = Seq.empty,
+    referredTempVariablesUnderIdentifier: Seq[Seq[String]] = Seq.empty)

Review Comment:
   **Non-blocking (P2):** This new payload is not propagated by 
`CacheTableAsSelect`: its `markAsAnalyzed` snapshots only temporary functions, 
and `CacheTableAsSelectExec` constructs an already-analyzed `CreateViewCommand` 
without this argument. For `CACHE TABLE cv AS SELECT IDENTIFIER(v) ...`, 
analysis records `v` and then drops it, so resolving the text-backed temp view 
for eager caching (or a later lazy read) cannot resolve the variable. Please 
thread the dependency through the cache command/strategy/exec path, while 
excluding a variable used only to compute the cache view name.
   
   **Recommended change:** Give CacheTableAsSelect and CacheTableAsSelectExec 
an explicit referredTempVariablesUnderIdentifier payload, capture only 
variables from the SELECT plan, forward it through DataSourceV2Strategy, and 
pass it to CreateViewCommand. Add eager and/or lazy cache coverage that 
resolves the created view while ensuring an IDENTIFIER used only for the cache 
target name is excluded.
   
   **Why this works:** Handle CacheTableAsSelect like CREATE/ALTER VIEW in 
ResolveIdentifierClause: analyze the target expression without recording a view 
dependency and analyze the SELECT body with recording enabled. Snapshot the 
resulting set in markAsAnalyzed and thread the immutable sequence through 
planning into the already-analyzed CreateViewCommand.
   
   **Scope:** 
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis, 
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical, 
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2, 
sql/core/src/test
   
   **Compatibility:** Existing CACHE TABLE AS SELECT naming, eager/lazy 
semantics, temporary-function propagation, storage-level options, and failure 
cleanup remain unchanged.
   
   **Risks:** Recording the variable used to compute the cache view name would 
pollute its dependency metadata. Changing case-class arity requires updating 
all pattern matches and constructors.
   
   **Constraints:** Preserve current eager versus lazy caching behavior and 
cleanup on cache failure. Do not treat a target-name IDENTIFIER variable as 
part of the cached view definition.
   
   **Success:** CACHE TABLE AS SELECT with an IDENTIFIER-only query dependency 
creates a resolvable text-backed temporary view. Both eager caching and a later 
lazy read can resolve the stored variable dependency. A variable used only to 
compute the cache view name is not stored as a referred variable.



##########
sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala:
##########
@@ -283,7 +304,8 @@ case class AlterViewAsCommand(
       Some(originalText),
       analyzedPlan,
       aliasedPlan = analyzedPlan,
-      referredTempFunctions)
+      referredTempFunctions,
+      referredTempVariablesUnderIdentifier = 
referredTempVariablesUnderIdentifier)

Review Comment:
   **Non-blocking (P2):** Please add an end-to-end case that creates a local 
temporary view, alters its body to read a relation or expression name through 
an `IDENTIFIER` session variable, and then selects from the altered view. The 
current permanent-ALTER and target-name cases do not consume this forwarding 
argument; removing it leaves those tests green while stored-text re-analysis of 
the temporary view fails. The SQL golden outputs should be regenerated through 
`SQLQueryTestSuite`.



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