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 @@ -199,7 +199,7 @@ query
;

insertInto
: INSERT OVERWRITE TABLE tableIdentifier partitionSpec? (IF NOT EXISTS)?
: INSERT OVERWRITE TABLE tableIdentifier (partitionSpec (IF NOT EXISTS)?)?
| INSERT INTO TABLE? tableIdentifier partitionSpec?
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
val tableIdent = visitTableIdentifier(ctx.tableIdentifier)
val partitionKeys = Option(ctx.partitionSpec).map(visitPartitionSpec).getOrElse(Map.empty)

val dynamicPartitionKeys = partitionKeys.filter(_._2.isEmpty)
if (ctx.EXISTS != null && dynamicPartitionKeys.nonEmpty) {
throw new ParseException(s"Dynamic partitions do not support IF NOT EXISTS. Specified " +
"partitions with value: " + dynamicPartitionKeys.keys.mkString("[", ",", "]"), ctx)
}

InsertIntoTable(
UnresolvedRelation(tableIdent, None),
partitionKeys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ case class InsertIntoTable(
}

assert(overwrite || !ifNotExists)
assert(partition.values.forall(_.nonEmpty) || !ifNotExists)
override lazy val resolved: Boolean =
childrenResolved && table.resolved && expectedColumns.forall { expected =>
child.output.size == expected.size && child.output.zip(expected).forall {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,12 @@ class PlanParserSuite extends PlanTest {
// Single inserts
assertEqual(s"insert overwrite table s $sql",
insert(Map.empty, overwrite = true))
assertEqual(s"insert overwrite table s if not exists $sql",
insert(Map.empty, overwrite = true, ifNotExists = true))
assertEqual(s"insert overwrite table s partition (e = 1) if not exists $sql",
insert(Map("e" -> Option("1")), overwrite = true, ifNotExists = true))
assertEqual(s"insert into s $sql",
insert(Map.empty))
assertEqual(s"insert into table s partition (c = 'd', e = 1) $sql",
insert(Map("c" -> Option("d"), "e" -> Option("1"))))
assertEqual(s"insert overwrite table s partition (c = 'd', x) if not exists $sql",
insert(Map("c" -> Option("d"), "x" -> None), overwrite = true, ifNotExists = true))

// Multi insert
val plan2 = table("t").where('x > 5).select(star())
Expand All @@ -200,6 +198,13 @@ class PlanParserSuite extends PlanTest {
table("u"), Map.empty, plan2, overwrite = false, ifNotExists = false)))
}

test ("insert with if not exists") {
val sql = "select * from t"
intercept(s"insert overwrite table s partition (e = 1, x) if not exists $sql",
"Dynamic partitions do not support IF NOT EXISTS. Specified partitions with value: [x]")
intercept[ParseException](parsePlan(s"insert overwrite table s if not exists $sql"))
}

test("aggregation") {
val sql = "select a, b, sum(c) as c from d group by a, b"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,74 @@ class InsertIntoHiveTableSuite extends QueryTest with TestHiveSingleton with Bef
sql("DROP TABLE tmp_table")
}

test("INSERT OVERWRITE - partition IF NOT EXISTS") {
withTempDir { tmpDir =>
val table = "table_with_partition"
withTable(table) {
val selQuery = s"select c1, p1, p2 from $table"
sql(
s"""
|CREATE TABLE $table(c1 string)
|PARTITIONED by (p1 string,p2 string)
|location '${tmpDir.toURI.toString}'
""".stripMargin)
sql(
s"""
|INSERT OVERWRITE TABLE $table
|partition (p1='a',p2='b')
|SELECT 'blarr'
""".stripMargin)
checkAnswer(
sql(selQuery),
Row("blarr", "a", "b"))

sql(
s"""
|INSERT OVERWRITE TABLE $table
|partition (p1='a',p2='b')
|SELECT 'blarr2'
""".stripMargin)
checkAnswer(
sql(selQuery),
Row("blarr2", "a", "b"))

var e = intercept[AnalysisException] {
sql(
s"""
|INSERT OVERWRITE TABLE $table
|partition (p1='a',p2) IF NOT EXISTS
|SELECT 'blarr3', 'newPartition'
""".stripMargin)
}
assert(e.getMessage.contains(
"Dynamic partitions do not support IF NOT EXISTS. Specified partitions with value: [p2]"))

e = intercept[AnalysisException] {
sql(
s"""
|INSERT OVERWRITE TABLE $table
|partition (p1='a',p2) IF NOT EXISTS
|SELECT 'blarr3', 'b'
""".stripMargin)
}
assert(e.getMessage.contains(
"Dynamic partitions do not support IF NOT EXISTS. Specified partitions with value: [p2]"))

// If the partition already exists, the insert will overwrite the data
// unless users specify IF NOT EXISTS
sql(
s"""
|INSERT OVERWRITE TABLE $table
|partition (p1='a',p2='b') IF NOT EXISTS
|SELECT 'blarr3'
""".stripMargin)
checkAnswer(
sql(selQuery),
Row("blarr2", "a", "b"))
}
}
}

test("Insert ArrayType.containsNull == false") {
val schema = StructType(Seq(
StructField("a", ArrayType(StringType, containsNull = false))))
Expand Down