Skip to content

Commit d63428a

Browse files
gatorsmilerxin
authored andcommitted
[SPARK-16368][SQL] Fix Strange Errors When Creating View With Unmatched Column Num
#### What changes were proposed in this pull request? When creating a view, a common user error is the number of columns produced by the `SELECT` clause does not match the number of column names specified by `CREATE VIEW`. For example, given Table `t1` only has 3 columns ```SQL create view v1(col2, col4, col3, col5) as select * from t1 ``` Currently, Spark SQL reports the following error: ``` requirement failed java.lang.IllegalArgumentException: requirement failed at scala.Predef$.require(Predef.scala:212) at org.apache.spark.sql.execution.command.CreateViewCommand.run(views.scala:90) ``` This error message is very confusing. This PR is to detect the error and issue a meaningful error message. #### How was this patch tested? Added test cases Author: gatorsmile <[email protected]> Closes #14047 from gatorsmile/viewMismatchedColumns. (cherry picked from commit ab05db0) Signed-off-by: Reynold Xin <[email protected]>
1 parent 920162a commit d63428a

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ case class CreateViewCommand(
8888
qe.assertAnalyzed()
8989
val analyzedPlan = qe.analyzed
9090

91-
require(tableDesc.schema == Nil || tableDesc.schema.length == analyzedPlan.output.length)
91+
if (tableDesc.schema != Nil && tableDesc.schema.length != analyzedPlan.output.length) {
92+
throw new AnalysisException(s"The number of columns produced by the SELECT clause " +
93+
s"(num: `${analyzedPlan.output.length}`) does not match the number of column names " +
94+
s"specified by CREATE VIEW (num: `${tableDesc.schema.length}`).")
95+
}
9296
val sessionState = sparkSession.sessionState
9397

9498
if (isTemporary) {

sql/core/src/test/scala/org/apache/spark/sql/execution/command/DDLSuite.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,29 @@ class DDLSuite extends QueryTest with SharedSQLContext with BeforeAndAfterEach {
13141314
}
13151315
}
13161316

1317+
test("create temporary view with mismatched schema") {
1318+
withTable("tab1") {
1319+
spark.range(10).write.saveAsTable("tab1")
1320+
withView("view1") {
1321+
val e = intercept[AnalysisException] {
1322+
sql("CREATE TEMPORARY VIEW view1 (col1, col3) AS SELECT * FROM tab1")
1323+
}.getMessage
1324+
assert(e.contains("the SELECT clause (num: `1`) does not match")
1325+
&& e.contains("CREATE VIEW (num: `2`)"))
1326+
}
1327+
}
1328+
}
1329+
1330+
test("create temporary view with specified schema") {
1331+
withView("view1") {
1332+
sql("CREATE TEMPORARY VIEW view1 (col1, col2) AS SELECT 1, 2")
1333+
checkAnswer(
1334+
sql("SELECT * FROM view1"),
1335+
Row(1, 2) :: Nil
1336+
)
1337+
}
1338+
}
1339+
13171340
test("truncate table - external table, temporary table, view (not allowed)") {
13181341
import testImplicits._
13191342
val path = Utils.createTempDir().getAbsolutePath

sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,29 @@ class HiveDDLSuite
391391
}
392392
}
393393

394+
test("create view with mismatched schema") {
395+
withTable("tab1") {
396+
spark.range(10).write.saveAsTable("tab1")
397+
withView("view1") {
398+
val e = intercept[AnalysisException] {
399+
sql("CREATE VIEW view1 (col1, col3) AS SELECT * FROM tab1")
400+
}.getMessage
401+
assert(e.contains("the SELECT clause (num: `1`) does not match")
402+
&& e.contains("CREATE VIEW (num: `2`)"))
403+
}
404+
}
405+
}
406+
407+
test("create view with specified schema") {
408+
withView("view1") {
409+
sql("CREATE VIEW view1 (col1, col2) AS SELECT 1, 2")
410+
checkAnswer(
411+
sql("SELECT * FROM view1"),
412+
Row(1, 2) :: Nil
413+
)
414+
}
415+
}
416+
394417
test("desc table for Hive table") {
395418
withTable("tab1") {
396419
val tabName = "tab1"

0 commit comments

Comments
 (0)