-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-17732][SQL] ALTER TABLE DROP PARTITION should support comparators #15704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e97bde9
ea33aba
475e5dc
1556819
17b7fa4
f006316
ac44a0a
9f04cb9
e157b66
580a5e7
2ff93fe
f3f0ad5
ae1d7df
fab5682
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ import org.apache.spark.sql.{AnalysisException, QueryTest, Row, SaveMode} | |
| import org.apache.spark.sql.catalyst.analysis.{NoSuchPartitionException, TableAlreadyExistsException} | ||
| import org.apache.spark.sql.catalyst.catalog.{CatalogDatabase, CatalogTable, CatalogTableType} | ||
| import org.apache.spark.sql.catalyst.TableIdentifier | ||
| import org.apache.spark.sql.catalyst.parser.ParseException | ||
| import org.apache.spark.sql.execution.command.DDLUtils | ||
| import org.apache.spark.sql.hive.HiveExternalCatalog | ||
| import org.apache.spark.sql.hive.test.TestHiveSingleton | ||
|
|
@@ -225,6 +226,108 @@ class HiveDDLSuite | |
| } | ||
| } | ||
|
|
||
| test("SPARK-17732: Drop partitions by filter") { | ||
| withTable("sales") { | ||
| sql("CREATE TABLE sales(id INT) PARTITIONED BY (country STRING, quarter STRING)") | ||
|
|
||
| for (country <- Seq("US", "CA", "KR")) { | ||
| for (quarter <- 1 to 4) { | ||
| sql(s"ALTER TABLE sales ADD PARTITION (country = '$country', quarter = '$quarter')") | ||
| } | ||
| } | ||
|
|
||
| sql("ALTER TABLE sales DROP PARTITION (country < 'KR', quarter > '2')") | ||
| checkAnswer(sql("SHOW PARTITIONS sales"), | ||
| Row("country=CA/quarter=1") :: | ||
| Row("country=CA/quarter=2") :: | ||
| Row("country=KR/quarter=1") :: | ||
| Row("country=KR/quarter=2") :: | ||
| Row("country=KR/quarter=3") :: | ||
| Row("country=KR/quarter=4") :: | ||
| Row("country=US/quarter=1") :: | ||
| Row("country=US/quarter=2") :: | ||
| Row("country=US/quarter=3") :: | ||
| Row("country=US/quarter=4") :: Nil) | ||
|
|
||
| sql("ALTER TABLE sales DROP PARTITION (country < 'KR'), PARTITION (quarter <= '1')") | ||
| checkAnswer(sql("SHOW PARTITIONS sales"), | ||
| Row("country=KR/quarter=2") :: | ||
| Row("country=KR/quarter=3") :: | ||
| Row("country=KR/quarter=4") :: | ||
| Row("country=US/quarter=2") :: | ||
| Row("country=US/quarter=3") :: | ||
| Row("country=US/quarter=4") :: Nil) | ||
|
|
||
| sql("ALTER TABLE sales DROP PARTITION (country='KR', quarter='4')") | ||
| sql("ALTER TABLE sales DROP PARTITION (country='US', quarter='3')") | ||
|
||
| checkAnswer(sql("SHOW PARTITIONS sales"), | ||
| Row("country=KR/quarter=2") :: | ||
| Row("country=KR/quarter=3") :: | ||
| Row("country=US/quarter=2") :: | ||
| Row("country=US/quarter=4") :: Nil) | ||
|
|
||
| sql("ALTER TABLE sales DROP PARTITION (quarter <= 2), PARTITION (quarter >= '4')") | ||
| checkAnswer(sql("SHOW PARTITIONS sales"), | ||
| Row("country=KR/quarter=3") :: Nil) | ||
|
|
||
| // According to the declarative partition spec definitions, this drops the union of target | ||
| // partitions without exceptions. Hive raises exceptions because it handles them sequentially. | ||
| sql("ALTER TABLE sales DROP PARTITION (quarter <= 4), PARTITION (quarter <= '3')") | ||
| checkAnswer(sql("SHOW PARTITIONS sales"), Nil) | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-17732: Error handling for drop partitions by filter") { | ||
| withTable("sales") { | ||
| sql("CREATE TABLE sales(id INT) PARTITIONED BY (country STRING, quarter STRING)") | ||
|
|
||
| val m = intercept[AnalysisException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (unknown = 'KR')") | ||
| }.getMessage | ||
| assert(m.contains("unknown is not a valid partition column in table")) | ||
|
|
||
| val m2 = intercept[AnalysisException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (unknown < 'KR')") | ||
| }.getMessage | ||
| assert(m2.contains("unknown is not a valid partition column in table")) | ||
|
|
||
| val m3 = intercept[AnalysisException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (unknown <=> 'KR')") | ||
| }.getMessage | ||
| assert(m3.contains("'<=>' operator is not allowed in partition specification")) | ||
|
||
|
|
||
| val m4 = intercept[ParseException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (unknown <=> upper('KR'))") | ||
| }.getMessage | ||
| assert(m4.contains("'<=>' operator is not allowed in partition specification")) | ||
|
|
||
| val m5 = intercept[ParseException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (country < 'KR', quarter)") | ||
| }.getMessage | ||
| assert(m5.contains("Invalid partition filter specification")) | ||
|
|
||
| sql(s"ALTER TABLE sales ADD PARTITION (country = 'KR', quarter = '3')") | ||
| val m6 = intercept[AnalysisException] { | ||
| sql("ALTER TABLE sales DROP PARTITION (quarter <= '4'), PARTITION (quarter <= '2')") | ||
| }.getMessage | ||
| // The query is not executed because `PARTITION (quarter <= '2')` is invalid. | ||
| checkAnswer(sql("SHOW PARTITIONS sales"), | ||
| Row("country=KR/quarter=3") :: Nil) | ||
| assert(m6.contains("There is no partition for (`quarter` <= '2')")) | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-17732: Partition filter is not allowed in ADD PARTITION") { | ||
| withTable("sales") { | ||
| sql("CREATE TABLE sales(id INT) PARTITIONED BY (country STRING, quarter STRING)") | ||
|
|
||
| val m = intercept[ParseException] { | ||
| sql("ALTER TABLE sales ADD PARTITION (country = 'US', quarter < '1')") | ||
| }.getMessage() | ||
| assert(m.contains("Invalid partition filter specification")) | ||
| } | ||
| } | ||
|
|
||
| test("drop views") { | ||
| withTable("tab1") { | ||
| val tabName = "tab1" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.