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 a57e5805427 HIVE-28274: Iceberg: Add support for 'If Not Exists' and 
'or Replace' for Create Branch. (#5259). (Ayush Saxena, reviewed by Butao Zhang)
a57e5805427 is described below

commit a57e580542701a5acdf4e66ce99b52bae90b4d63
Author: Ayush Saxena <ayushsax...@apache.org>
AuthorDate: Mon May 27 13:36:23 2024 +0530

    HIVE-28274: Iceberg: Add support for 'If Not Exists' and 'or Replace' for 
Create Branch. (#5259). (Ayush Saxena, reviewed by Butao Zhang)
---
 .../iceberg/mr/hive/IcebergSnapshotRefExec.java    | 45 +++++++++++++--
 .../mr/hive/TestHiveIcebergBranchOperation.java    | 28 +++++++++
 .../queries/positive/alter_table_create_branch.q   | 11 +++-
 .../positive/alter_table_create_branch.q.out       | 66 ++++++++++++++++++++--
 .../results/positive/alter_table_create_tag.q.out  |  4 +-
 .../hadoop/hive/ql/parse/AlterClauseParser.g       |  6 +-
 .../AlterTableCreateSnapshotRefAnalyzer.java       | 10 +++-
 .../hive/ql/parse/AlterTableSnapshotRefSpec.java   | 17 +++++-
 8 files changed, 169 insertions(+), 18 deletions(-)

diff --git 
a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergSnapshotRefExec.java
 
b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergSnapshotRefExec.java
index 6332cbb767f..3e251913801 100644
--- 
a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergSnapshotRefExec.java
+++ 
b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/IcebergSnapshotRefExec.java
@@ -22,6 +22,7 @@ package org.apache.iceberg.mr.hive;
 import java.util.Optional;
 import org.apache.hadoop.hive.ql.parse.AlterTableSnapshotRefSpec;
 import org.apache.iceberg.ManageSnapshots;
+import org.apache.iceberg.Snapshot;
 import org.apache.iceberg.SnapshotRef;
 import org.apache.iceberg.Table;
 import org.apache.iceberg.util.SnapshotUtil;
@@ -42,6 +43,11 @@ public class IcebergSnapshotRefExec {
    */
   public static void createBranch(Table table, 
AlterTableSnapshotRefSpec.CreateSnapshotRefSpec createBranchSpec) {
     String branchName = createBranchSpec.getRefName();
+    boolean refExistsAsBranch = refExistsAsBranch(table, branchName);
+    if (createBranchSpec.isIfNotExists() && refExistsAsBranch) {
+      return;
+    }
+    boolean isReplace = createBranchSpec.isReplace() && refExistsAsBranch;
     Long snapshotId = null;
     if (createBranchSpec.getSnapshotId() != null) {
       snapshotId = createBranchSpec.getSnapshotId();
@@ -56,16 +62,25 @@ public class IcebergSnapshotRefExec {
         throw new IllegalArgumentException(String.format("Tag %s does not 
exist", tagName));
       }
     } else {
-      snapshotId = Optional.ofNullable(table.currentSnapshot()).map(snapshot 
-> snapshot.snapshotId()).orElse(null);
+      snapshotId = 
Optional.ofNullable(table.currentSnapshot()).map(Snapshot::snapshotId).orElse(null);
     }
     ManageSnapshots manageSnapshots = table.manageSnapshots();
     if (snapshotId != null) {
-      LOG.info("Creating a branch {} on an iceberg table {} with snapshotId 
{}", branchName, table.name(), snapshotId);
-      manageSnapshots.createBranch(branchName, snapshotId);
+      createOrReplaceBranch(manageSnapshots, table, isReplace, branchName, 
snapshotId);
+    } else if (isReplace) {
+      throw new IllegalArgumentException(
+          "Cannot complete replace branch operation on " + branchName + ", 
main has no snapshot");
     } else {
       LOG.info("Creating a branch {} on an empty iceberg table {}", 
branchName, table.name());
       manageSnapshots.createBranch(branchName);
     }
+
+    setCreateBranchOptionalParams(createBranchSpec, manageSnapshots, 
branchName);
+    manageSnapshots.commit();
+  }
+
+  private static void 
setCreateBranchOptionalParams(AlterTableSnapshotRefSpec.CreateSnapshotRefSpec 
createBranchSpec,
+      ManageSnapshots manageSnapshots, String branchName) {
     if (createBranchSpec.getMaxRefAgeMs() != null) {
       manageSnapshots.setMaxRefAgeMs(branchName, 
createBranchSpec.getMaxRefAgeMs());
     }
@@ -75,8 +90,30 @@ public class IcebergSnapshotRefExec {
     if (createBranchSpec.getMaxSnapshotAgeMs() != null) {
       manageSnapshots.setMaxSnapshotAgeMs(branchName, 
createBranchSpec.getMaxSnapshotAgeMs());
     }
+  }
 
-    manageSnapshots.commit();
+  private static void createOrReplaceBranch(ManageSnapshots manageSnapshots, 
Table table, boolean isReplace,
+      String branchName, Long snapshotId) {
+    if (isReplace) {
+      LOG.info("Replacing branch {} on an iceberg table {} with snapshotId 
{}", branchName, table.name(), snapshotId);
+      manageSnapshots.replaceBranch(branchName, snapshotId);
+    } else {
+      LOG.info("Creating a branch {} on an iceberg table {} with snapshotId 
{}", branchName, table.name(), snapshotId);
+      manageSnapshots.createBranch(branchName, snapshotId);
+    }
+  }
+
+  private static boolean refExistsAsBranch(Table table, String branchName) {
+    SnapshotRef branchRef = table.refs().get(branchName);
+    if (branchRef != null) {
+      if (branchRef.isBranch()) {
+        return true;
+      } else {
+        throw new IllegalArgumentException(
+            "Cannot complete replace branch operation on " + branchName + ", 
as it exists as Tag");
+      }
+    }
+    return false;
   }
 
   public static void dropBranch(Table table, 
AlterTableSnapshotRefSpec.DropSnapshotRefSpec dropBranchSpec) {
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 9f88bae3496..c5eb59987fb 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
@@ -252,4 +252,32 @@ public class TestHiveIcebergBranchOperation extends 
HiveIcebergStorageHandlerWit
     // Select with non-lower case branch name shouldn't throw exception.
     shell.executeStatement(String.format("SELECT * FROM 
default.customers.branch_%s", branchName));
   }
+
+  @Test
+  public void testCreateOrReplaceBranchWithTag() throws InterruptedException, 
IOException {
+    Table table =
+        testTables.createTableWithVersions(shell, "customers", 
HiveIcebergStorageHandlerTestUtils.CUSTOMER_SCHEMA,
+            fileFormat, HiveIcebergStorageHandlerTestUtils.CUSTOMER_RECORDS, 
2);
+
+    Long snapshotId = table.history().get(0).snapshotId();
+    shell.executeStatement(
+        String.format("ALTER TABLE customers CREATE TAG %s FOR SYSTEM_VERSION 
AS OF %d", "test1", snapshotId));
+
+    Assertions.assertThatThrownBy(() -> shell.executeStatement("ALTER TABLE 
customers CREATE OR REPLACE BRANCH test1"))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining("Cannot complete replace branch operation on 
test1, as it exists as Tag");
+  }
+
+  @Test
+  public void testCreateOrReplaceBranchWithEmptyTable() throws IOException {
+    Table table =
+        testTables.createTable(shell, "customers", 
HiveIcebergStorageHandlerTestUtils.CUSTOMER_SCHEMA, fileFormat, null,
+            2);
+
+    Assert.assertEquals(0, table.history().size());
+    shell.executeStatement("ALTER TABLE customers CREATE BRANCH test1");
+    Assertions.assertThatThrownBy(() -> shell.executeStatement("ALTER TABLE 
customers CREATE OR REPLACE BRANCH test1"))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining(" Cannot complete replace branch operation on 
test1, main has no snapshot");
+  }
 }
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 6e83bef5a4c..55581ce6968 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
@@ -9,7 +9,7 @@ alter table iceTbl create branch test_branch_0;
 
 insert into iceTbl values(1, 'jack');
 
--- create s branch test_branch_1 with default values based on the current 
snapshotId
+-- create a branch test_branch_1 with default values based on the current 
snapshotId
 explain alter table iceTbl create branch test_branch_1;
 alter table iceTbl create branch test_branch_1;
 -- check the values, one value
@@ -41,6 +41,15 @@ alter table iceTbl create tag test_tag;
 explain alter table iceTbl create branch test_branch_10 for tag as of test_tag;
 alter table iceTbl create branch test_branch_10 for tag as of test_tag;
 
+-- create a branch which already exists
+explain alter table iceTbl create branch if not exists test_branch_10;
+alter table iceTbl create branch if not exists test_branch_10;
+
+-- create or replace
+explain alter table iceTbl create or replace branch test_branch_1;
+alter table iceTbl create or replace branch test_branch_1;
+select * from default.iceTbl.branch_test_branch_1;
+
 -- drop a branch
 explain alter table iceTbl drop branch test_branch_3;
 alter table iceTbl drop branch test_branch_3;
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 f86670d182a..9aa8e112c4c 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
@@ -19,7 +19,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_0}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_0, isReplace=false, 
ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_0
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -48,7 +48,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_1}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_1, isReplace=false, 
ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_1
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -86,7 +86,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_2, 
maxRefAgeMs=432000000}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_2, 
maxRefAgeMs=432000000, isReplace=false, ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_2 retain 5 days
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -125,7 +125,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_3, 
minSnapshotsToKeep=5}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_3, 
minSnapshotsToKeep=5, isReplace=false, ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_3 with snapshot 
retention 5 snapshots
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -165,7 +165,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_4, 
minSnapshotsToKeep=5, maxSnapshotAgeMs=432000000}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_4, 
minSnapshotsToKeep=5, maxSnapshotAgeMs=432000000, isReplace=false, 
ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_4 with snapshot 
retention 5 snapshots 5 days
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -204,7 +204,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_10}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_10, isReplace=false, 
ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create branch test_branch_10 for tag as of 
test_tag
 PREHOOK: type: ALTERTABLE_CREATEBRANCH
@@ -212,6 +212,60 @@ PREHOOK: Input: default@icetbl
 POSTHOOK: query: alter table iceTbl create branch test_branch_10 for tag as of 
test_tag
 POSTHOOK: type: ALTERTABLE_CREATEBRANCH
 POSTHOOK: Input: default@icetbl
+PREHOOK: query: explain alter table iceTbl create branch if not exists 
test_branch_10
+PREHOOK: type: ALTERTABLE_CREATEBRANCH
+PREHOOK: Input: default@icetbl
+POSTHOOK: query: explain alter table iceTbl create branch if not exists 
test_branch_10
+POSTHOOK: type: ALTERTABLE_CREATEBRANCH
+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=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_10, isReplace=false, 
ifNotExists=true}}
+
+PREHOOK: query: alter table iceTbl create branch if not exists test_branch_10
+PREHOOK: type: ALTERTABLE_CREATEBRANCH
+PREHOOK: Input: default@icetbl
+POSTHOOK: query: alter table iceTbl create branch if not exists test_branch_10
+POSTHOOK: type: ALTERTABLE_CREATEBRANCH
+POSTHOOK: Input: default@icetbl
+PREHOOK: query: explain alter table iceTbl create or replace branch 
test_branch_1
+PREHOOK: type: ALTERTABLE_CREATEBRANCH
+PREHOOK: Input: default@icetbl
+POSTHOOK: query: explain alter table iceTbl create or replace branch 
test_branch_1
+POSTHOOK: type: ALTERTABLE_CREATEBRANCH
+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=CREATE_BRANCH, 
operationParams=CreateSnapshotRefSpec{refName=test_branch_1, isReplace=true, 
ifNotExists=false}}
+
+PREHOOK: query: alter table iceTbl create or replace branch test_branch_1
+PREHOOK: type: ALTERTABLE_CREATEBRANCH
+PREHOOK: Input: default@icetbl
+POSTHOOK: query: alter table iceTbl create or replace branch test_branch_1
+POSTHOOK: type: ALTERTABLE_CREATEBRANCH
+POSTHOOK: Input: default@icetbl
+PREHOOK: query: select * from default.iceTbl.branch_test_branch_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@icetbl
+PREHOOK: Output: hdfs://### HDFS PATH ###
+POSTHOOK: query: select * from default.iceTbl.branch_test_branch_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@icetbl
+POSTHOOK: Output: hdfs://### HDFS PATH ###
+1      jack
+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
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 312a93f7f05..803891e4b28 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
@@ -27,7 +27,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, 
operationParams=CreateSnapshotRefSpec{refName=test_tag_1}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, 
operationParams=CreateSnapshotRefSpec{refName=test_tag_1, isReplace=false, 
ifNotExists=false}}
 
 PREHOOK: query: alter table iceTbl create tag test_tag_1
 PREHOOK: type: ALTERTABLE_CREATETAG
@@ -65,7 +65,7 @@ STAGE PLANS:
   Stage: Stage-0
     SnapshotRef Operation
       table name: default.iceTbl
-      spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, 
operationParams=CreateSnapshotRefSpec{refName=test_tag_2, 
maxRefAgeMs=432000000}}
+      spec: AlterTableSnapshotRefSpec{operationType=CREATE_TAG, 
operationParams=CreateSnapshotRefSpec{refName=test_tag_2, 
maxRefAgeMs=432000000, isReplace=false, ifNotExists=false}}
 
 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 5d3c837b0bd..2f136a5d998 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
@@ -539,8 +539,10 @@ alterStatementSuffixDropBranch
 alterStatementSuffixCreateBranch
 @init { gParent.pushMsg("alter table create branch", state); }
 @after { gParent.popMsg(state); }
-    : KW_CREATE KW_BRANCH branchName=identifier snapshotIdOfRef? refRetain? 
retentionOfSnapshots?
-    -> ^(TOK_ALTERTABLE_CREATE_BRANCH $branchName snapshotIdOfRef? refRetain? 
retentionOfSnapshots?)
+    : KW_CREATE KW_BRANCH ifNotExists? branchName=identifier snapshotIdOfRef? 
refRetain? retentionOfSnapshots?
+    -> ^(TOK_ALTERTABLE_CREATE_BRANCH $branchName ifNotExists? 
snapshotIdOfRef? refRetain? retentionOfSnapshots?)
+    | KW_CREATE KW_OR KW_REPLACE KW_BRANCH branchName=identifier 
snapshotIdOfRef? refRetain? retentionOfSnapshots?
+    -> ^(TOK_ALTERTABLE_CREATE_BRANCH $branchName KW_REPLACE snapshotIdOfRef? 
refRetain? retentionOfSnapshots?)
     ;
 
 snapshotIdOfRef
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 3b581ddfa0b..b4ec5380e3a 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
@@ -62,6 +62,8 @@ public abstract class AlterTableCreateSnapshotRefAnalyzer 
extends AbstractAlterT
     Long maxRefAgeMs = null;
     Integer minSnapshotsToKeep = null;
     Long maxSnapshotAgeMs = null;
+    boolean isReplace = false;
+    boolean ifNotExists = false;
     String asOfTag = null;
     for (int i = 1; i < command.getChildCount(); i++) {
       ASTNode childNode = (ASTNode) command.getChild(i);
@@ -93,6 +95,12 @@ public abstract class AlterTableCreateSnapshotRefAnalyzer 
extends AbstractAlterT
               .toMillis(Long.parseLong(maxSnapshotAge));
         }
         break;
+      case HiveParser.KW_REPLACE:
+        isReplace = true;
+        break;
+      case HiveParser.TOK_IFNOTEXISTS:
+        ifNotExists = true;
+        break;
       default:
         throw new SemanticException("Unrecognized token in ALTER " + 
alterTableType.getName() + " statement");
       }
@@ -100,7 +108,7 @@ public abstract class AlterTableCreateSnapshotRefAnalyzer 
extends AbstractAlterT
 
     AlterTableSnapshotRefSpec.CreateSnapshotRefSpec createSnapshotRefSpec =
         new AlterTableSnapshotRefSpec.CreateSnapshotRefSpec(refName, 
snapshotId, asOfTime,
-            maxRefAgeMs, minSnapshotsToKeep, maxSnapshotAgeMs, asOfTag);
+            maxRefAgeMs, minSnapshotsToKeep, maxSnapshotAgeMs, asOfTag, 
isReplace, ifNotExists);
     AlterTableSnapshotRefSpec<AlterTableSnapshotRefSpec.CreateSnapshotRefSpec> 
alterTableSnapshotRefSpec
         = new AlterTableSnapshotRefSpec(alterTableType, createSnapshotRefSpec);
     AbstractAlterTableDesc alterTableDesc =
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 675f9ee9d05..0dcf08f1e9c 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
@@ -56,6 +56,8 @@ public class AlterTableSnapshotRefSpec<T> {
     private Integer minSnapshotsToKeep;
     private Long maxSnapshotAgeMs;
     private String asOfTag;
+    private boolean isReplace;
+    private boolean ifNotExists;
 
     public String getRefName() {
       return refName;
@@ -85,8 +87,16 @@ public class AlterTableSnapshotRefSpec<T> {
       return asOfTag;
     }
 
+    public boolean isReplace() {
+      return isReplace;
+    }
+
+    public boolean isIfNotExists() {
+      return ifNotExists;
+    }
+
     public CreateSnapshotRefSpec(String refName, Long snapShotId, Long 
asOfTime, Long maxRefAgeMs,
-                             Integer minSnapshotsToKeep, Long 
maxSnapshotAgeMs, String asOfTag) {
+        Integer minSnapshotsToKeep, Long maxSnapshotAgeMs, String asOfTag, 
boolean isReplace, boolean ifNotExists) {
       this.refName = refName;
       this.snapshotId = snapShotId;
       this.asOfTime = asOfTime;
@@ -94,12 +104,15 @@ public class AlterTableSnapshotRefSpec<T> {
       this.minSnapshotsToKeep = minSnapshotsToKeep;
       this.maxSnapshotAgeMs = maxSnapshotAgeMs;
       this.asOfTag = asOfTag;
+      this.isReplace = isReplace;
+      this.ifNotExists = ifNotExists;
     }
 
     public String toString() {
       return MoreObjects.toStringHelper(this).add("refName", 
refName).add("snapshotId", snapshotId)
           .add("asOfTime", asOfTime).add("maxRefAgeMs", 
maxRefAgeMs).add("minSnapshotsToKeep", minSnapshotsToKeep)
-          .add("maxSnapshotAgeMs", 
maxSnapshotAgeMs).omitNullValues().toString();
+          .add("maxSnapshotAgeMs", maxSnapshotAgeMs).add("isReplace", 
isReplace).add("ifNotExists", ifNotExists)
+          .omitNullValues().toString();
     }
   }
   public static class DropSnapshotRefSpec {

Reply via email to