This is an automated email from the ASF dual-hosted git repository. ayushsaxena pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push: new fc47118169c HIVE-27236: Iceberg: DROP BRANCH SQL implementation (#4510). (zhangbutao, reviewed by Ayush Saxena) fc47118169c is described below commit fc47118169cf8e73ce06726be3627e9d2e52aaac Author: Butao Zhang <zhangbu...@cmss.chinamobile.com> AuthorDate: Fri Aug 4 16:07:28 2023 +0800 HIVE-27236: Iceberg: DROP BRANCH SQL implementation (#4510). (zhangbutao, reviewed by Ayush Saxena) --- .../iceberg/mr/hive/HiveIcebergMetaHook.java | 2 +- .../iceberg/mr/hive/HiveIcebergStorageHandler.java | 5 ++ .../apache/iceberg/mr/hive/IcebergBranchExec.java | 12 ++++ .../mr/hive/TestHiveIcebergBranchOperation.java | 16 ++++++ .../negative/alter_table_drop_branch_negative.q | 5 ++ .../queries/positive/alter_table_create_branch.q | 11 ++++ .../alter_table_drop_branch_negative.q.out | 20 +++++++ .../positive/alter_table_create_branch.q.out | 64 +++++++++++++++++++--- .../results/positive/alter_table_create_tag.q.out | 8 +-- .../hadoop/hive/ql/parse/AlterClauseParser.g | 8 +++ .../org/apache/hadoop/hive/ql/parse/HiveParser.g | 1 + .../hadoop/hive/ql/ddl/table/AlterTableType.java | 1 + .../AlterTableCreateSnapshotRefAnalyzer.java | 2 +- .../AlterTableDropSnapshotRefAnalyzer.java | 62 +++++++++++++++++++++ ...RefDesc.java => AlterTableSnapshotRefDesc.java} | 8 +-- ...on.java => AlterTableSnapshotRefOperation.java} | 7 ++- .../drop/AlterTableDropBranchAnalyzer.java} | 25 ++++----- .../hive/ql/parse/AlterTableSnapshotRefSpec.java | 24 +++++++- .../apache/hadoop/hive/ql/plan/HiveOperation.java | 1 + .../authorization/plugin/HiveOperationType.java | 1 + .../plugin/sqlstd/Operation2Privilege.java | 2 + 21 files changed, 251 insertions(+), 34 deletions(-) diff --git a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java index a470486ba74..b7900b97e11 100644 --- a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java +++ b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java @@ -121,7 +121,7 @@ public class HiveIcebergMetaHook implements HiveMetaHook { AlterTableType.ADDCOLS, AlterTableType.REPLACE_COLUMNS, AlterTableType.RENAME_COLUMN, AlterTableType.ADDPROPS, AlterTableType.DROPPROPS, AlterTableType.SETPARTITIONSPEC, AlterTableType.UPDATE_COLUMNS, AlterTableType.RENAME, AlterTableType.EXECUTE, AlterTableType.CREATE_BRANCH, - AlterTableType.CREATE_TAG); + AlterTableType.CREATE_TAG, AlterTableType.DROP_BRANCH); private static final List<String> MIGRATION_ALLOWED_SOURCE_FORMATS = ImmutableList.of( FileFormat.PARQUET.name().toLowerCase(), FileFormat.ORC.name().toLowerCase(), diff --git a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java index 14507a733aa..6737a6bff8b 100644 --- a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java +++ b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java @@ -866,6 +866,11 @@ public class HiveIcebergStorageHandler implements HiveStoragePredicateHandler, H (AlterTableSnapshotRefSpec.CreateSnapshotRefSpec) alterTableSnapshotRefSpec.getOperationParams(); IcebergTagExec.createTag(icebergTable, createTagSpec); break; + case DROP_BRANCH: + AlterTableSnapshotRefSpec.DropSnapshotRefSpec dropBranchSpec = + (AlterTableSnapshotRefSpec.DropSnapshotRefSpec) alterTableSnapshotRefSpec.getOperationParams(); + IcebergBranchExec.dropBranch(icebergTable, dropBranchSpec); + break; default: throw new UnsupportedOperationException(String.format( "Operation type %s is not supported", alterTableSnapshotRefSpec.getOperationType().getName())); diff --git a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergBranchExec.java b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergBranchExec.java index 0115b303580..57d3457b653 100644 --- a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergBranchExec.java +++ b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergBranchExec.java @@ -21,6 +21,7 @@ package org.apache.iceberg.mr.hive; import org.apache.hadoop.hive.ql.parse.AlterTableSnapshotRefSpec; import org.apache.iceberg.ManageSnapshots; +import org.apache.iceberg.SnapshotRef; import org.apache.iceberg.Table; import org.apache.iceberg.util.SnapshotUtil; import org.slf4j.Logger; @@ -63,4 +64,15 @@ public class IcebergBranchExec { manageSnapshots.commit(); } + + public static void dropBranch(Table table, AlterTableSnapshotRefSpec.DropSnapshotRefSpec dropBranchSpec) { + String branchName = dropBranchSpec.getRefName(); + boolean ifExists = dropBranchSpec.getIfExists(); + + SnapshotRef snapshotRef = table.refs().get(branchName); + if (snapshotRef != null || !ifExists) { + LOG.info("Dropping branch {} on iceberg table {}", branchName, table.name()); + table.manageSnapshots().removeBranch(branchName).commit(); + } + } } diff --git a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergBranchOperation.java b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergBranchOperation.java index ef4b94f2945..07f2e7a6723 100644 --- a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergBranchOperation.java +++ b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergBranchOperation.java @@ -181,4 +181,20 @@ public class TestHiveIcebergBranchOperation extends HiveIcebergStorageHandlerWit Assert.assertTrue(e.getMessage().contains("Not an iceberg table")); } } + + @Test + public void testDropBranch() throws InterruptedException, IOException { + Table table = + testTables.createTableWithVersions(shell, "customers", HiveIcebergStorageHandlerTestUtils.CUSTOMER_SCHEMA, + fileFormat, HiveIcebergStorageHandlerTestUtils.CUSTOMER_RECORDS, 2); + + String branchName = "test_branch_1"; + shell.executeStatement(String.format("ALTER TABLE customers CREATE BRANCH %s", branchName)); + table.refresh(); + Assert.assertNotNull(table.refs().get(branchName)); + + shell.executeStatement(String.format("ALTER TABLE customers DROP BRANCH IF EXISTS %s", branchName)); + table.refresh(); + Assert.assertNull(table.refs().get(branchName)); + } } diff --git a/iceberg/iceberg-handler/src/test/queries/negative/alter_table_drop_branch_negative.q b/iceberg/iceberg-handler/src/test/queries/negative/alter_table_drop_branch_negative.q new file mode 100644 index 00000000000..15622465f2c --- /dev/null +++ b/iceberg/iceberg-handler/src/test/queries/negative/alter_table_drop_branch_negative.q @@ -0,0 +1,5 @@ +create table iceTbl (id int, name string) Stored by Iceberg; +insert into iceTbl values(1, 'jack'); + +-- drop a non-exist branch +alter table iceTbl drop branch test_branch; \ No newline at end of file diff --git a/iceberg/iceberg-handler/src/test/queries/positive/alter_table_create_branch.q b/iceberg/iceberg-handler/src/test/queries/positive/alter_table_create_branch.q index 4eee6ecf114..d647a2eda5f 100644 --- a/iceberg/iceberg-handler/src/test/queries/positive/alter_table_create_branch.q +++ b/iceberg/iceberg-handler/src/test/queries/positive/alter_table_create_branch.q @@ -32,3 +32,14 @@ explain alter table iceTbl create branch test_branch_4 with snapshot retention 5 alter table iceTbl create branch test_branch_4 with snapshot retention 5 snapshots 5 days; -- check the values, four values select * from iceTbl for system_version as of 'test_branch_4'; + +-- drop a branch +explain alter table iceTbl drop branch test_branch_3; +alter table iceTbl drop branch test_branch_3; + +-- drop a branch with if exists +explain alter table iceTbl drop branch if exists test_branch_4; +alter table iceTbl drop branch if exists test_branch_4; + +-- drop a non-exist branch with if exists +alter table iceTbl drop branch if exists test_branch_5; diff --git a/iceberg/iceberg-handler/src/test/results/negative/alter_table_drop_branch_negative.q.out b/iceberg/iceberg-handler/src/test/results/negative/alter_table_drop_branch_negative.q.out new file mode 100644 index 00000000000..65cbfcc2fb5 --- /dev/null +++ b/iceberg/iceberg-handler/src/test/results/negative/alter_table_drop_branch_negative.q.out @@ -0,0 +1,20 @@ +PREHOOK: query: create table iceTbl (id int, name string) Stored by Iceberg +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@iceTbl +POSTHOOK: query: create table iceTbl (id int, name string) Stored by Iceberg +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@iceTbl +PREHOOK: query: insert into iceTbl values(1, 'jack') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@icetbl +POSTHOOK: query: insert into iceTbl values(1, 'jack') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@icetbl +PREHOOK: query: alter table iceTbl drop branch test_branch +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +FAILED: Execution Error, return code 40000 from org.apache.hadoop.hive.ql.ddl.DDLTask. java.lang.IllegalArgumentException: Branch does not exist: test_branch diff --git a/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_branch.q.out b/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_branch.q.out index 8cc5c2a0c47..29ca70a69cf 100644 --- a/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_branch.q.out +++ b/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_branch.q.out @@ -25,9 +25,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{branchName=test_branch_1}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{refName=test_branch_1}} PREHOOK: query: alter table iceTbl create branch test_branch_1 PREHOOK: type: ALTERTABLE_CREATEBRANCH @@ -63,9 +63,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{branchName=test_branch_2, maxRefAgeMs=432000000}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{refName=test_branch_2, maxRefAgeMs=432000000}} PREHOOK: query: alter table iceTbl create branch test_branch_2 retain 5 days PREHOOK: type: ALTERTABLE_CREATEBRANCH @@ -102,9 +102,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{branchName=test_branch_3, minSnapshotsToKeep=5}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{refName=test_branch_3, minSnapshotsToKeep=5}} PREHOOK: query: alter table iceTbl create branch test_branch_3 with snapshot retention 5 snapshots PREHOOK: type: ALTERTABLE_CREATEBRANCH @@ -142,9 +142,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{branchName=test_branch_4, minSnapshotsToKeep=5, maxSnapshotAgeMs=432000000}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, operationParams=CreateSnapshotRefSpec{refName=test_branch_4, minSnapshotsToKeep=5, maxSnapshotAgeMs=432000000}} PREHOOK: query: alter table iceTbl create branch test_branch_4 with snapshot retention 5 snapshots 5 days PREHOOK: type: ALTERTABLE_CREATEBRANCH @@ -164,3 +164,51 @@ POSTHOOK: Output: hdfs://### HDFS PATH ### 2 bob 3 tom 4 lisa +PREHOOK: query: explain alter table iceTbl drop branch test_branch_3 +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +POSTHOOK: query: explain alter table iceTbl drop branch test_branch_3 +POSTHOOK: type: ALTERTABLE_DROPBRANCH +POSTHOOK: Input: default@icetbl +STAGE DEPENDENCIES: + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-0 + SnapshotRef Operation + table name: default.iceTbl + spec: AlterTableSnapshotRefSpec{operationType=DROP_BRANCH, operationParams=DropSnapshotRefSpec{refName=test_branch_3, ifExists=false}} + +PREHOOK: query: alter table iceTbl drop branch test_branch_3 +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +POSTHOOK: query: alter table iceTbl drop branch test_branch_3 +POSTHOOK: type: ALTERTABLE_DROPBRANCH +POSTHOOK: Input: default@icetbl +PREHOOK: query: explain alter table iceTbl drop branch if exists test_branch_4 +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +POSTHOOK: query: explain alter table iceTbl drop branch if exists test_branch_4 +POSTHOOK: type: ALTERTABLE_DROPBRANCH +POSTHOOK: Input: default@icetbl +STAGE DEPENDENCIES: + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-0 + SnapshotRef Operation + table name: default.iceTbl + spec: AlterTableSnapshotRefSpec{operationType=DROP_BRANCH, operationParams=DropSnapshotRefSpec{refName=test_branch_4, ifExists=true}} + +PREHOOK: query: alter table iceTbl drop branch if exists test_branch_4 +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +POSTHOOK: query: alter table iceTbl drop branch if exists test_branch_4 +POSTHOOK: type: ALTERTABLE_DROPBRANCH +POSTHOOK: Input: default@icetbl +PREHOOK: query: alter table iceTbl drop branch if exists test_branch_5 +PREHOOK: type: ALTERTABLE_DROPBRANCH +PREHOOK: Input: default@icetbl +POSTHOOK: query: alter table iceTbl drop branch if exists test_branch_5 +POSTHOOK: type: ALTERTABLE_DROPBRANCH +POSTHOOK: Input: default@icetbl diff --git a/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_tag.q.out b/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_tag.q.out index 789cb3c9ecb..66b3eaa705a 100644 --- a/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_tag.q.out +++ b/iceberg/iceberg-handler/src/test/results/positive/alter_table_create_tag.q.out @@ -25,9 +25,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, operationParams=CreateSnapshotRefSpec{branchName=test_tag_1}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, operationParams=CreateSnapshotRefSpec{refName=test_tag_1}} PREHOOK: query: alter table iceTbl create tag test_tag_1 PREHOOK: type: ALTERTABLE_CREATETAG @@ -63,9 +63,9 @@ STAGE DEPENDENCIES: STAGE PLANS: Stage: Stage-0 - CreateSnapshotRef Operation + SnapshotRef Operation table name: default.iceTbl - spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, operationParams=CreateSnapshotRefSpec{branchName=test_tag_2, maxRefAgeMs=432000000}} + spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, operationParams=CreateSnapshotRefSpec{refName=test_tag_2, maxRefAgeMs=432000000}} PREHOOK: query: alter table iceTbl create tag test_tag_2 retain 5 days PREHOOK: type: ALTERTABLE_CREATETAG diff --git a/parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g b/parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g index 3dc8c4a3b0b..aabc136bf5c 100644 --- a/parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g +++ b/parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g @@ -77,6 +77,7 @@ alterTableStatementSuffix | alterStatementSuffixCreateBranch | alterStatementSuffixCreateTag | alterStatementSuffixConvert + | alterStatementSuffixDropBranch ; alterTblPartitionStatementSuffix[boolean partition] @@ -479,6 +480,13 @@ alterStatementSuffixExecute -> ^(TOK_ALTERTABLE_EXECUTE KW_SET_CURRENT_SNAPSHOT $snapshotParam) ; +alterStatementSuffixDropBranch +@init { gParent.pushMsg("alter table drop branch (if exists) branchName", state); } +@after { gParent.popMsg(state); } + : KW_DROP KW_BRANCH ifExists? branchName=identifier + -> ^(TOK_ALTERTABLE_DROP_BRANCH ifExists? $branchName) + ; + alterStatementSuffixCreateBranch @init { gParent.pushMsg("alter table create branch", state); } @after { gParent.popMsg(state); } diff --git a/parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g b/parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g index 406e9a73d2f..1fb963e297a 100644 --- a/parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g +++ b/parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g @@ -220,6 +220,7 @@ TOK_ALTERTABLE_OWNER; TOK_ALTERTABLE_SETPARTSPEC; TOK_ALTERTABLE_EXECUTE; TOK_ALTERTABLE_CREATE_BRANCH; +TOK_ALTERTABLE_DROP_BRANCH; TOK_ALTERTABLE_CREATE_TAG; TOK_RETAIN; TOK_WITH_SNAPSHOT_RETENTION; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/AlterTableType.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/AlterTableType.java index 17a28bd0d9b..a0e59181283 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/AlterTableType.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/AlterTableType.java @@ -41,6 +41,7 @@ public enum AlterTableType { SETPARTITIONSPEC("set partition spec"), EXECUTE("execute"), CREATE_BRANCH("create branch"), + DROP_BRANCH("drop branch"), CREATE_TAG("create tag"), // constraint ADD_CONSTRAINT("add constraint"), diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefAnalyzer.java index 7d02d8a7d9f..8708d3d3479 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefAnalyzer.java @@ -100,7 +100,7 @@ public abstract class AlterTableCreateSnapshotRefAnalyzer extends AbstractAlterT AlterTableSnapshotRefSpec<AlterTableSnapshotRefSpec.CreateSnapshotRefSpec> alterTableSnapshotRefSpec = new AlterTableSnapshotRefSpec(alterTableType, createSnapshotRefSpec); AbstractAlterTableDesc alterTableDesc = - new AlterTableCreateSnapshotRefDesc(alterTableType, tableName, alterTableSnapshotRefSpec); + new AlterTableSnapshotRefDesc(alterTableType, tableName, alterTableSnapshotRefSpec); rootTasks.add(TaskFactory.get(new DDLWork(getInputs(), getOutputs(), alterTableDesc))); } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableDropSnapshotRefAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableDropSnapshotRefAnalyzer.java new file mode 100644 index 00000000000..b039562db0f --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableDropSnapshotRefAnalyzer.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hive.ql.ddl.table.snapshotref; + +import java.util.Map; +import org.apache.hadoop.hive.common.TableName; +import org.apache.hadoop.hive.ql.QueryState; +import org.apache.hadoop.hive.ql.ddl.DDLUtils; +import org.apache.hadoop.hive.ql.ddl.DDLWork; +import org.apache.hadoop.hive.ql.ddl.table.AbstractAlterTableAnalyzer; +import org.apache.hadoop.hive.ql.ddl.table.AbstractAlterTableDesc; +import org.apache.hadoop.hive.ql.ddl.table.AlterTableType; +import org.apache.hadoop.hive.ql.exec.TaskFactory; +import org.apache.hadoop.hive.ql.hooks.ReadEntity; +import org.apache.hadoop.hive.ql.metadata.Table; +import org.apache.hadoop.hive.ql.parse.ASTNode; +import org.apache.hadoop.hive.ql.parse.AlterTableSnapshotRefSpec; +import org.apache.hadoop.hive.ql.parse.HiveParser; +import org.apache.hadoop.hive.ql.parse.SemanticException; + +public class AlterTableDropSnapshotRefAnalyzer extends AbstractAlterTableAnalyzer { + protected AlterTableType alterTableType; + + public AlterTableDropSnapshotRefAnalyzer(QueryState queryState) throws SemanticException { + super(queryState); + } + + @Override + protected void analyzeCommand(TableName tableName, Map<String, String> partitionSpec, ASTNode command) + throws SemanticException { + boolean ifExists = (command.getFirstChildWithType(HiveParser.TOK_IFEXISTS) != null); + Table table = getTable(tableName); + DDLUtils.validateTableIsIceberg(table); + inputs.add(new ReadEntity(table)); + validateAlterTableType(table, alterTableType, false); + String refName = ifExists ? command.getChild(1).getText() : command.getChild(0).getText(); + + AlterTableSnapshotRefSpec.DropSnapshotRefSpec dropSnapshotRefSpec = + new AlterTableSnapshotRefSpec.DropSnapshotRefSpec(refName, ifExists); + AlterTableSnapshotRefSpec<AlterTableSnapshotRefSpec.DropSnapshotRefSpec> alterTableSnapshotRefSpec + = new AlterTableSnapshotRefSpec(alterTableType, dropSnapshotRefSpec); + AbstractAlterTableDesc alterTableDesc = + new AlterTableSnapshotRefDesc(alterTableType, tableName, alterTableSnapshotRefSpec); + rootTasks.add(TaskFactory.get(new DDLWork(getInputs(), getOutputs(), alterTableDesc))); + } +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefDesc.java similarity index 83% rename from ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefDesc.java rename to ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefDesc.java index e1315484541..3ce02432e91 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefDesc.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefDesc.java @@ -25,15 +25,15 @@ import org.apache.hadoop.hive.ql.parse.AlterTableSnapshotRefSpec; import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.plan.Explain; -@Explain(displayName = "CreateSnapshotRef Operation", explainLevels = { Explain.Level.USER, Explain.Level.DEFAULT, +@Explain(displayName = "SnapshotRef Operation", explainLevels = { Explain.Level.USER, Explain.Level.DEFAULT, Explain.Level.EXTENDED }) -public class AlterTableCreateSnapshotRefDesc extends AbstractAlterTableDesc { +public class AlterTableSnapshotRefDesc extends AbstractAlterTableDesc { private static final long serialVersionUID = 1L; protected AlterTableSnapshotRefSpec alterTableSnapshotRefSpec; - public AlterTableCreateSnapshotRefDesc(AlterTableType alterTableType, TableName tableName, AlterTableSnapshotRefSpec alterTableSnapshotRefSpec) - throws SemanticException { + public AlterTableSnapshotRefDesc(AlterTableType alterTableType, TableName tableName, AlterTableSnapshotRefSpec + alterTableSnapshotRefSpec) throws SemanticException { super(alterTableType, tableName, null, null, false, false, null); this.alterTableSnapshotRefSpec = alterTableSnapshotRefSpec; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefOperation.java similarity index 83% copy from ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java copy to ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefOperation.java index a36c400ef45..416e7e34e18 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableSnapshotRefOperation.java @@ -22,8 +22,11 @@ import org.apache.hadoop.hive.ql.ddl.DDLOperation; import org.apache.hadoop.hive.ql.ddl.DDLOperationContext; import org.apache.hadoop.hive.ql.metadata.Table; -public class AlterTableCreateSnapshotRefOperation extends DDLOperation<AlterTableCreateSnapshotRefDesc> { - public AlterTableCreateSnapshotRefOperation(DDLOperationContext context, AlterTableCreateSnapshotRefDesc desc) { +/** + * Operation process of Create/Drop a table snapshotRef. + */ +public class AlterTableSnapshotRefOperation extends DDLOperation<AlterTableSnapshotRefDesc> { + public AlterTableSnapshotRefOperation(DDLOperationContext context, AlterTableSnapshotRefDesc desc) { super(context, desc); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/branch/drop/AlterTableDropBranchAnalyzer.java similarity index 51% rename from ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java rename to ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/branch/drop/AlterTableDropBranchAnalyzer.java index a36c400ef45..c3e23a62e05 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/AlterTableCreateSnapshotRefOperation.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/snapshotref/branch/drop/AlterTableDropBranchAnalyzer.java @@ -16,21 +16,20 @@ * limitations under the License. */ -package org.apache.hadoop.hive.ql.ddl.table.snapshotref; +package org.apache.hadoop.hive.ql.ddl.table.snapshotref.branch.drop; -import org.apache.hadoop.hive.ql.ddl.DDLOperation; -import org.apache.hadoop.hive.ql.ddl.DDLOperationContext; -import org.apache.hadoop.hive.ql.metadata.Table; +import org.apache.hadoop.hive.ql.QueryState; +import org.apache.hadoop.hive.ql.ddl.DDLSemanticAnalyzerFactory; +import org.apache.hadoop.hive.ql.ddl.table.AlterTableType; +import org.apache.hadoop.hive.ql.ddl.table.snapshotref.AlterTableDropSnapshotRefAnalyzer; +import org.apache.hadoop.hive.ql.parse.HiveParser; +import org.apache.hadoop.hive.ql.parse.SemanticException; -public class AlterTableCreateSnapshotRefOperation extends DDLOperation<AlterTableCreateSnapshotRefDesc> { - public AlterTableCreateSnapshotRefOperation(DDLOperationContext context, AlterTableCreateSnapshotRefDesc desc) { - super(context, desc); - } +@DDLSemanticAnalyzerFactory.DDLType(types = HiveParser.TOK_ALTERTABLE_DROP_BRANCH) +public class AlterTableDropBranchAnalyzer extends AlterTableDropSnapshotRefAnalyzer { - @Override - public int execute() throws Exception { - Table table = context.getDb().getTable(desc.getFullTableName()); - context.getDb().alterTableSnapshotRefOperation(table, desc.getAlterTableSnapshotRefSpec()); - return 0; + public AlterTableDropBranchAnalyzer(QueryState queryState) throws SemanticException { + super(queryState); + alterTableType = AlterTableType.DROP_BRANCH; } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/AlterTableSnapshotRefSpec.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/AlterTableSnapshotRefSpec.java index e02e6646c23..1cd98fbef33 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/AlterTableSnapshotRefSpec.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/AlterTableSnapshotRefSpec.java @@ -89,9 +89,31 @@ public class AlterTableSnapshotRefSpec<T> { } public String toString() { - return MoreObjects.toStringHelper(this).add("branchName", refName).add("snapshotId", snapshotId) + return MoreObjects.toStringHelper(this).add("refName", refName).add("snapshotId", snapshotId) .add("asOfTime", asOfTime).add("maxRefAgeMs", maxRefAgeMs).add("minSnapshotsToKeep", minSnapshotsToKeep) .add("maxSnapshotAgeMs", maxSnapshotAgeMs).omitNullValues().toString(); } } + public static class DropSnapshotRefSpec { + + private final String refName; + private final boolean ifExists; + + public String getRefName() { + return refName; + } + + public boolean getIfExists() { + return ifExists; + } + + public DropSnapshotRefSpec(String refName, Boolean ifExists) { + this.refName = refName; + this.ifExists = ifExists; + } + + public String toString() { + return MoreObjects.toStringHelper(this).add("refName", refName).add("ifExists", ifExists).toString(); + } + } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/HiveOperation.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/HiveOperation.java index 4385d10ca5e..9e9668742e9 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/plan/HiveOperation.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/HiveOperation.java @@ -79,6 +79,7 @@ public enum HiveOperation { ALTERTABLE_EXECUTE("ALTERTABLE_EXECUTE", HiveParser.TOK_ALTERTABLE_EXECUTE, null, null), ALTERTABLE_CREATEBRANCH("ALTERTABLE_CREATEBRANCH", HiveParser.TOK_ALTERTABLE_CREATE_BRANCH, null, null), ALTERTABLE_CREATETAG("ALTERTABLE_CREATETAG", HiveParser.TOK_ALTERTABLE_CREATE_TAG, null, null), + ALTERTABLE_DROPBRANCH("ALTERTABLE_DROPBRANCH", HiveParser.TOK_ALTERTABLE_DROP_BRANCH, null, null), ALTERTABLE_CONVERT("ALTERTABLE_CONVERT", HiveParser.TOK_ALTERTABLE_CONVERT, null, null), ALTERTABLE_SERIALIZER("ALTERTABLE_SERIALIZER", HiveParser.TOK_ALTERTABLE_SERIALIZER, new Privilege[]{Privilege.ALTER_METADATA}, null), diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveOperationType.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveOperationType.java index 909ac7f5318..447a0bcf4b2 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveOperationType.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveOperationType.java @@ -140,6 +140,7 @@ public enum HiveOperationType { ALTERTABLE_COMPACT, ALTERTABLE_UPDATECOLUMNS, ALTERTABLE_CREATEBRANCH, + ALTERTABLE_DROPBRANCH, ALTERTABLE_CREATETAG, SHOW_COMPACTIONS, SHOW_TRANSACTIONS, diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java index 48b7257dba5..97e08a29c23 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java @@ -244,6 +244,8 @@ public class Operation2Privilege { PrivRequirement.newIOPrivRequirement(OWNER_PRIV_AR, OWNER_PRIV_AR)); op2Priv.put(HiveOperationType.ALTERTABLE_CREATETAG, PrivRequirement.newIOPrivRequirement(OWNER_PRIV_AR, OWNER_PRIV_AR)); + op2Priv.put(HiveOperationType.ALTERTABLE_DROPBRANCH, + PrivRequirement.newIOPrivRequirement(OWNER_PRIV_AR, OWNER_PRIV_AR)); // require view ownership for alter/drop view op2Priv.put(HiveOperationType.ALTERVIEW_PROPERTIES,