Skip to content

Commit 1578ee2

Browse files
fenzhuGitHub Enterprise
authored andcommitted
[CARMEL-5867] ShowCreateTableCommand and DescribeTableCommand miss nullable information (#880)
1 parent 4c840e3 commit 1578ee2

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/types/StructField.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ case class StructField(
9393
.map(escapeSingleQuotedString)
9494
.map(" COMMENT '" + _ + "'")
9595

96-
s"${quoteIdentifier(name)} ${dataType.sql}${comment.getOrElse("")}"
96+
val notNull = if (nullable) "" else " NOT NULL"
97+
98+
s"${quoteIdentifier(name)} ${dataType.sql}$notNull${comment.getOrElse("")}"
9799
}
98100
}

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -972,12 +972,15 @@ abstract class DescribeCommandBase extends RunnableCommand {
972972
protected def describeSchema(
973973
schema: StructType,
974974
buffer: ArrayBuffer[Row],
975-
header: Boolean): Unit = {
975+
header: Boolean,
976+
ignoreNullable: Boolean = true): Unit = {
976977
if (header) {
977978
append(buffer, s"# ${output.head.name}", output(1).name, output(2).name)
978979
}
979980
schema.foreach { column =>
980-
append(buffer, column.name, column.dataType.simpleString, column.getComment().orNull)
981+
val columnNullableInfo = if (ignoreNullable || column.nullable) "" else " not null"
982+
val columnTypeInfo = column.dataType.simpleString + columnNullableInfo
983+
append(buffer, column.name, columnTypeInfo, column.getComment().orNull)
981984
}
982985
}
983986

@@ -1001,24 +1004,28 @@ case class DescribeTableCommand(
10011004
override def run(sparkSession: SparkSession): Seq[Row] = {
10021005
val result = new ArrayBuffer[Row]
10031006
val catalog = sparkSession.sessionState.catalog
1007+
val enforceNotNull = sparkSession.sessionState.conf.enforceSchemaNotNull
10041008

10051009
if (catalog.isTemporaryView(table)) {
10061010
if (partitionSpec.nonEmpty) {
10071011
throw new AnalysisException(
10081012
s"DESC PARTITION is not allowed on a temporary view: ${table.identifier}")
10091013
}
1010-
describeSchema(catalog.lookupRelation(table).schema, result, header = false)
1014+
describeSchema(catalog.lookupRelation(table).schema, result,
1015+
header = false, ignoreNullable = !enforceNotNull)
10111016
} else {
10121017
val metadata = catalog.getTableMetadata(table)
10131018
if (metadata.schema.isEmpty) {
10141019
// In older version(prior to 2.1) of Spark, the table schema can be empty and should be
10151020
// inferred at runtime. We should still support it.
1016-
describeSchema(sparkSession.table(metadata.identifier).schema, result, header = false)
1021+
describeSchema(sparkSession.table(metadata.identifier).schema, result,
1022+
header = false, ignoreNullable = !enforceNotNull)
10171023
} else {
1018-
describeSchema(metadata.schema, result, header = false)
1024+
describeSchema(metadata.schema, result,
1025+
header = false, ignoreNullable = !enforceNotNull)
10191026
}
10201027

1021-
describePartitionInfo(metadata, result)
1028+
describePartitionInfo(metadata, result, !enforceNotNull)
10221029

10231030
if (partitionSpec.nonEmpty) {
10241031
// Outputs the partition-specific info for the DDL command:
@@ -1032,10 +1039,12 @@ case class DescribeTableCommand(
10321039
result
10331040
}
10341041

1035-
private def describePartitionInfo(table: CatalogTable, buffer: ArrayBuffer[Row]): Unit = {
1042+
private def describePartitionInfo(table: CatalogTable,
1043+
buffer: ArrayBuffer[Row], ignoreNullable: Boolean): Unit = {
10361044
if (table.partitionColumnNames.nonEmpty) {
10371045
append(buffer, "# Partition Information", "", "")
1038-
describeSchema(table.partitionSchema, buffer, header = true)
1046+
describeSchema(table.partitionSchema, buffer,
1047+
header = true, ignoreNullable = ignoreNullable)
10391048
}
10401049
}
10411050

@@ -1111,7 +1120,9 @@ case class DescribeQueryCommand(queryText: String, plan: LogicalPlan)
11111120
override def run(sparkSession: SparkSession): Seq[Row] = {
11121121
val result = new ArrayBuffer[Row]
11131122
val queryExecution = sparkSession.sessionState.executePlan(plan)
1114-
describeSchema(queryExecution.analyzed.schema, result, header = false)
1123+
val enforceNotNull = sparkSession.sessionState.conf.enforceSchemaNotNull
1124+
describeSchema(queryExecution.analyzed.schema, result,
1125+
header = false, ignoreNullable = !enforceNotNull)
11151126
result
11161127
}
11171128
}

sql/core/src/test/scala/org/apache/spark/sql/ShowCreateTableSuite.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.apache.spark.sql
1919

2020
import org.apache.spark.sql.catalyst.TableIdentifier
2121
import org.apache.spark.sql.catalyst.catalog.CatalogTable
22+
import org.apache.spark.sql.internal.SQLConf
2223
import org.apache.spark.sql.test.{SharedSparkSession, SQLTestUtils}
2324
import org.apache.spark.util.Utils
2425

@@ -179,6 +180,26 @@ abstract class ShowCreateTableSuite extends QueryTest with SQLTestUtils {
179180
}
180181
}
181182

183+
test("CARMEL-5867: ShowCreateTableCommand and DescribeTableCommand miss nullable information") {
184+
withSQLConf(SQLConf.ENFORCE_SCHEMA_NOT_NULL.key -> "true") {
185+
withTable("tab") {
186+
sql("create table tab(id int not null comment 'test'," +
187+
" name string, score double not null) using parquet")
188+
checkAnswer(
189+
sql("show create table tab"),
190+
Row("CREATE TABLE `default`.`tab` (" +
191+
"\n `id` INT NOT NULL COMMENT 'test'," +
192+
"\n `name` STRING," +
193+
"\n `score` DOUBLE NOT NULL)" +
194+
"\nUSING parquet" +
195+
"\n"))
196+
val descResult = sql("desc extended tab").collect()
197+
val res = descResult.filter(_.getString(1).contains(" not null"))
198+
assert(res.length == 2)
199+
}
200+
}
201+
}
202+
182203
protected def getShowDDL(showCreateTableSql: String): String = {
183204
val result = sql(showCreateTableSql)
184205
.head()

0 commit comments

Comments
 (0)