You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by gu...@apache.org on 2023/05/10 08:17:28 UTC
[spark] branch master updated: [SPARK-43422][SQL] Keep tags on LogicalRelation with metadata output
This is an automated email from the ASF dual-hosted git repository.
gurwls223 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 27b0c5ec12e [SPARK-43422][SQL] Keep tags on LogicalRelation with metadata output
27b0c5ec12e is described below
commit 27b0c5ec12e7fcb8e442aabe448b825a400fa755
Author: Ole Sasse <ol...@databricks.com>
AuthorDate: Wed May 10 17:17:11 2023 +0900
[SPARK-43422][SQL] Keep tags on LogicalRelation with metadata output
### What changes were proposed in this pull request?
Maintain tags on LogicalRelation if that relation has metadata output
### Why are the changes needed?
Tags were lost before when the Dataframe queries for a metadata column or SchemaPruning happened during optimization.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Added a new test
Closes #41104 from olaky/lost-tags-on-relations-with-metadata.
Authored-by: Ole Sasse <ol...@databricks.com>
Signed-off-by: Hyukjin Kwon <gu...@apache.org>
---
.../execution/datasources/LogicalRelation.scala | 4 +++-
.../sql/execution/datasources/SchemaPruning.scala | 4 +++-
.../datasources/FileMetadataStructSuite.scala | 28 ++++++++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/LogicalRelation.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/LogicalRelation.scala
index bff054fe783..5a3ad0021ae 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/LogicalRelation.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/LogicalRelation.scala
@@ -77,7 +77,9 @@ case class LogicalRelation(
override def withMetadataColumns(): LogicalRelation = {
val newMetadata = metadataOutput.filterNot(outputSet.contains)
if (newMetadata.nonEmpty) {
- this.copy(output = output ++ newMetadata)
+ val newRelation = this.copy(output = output ++ newMetadata)
+ newRelation.copyTagsFrom(this)
+ newRelation
} else {
this
}
diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SchemaPruning.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SchemaPruning.scala
index 279fea6d64b..e361e9eb8c0 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SchemaPruning.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SchemaPruning.scala
@@ -172,7 +172,9 @@ object SchemaPruning extends Rule[LogicalPlan] {
prunedMetadataSchema: StructType) = {
val finalSchema = prunedBaseRelation.schema.merge(prunedMetadataSchema)
val prunedOutput = getPrunedOutput(outputRelation.output, finalSchema)
- outputRelation.copy(relation = prunedBaseRelation, output = prunedOutput)
+ val prunedRelation = outputRelation.copy(relation = prunedBaseRelation, output = prunedOutput)
+ prunedRelation.copyTagsFrom(outputRelation)
+ prunedRelation
}
// Prune the given output to make it consistent with `requiredSchema`.
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala
index 3a1b361beee..a9cc3cabc3a 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala
@@ -24,6 +24,8 @@ import java.text.SimpleDateFormat
import org.apache.spark.TestUtils
import org.apache.spark.paths.SparkPath
import org.apache.spark.sql.{AnalysisException, Column, DataFrame, QueryTest, Row}
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.catalyst.trees.TreeNodeTag
import org.apache.spark.sql.execution.FileSourceScanExec
import org.apache.spark.sql.functions._
import org.apache.spark.sql.internal.SQLConf
@@ -1027,4 +1029,30 @@ class FileMetadataStructSuite extends QueryTest with SharedSparkSession {
}
}
}
+
+ test("SPARK-43422: Keep tags during optimization when adding metadata columns") {
+ withTempPath { path =>
+ spark.range(end = 10).write.format("parquet").save(path.toString)
+
+ // Add the tag to the base Dataframe before selecting a metadata column.
+ val customTag = TreeNodeTag[Boolean]("customTag")
+ val baseDf = spark.read.format("parquet").load(path.toString)
+ val tagsPut = baseDf.queryExecution.analyzed.collect {
+ case rel: LogicalRelation => rel.setTagValue(customTag, true)
+ }
+
+ assert(tagsPut.nonEmpty)
+
+ val dfWithMetadata = baseDf.select("_metadata.row_index")
+
+ // Expect the tag in the analyzed and optimized plan after querying a metadata column.
+ def isTaggedRelation(plan: LogicalPlan): Boolean = plan match {
+ case rel: LogicalRelation => rel.getTagValue(customTag).getOrElse(false)
+ case _ => false
+ }
+
+ assert(dfWithMetadata.queryExecution.analyzed.exists(isTaggedRelation))
+ assert(dfWithMetadata.queryExecution.optimizedPlan.exists(isTaggedRelation))
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org