This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 0601fc7  [SPARK-33118][SQL] CREATE TEMPORARY TABLE fails with location
0601fc7 is described below

commit 0601fc7bfc85b76be960c0b4ce642fd39675926c
Author: Pablo <pablo.la...@stratio.com>
AuthorDate: Mon Oct 12 14:18:34 2020 -0700

    [SPARK-33118][SQL] CREATE TEMPORARY TABLE fails with location
    
    We have a problem when you use CREATE TEMPORARY TABLE with LOCATION
    
    ```scala
    spark.range(3).write.parquet("/tmp/testspark1")
    
    sql("CREATE TEMPORARY TABLE t USING parquet OPTIONS (path 
'/tmp/testspark1')")
    sql("CREATE TEMPORARY TABLE t USING parquet LOCATION '/tmp/testspark1'")
    ```
    ```scala
    org.apache.spark.sql.AnalysisException: Unable to infer schema for Parquet. 
It must be specified manually.;
      at 
org.apache.spark.sql.execution.datasources.DataSource.$anonfun$getOrInferFileFormatSchema$12(DataSource.scala:200)
      at scala.Option.getOrElse(Option.scala:189)
      at 
org.apache.spark.sql.execution.datasources.DataSource.getOrInferFileFormatSchema(DataSource.scala:200)
      at 
org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:408)
      at 
org.apache.spark.sql.execution.datasources.CreateTempViewUsing.run(ddl.scala:94)
      at 
org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult$lzycompute(commands.scala:70)
      at 
org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult(commands.scala:68)
      at 
org.apache.spark.sql.execution.command.ExecutedCommandExec.executeCollect(commands.scala:79)
      at org.apache.spark.sql.Dataset.$anonfun$logicalPlan$1(Dataset.scala:229)
      at org.apache.spark.sql.Dataset.$anonfun$withAction$1(Dataset.scala:3618)
      at 
org.apache.spark.sql.execution.SQLExecution$.$anonfun$withNewExecutionId$5(SQLExecution.scala:100)
      at 
org.apache.spark.sql.execution.SQLExecution$.withSQLConfPropagated(SQLExecution.scala:160)
      at 
org.apache.spark.sql.execution.SQLExecution$.$anonfun$withNewExecutionId$1(SQLExecution.scala:87)
      at org.apache.spark.sql.SparkSession.withActive(SparkSession.scala:764)
      at 
org.apache.spark.sql.execution.SQLExecution$.withNewExecutionId(SQLExecution.scala:64)
      at org.apache.spark.sql.Dataset.withAction(Dataset.scala:3616)
      at org.apache.spark.sql.Dataset.<init>(Dataset.scala:229)
      at org.apache.spark.sql.Dataset$.$anonfun$ofRows$2(Dataset.scala:100)
      at org.apache.spark.sql.SparkSession.withActive(SparkSession.scala:764)
      at org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:97)
      at 
org.apache.spark.sql.SparkSession.$anonfun$sql$1(SparkSession.scala:607)
      at org.apache.spark.sql.SparkSession.withActive(SparkSession.scala:764)
      at org.apache.spark.sql.SparkSession.sql(SparkSession.scala:602)
    ```
    This bug was introduced by SPARK-30507.
    sparksqlparser --> visitCreateTable --> visitCreateTableClauses --> 
cleanTableOptions extract the path from the options but in this case 
CreateTempViewUsing need the path in the options map.
    
    To fix the problem
    
    No
    
    Unit testing and manual testing
    
    Closes #30014 from planga82/bugfix/SPARK-33118_create_temp_table_location.
    
    Authored-by: Pablo <pablo.la...@stratio.com>
    Signed-off-by: Dongjoon Hyun <dh...@apple.com>
    (cherry picked from commit 819f12ee2fe3cce0c59221c2b02831274c769b23)
    Signed-off-by: Dongjoon Hyun <dh...@apple.com>
---
 .../org/apache/spark/sql/execution/SparkSqlParser.scala     |  6 ++++--
 .../apache/spark/sql/execution/SparkSqlParserSuite.scala    | 13 +++++++++++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala
index 44069f3..3e4bc48 100644
--- 
a/sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala
+++ 
b/sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala
@@ -196,7 +196,7 @@ class SparkSqlAstBuilder(conf: SQLConf) extends 
AstBuilder(conf) {
         operationNotAllowed("CREATE TEMPORARY TABLE IF NOT EXISTS", ctx)
       }
 
-      val (_, _, _, options, _, _) = 
visitCreateTableClauses(ctx.createTableClauses())
+      val (_, _, _, options, location, _) = 
visitCreateTableClauses(ctx.createTableClauses())
       val provider = 
Option(ctx.tableProvider).map(_.multipartIdentifier.getText).getOrElse(
         throw new ParseException("CREATE TEMPORARY TABLE without a provider is 
not allowed.", ctx))
       val schema = Option(ctx.colTypeList()).map(createSchema)
@@ -205,7 +205,9 @@ class SparkSqlAstBuilder(conf: SQLConf) extends 
AstBuilder(conf) {
           "CREATE TEMPORARY VIEW ... USING ... instead")
 
       val table = tableIdentifier(ident, "CREATE TEMPORARY VIEW", ctx)
-      CreateTempViewUsing(table, schema, replace = false, global = false, 
provider, options)
+      val optionsWithLocation = location.map(l => options + ("path" -> 
l)).getOrElse(options)
+      CreateTempViewUsing(table, schema, replace = false, global = false, 
provider,
+        optionsWithLocation)
     }
   }
 
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
index 6a58c8f..343d3c1 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
@@ -25,8 +25,8 @@ import org.apache.spark.sql.catalyst.dsl.expressions._
 import org.apache.spark.sql.catalyst.expressions.{Ascending, 
AttributeReference, Concat, SortOrder}
 import org.apache.spark.sql.catalyst.plans.logical._
 import org.apache.spark.sql.execution.command._
-import org.apache.spark.sql.execution.datasources.{CreateTable, 
RefreshResource}
-import org.apache.spark.sql.internal.{HiveSerDe, SQLConf}
+import org.apache.spark.sql.execution.datasources.{CreateTable, 
CreateTempViewUsing, RefreshResource}
+import org.apache.spark.sql.internal.{HiveSerDe, SQLConf, StaticSQLConf}
 import org.apache.spark.sql.types.{IntegerType, LongType, StringType, 
StructType}
 
 /**
@@ -81,6 +81,15 @@ class SparkSqlParserSuite extends AnalysisTest {
     intercept("REFRESH", "Resource paths cannot be empty in REFRESH 
statements")
   }
 
+  test("SPARK-33118 CREATE TMEPORARY TABLE with LOCATION") {
+    assertEqual("CREATE TEMPORARY TABLE t USING parquet OPTIONS (path 
'/data/tmp/testspark1')",
+      CreateTempViewUsing(TableIdentifier("t", None), None, false, false, 
"parquet",
+        Map("path" -> "/data/tmp/testspark1")))
+    assertEqual("CREATE TEMPORARY TABLE t USING parquet LOCATION 
'/data/tmp/testspark1'",
+      CreateTempViewUsing(TableIdentifier("t", None), None, false, false, 
"parquet",
+        Map("path" -> "/data/tmp/testspark1")))
+  }
+
   private def createTableUsing(
       table: String,
       database: Option[String] = None,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org
For additional commands, e-mail: commits-h...@spark.apache.org

Reply via email to