Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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 @@ -880,6 +880,23 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder {
val properties = Option(ctx.tablePropertyList).map(visitPropertyKeyValues).getOrElse(Map.empty)
val selectQuery = Option(ctx.query).map(plan)

// Ensuring whether no duplicate name is used in table definition
val colNames = cols.map(_.name)
if (colNames.length != colNames.distinct.length) {
val duplicateColumns = colNames.groupBy(identity).collect {
case (x, ys) if ys.length > 1 => "\"" + x + "\""
}
throw operationNotAllowed(s"Duplicated column names found in table definition of $name: " +
duplicateColumns.mkString("[", ",", "]"), ctx)
}

// For Hive tables, partition columns must not be part of the schema
val badPartCols = partitionCols.map(_.name).toSet.intersect(colNames.toSet)
if (badPartCols.nonEmpty) {
throw operationNotAllowed(s"Partition columns may not be specified in the schema: " +
badPartCols.map("\"" + _ + "\"").mkString("[", ",", "]"), ctx)
}

// Note: Hive requires partition columns to be distinct from the schema, so we need
// to include the partition columns here explicitly
val schema = cols ++ partitionCols
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,20 @@ class DDLCommandSuite extends PlanTest {
assert(ct.table.storage.locationUri == Some("/something/anything"))
}

test("create table - column repeated in partitioning columns") {
val query = "CREATE TABLE tab1 (key INT, value STRING) PARTITIONED BY (key INT, hr STRING)"
val e = intercept[ParseException] { parser.parsePlan(query) }
assert(e.getMessage.contains(
"Operation not allowed: Partition columns may not be specified in the schema: [\"key\"]"))
}

test("create table - duplicate column names in the table definition") {
val query = "CREATE TABLE default.tab1 (key INT, key STRING)"
val e = intercept[ParseException] { parser.parsePlan(query) }
assert(e.getMessage.contains("Operation not allowed: Duplicated column names found in " +
"table definition of `default`.`tab1`: [\"key\"]"))
}

test("create table using - with partitioned by") {
val query = "CREATE TABLE my_tab(a INT, b STRING) USING parquet PARTITIONED BY (a)"
val expected = CreateTableUsing(
Expand Down