aboutsummaryrefslogtreecommitdiff
path: root/sql/hive
diff options
context:
space:
mode:
authorgatorsmile <gatorsmile@gmail.com>2016-04-05 22:33:44 -0700
committerAndrew Or <andrew@databricks.com>2016-04-05 22:33:44 -0700
commit68be5b9e8a5ac1fc4d243bb54c2ca95fee3f74dc (patch)
tree9ba0f8e3dc8af4ade430b5c96ce29ec6db0f574d /sql/hive
parent48467f4eb02209a884adbcf052670a057a75fcbd (diff)
downloadspark-68be5b9e8a5ac1fc4d243bb54c2ca95fee3f74dc.tar.gz
spark-68be5b9e8a5ac1fc4d243bb54c2ca95fee3f74dc.tar.bz2
spark-68be5b9e8a5ac1fc4d243bb54c2ca95fee3f74dc.zip
[SPARK-14396][SQL] Throw Exceptions for DDLs of Partitioned Views
#### What changes were proposed in this pull request? Because the concept of partitioning is associated with physical tables, we disable all the supports of partitioned views, which are defined in the following three commands in [Hive DDL Manual](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-Create/Drop/AlterView): ``` ALTER VIEW view DROP [IF EXISTS] PARTITION spec1[, PARTITION spec2, ...]; ALTER VIEW view ADD [IF NOT EXISTS] PARTITION spec; CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name [COMMENT column_comment], ...) ] [COMMENT view_comment] [TBLPROPERTIES (property_name = property_value, ...)] AS SELECT ...; ``` An exception is thrown when users issue any of these three DDL commands. #### How was this patch tested? Added test cases for parsing create view and changed the existing test cases to verify if the exceptions are thrown. Author: gatorsmile <gatorsmile@gmail.com> Author: xiaoli <lixiao1983@gmail.com> Author: Xiao Li <xiaoli@Xiaos-MacBook-Pro.local> Closes #12169 from gatorsmile/viewPartition.
Diffstat (limited to 'sql/hive')
-rw-r--r--sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala8
-rw-r--r--sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala12
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala (renamed from sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveQlSuite.scala)60
3 files changed, 72 insertions, 8 deletions
diff --git a/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala b/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
index b01f556f0a..9e3cb18d45 100644
--- a/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
+++ b/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
@@ -372,7 +372,11 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
"alter_index",
// Macro commands are not supported
- "macro"
+ "macro",
+
+ // Create partitioned view is not supported
+ "create_like_view",
+ "describe_formatted_view_partitioned"
)
/**
@@ -482,7 +486,6 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
"cp_mj_rc",
"create_insert_outputformat",
"create_like_tbl_props",
- "create_like_view",
"create_nested_type",
"create_skewed_table1",
"create_struct_table",
@@ -507,7 +510,6 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
"default_partition_name",
"delimiter",
"desc_non_existent_tbl",
- "describe_formatted_view_partitioned",
"diff_part_input_formats",
"disable_file_format_check",
"disallow_incompatible_type_change_off",
diff --git a/sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala b/sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala
index c6c0b2ca59..ab69d3502e 100644
--- a/sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala
+++ b/sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala
@@ -215,11 +215,19 @@ class HiveSqlAstBuilder extends SparkSqlAstBuilder {
/**
* Create or replace a view. This creates a [[CreateViewAsSelect]] command.
+ *
+ * For example:
+ * {{{
+ * CREATE VIEW [IF NOT EXISTS] [db_name.]view_name
+ * [(column_name [COMMENT column_comment], ...) ]
+ * [COMMENT view_comment]
+ * [TBLPROPERTIES (property_name = property_value, ...)]
+ * AS SELECT ...;
+ * }}}
*/
override def visitCreateView(ctx: CreateViewContext): LogicalPlan = withOrigin(ctx) {
- // Pass a partitioned view on to hive.
if (ctx.identifierList != null) {
- HiveNativeCommand(command(ctx))
+ throw new ParseException(s"Operation not allowed: partitioned views", ctx)
} else {
if (ctx.STRING != null) {
logWarning("COMMENT clause is ignored.")
diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveQlSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala
index a8a0d6b8de..b4e5d4adf1 100644
--- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveQlSuite.scala
+++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveDDLCommandSuite.scala
@@ -26,16 +26,18 @@ import org.apache.spark.sql.catalyst.dsl.expressions._
import org.apache.spark.sql.catalyst.dsl.plans
import org.apache.spark.sql.catalyst.dsl.plans.DslLogicalPlan
import org.apache.spark.sql.catalyst.expressions.JsonTuple
+import org.apache.spark.sql.catalyst.parser.ParseException
import org.apache.spark.sql.catalyst.plans.PlanTest
import org.apache.spark.sql.catalyst.plans.logical.{Generate, ScriptTransformation}
-import org.apache.spark.sql.hive.execution.HiveSqlParser
+import org.apache.spark.sql.hive.execution.{HiveNativeCommand, HiveSqlParser}
-class HiveQlSuite extends PlanTest {
+class HiveDDLCommandSuite extends PlanTest {
val parser = HiveSqlParser
private def extractTableDesc(sql: String): (CatalogTable, Boolean) = {
parser.parsePlan(sql).collect {
- case CreateTableAsSelect(desc, child, allowExisting) => (desc, allowExisting)
+ case CreateTableAsSelect(desc, _, allowExisting) => (desc, allowExisting)
+ case CreateViewAsSelect(desc, _, allowExisting, _, _) => (desc, allowExisting)
}.head
}
@@ -251,4 +253,56 @@ class HiveQlSuite extends PlanTest {
|LATERAL VIEW explode(`gen``tab1`.`gen``col1`) `gen``tab2` AS `gen``col2`
""".stripMargin)
}
+
+ test("create view -- basic") {
+ val v1 = "CREATE VIEW view1 AS SELECT * FROM tab1"
+ val (desc, exists) = extractTableDesc(v1)
+ assert(!exists)
+ assert(desc.identifier.database.isEmpty)
+ assert(desc.identifier.table == "view1")
+ assert(desc.tableType == CatalogTableType.VIRTUAL_VIEW)
+ assert(desc.storage.locationUri.isEmpty)
+ assert(desc.schema == Seq.empty[CatalogColumn])
+ assert(desc.viewText.contains("SELECT * FROM tab1"))
+ assert(desc.viewOriginalText.contains("SELECT * FROM tab1"))
+ assert(desc.storage.serdeProperties == Map())
+ assert(desc.storage.inputFormat.isEmpty)
+ assert(desc.storage.outputFormat.isEmpty)
+ assert(desc.storage.serde.isEmpty)
+ assert(desc.properties == Map())
+ }
+
+ test("create view - full") {
+ val v1 =
+ """
+ |CREATE OR REPLACE VIEW IF NOT EXISTS view1
+ |(col1, col3)
+ |COMMENT 'I cannot spell'
+ |TBLPROPERTIES('prop1Key'="prop1Val")
+ |AS SELECT * FROM tab1
+ """.stripMargin
+ val (desc, exists) = extractTableDesc(v1)
+ assert(exists)
+ assert(desc.identifier.database.isEmpty)
+ assert(desc.identifier.table == "view1")
+ assert(desc.tableType == CatalogTableType.VIRTUAL_VIEW)
+ assert(desc.storage.locationUri.isEmpty)
+ assert(desc.schema ==
+ CatalogColumn("col1", null, nullable = true, None) ::
+ CatalogColumn("col3", null, nullable = true, None) :: Nil)
+ assert(desc.viewText.contains("SELECT * FROM tab1"))
+ assert(desc.viewOriginalText.contains("SELECT * FROM tab1"))
+ assert(desc.storage.serdeProperties == Map())
+ assert(desc.storage.inputFormat.isEmpty)
+ assert(desc.storage.outputFormat.isEmpty)
+ assert(desc.storage.serde.isEmpty)
+ assert(desc.properties == Map("prop1Key" -> "prop1Val"))
+ }
+
+ test("create view -- partitioned view") {
+ val v1 = "CREATE VIEW view1 partitioned on (ds, hr) as select * from srcpart"
+ intercept[ParseException] {
+ parser.parsePlan(v1).isInstanceOf[HiveNativeCommand]
+ }
+ }
}