aboutsummaryrefslogtreecommitdiff
path: root/sql/hive/src/test/scala/org
diff options
context:
space:
mode:
authorWenchen Fan <wenchen@databricks.com>2017-01-05 17:40:27 -0800
committerYin Huai <yhuai@databricks.com>2017-01-05 17:40:27 -0800
commitcca945b6aa679e61864c1cabae91e6ae7703362e (patch)
treef7b33ef60fc92237503fb911270b8bedba76815b /sql/hive/src/test/scala/org
parentf5d18af6a8a0b9f8c2e9677f9d8ae1712eb701c6 (diff)
downloadspark-cca945b6aa679e61864c1cabae91e6ae7703362e.tar.gz
spark-cca945b6aa679e61864c1cabae91e6ae7703362e.tar.bz2
spark-cca945b6aa679e61864c1cabae91e6ae7703362e.zip
[SPARK-18885][SQL] unify CREATE TABLE syntax for data source and hive serde tables
## What changes were proposed in this pull request? Today we have different syntax to create data source or hive serde tables, we should unify them to not confuse users and step forward to make hive a data source. Please read https://issues.apache.org/jira/secure/attachment/12843835/CREATE-TABLE.pdf for details. TODO(for follow-up PRs): 1. TBLPROPERTIES is not added to the new syntax, we should decide if we wanna add it later. 2. `SHOW CREATE TABLE` should be updated to use the new syntax. 3. we should decide if we wanna change the behavior of `SET LOCATION`. ## How was this patch tested? new tests Author: Wenchen Fan <wenchen@databricks.com> Closes #16296 from cloud-fan/create-table.
Diffstat (limited to 'sql/hive/src/test/scala/org')
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala107
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveExternalCatalogSuite.scala2
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/MetastoreDataSourcesSuite.scala15
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala39
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/orc/OrcHadoopFsRelationSuite.scala2
5 files changed, 141 insertions, 24 deletions
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala
index d13e29b302..b67e5f6fe5 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala
@@ -31,7 +31,6 @@ import org.apache.spark.sql.catalyst.plans.logical.{Generate, ScriptTransformati
import org.apache.spark.sql.execution.command._
import org.apache.spark.sql.execution.datasources.CreateTable
import org.apache.spark.sql.hive.test.{TestHive, TestHiveSingleton}
-import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.test.SQLTestUtils
import org.apache.spark.sql.types.StructType
@@ -51,6 +50,12 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
assert(e.getMessage.toLowerCase.contains("operation not allowed"))
}
+ private def analyzeCreateTable(sql: String): CatalogTable = {
+ TestHive.sessionState.analyzer.execute(parser.parsePlan(sql)).collect {
+ case CreateTable(tableDesc, mode, _) => tableDesc
+ }.head
+ }
+
test("Test CTAS #1") {
val s1 =
"""CREATE EXTERNAL TABLE IF NOT EXISTS mydb.page_view
@@ -76,7 +81,7 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
assert(desc.storage.outputFormat == Some("org.apache.hadoop.hive.ql.io.RCFileOutputFormat"))
assert(desc.storage.serde ==
Some("org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe"))
- assert(desc.properties == Map(("p1", "v1"), ("p2", "v2")))
+ assert(desc.properties == Map("p1" -> "v1", "p2" -> "v2"))
}
test("Test CTAS #2") {
@@ -107,7 +112,7 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
assert(desc.storage.inputFormat == Some("parquet.hive.DeprecatedParquetInputFormat"))
assert(desc.storage.outputFormat == Some("parquet.hive.DeprecatedParquetOutputFormat"))
assert(desc.storage.serde == Some("parquet.hive.serde.ParquetHiveSerDe"))
- assert(desc.properties == Map(("p1", "v1"), ("p2", "v2")))
+ assert(desc.properties == Map("p1" -> "v1", "p2" -> "v2"))
}
test("Test CTAS #3") {
@@ -125,7 +130,7 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
assert(desc.storage.inputFormat == Some("org.apache.hadoop.mapred.TextInputFormat"))
assert(desc.storage.outputFormat ==
Some("org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"))
- assert(desc.storage.serde.isEmpty)
+ assert(desc.storage.serde == Some("org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"))
assert(desc.properties == Map())
}
@@ -305,7 +310,7 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
Some("org.apache.hadoop.mapred.TextInputFormat"))
assert(desc.storage.outputFormat ==
Some("org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"))
- assert(desc.storage.serde.isEmpty)
+ assert(desc.storage.serde == Some("org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"))
assert(desc.storage.properties.isEmpty)
assert(desc.properties.isEmpty)
assert(desc.comment.isEmpty)
@@ -412,7 +417,7 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
val (desc2, _) = extractTableDesc(query2)
assert(desc1.storage.inputFormat == Some("winput"))
assert(desc1.storage.outputFormat == Some("wowput"))
- assert(desc1.storage.serde.isEmpty)
+ assert(desc1.storage.serde == Some("org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"))
assert(desc2.storage.inputFormat == Some("org.apache.hadoop.hive.ql.io.orc.OrcInputFormat"))
assert(desc2.storage.outputFormat == Some("org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat"))
assert(desc2.storage.serde == Some("org.apache.hadoop.hive.ql.io.orc.OrcSerde"))
@@ -592,4 +597,94 @@ class HiveDDLCommandSuite extends PlanTest with SQLTestUtils with TestHiveSingle
val hiveClient = spark.sharedState.externalCatalog.asInstanceOf[HiveExternalCatalog].client
assert(hiveClient.getConf("hive.in.test", "") == "true")
}
+
+ test("create hive serde table with new syntax - basic") {
+ val sql =
+ """
+ |CREATE TABLE t
+ |(id int, name string COMMENT 'blabla')
+ |USING hive
+ |OPTIONS (fileFormat 'parquet', my_prop 1)
+ |LOCATION '/tmp/file'
+ |COMMENT 'BLABLA'
+ """.stripMargin
+
+ val table = analyzeCreateTable(sql)
+ assert(table.schema == new StructType()
+ .add("id", "int")
+ .add("name", "string", nullable = true, comment = "blabla"))
+ assert(table.provider == Some(DDLUtils.HIVE_PROVIDER))
+ assert(table.storage.locationUri == Some("/tmp/file"))
+ assert(table.storage.properties == Map("my_prop" -> "1"))
+ assert(table.comment == Some("BLABLA"))
+
+ assert(table.storage.inputFormat ==
+ Some("org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat"))
+ assert(table.storage.outputFormat ==
+ Some("org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat"))
+ assert(table.storage.serde ==
+ Some("org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"))
+ }
+
+ test("create hive serde table with new syntax - with partition and bucketing") {
+ val v1 = "CREATE TABLE t (c1 int, c2 int) USING hive PARTITIONED BY (c2)"
+ val table = analyzeCreateTable(v1)
+ assert(table.schema == new StructType().add("c1", "int").add("c2", "int"))
+ assert(table.partitionColumnNames == Seq("c2"))
+ // check the default formats
+ assert(table.storage.serde == Some("org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"))
+ assert(table.storage.inputFormat == Some("org.apache.hadoop.mapred.TextInputFormat"))
+ assert(table.storage.outputFormat ==
+ Some("org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"))
+
+ val v2 = "CREATE TABLE t (c1 int, c2 int) USING hive CLUSTERED BY (c2) INTO 4 BUCKETS"
+ val e2 = intercept[AnalysisException](analyzeCreateTable(v2))
+ assert(e2.message.contains("Creating bucketed Hive serde table is not supported yet"))
+
+ val v3 =
+ """
+ |CREATE TABLE t (c1 int, c2 int) USING hive
+ |PARTITIONED BY (c2)
+ |CLUSTERED BY (c2) INTO 4 BUCKETS""".stripMargin
+ val e3 = intercept[AnalysisException](analyzeCreateTable(v3))
+ assert(e3.message.contains("Creating bucketed Hive serde table is not supported yet"))
+ }
+
+ test("create hive serde table with new syntax - Hive options error checking") {
+ val v1 = "CREATE TABLE t (c1 int) USING hive OPTIONS (inputFormat 'abc')"
+ val e1 = intercept[IllegalArgumentException](analyzeCreateTable(v1))
+ assert(e1.getMessage.contains("Cannot specify only inputFormat or outputFormat"))
+
+ val v2 = "CREATE TABLE t (c1 int) USING hive OPTIONS " +
+ "(fileFormat 'x', inputFormat 'a', outputFormat 'b')"
+ val e2 = intercept[IllegalArgumentException](analyzeCreateTable(v2))
+ assert(e2.getMessage.contains(
+ "Cannot specify fileFormat and inputFormat/outputFormat together"))
+
+ val v3 = "CREATE TABLE t (c1 int) USING hive OPTIONS (fileFormat 'parquet', serde 'a')"
+ val e3 = intercept[IllegalArgumentException](analyzeCreateTable(v3))
+ assert(e3.getMessage.contains("fileFormat 'parquet' already specifies a serde"))
+
+ val v4 = "CREATE TABLE t (c1 int) USING hive OPTIONS (serde 'a', fieldDelim ' ')"
+ val e4 = intercept[IllegalArgumentException](analyzeCreateTable(v4))
+ assert(e4.getMessage.contains("Cannot specify delimiters with a custom serde"))
+
+ val v5 = "CREATE TABLE t (c1 int) USING hive OPTIONS (fieldDelim ' ')"
+ val e5 = intercept[IllegalArgumentException](analyzeCreateTable(v5))
+ assert(e5.getMessage.contains("Cannot specify delimiters without fileFormat"))
+
+ val v6 = "CREATE TABLE t (c1 int) USING hive OPTIONS (fileFormat 'parquet', fieldDelim ' ')"
+ val e6 = intercept[IllegalArgumentException](analyzeCreateTable(v6))
+ assert(e6.getMessage.contains(
+ "Cannot specify delimiters as they are only compatible with fileFormat 'textfile'"))
+
+ // The value of 'fileFormat' option is case-insensitive.
+ val v7 = "CREATE TABLE t (c1 int) USING hive OPTIONS (fileFormat 'TEXTFILE', lineDelim ',')"
+ val e7 = intercept[IllegalArgumentException](analyzeCreateTable(v7))
+ assert(e7.getMessage.contains("Hive data source only support newline '\\n' as line delimiter"))
+
+ val v8 = "CREATE TABLE t (c1 int) USING hive OPTIONS (fileFormat 'wrong')"
+ val e8 = intercept[IllegalArgumentException](analyzeCreateTable(v8))
+ assert(e8.getMessage.contains("invalid fileFormat: 'wrong'"))
+ }
}
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveExternalCatalogSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveExternalCatalogSuite.scala
index 6fee45824e..2f02bb5d3b 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveExternalCatalogSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveExternalCatalogSuite.scala
@@ -68,6 +68,6 @@ class HiveExternalCatalogSuite extends ExternalCatalogSuite {
val rawTable = externalCatalog.client.getTable("db1", "hive_tbl")
assert(!rawTable.properties.contains(HiveExternalCatalog.DATASOURCE_PROVIDER))
- assert(externalCatalog.getTable("db1", "hive_tbl").provider == Some(DDLUtils.HIVE_PROVIDER))
+ assert(DDLUtils.isHiveTable(externalCatalog.getTable("db1", "hive_tbl")))
}
}
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/MetastoreDataSourcesSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/MetastoreDataSourcesSuite.scala
index 2b8d4e2bb3..aed825e2f3 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/MetastoreDataSourcesSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/MetastoreDataSourcesSuite.scala
@@ -1189,21 +1189,6 @@ class MetastoreDataSourcesSuite extends QueryTest with SQLTestUtils with TestHiv
}
}
- test("create a data source table using hive") {
- val tableName = "tab1"
- withTable (tableName) {
- val e = intercept[AnalysisException] {
- sql(
- s"""
- |CREATE TABLE $tableName
- |(col1 int)
- |USING hive
- """.stripMargin)
- }.getMessage
- assert(e.contains("Cannot create hive serde table with CREATE TABLE USING"))
- }
- }
-
test("create a temp view using hive") {
val tableName = "tab1"
withTable (tableName) {
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
index 8b34219530..3ac07d0933 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
@@ -28,6 +28,7 @@ import org.apache.spark.sql.catalyst.catalog.{CatalogDatabase, CatalogTable, Cat
import org.apache.spark.sql.catalyst.TableIdentifier
import org.apache.spark.sql.execution.command.DDLUtils
import org.apache.spark.sql.hive.HiveExternalCatalog
+import org.apache.spark.sql.hive.orc.OrcFileOperator
import org.apache.spark.sql.hive.test.TestHiveSingleton
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.internal.StaticSQLConf.CATALOG_IMPLEMENTATION
@@ -1250,4 +1251,42 @@ class HiveDDLSuite
assert(e.message.contains("unknown is not a valid partition column"))
}
}
+
+ test("create hive serde table with new syntax") {
+ withTable("t", "t2", "t3") {
+ withTempPath { path =>
+ sql(
+ s"""
+ |CREATE TABLE t(id int) USING hive
+ |OPTIONS(fileFormat 'orc', compression 'Zlib')
+ |LOCATION '${path.getCanonicalPath}'
+ """.stripMargin)
+ val table = spark.sessionState.catalog.getTableMetadata(TableIdentifier("t"))
+ assert(DDLUtils.isHiveTable(table))
+ assert(table.storage.serde == Some("org.apache.hadoop.hive.ql.io.orc.OrcSerde"))
+ assert(table.storage.properties.get("compression") == Some("Zlib"))
+ assert(spark.table("t").collect().isEmpty)
+
+ sql("INSERT INTO t SELECT 1")
+ checkAnswer(spark.table("t"), Row(1))
+ // Check if this is compressed as ZLIB.
+ val maybeOrcFile = path.listFiles().find(_.getName.endsWith("part-00000"))
+ assert(maybeOrcFile.isDefined)
+ val orcFilePath = maybeOrcFile.get.toPath.toString
+ val expectedCompressionKind =
+ OrcFileOperator.getFileReader(orcFilePath).get.getCompression
+ assert("ZLIB" === expectedCompressionKind.name())
+
+ sql("CREATE TABLE t2 USING HIVE AS SELECT 1 AS c1, 'a' AS c2")
+ val table2 = spark.sessionState.catalog.getTableMetadata(TableIdentifier("t2"))
+ assert(DDLUtils.isHiveTable(table2))
+ assert(table2.storage.serde == Some("org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"))
+ checkAnswer(spark.table("t2"), Row(1, "a"))
+
+ sql("CREATE TABLE t3(a int, p int) USING hive PARTITIONED BY (p)")
+ sql("INSERT INTO t3 PARTITION(p=1) SELECT 0")
+ checkAnswer(spark.table("t3"), Row(0, 1))
+ }
+ }
+ }
}
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/orc/OrcHadoopFsRelationSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/orc/OrcHadoopFsRelationSuite.scala
index 463c368fc4..e678cf6f22 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/orc/OrcHadoopFsRelationSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/orc/OrcHadoopFsRelationSuite.scala
@@ -93,8 +93,6 @@ class OrcHadoopFsRelationSuite extends HadoopFsRelationTest {
.orc(path)
// Check if this is compressed as ZLIB.
- val conf = spark.sessionState.newHadoopConf()
- val fs = FileSystem.getLocal(conf)
val maybeOrcFile = new File(path).listFiles().find(_.getName.endsWith(".zlib.orc"))
assert(maybeOrcFile.isDefined)
val orcFilePath = maybeOrcFile.get.toPath.toString