Skip to content

Commit 94b20bc

Browse files
committed
backport
1 parent 3686c2e commit 94b20bc

File tree

3 files changed

+67
-26
lines changed

3 files changed

+67
-26
lines changed

python/pyspark/sql/dataframe.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,23 @@ def createGlobalTempView(self, name):
191191
"""
192192
self._jdf.createGlobalTempView(name)
193193

194+
@since(2.2)
195+
def createOrReplaceGlobalTempView(self, name):
196+
"""Creates or replaces a global temporary view using the given name.
197+
198+
The lifetime of this temporary view is tied to this Spark application.
199+
200+
>>> df.createOrReplaceGlobalTempView("people")
201+
>>> df2 = df.filter(df.age > 3)
202+
>>> df2.createOrReplaceGlobalTempView("people")
203+
>>> df3 = spark.sql("select * from global_temp.people")
204+
>>> sorted(df3.collect()) == sorted(df2.collect())
205+
True
206+
>>> spark.catalog.dropGlobalTempView("people")
207+
208+
"""
209+
self._jdf.createOrReplaceGlobalTempView(name)
210+
194211
@property
195212
@since(1.4)
196213
def write(self):

sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,6 +2657,22 @@ class Dataset[T] private[sql](
26572657
createTempViewCommand(viewName, replace = false, global = true)
26582658
}
26592659

2660+
/**
2661+
* Creates or replaces a global temporary view using the given name. The lifetime of this
2662+
* temporary view is tied to this Spark application.
2663+
*
2664+
* Global temporary view is cross-session. Its lifetime is the lifetime of the Spark application,
2665+
* i.e. it will be automatically dropped when the application terminates. It's tied to a system
2666+
* preserved database `_global_temp`, and we must use the qualified name to refer a global temp
2667+
* view, e.g. `SELECT * FROM _global_temp.view1`.
2668+
*
2669+
* @group basic
2670+
* @since 2.2.0
2671+
*/
2672+
def createOrReplaceGlobalTempView(viewName: String): Unit = withPlan {
2673+
createTempViewCommand(viewName, replace = true, global = true)
2674+
}
2675+
26602676
private def createTempViewCommand(
26612677
viewName: String,
26622678
replace: Boolean,

sql/core/src/test/scala/org/apache/spark/sql/execution/GlobalTempViewSuite.scala

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,47 @@ class GlobalTempViewSuite extends QueryTest with SharedSQLContext {
3535
private var globalTempDB: String = _
3636

3737
test("basic semantic") {
38-
sql("CREATE GLOBAL TEMP VIEW src AS SELECT 1, 'a'")
38+
try {
39+
sql("CREATE GLOBAL TEMP VIEW src AS SELECT 1, 'a'")
40+
41+
// If there is no database in table name, we should try local temp view first, if not found,
42+
// try table/view in current database, which is "default" in this case. So we expect
43+
// NoSuchTableException here.
44+
intercept[NoSuchTableException](spark.table("src"))
3945

40-
// If there is no database in table name, we should try local temp view first, if not found,
41-
// try table/view in current database, which is "default" in this case. So we expect
42-
// NoSuchTableException here.
43-
intercept[NoSuchTableException](spark.table("src"))
46+
// Use qualified name to refer to the global temp view explicitly.
47+
checkAnswer(spark.table(s"$globalTempDB.src"), Row(1, "a"))
4448

45-
// Use qualified name to refer to the global temp view explicitly.
46-
checkAnswer(spark.table(s"$globalTempDB.src"), Row(1, "a"))
49+
// Table name without database will never refer to a global temp view.
50+
intercept[NoSuchTableException](sql("DROP VIEW src"))
4751

48-
// Table name without database will never refer to a global temp view.
49-
intercept[NoSuchTableException](sql("DROP VIEW src"))
52+
sql(s"DROP VIEW $globalTempDB.src")
53+
// The global temp view should be dropped successfully.
54+
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src"))
5055

51-
sql(s"DROP VIEW $globalTempDB.src")
52-
// The global temp view should be dropped successfully.
53-
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src"))
56+
// We can also use Dataset API to create global temp view
57+
Seq(1 -> "a").toDF("i", "j").createGlobalTempView("src")
58+
checkAnswer(spark.table(s"$globalTempDB.src"), Row(1, "a"))
5459

55-
// We can also use Dataset API to create global temp view
56-
Seq(1 -> "a").toDF("i", "j").createGlobalTempView("src")
57-
checkAnswer(spark.table(s"$globalTempDB.src"), Row(1, "a"))
60+
// Use qualified name to rename a global temp view.
61+
sql(s"ALTER VIEW $globalTempDB.src RENAME TO src2")
62+
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src"))
63+
checkAnswer(spark.table(s"$globalTempDB.src2"), Row(1, "a"))
5864

59-
// Use qualified name to rename a global temp view.
60-
sql(s"ALTER VIEW $globalTempDB.src RENAME TO src2")
61-
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src"))
62-
checkAnswer(spark.table(s"$globalTempDB.src2"), Row(1, "a"))
65+
// Use qualified name to alter a global temp view.
66+
sql(s"ALTER VIEW $globalTempDB.src2 AS SELECT 2, 'b'")
67+
checkAnswer(spark.table(s"$globalTempDB.src2"), Row(2, "b"))
6368

64-
// Use qualified name to alter a global temp view.
65-
sql(s"ALTER VIEW $globalTempDB.src2 AS SELECT 2, 'b'")
66-
checkAnswer(spark.table(s"$globalTempDB.src2"), Row(2, "b"))
69+
// We can also use Catalog API to drop global temp view
70+
spark.catalog.dropGlobalTempView("src2")
71+
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src2"))
6772

68-
// We can also use Catalog API to drop global temp view
69-
spark.catalog.dropGlobalTempView("src2")
70-
intercept[NoSuchTableException](spark.table(s"$globalTempDB.src2"))
73+
// We can also use Dataset API to replace global temp view
74+
Seq(2 -> "b").toDF("i", "j").createOrReplaceGlobalTempView("src")
75+
checkAnswer(spark.table(s"$globalTempDB.src"), Row(2, "b"))
76+
} finally {
77+
spark.catalog.dropGlobalTempView("src")
78+
}
7179
}
7280

7381
test("global temp view is shared among all sessions") {
@@ -106,7 +114,7 @@ class GlobalTempViewSuite extends QueryTest with SharedSQLContext {
106114
test("CREATE TABLE LIKE should work for global temp view") {
107115
try {
108116
sql("CREATE GLOBAL TEMP VIEW src AS SELECT 1 AS a, '2' AS b")
109-
sql(s"CREATE TABLE cloned LIKE ${globalTempDB}.src")
117+
sql(s"CREATE TABLE cloned LIKE $globalTempDB.src")
110118
val tableMeta = spark.sessionState.catalog.getTableMetadata(TableIdentifier("cloned"))
111119
assert(tableMeta.schema == new StructType().add("a", "int", false).add("b", "string", false))
112120
} finally {

0 commit comments

Comments
 (0)