This is an automated email from the ASF dual-hosted git repository.
rui pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git
The following commit(s) were added to refs/heads/main by this push:
new 240ec750f7 [VL] Enable GlutenQueryExecutionSuite (#10268)
240ec750f7 is described below
commit 240ec750f7fb9fef98993ab265021a722fbb8b21
Author: Ankita Victor <[email protected]>
AuthorDate: Wed Jul 30 22:45:36 2025 +0530
[VL] Enable GlutenQueryExecutionSuite (#10268)
---
.../gluten/utils/velox/VeloxTestSettings.scala | 5 +
.../sql/execution/GlutenQueryExecutionSuite.scala | 100 +++++++++++++++++++
.../gluten/utils/velox/VeloxTestSettings.scala | 5 +
.../sql/execution/GlutenQueryExecutionSuite.scala | 107 +++++++++++++++++++++
.../gluten/utils/velox/VeloxTestSettings.scala | 7 +-
.../sql/execution/GlutenQueryExecutionSuite.scala | 107 +++++++++++++++++++++
.../gluten/utils/velox/VeloxTestSettings.scala | 5 +
.../sql/execution/GlutenQueryExecutionSuite.scala | 107 +++++++++++++++++++++
8 files changed, 442 insertions(+), 1 deletion(-)
diff --git
a/gluten-ut/spark32/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
b/gluten-ut/spark32/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
index 9c592e5448..e056610ffa 100644
---
a/gluten-ut/spark32/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
+++
b/gluten-ut/spark32/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
@@ -832,6 +832,11 @@ class VeloxTestSettings extends BackendTestSettings {
.exclude("Independent Batched Python UDFs and Scalar Pandas UDFs should be
combined separately")
.exclude("Dependent Batched Python UDFs and Scalar Pandas UDFs should not
be combined")
.exclude("Python UDF should not break column pruning/filter pushdown --
Parquet V2")
+ enableSuite[GlutenQueryExecutionSuite]
+ // Rewritten to set root logger level to INFO so that logs can be parsed
+ .exclude("Logging plan changes for execution")
+ // Rewrite for transformed plan
+ .exclude("dumping query execution info to a file - explainMode=formatted")
override def getSQLQueryTestSettings: SQLQueryTestSettings =
VeloxSQLQueryTestSettings
}
diff --git
a/gluten-ut/spark32/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
b/gluten-ut/spark32/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
new file mode 100644
index 0000000000..ffdc0524df
--- /dev/null
+++
b/gluten-ut/spark32/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution
+
+import org.apache.spark.sql.GlutenSQLTestsBaseTrait
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.util.Utils
+
+import scala.io.Source
+
+class GlutenQueryExecutionSuite extends QueryExecutionSuite with
GlutenSQLTestsBaseTrait {
+
+ override def checkDumpedPlans(path: String, expected: Int): Unit =
+ Utils.tryWithResource(Source.fromFile(path)) {
+ source =>
+ assert(
+ source.getLines.toList
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Parsed Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Analyzed Logical Plan ==",
+ "id: bigint",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Optimized Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Physical Plan ==",
+ "*(1) ColumnarToRow",
+ s"+- ColumnarRange 0, $expected, 1, 2, $expected, [id#xL]",
+ ""
+ ))
+ }
+
+ testGluten("dumping query execution info to a file - explainMode=formatted")
{
+ withTempDir {
+ dir =>
+ val path = dir.getCanonicalPath + "/plans.txt"
+ val df = spark.range(0, 10)
+ df.queryExecution.debug.toFile(path, explainMode = Option("formatted"))
+ val lines =
Utils.tryWithResource(Source.fromFile(path))(_.getLines().toList)
+ assert(
+ lines
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Physical Plan ==",
+ "* ColumnarToRow (2)",
+ "+- ColumnarRange (1)",
+ "",
+ "",
+ "(1) ColumnarRange",
+ "Output [1]: [id#xL]",
+ "Arguments: 0, 10, 1, 2, 10, [id#xL]",
+ "",
+ "(2) ColumnarToRow [codegen id : 1]",
+ "Input [1]: [id#xL]",
+ "",
+ ""
+ ))
+ }
+ }
+
+ testGluten("Logging plan changes for execution") {
+ sparkContext.setLogLevel("INFO")
+
+ val testAppender = new LogAppender("plan changes")
+ withLogAppender(testAppender) {
+ withSQLConf(
+ SQLConf.PLAN_CHANGE_LOG_LEVEL.key -> "INFO"
+ ) {
+ spark.range(1).groupBy("id").count().queryExecution.executedPlan
+ }
+ }
+ Seq("=== Applying Rule org.apache.spark.sql.execution", "=== Result of
Batch Preparations ===")
+ .foreach {
+ expectedMsg =>
+ assert(
+ testAppender.loggingEvents.exists(
+ _.getRenderedMessage.contains(expectedMsg)
+ )
+ )
+ }
+ }
+}
diff --git
a/gluten-ut/spark33/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
b/gluten-ut/spark33/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
index 1b90f2178d..46f1519f4a 100644
---
a/gluten-ut/spark33/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
+++
b/gluten-ut/spark33/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
@@ -883,6 +883,11 @@ class VeloxTestSettings extends BackendTestSettings {
.exclude("Independent Batched Python UDFs and Scalar Pandas UDFs should be
combined separately")
.exclude("Dependent Batched Python UDFs and Scalar Pandas UDFs should not
be combined")
.exclude("Python UDF should not break column pruning/filter pushdown --
Parquet V2")
+ enableSuite[GlutenQueryExecutionSuite]
+ // Rewritten to set root logger level to INFO so that logs can be parsed
+ .exclude("Logging plan changes for execution")
+ // Rewrite for transformed plan
+ .exclude("dumping query execution info to a file - explainMode=formatted")
override def getSQLQueryTestSettings: SQLQueryTestSettings =
VeloxSQLQueryTestSettings
}
diff --git
a/gluten-ut/spark33/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
b/gluten-ut/spark33/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
new file mode 100644
index 0000000000..2819584558
--- /dev/null
+++
b/gluten-ut/spark33/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution
+
+import org.apache.spark.sql.GlutenSQLTestsBaseTrait
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.util.Utils
+
+import org.apache.logging.log4j.{Level, LogManager}
+import org.apache.logging.log4j.core.LoggerContext
+
+import scala.io.Source
+
+class GlutenQueryExecutionSuite extends QueryExecutionSuite with
GlutenSQLTestsBaseTrait {
+
+ override def checkDumpedPlans(path: String, expected: Int): Unit =
+ Utils.tryWithResource(Source.fromFile(path)) {
+ source =>
+ assert(
+ source.getLines.toList
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Parsed Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Analyzed Logical Plan ==",
+ "id: bigint",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Optimized Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Physical Plan ==",
+ "*(1) ColumnarToRow",
+ s"+- ColumnarRange 0, $expected, 1, 2, $expected, [id#xL]",
+ ""
+ ))
+ }
+
+ testGluten("dumping query execution info to a file - explainMode=formatted")
{
+ withTempDir {
+ dir =>
+ val path = dir.getCanonicalPath + "/plans.txt"
+ val df = spark.range(0, 10)
+ df.queryExecution.debug.toFile(path, explainMode = Option("formatted"))
+ val lines =
Utils.tryWithResource(Source.fromFile(path))(_.getLines().toList)
+ assert(
+ lines
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Physical Plan ==",
+ "* ColumnarToRow (2)",
+ "+- ColumnarRange (1)",
+ "",
+ "",
+ "(1) ColumnarRange",
+ "Output [1]: [id#xL]",
+ "Arguments: 0, 10, 1, 2, 10, [id#xL]",
+ "",
+ "(2) ColumnarToRow [codegen id : 1]",
+ "Input [1]: [id#xL]",
+ "",
+ ""
+ ))
+ }
+ }
+
+ testGluten("Logging plan changes for execution") {
+ val ctx = LogManager.getContext(false).asInstanceOf[LoggerContext]
+ val config = ctx.getConfiguration
+ val loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME)
+ loggerConfig.setLevel(Level.INFO)
+ ctx.updateLoggers()
+
+ val testAppender = new LogAppender("plan changes")
+ withLogAppender(testAppender) {
+ withSQLConf(
+ SQLConf.PLAN_CHANGE_LOG_LEVEL.key -> "INFO"
+ ) {
+ spark.range(1).groupBy("id").count().queryExecution.executedPlan
+ }
+ }
+ Seq("=== Applying Rule org.apache.spark.sql.execution", "=== Result of
Batch Preparations ===")
+ .foreach {
+ expectedMsg =>
+ assert(
+ testAppender.loggingEvents.exists(
+ _.getMessage.getFormattedMessage.contains(expectedMsg)
+ )
+ )
+ }
+ }
+}
diff --git
a/gluten-ut/spark34/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
b/gluten-ut/spark34/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
index fe249fa406..819d0a69ee 100644
---
a/gluten-ut/spark34/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
+++
b/gluten-ut/spark34/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
@@ -24,7 +24,7 @@ import org.apache.spark.sql._
import org.apache.spark.sql.catalyst.expressions._
import
org.apache.spark.sql.connector.{GlutenDataSourceV2DataFrameSessionCatalogSuite,
GlutenDataSourceV2DataFrameSuite, GlutenDataSourceV2FunctionSuite,
GlutenDataSourceV2SQLSessionCatalogSuite, GlutenDataSourceV2SQLSuiteV1Filter,
GlutenDataSourceV2SQLSuiteV2Filter, GlutenDataSourceV2Suite,
GlutenDeleteFromTableSuite, GlutenDeltaBasedDeleteFromTableSuite,
GlutenFileDataSourceV2FallBackSuite, GlutenGroupBasedDeleteFromTableSuite,
GlutenKeyGroupedPartitioningSuite, GlutenLocalScanSuite, G [...]
import org.apache.spark.sql.errors.{GlutenQueryCompilationErrorsDSv2Suite,
GlutenQueryCompilationErrorsSuite, GlutenQueryExecutionErrorsSuite,
GlutenQueryParsingErrorsSuite}
-import org.apache.spark.sql.execution.{FallbackStrategiesSuite,
GlutenBroadcastExchangeSuite, GlutenCoalesceShufflePartitionsSuite,
GlutenExchangeSuite, GlutenLocalBroadcastExchangeSuite,
GlutenReplaceHashWithSortAggSuite, GlutenReuseExchangeAndSubquerySuite,
GlutenSameResultSuite, GlutenSortSuite, GlutenSQLAggregateFunctionSuite,
GlutenSQLWindowFunctionSuite, GlutenTakeOrderedAndProjectSuite}
+import org.apache.spark.sql.execution.{FallbackStrategiesSuite,
GlutenBroadcastExchangeSuite, GlutenCoalesceShufflePartitionsSuite,
GlutenExchangeSuite, GlutenLocalBroadcastExchangeSuite,
GlutenQueryExecutionSuite, GlutenReplaceHashWithSortAggSuite,
GlutenReuseExchangeAndSubquerySuite, GlutenSameResultSuite, GlutenSortSuite,
GlutenSQLAggregateFunctionSuite, GlutenSQLWindowFunctionSuite,
GlutenTakeOrderedAndProjectSuite}
import
org.apache.spark.sql.execution.adaptive.velox.VeloxAdaptiveQueryExecSuite
import org.apache.spark.sql.execution.datasources._
import
org.apache.spark.sql.execution.datasources.binaryfile.GlutenBinaryFileFormatSuite
@@ -922,6 +922,11 @@ class VeloxTestSettings extends BackendTestSettings {
.exclude("Independent Batched Python UDFs and Scalar Pandas UDFs should be
combined separately")
.exclude("Dependent Batched Python UDFs and Scalar Pandas UDFs should not
be combined")
.exclude("Python UDF should not break column pruning/filter pushdown --
Parquet V2")
+ enableSuite[GlutenQueryExecutionSuite]
+ // Rewritten to set root logger level to INFO so that logs can be parsed
+ .exclude("Logging plan changes for execution")
+ // Rewrite for transformed plan
+ .exclude("dumping query execution info to a file - explainMode=formatted")
override def getSQLQueryTestSettings: SQLQueryTestSettings =
VeloxSQLQueryTestSettings
}
diff --git
a/gluten-ut/spark34/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
b/gluten-ut/spark34/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
new file mode 100644
index 0000000000..2819584558
--- /dev/null
+++
b/gluten-ut/spark34/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution
+
+import org.apache.spark.sql.GlutenSQLTestsBaseTrait
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.util.Utils
+
+import org.apache.logging.log4j.{Level, LogManager}
+import org.apache.logging.log4j.core.LoggerContext
+
+import scala.io.Source
+
+class GlutenQueryExecutionSuite extends QueryExecutionSuite with
GlutenSQLTestsBaseTrait {
+
+ override def checkDumpedPlans(path: String, expected: Int): Unit =
+ Utils.tryWithResource(Source.fromFile(path)) {
+ source =>
+ assert(
+ source.getLines.toList
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Parsed Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Analyzed Logical Plan ==",
+ "id: bigint",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Optimized Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Physical Plan ==",
+ "*(1) ColumnarToRow",
+ s"+- ColumnarRange 0, $expected, 1, 2, $expected, [id#xL]",
+ ""
+ ))
+ }
+
+ testGluten("dumping query execution info to a file - explainMode=formatted")
{
+ withTempDir {
+ dir =>
+ val path = dir.getCanonicalPath + "/plans.txt"
+ val df = spark.range(0, 10)
+ df.queryExecution.debug.toFile(path, explainMode = Option("formatted"))
+ val lines =
Utils.tryWithResource(Source.fromFile(path))(_.getLines().toList)
+ assert(
+ lines
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Physical Plan ==",
+ "* ColumnarToRow (2)",
+ "+- ColumnarRange (1)",
+ "",
+ "",
+ "(1) ColumnarRange",
+ "Output [1]: [id#xL]",
+ "Arguments: 0, 10, 1, 2, 10, [id#xL]",
+ "",
+ "(2) ColumnarToRow [codegen id : 1]",
+ "Input [1]: [id#xL]",
+ "",
+ ""
+ ))
+ }
+ }
+
+ testGluten("Logging plan changes for execution") {
+ val ctx = LogManager.getContext(false).asInstanceOf[LoggerContext]
+ val config = ctx.getConfiguration
+ val loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME)
+ loggerConfig.setLevel(Level.INFO)
+ ctx.updateLoggers()
+
+ val testAppender = new LogAppender("plan changes")
+ withLogAppender(testAppender) {
+ withSQLConf(
+ SQLConf.PLAN_CHANGE_LOG_LEVEL.key -> "INFO"
+ ) {
+ spark.range(1).groupBy("id").count().queryExecution.executedPlan
+ }
+ }
+ Seq("=== Applying Rule org.apache.spark.sql.execution", "=== Result of
Batch Preparations ===")
+ .foreach {
+ expectedMsg =>
+ assert(
+ testAppender.loggingEvents.exists(
+ _.getMessage.getFormattedMessage.contains(expectedMsg)
+ )
+ )
+ }
+ }
+}
diff --git
a/gluten-ut/spark35/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
b/gluten-ut/spark35/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
index b4903b4d61..8bb7dc340e 100644
---
a/gluten-ut/spark35/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
+++
b/gluten-ut/spark35/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala
@@ -966,6 +966,11 @@ class VeloxTestSettings extends BackendTestSettings {
// requires test resources that don't exist in Gluten repo
.exclude("detect escaped path and report the migration guide")
.exclude("ignore the escaped path check when the flag is off")
+ enableSuite[GlutenQueryExecutionSuite]
+ // Rewritten to set root logger level to INFO so that logs can be parsed
+ .exclude("Logging plan changes for execution")
+ // Rewrite for transformed plan
+ .exclude("dumping query execution info to a file - explainMode=formatted")
override def getSQLQueryTestSettings: SQLQueryTestSettings =
VeloxSQLQueryTestSettings
}
diff --git
a/gluten-ut/spark35/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
b/gluten-ut/spark35/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
new file mode 100644
index 0000000000..2819584558
--- /dev/null
+++
b/gluten-ut/spark35/src/test/scala/org/apache/spark/sql/execution/GlutenQueryExecutionSuite.scala
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution
+
+import org.apache.spark.sql.GlutenSQLTestsBaseTrait
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.util.Utils
+
+import org.apache.logging.log4j.{Level, LogManager}
+import org.apache.logging.log4j.core.LoggerContext
+
+import scala.io.Source
+
+class GlutenQueryExecutionSuite extends QueryExecutionSuite with
GlutenSQLTestsBaseTrait {
+
+ override def checkDumpedPlans(path: String, expected: Int): Unit =
+ Utils.tryWithResource(Source.fromFile(path)) {
+ source =>
+ assert(
+ source.getLines.toList
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Parsed Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Analyzed Logical Plan ==",
+ "id: bigint",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Optimized Logical Plan ==",
+ s"Range (0, $expected, step=1, splits=Some(2))",
+ "",
+ "== Physical Plan ==",
+ "*(1) ColumnarToRow",
+ s"+- ColumnarRange 0, $expected, 1, 2, $expected, [id#xL]",
+ ""
+ ))
+ }
+
+ testGluten("dumping query execution info to a file - explainMode=formatted")
{
+ withTempDir {
+ dir =>
+ val path = dir.getCanonicalPath + "/plans.txt"
+ val df = spark.range(0, 10)
+ df.queryExecution.debug.toFile(path, explainMode = Option("formatted"))
+ val lines =
Utils.tryWithResource(Source.fromFile(path))(_.getLines().toList)
+ assert(
+ lines
+ .takeWhile(_ != "== Whole Stage Codegen ==")
+ .map(_.replaceAll("#\\d+", "#x")) == List(
+ "== Physical Plan ==",
+ "* ColumnarToRow (2)",
+ "+- ColumnarRange (1)",
+ "",
+ "",
+ "(1) ColumnarRange",
+ "Output [1]: [id#xL]",
+ "Arguments: 0, 10, 1, 2, 10, [id#xL]",
+ "",
+ "(2) ColumnarToRow [codegen id : 1]",
+ "Input [1]: [id#xL]",
+ "",
+ ""
+ ))
+ }
+ }
+
+ testGluten("Logging plan changes for execution") {
+ val ctx = LogManager.getContext(false).asInstanceOf[LoggerContext]
+ val config = ctx.getConfiguration
+ val loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME)
+ loggerConfig.setLevel(Level.INFO)
+ ctx.updateLoggers()
+
+ val testAppender = new LogAppender("plan changes")
+ withLogAppender(testAppender) {
+ withSQLConf(
+ SQLConf.PLAN_CHANGE_LOG_LEVEL.key -> "INFO"
+ ) {
+ spark.range(1).groupBy("id").count().queryExecution.executedPlan
+ }
+ }
+ Seq("=== Applying Rule org.apache.spark.sql.execution", "=== Result of
Batch Preparations ===")
+ .foreach {
+ expectedMsg =>
+ assert(
+ testAppender.loggingEvents.exists(
+ _.getMessage.getFormattedMessage.contains(expectedMsg)
+ )
+ )
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]