Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private[sql] object CatalogV2Util {
}
if (containsNullType(dt)) {
throw new AnalysisException(
s"Cannot create tables with ${NullType.simpleString} type.")
s"Cannot create tables/views with ${NullType.simpleString} type.")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,9 @@ class ResolveSessionCatalog(
partitionSpec)

case AlterViewAsStatement(name, originalText, query) =>
if (query.resolved) {
assertNoNullTypeInSchema(query.schema)
}
val viewName = parseTempViewOrV1Table(name, "ALTER VIEW QUERY")
AlterViewAsCommand(
viewName.asTableIdentifier,
Expand All @@ -538,7 +541,9 @@ class ResolveSessionCatalog(
case CreateViewStatement(
tbl, userSpecifiedColumns, comment, properties,
originalText, child, allowExisting, replace, viewType) =>

if (child.resolved) {
assertNoNullTypeInSchema(child.schema)
}
val v1TableName = if (viewType != PersistedView) {
// temp view doesn't belong to any catalog and we shouldn't resolve catalog in the name.
tbl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.apache.spark.sql.catalyst.TableIdentifier
import org.apache.spark.sql.catalyst.analysis.NoSuchTableException
import org.apache.spark.sql.internal.SQLConf.MAX_NESTED_VIEW_DEPTH
import org.apache.spark.sql.test.{SharedSparkSession, SQLTestUtils}
import org.apache.spark.sql.types.NullType

class SimpleSQLViewSuite extends SQLViewSuite with SharedSparkSession

Expand Down Expand Up @@ -735,4 +736,15 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils {
}
}
}

test("SPARK-32356: forbid null type in create view") {
val msg = intercept[AnalysisException] {
sql("select null as c").createTempView("null_type_view")
}.getMessage
assert(msg.contains(s"Cannot create tables/views with ${NullType.simpleString} type."))
val msg2 = intercept[AnalysisException] {
sql("select null as c").createGlobalTempView("null_type_view")
}.getMessage
assert(msg2.contains(s"Cannot create tables/views with ${NullType.simpleString} type."))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import org.apache.spark.sql.execution.datasources.CreateTable
import org.apache.spark.sql.execution.datasources.v2.DataSourceV2Relation
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.sources.SimpleScanSource
import org.apache.spark.sql.types.{CharType, DoubleType, HIVE_TYPE_STRING, IntegerType, LongType, MetadataBuilder, StringType, StructField, StructType}
import org.apache.spark.sql.types.{CharType, DoubleType, HIVE_TYPE_STRING, IntegerType, LongType, MetadataBuilder, NullType, StringType, StructField, StructType}

class PlanResolutionSuite extends AnalysisTest {
import CatalystSqlParser._
Expand Down Expand Up @@ -1557,6 +1557,19 @@ class PlanResolutionSuite extends AnalysisTest {
checkFailure("testcat.tab", "foo")
}

test("SPARK-32356: forbid null type in create view") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to SQLViewSuite as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved.

val sql1 = "create view v as select null as c"
val sql2 = "alter view v as select null as c"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we test temp view as well? also the df api df.createTempView

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added.

val sql3 = "create temporary view v as select null as c"
val sql4 = "create global temporary view v as select null as c"
Seq(sql1, sql2, sql3, sql4).foreach { sql =>
val msg = intercept[AnalysisException] {
parseAndResolve(sql)
}.getMessage
assert(msg.contains(s"Cannot create tables/views with ${NullType.simpleString} type."))
}
}

// TODO: add tests for more commands.
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2314,6 +2314,7 @@ class HiveDDLSuite
}

test("SPARK-20680: do not support for null column datatype") {
val errMsg = s"Cannot create tables/views with ${NullType.simpleString} type."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed old error msg tables -> tables/views.

withTable("t") {
withView("tabNullType") {
hiveClient.runSqlHive("CREATE TABLE t (t1 int)")
Expand All @@ -2331,17 +2332,17 @@ class HiveDDLSuite
val e1 = intercept[AnalysisException] {
spark.sql("CREATE TABLE t1 USING PARQUET AS SELECT null as null_col")
}.getMessage
assert(e1.contains("Cannot create tables with null type"))
assert(e1.contains(errMsg))

val e2 = intercept[AnalysisException] {
spark.sql("CREATE TABLE t2 AS SELECT null as null_col")
}.getMessage
assert(e2.contains("Cannot create tables with null type"))
assert(e2.contains(errMsg))

val e3 = intercept[AnalysisException] {
spark.sql("CREATE TABLE t3 STORED AS PARQUET AS SELECT null as null_col")
}.getMessage
assert(e3.contains("Cannot create tables with null type"))
assert(e3.contains(errMsg))
}

// Forbid Replace table AS SELECT with null type
Expand All @@ -2350,27 +2351,27 @@ class HiveDDLSuite
val e = intercept[AnalysisException] {
spark.sql(s"CREATE OR REPLACE TABLE t USING $v2Source AS SELECT null as null_col")
}.getMessage
assert(e.contains("Cannot create tables with null type"))
assert(e.contains(errMsg))
}

// Forbid creating table with VOID type in Spark
withTable("t1", "t2", "t3", "t4") {
val e1 = intercept[AnalysisException] {
spark.sql(s"CREATE TABLE t1 (v VOID) USING PARQUET")
}.getMessage
assert(e1.contains("Cannot create tables with null type"))
assert(e1.contains(errMsg))
val e2 = intercept[AnalysisException] {
spark.sql(s"CREATE TABLE t2 (v VOID) USING hive")
}.getMessage
assert(e2.contains("Cannot create tables with null type"))
assert(e2.contains(errMsg))
val e3 = intercept[AnalysisException] {
spark.sql(s"CREATE TABLE t3 (v VOID)")
}.getMessage
assert(e3.contains("Cannot create tables with null type"))
assert(e3.contains(errMsg))
val e4 = intercept[AnalysisException] {
spark.sql(s"CREATE TABLE t4 (v VOID) STORED AS PARQUET")
}.getMessage
assert(e4.contains("Cannot create tables with null type"))
assert(e4.contains(errMsg))
}

// Forbid Replace table with VOID type
Expand All @@ -2379,7 +2380,7 @@ class HiveDDLSuite
val e = intercept[AnalysisException] {
spark.sql(s"CREATE OR REPLACE TABLE t (v VOID) USING $v2Source")
}.getMessage
assert(e.contains("Cannot create tables with null type"))
assert(e.contains(errMsg))
}

// Make sure spark.catalog.createTable with null type will fail
Expand Down Expand Up @@ -2416,7 +2417,7 @@ class HiveDDLSuite
schema = schema,
options = Map("fileFormat" -> "parquet"))
}.getMessage
assert(e.contains("Cannot create tables with null type"))
assert(e.contains(s"Cannot create tables/views with ${NullType.simpleString} type."))
}
}

Expand All @@ -2429,7 +2430,7 @@ class HiveDDLSuite
schema = schema,
options = Map.empty[String, String])
}.getMessage
assert(e.contains("Cannot create tables with null type"))
assert(e.contains(s"Cannot create tables/views with ${NullType.simpleString} type."))
}
}

Expand Down