Skip to content

Commit 68170bb

Browse files
committed
fix.
1 parent 0894f5e commit 68170bb

File tree

2 files changed

+17
-39
lines changed

2 files changed

+17
-39
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/ParserUtils.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,8 @@ object ParserUtils {
4141
throw new ParseException(s"Operation not allowed: $message", ctx)
4242
}
4343

44-
def duplicateClausesNotAllowed(message: String, ctx: ParserRuleContext): Nothing = {
45-
throw new ParseException(s"Found duplicate clauses: $message", ctx)
46-
}
47-
48-
def checkDuplicateClauses(
49-
nodes: util.List[TerminalNode], clauseName: String, ctx: ParserRuleContext): Unit = {
44+
def checkDuplicateClauses[T](
45+
nodes: util.List[T], clauseName: String, ctx: ParserRuleContext): Unit = {
5046
if (nodes.size() > 1) {
5147
throw new ParseException(s"Found duplicate clauses: $clauseName", ctx)
5248
}

sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,11 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
383383
* {{{
384384
* CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db_name.]table_name
385385
* USING table_provider
386-
* [OPTIONS table_property_list]
387386
* create_table_clauses
388387
* [[AS] select_statement];
389388
*
390389
* create_table_clauses (order insensitive):
390+
* [OPTIONS table_property_list]
391391
* [PARTITIONED BY (col_name, col_name, ...)]
392392
* [CLUSTERED BY (col_name, col_name, ...)
393393
* [SORTED BY (col_name [ASC|DESC], ...)]
@@ -408,6 +408,8 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
408408
checkDuplicateClauses(ctx.OPTIONS, "OPTIONS", ctx)
409409
checkDuplicateClauses(ctx.PARTITIONED, "PARTITIONED BY", ctx)
410410
checkDuplicateClauses(ctx.COMMENT, "COMMENT", ctx)
411+
checkDuplicateClauses(ctx.bucketSpec(), "CLUSTERED BY", ctx)
412+
checkDuplicateClauses(ctx.locationSpec, "LOCATION", ctx)
411413

412414
val options = Option(ctx.options).map(visitPropertyKeyValues).getOrElse(Map.empty)
413415
val provider = ctx.tableProvider.qualifiedName.getText
@@ -417,17 +419,9 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
417419
.map(visitIdentifierList(_).toArray)
418420
.getOrElse(Array.empty[String])
419421
val properties = Option(ctx.tableProps).map(visitPropertyKeyValues).getOrElse(Map.empty)
420-
val bucketSpec = if (ctx.bucketSpec().size > 1) {
421-
duplicateClausesNotAllowed("CLUSTERED BY", ctx)
422-
} else {
423-
ctx.bucketSpec().asScala.headOption.map(visitBucketSpec)
424-
}
422+
val bucketSpec = ctx.bucketSpec().asScala.headOption.map(visitBucketSpec)
425423

426-
val location = if (ctx.locationSpec.size > 1) {
427-
duplicateClausesNotAllowed("LOCATION", ctx)
428-
} else {
429-
ctx.locationSpec.asScala.headOption.map(visitLocationSpec)
430-
}
424+
val location = ctx.locationSpec.asScala.headOption.map(visitLocationSpec)
431425
val storage = DataSource.buildStorageFormatFromOptions(options)
432426

433427
if (location.isDefined && storage.locationUri.isDefined) {
@@ -1131,16 +1125,16 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
11311125
checkDuplicateClauses(ctx.TBLPROPERTIES, "TBLPROPERTIES", ctx)
11321126
checkDuplicateClauses(ctx.PARTITIONED, "PARTITIONED BY", ctx)
11331127
checkDuplicateClauses(ctx.COMMENT, "COMMENT", ctx)
1128+
checkDuplicateClauses(ctx.bucketSpec(), "CLUSTERED BY", ctx)
1129+
checkDuplicateClauses(ctx.createFileFormat, "STORED AS/BY", ctx)
1130+
checkDuplicateClauses(ctx.rowFormat, "ROW FORMAT", ctx)
1131+
checkDuplicateClauses(ctx.locationSpec, "LOCATION", ctx)
11341132

11351133
val dataCols = Option(ctx.columns).map(visitColTypeList).getOrElse(Nil)
11361134
val partitionCols = Option(ctx.partitionColumns).map(visitColTypeList).getOrElse(Nil)
11371135
val properties = Option(ctx.tableProps).map(visitPropertyKeyValues).getOrElse(Map.empty)
11381136
val selectQuery = Option(ctx.query).map(plan)
1139-
val bucketSpec = if (ctx.bucketSpec().size > 1) {
1140-
duplicateClausesNotAllowed("CLUSTERED BY", ctx)
1141-
} else {
1142-
ctx.bucketSpec().asScala.headOption.map(visitBucketSpec)
1143-
}
1137+
val bucketSpec = ctx.bucketSpec().asScala.headOption.map(visitBucketSpec)
11441138

11451139
// Note: Hive requires partition columns to be distinct from the schema, so we need
11461140
// to include the partition columns here explicitly
@@ -1149,23 +1143,11 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
11491143
// Storage format
11501144
val defaultStorage = HiveSerDe.getDefaultStorage(conf)
11511145
validateRowFormatFileFormat(ctx.rowFormat.asScala, ctx.createFileFormat.asScala, ctx)
1152-
val fileStorage = if (ctx.createFileFormat.size > 1) {
1153-
duplicateClausesNotAllowed("STORED AS/BY", ctx)
1154-
} else {
1155-
ctx.createFileFormat.asScala.headOption.map(visitCreateFileFormat)
1156-
.getOrElse(CatalogStorageFormat.empty)
1157-
}
1158-
val rowStorage = if (ctx.rowFormat.size > 1) {
1159-
duplicateClausesNotAllowed("ROW FORMAT", ctx)
1160-
} else {
1161-
ctx.rowFormat.asScala.headOption.map(visitRowFormat)
1162-
.getOrElse(CatalogStorageFormat.empty)
1163-
}
1164-
val location = if (ctx.locationSpec.size > 1) {
1165-
duplicateClausesNotAllowed("LOCATION", ctx)
1166-
} else {
1167-
ctx.locationSpec.asScala.headOption.map(visitLocationSpec)
1168-
}
1146+
val fileStorage = ctx.createFileFormat.asScala.headOption.map(visitCreateFileFormat)
1147+
.getOrElse(CatalogStorageFormat.empty)
1148+
val rowStorage = ctx.rowFormat.asScala.headOption.map(visitRowFormat)
1149+
.getOrElse(CatalogStorageFormat.empty)
1150+
val location = ctx.locationSpec.asScala.headOption.map(visitLocationSpec)
11691151
// If we are creating an EXTERNAL table, then the LOCATION field is required
11701152
if (external && location.isEmpty) {
11711153
operationNotAllowed("CREATE EXTERNAL TABLE must be accompanied by LOCATION", ctx)

0 commit comments

Comments
 (0)