[ https://issues.apache.org/jira/browse/HIVE-27234?focusedWorklogId=859862&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-859862 ]
ASF GitHub Bot logged work on HIVE-27234: ----------------------------------------- Author: ASF GitHub Bot Created on: 01/May/23 12:10 Start Date: 01/May/23 12:10 Worklog Time Spent: 10m Work Description: deniskuzZ commented on code in PR #4216: URL: https://github.com/apache/hive/pull/4216#discussion_r1181518994 ########## iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java: ########## @@ -676,6 +678,35 @@ public void executeOperation(org.apache.hadoop.hive.ql.metadata.Table hmsTable, } } + @Override + public void createBranchOperation(org.apache.hadoop.hive.ql.metadata.Table hmsTable, + AlterTableCreateBranchSpec createBranchSpec) { + TableDesc tableDesc = Utilities.getTableDesc(hmsTable); + Table icebergTable = IcebergTableUtil.getTable(conf, tableDesc.getProperties()); + + String branchName = createBranchSpec.getBranchName(); + Optional.ofNullable(icebergTable.currentSnapshot()).orElseThrow(() -> new UnsupportedOperationException( + String.format("Cannot create branch %s on iceberg table %s.%s which has no snapshot", + branchName, hmsTable.getDbName(), hmsTable.getTableName()))); + Long snapshotId = Optional.ofNullable(createBranchSpec.getSnapshotId()) + .orElse(icebergTable.currentSnapshot().snapshotId()); + LOG.info("Creating branch {} on iceberg table {}.{}", branchName, hmsTable.getDbName(), Review Comment: Could we add `snapshotId` to the log output? Btw, should we log under DEBUG? ########## iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java: ########## @@ -676,6 +678,35 @@ public void executeOperation(org.apache.hadoop.hive.ql.metadata.Table hmsTable, } } + @Override + public void createBranchOperation(org.apache.hadoop.hive.ql.metadata.Table hmsTable, + AlterTableCreateBranchSpec createBranchSpec) { + TableDesc tableDesc = Utilities.getTableDesc(hmsTable); + Table icebergTable = IcebergTableUtil.getTable(conf, tableDesc.getProperties()); + + String branchName = createBranchSpec.getBranchName(); + Optional.ofNullable(icebergTable.currentSnapshot()).orElseThrow(() -> new UnsupportedOperationException( + String.format("Cannot create branch %s on iceberg table %s.%s which has no snapshot", + branchName, hmsTable.getDbName(), hmsTable.getTableName()))); + Long snapshotId = Optional.ofNullable(createBranchSpec.getSnapshotId()) + .orElse(icebergTable.currentSnapshot().snapshotId()); + LOG.info("Creating branch {} on iceberg table {}.{}", branchName, hmsTable.getDbName(), + hmsTable.getTableName()); + ManageSnapshots manageSnapshots = icebergTable.manageSnapshots(); + manageSnapshots.createBranch(branchName, snapshotId); Review Comment: what happens if supplied `snapshotId` doesn't exist? ########## parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g: ########## @@ -477,6 +478,34 @@ alterStatementSuffixExecute -> ^(TOK_ALTERTABLE_EXECUTE KW_SET_CURRENT_SNAPSHOT $snapshotParam) ; +alterStatementSuffixCreateBranch +@init { gParent.pushMsg("alter table create branch", state); } +@after { gParent.popMsg(state); } + : KW_CREATE KW_BRANCH branchName=identifier snapshotIdOfBranch? branchRetain? retentionOfSnapshots? + -> ^(TOK_ALTERTABLE_CREATE_BRANCH $branchName snapshotIdOfBranch? branchRetain? retentionOfSnapshots?) + ; + +snapshotIdOfBranch +@init { gParent.pushMsg("alter table create branch as of version", state); } +@after { gParent.popMsg(state); } + : KW_AS KW_OF KW_VERSION snapshotId=Number + -> ^(TOK_AS_OF_VERSION_BRANCH $snapshotId) Review Comment: can't we reuse `TOK_AS_OF_VERSION`? ########## parser/src/java/org/apache/hadoop/hive/ql/parse/AlterClauseParser.g: ########## @@ -477,6 +478,34 @@ alterStatementSuffixExecute -> ^(TOK_ALTERTABLE_EXECUTE KW_SET_CURRENT_SNAPSHOT $snapshotParam) ; +alterStatementSuffixCreateBranch +@init { gParent.pushMsg("alter table create branch", state); } +@after { gParent.popMsg(state); } + : KW_CREATE KW_BRANCH branchName=identifier snapshotIdOfBranch? branchRetain? retentionOfSnapshots? + -> ^(TOK_ALTERTABLE_CREATE_BRANCH $branchName snapshotIdOfBranch? branchRetain? retentionOfSnapshots?) + ; + +snapshotIdOfBranch +@init { gParent.pushMsg("alter table create branch as of version", state); } Review Comment: should we support `as of timestamp` as well? Note, that syntax is different from the 'select' statement: ```` FOR SYSTEM_VERSION AS OF FOR SYSTEM_TIME AS OF ```` i think we should be consistent here. cc @ayushtkn ########## ql/src/java/org/apache/hadoop/hive/ql/ddl/table/AlterTableType.java: ########## @@ -40,6 +40,7 @@ public enum AlterTableType { ALTERPARTITION("alter partition"), // Note: this is never used in AlterTableDesc. SETPARTITIONSPEC("set partition spec"), EXECUTE("execute"), + CREATEBRANCH("create branch"), Review Comment: could we use a separator here, like `CREATE_BRANCH` ########## ql/src/java/org/apache/hadoop/hive/ql/ddl/table/branch/create/AlterTableCreateBranchAnalyzer.java: ########## @@ -0,0 +1,93 @@ +/* + * 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.branch.create; + +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.hadoop.hive.common.TableName; +import org.apache.hadoop.hive.metastore.HiveMetaHook; +import org.apache.hadoop.hive.ql.QueryState; +import org.apache.hadoop.hive.ql.ddl.DDLSemanticAnalyzerFactory; +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.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.AlterTableCreateBranchSpec; +import org.apache.hadoop.hive.ql.parse.HiveParser; +import org.apache.hadoop.hive.ql.parse.SemanticException; + +@DDLSemanticAnalyzerFactory.DDLType(types = HiveParser.TOK_ALTERTABLE_CREATE_BRANCH) +public class AlterTableCreateBranchAnalyzer extends AbstractAlterTableAnalyzer { + + public AlterTableCreateBranchAnalyzer(QueryState queryState) throws SemanticException { + super(queryState); + } + + @Override + protected void analyzeCommand(TableName tableName, Map<String, String> partitionSpec, ASTNode command) + throws SemanticException { + Table table = getTable(tableName); + validateAlterTableType(table, AlterTableType.CREATEBRANCH, false); + if (!HiveMetaHook.ICEBERG.equalsIgnoreCase(table.getParameters().get(HiveMetaHook.TABLE_TYPE))) { Review Comment: we should move this logic into a helper class ########## ql/src/java/org/apache/hadoop/hive/ql/parse/AlterTableCreateBranchSpec.java: ########## @@ -0,0 +1,63 @@ +/* + * 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.parse; + +import com.google.common.base.MoreObjects; + +public class AlterTableCreateBranchSpec { Review Comment: can we reuse `AlterTableExecuteSpec` and define inner `CreateBranchSpec`, similar to `RollbackSpec`? Issue Time Tracking ------------------- Worklog Id: (was: 859862) Time Spent: 4h 50m (was: 4h 40m) > Iceberg: CREATE BRANCH SQL implementation > ------------------------------------------ > > Key: HIVE-27234 > URL: https://issues.apache.org/jira/browse/HIVE-27234 > Project: Hive > Issue Type: Sub-task > Components: Iceberg integration > Reporter: zhangbutao > Assignee: zhangbutao > Priority: Major > Labels: pull-request-available > Time Spent: 4h 50m > Remaining Estimate: 0h > > Maybe we can follow spark sql about branch ddl implementation > [https://github.com/apache/iceberg/pull/6617] -- This message was sent by Atlassian Jira (v8.20.10#820010)