You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2020/12/11 22:52:24 UTC
[spark] branch branch-3.1 updated: [SPARK-33729][SQL] When
refreshing cache, Spark should not use cached plan when recaching data
This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new cc7fa23 [SPARK-33729][SQL] When refreshing cache, Spark should not use cached plan when recaching data
cc7fa23 is described below
commit cc7fa236622f6e34bbf10ea9bf2693f647cd145b
Author: Chao Sun <su...@apple.com>
AuthorDate: Fri Dec 11 14:43:51 2020 -0800
[SPARK-33729][SQL] When refreshing cache, Spark should not use cached plan when recaching data
### What changes were proposed in this pull request?
This fixes `CatalogImpl.refreshTable` by using a new logical plan when recache the target table.
### Why are the changes needed?
In `CatalogImpl.refreshTable`, we currently recache the target table via:
```scala
sparkSession.sharedState.cacheManager.cacheQuery(table, cacheName, cacheLevel)
```
However, here `table` is generated before the `tableRelationCache` in `SessionCatalog` is invalidated, and therefore it still refers to old and staled logical plan, which is incorrect.
### Does this PR introduce _any_ user-facing change?
Yes, this fix behavior when a table is refreshed.
### How was this patch tested?
Added a unit test.
Closes #30699 from sunchao/SPARK-33729.
Authored-by: Chao Sun <su...@apple.com>
Signed-off-by: Dongjoon Hyun <do...@apache.org>
(cherry picked from commit be09d37398f6b62c853e961df64b94b34fd3389d)
Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
.../apache/spark/sql/internal/CatalogImpl.scala | 6 +++-
.../org/apache/spark/sql/CachedTableSuite.scala | 33 ++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala b/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
index 3e21641..8008a21 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
@@ -538,8 +538,12 @@ class CatalogImpl(sparkSession: SparkSession) extends Catalog {
val cacheName = cache.get.cachedRepresentation.cacheBuilder.tableName
val cacheLevel = cache.get.cachedRepresentation.cacheBuilder.storageLevel
+ // creates a new logical plan since the old table refers to old relation which
+ // should be refreshed
+ val newTable = sparkSession.table(tableIdent)
+
// recache with the same name and cache level.
- sparkSession.sharedState.cacheManager.cacheQuery(table, cacheName, cacheLevel)
+ sparkSession.sharedState.cacheManager.cacheQuery(newTable, cacheName, cacheLevel)
}
}
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/CachedTableSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/CachedTableSuite.scala
index d015061..3c85ea4 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/CachedTableSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/CachedTableSuite.scala
@@ -17,6 +17,9 @@
package org.apache.spark.sql
+import java.io.{File, FilenameFilter}
+import java.nio.file.{Files, Paths}
+
import scala.collection.mutable.HashSet
import scala.concurrent.duration._
@@ -1239,4 +1242,34 @@ class CachedTableSuite extends QueryTest with SQLTestUtils
}
}
}
+
+ test("SPARK-33729: REFRESH TABLE should not use cached/stale plan") {
+ def moveParquetFiles(src: File, dst: File): Unit = {
+ src.listFiles(new FilenameFilter {
+ override def accept(dir: File, name: String): Boolean = name.endsWith("parquet")
+ }).foreach { f =>
+ Files.move(f.toPath, Paths.get(dst.getAbsolutePath, f.getName))
+ }
+ // cleanup the rest of the files
+ src.listFiles().foreach(_.delete())
+ src.delete()
+ }
+
+ withTable("t") {
+ withTempDir { dir =>
+ val path1 = new File(dir, "path1")
+ Seq((1 -> "a")).toDF("i", "j").write.parquet(path1.getCanonicalPath)
+ moveParquetFiles(path1, dir)
+ sql(s"CREATE TABLE t (i INT, j STRING) USING parquet LOCATION '${dir.toURI}'")
+ sql("CACHE TABLE t")
+ checkAnswer(sql("SELECT * FROM t"), Row(1, "a") :: Nil)
+
+ val path2 = new File(dir, "path2")
+ Seq(2 -> "b").toDF("i", "j").write.parquet(path2.getCanonicalPath)
+ moveParquetFiles(path2, dir)
+ sql("REFRESH TABLE t")
+ checkAnswer(sql("SELECT * FROM t"), Row(1, "a") :: Row(2, "b") :: Nil)
+ }
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org