uros-b commented on code in PR #58944:
URL: https://github.com/apache/spark/pull/58944#discussion_r4075675246
##########
sql/core/src/test/scala/org/apache/spark/sql/execution/ExecuteImmediateEndToEndSuite.scala:
##########
@@ -143,4 +174,187 @@ class ExecuteImmediateEndToEndSuite extends
SharedSparkSession {
fragment = "v2"))
}
}
+
+ test("EXPLAIN EXECUTE IMMEDIATE does not execute the command payload") {
+ withTable("execute_immediate_explain") {
+ spark.sql("CREATE TABLE execute_immediate_explain (id INT) USING
parquet")
+ // EXPLAIN analyzes the payload but must not run it: command execution
is deferred to the
+ // execution level, so the DROP should have no effect here.
+ spark.sql("EXPLAIN EXECUTE IMMEDIATE 'DROP TABLE
execute_immediate_explain'").collect()
+ assert(spark.catalog.tableExists("execute_immediate_explain"),
+ "EXPLAIN must not execute the EXECUTE IMMEDIATE command payload")
+ }
+ }
+
+ test("EXECUTE IMMEDIATE executes the command payload when run") {
+ withTable("execute_immediate_run") {
+ spark.sql("CREATE TABLE execute_immediate_run (id INT) USING parquet")
+ spark.sql("EXECUTE IMMEDIATE 'DROP TABLE execute_immediate_run'")
+ assert(!spark.catalog.tableExists("execute_immediate_run"),
+ "EXECUTE IMMEDIATE must execute the command payload")
+ }
+ }
+
+ test("EXECUTE IMMEDIATE runs a command payload exactly once") {
+ withTable("execute_immediate_once") {
+ spark.sql("CREATE TABLE execute_immediate_once (id INT) USING parquet")
+ // ExecuteImmediateExec is the sole executor of the payload; a double
execution would insert
+ // the row twice. Asserting exactly one row guards the single-execution
invariant.
+ spark.sql("EXECUTE IMMEDIATE 'INSERT INTO execute_immediate_once VALUES
(?)' USING 1")
+ checkAnswer(spark.table("execute_immediate_once"), Row(1))
+ }
+ }
+
+ test("EXPLAIN shows the EXECUTE IMMEDIATE command payload node") {
+ withSQLConf(SQLConf.ANSI_ENABLED.key -> "false") {
+ val plan = spark.sql("EXPLAIN EXECUTE IMMEDIATE 'SET
spark.sql.ansi.enabled=true'")
+ .collect().map(_.getString(0)).mkString("\n")
+ // The physical node renders as "ExecuteImmediate" (TreeNode.nodeName
strips the "Exec"
+ // suffix); assert it appears together with its supervised payload,
which EXPLAIN surfaces via
+ // innerChildren.
+ assert(plan.contains("ExecuteImmediate") && plan.contains("SetCommand"),
+ s"EXPLAIN should show the ExecuteImmediate node wrapping its payload,
but was:\n$plan")
+ // EXPLAIN must analyze but not run the SET, so the conf stays at its
pre-EXPLAIN value;
+ // otherwise it would pollute later tests in this suite.
+ assert(spark.conf.get(SQLConf.ANSI_ENABLED.key) == "false",
+ "EXPLAIN must not execute the EXECUTE IMMEDIATE SET payload")
+ }
+ }
+
+ test("EXECUTE IMMEDIATE runs a nested command payload exactly once") {
Review Comment:
The comment states "ExecuteImmediateExec re-enters Dataset.ofRows on a
nested ExecuteImmediateCommand", but `run()` no longer uses `Dataset.ofRows` -
it calls `QueryExecution.runCommand` (which builds a fresh `QueryExecution`
with `mode = SKIP` and `executeCollect()`s it). The stale reference misleads on
the actual nested-execution mechanism; update it.
--
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]