aboutsummaryrefslogtreecommitdiff
path: root/sql/hive
diff options
context:
space:
mode:
authorgatorsmile <gatorsmile@gmail.com>2016-04-05 11:19:46 +0200
committerHerman van Hovell <hvanhovell@questtec.nl>2016-04-05 11:19:46 +0200
commit78071736799b6c86b5c01b27395f4ab87075342b (patch)
tree08a4b18ebd0563c84cc8540ac81f511838e3810d /sql/hive
parent2715bc68bd1661d207b1af5f44ae8d02aec9d4ec (diff)
downloadspark-78071736799b6c86b5c01b27395f4ab87075342b.tar.gz
spark-78071736799b6c86b5c01b27395f4ab87075342b.tar.bz2
spark-78071736799b6c86b5c01b27395f4ab87075342b.zip
[SPARK-14349][SQL] Issue Error Messages for Unsupported Operators/DML/DDL in SQL Context.
#### What changes were proposed in this pull request? Currently, the weird error messages are issued if we use Hive Context-only operations in SQL Context. For example, - When calling `Drop Table` in SQL Context, we got the following message: ``` Expected exception org.apache.spark.sql.catalyst.parser.ParseException to be thrown, but java.lang.ClassCastException was thrown. ``` - When calling `Script Transform` in SQL Context, we got the message: ``` assertion failed: No plan for ScriptTransformation [key#9,value#10], cat, [tKey#155,tValue#156], null +- LogicalRDD [key#9,value#10], MapPartitionsRDD[3] at beforeAll at BeforeAndAfterAll.scala:187 ``` Updates: Based on the investigation from hvanhovell , the root cause is `visitChildren`, which is the default implementation. It always returns the result of the last defined context child. After merging the code changes from hvanhovell , it works! Thank you hvanhovell ! #### How was this patch tested? A few test cases are added. Not sure if the same issue exist for the other operators/DDL/DML. hvanhovell Author: gatorsmile <gatorsmile@gmail.com> Author: xiaoli <lixiao1983@gmail.com> Author: Herman van Hovell <hvanhovell@questtec.nl> Author: Xiao Li <xiaoli@Xiaos-MacBook-Pro.local> Closes #12134 from gatorsmile/hiveParserCommand.
Diffstat (limited to 'sql/hive')
-rw-r--r--sql/hive/src/main/scala/org/apache/spark/sql/hive/execution/HiveSqlParser.scala16
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/HiveQlSuite.scala31
2 files changed, 42 insertions, 5 deletions
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 12e4f49756..55e69f99a4 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
@@ -134,6 +134,18 @@ class HiveSqlAstBuilder extends SparkSqlAstBuilder {
}
/**
+ * Create a [[CatalogStorageFormat]]. This is part of the [[CreateTableAsSelect]] command.
+ */
+ override def visitCreateFileFormat(
+ ctx: CreateFileFormatContext): CatalogStorageFormat = withOrigin(ctx) {
+ if (ctx.storageHandler == null) {
+ typedVisit[CatalogStorageFormat](ctx.fileFormat)
+ } else {
+ visitStorageHandler(ctx.storageHandler)
+ }
+ }
+
+ /**
* Create a [[CreateTableAsSelect]] command.
*/
override def visitCreateTable(ctx: CreateTableContext): LogicalPlan = {
@@ -282,6 +294,7 @@ class HiveSqlAstBuilder extends SparkSqlAstBuilder {
* Create a [[HiveScriptIOSchema]].
*/
override protected def withScriptIOSchema(
+ ctx: QuerySpecificationContext,
inRowFormat: RowFormatContext,
recordWriter: Token,
outRowFormat: RowFormatContext,
@@ -391,7 +404,8 @@ class HiveSqlAstBuilder extends SparkSqlAstBuilder {
/**
* Storage Handlers are currently not supported in the statements we support (CTAS).
*/
- override def visitStorageHandler(ctx: StorageHandlerContext): AnyRef = withOrigin(ctx) {
+ override def visitStorageHandler(
+ ctx: StorageHandlerContext): CatalogStorageFormat = withOrigin(ctx) {
throw new ParseException("Storage Handlers are currently unsupported.", ctx)
}
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/HiveQlSuite.scala
index 75108c6d47..a8a0d6b8de 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/HiveQlSuite.scala
@@ -18,16 +18,19 @@
package org.apache.spark.sql.hive
import org.apache.hadoop.hive.serde.serdeConstants
-import org.scalatest.BeforeAndAfterAll
-import org.apache.spark.SparkFunSuite
import org.apache.spark.sql.AnalysisException
+import org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute
import org.apache.spark.sql.catalyst.catalog.{CatalogColumn, CatalogTable, CatalogTableType}
+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.plans.logical.Generate
+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
-class HiveQlSuite extends SparkFunSuite with BeforeAndAfterAll {
+class HiveQlSuite extends PlanTest {
val parser = HiveSqlParser
private def extractTableDesc(sql: String): (CatalogTable, Boolean) = {
@@ -201,6 +204,26 @@ class HiveQlSuite extends SparkFunSuite with BeforeAndAfterAll {
assert(plan.children.head.asInstanceOf[Generate].generator.isInstanceOf[JsonTuple])
}
+ test("transform query spec") {
+ val plan1 = parser.parsePlan("select transform(a, b) using 'func' from e where f < 10")
+ .asInstanceOf[ScriptTransformation].copy(ioschema = null)
+ val plan2 = parser.parsePlan("map a, b using 'func' as c, d from e")
+ .asInstanceOf[ScriptTransformation].copy(ioschema = null)
+ val plan3 = parser.parsePlan("reduce a, b using 'func' as (c: int, d decimal(10, 0)) from e")
+ .asInstanceOf[ScriptTransformation].copy(ioschema = null)
+
+ val p = ScriptTransformation(
+ Seq(UnresolvedAttribute("a"), UnresolvedAttribute("b")),
+ "func", Seq.empty, plans.table("e"), null)
+
+ comparePlans(plan1,
+ p.copy(child = p.child.where('f < 10), output = Seq('key.string, 'value.string)))
+ comparePlans(plan2,
+ p.copy(output = Seq('c.string, 'd.string)))
+ comparePlans(plan3,
+ p.copy(output = Seq('c.int, 'd.decimal(10, 0))))
+ }
+
test("use backticks in output of Script Transform") {
val plan = parser.parsePlan(
"""SELECT `t`.`thing1`