This is an automated email from the ASF dual-hosted git repository.

dkuzmenko 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 2d8b0a31f46 HIVE-26474: Enable converting insert-only tables to full 
ACID tables (Simhadri Govindappa, reviewed by Denys Kuzmenko)
2d8b0a31f46 is described below

commit 2d8b0a31f461a33ef2e19c0269ec44778d5ca136
Author: SimhadriGovindappa <[email protected]>
AuthorDate: Thu Sep 1 16:22:52 2022 +0530

    HIVE-26474: Enable converting insert-only tables to full ACID tables 
(Simhadri Govindappa, reviewed by Denys Kuzmenko)
    
    Closes #3550
---
 .../org/apache/hadoop/hive/conf/Constants.java     |   4 +
 .../AlterTableSetPropertiesOperation.java          |  13 +-
 .../org/apache/hadoop/hive/ql/io/AcidUtils.java    | 132 +++----
 .../hadoop/hive/ql/parse/SemanticAnalyzer.java     |   3 +-
 .../apache/hadoop/hive/ql/util/UpgradeTool.java    |  35 +-
 .../clientpositive/insert_only_to_acid_convert.q   |  31 ++
 .../llap/insert_only_to_acid_convert.q.out         | 394 +++++++++++++++++++++
 .../metastore/TransactionalValidationListener.java |   4 +-
 .../apache/hadoop/hive/metastore/txn/TxnUtils.java |  27 +-
 9 files changed, 526 insertions(+), 117 deletions(-)

diff --git a/common/src/java/org/apache/hadoop/hive/conf/Constants.java 
b/common/src/java/org/apache/hadoop/hive/conf/Constants.java
index b89cdf3fadc..bd489f84400 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/Constants.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/Constants.java
@@ -93,4 +93,8 @@ public class Constants {
   public static final String INSERT_ONLY_FETCH_BUCKET_ID = 
"insertonly.fetch.bucketid";
 
   public static final String ERROR_MESSAGE_NO_DETAILS_AVAILABLE = "No detailed 
message available";
+
+  public static final String ORC_INPUT_FORMAT = 
"org.apache.hadoop.hive.ql.io.orc.OrcInputFormat";
+  public static final String ORC_OUTPUT_FORMAT = 
"org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat";
+
 }
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/misc/properties/AlterTableSetPropertiesOperation.java
 
b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/misc/properties/AlterTableSetPropertiesOperation.java
index fb29d07054c..ee53595e975 100644
--- 
a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/misc/properties/AlterTableSetPropertiesOperation.java
+++ 
b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/misc/properties/AlterTableSetPropertiesOperation.java
@@ -27,6 +27,7 @@ import org.apache.hadoop.hive.common.StatsSetupConst;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
 import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
 import org.apache.hadoop.hive.ql.ddl.DDLOperationContext;
 import org.apache.hadoop.hive.ql.ddl.table.AbstractAlterTableOperation;
@@ -43,6 +44,8 @@ import org.apache.hadoop.hive.ql.plan.MoveWork;
 
 import com.google.common.collect.Lists;
 
+import static 
org.apache.hadoop.hive.metastore.TransactionalValidationListener.DEFAULT_TRANSACTIONAL_PROPERTY;
+
 /**
  * Operation process of setting properties of a table.
  */
@@ -62,6 +65,7 @@ public class AlterTableSetPropertiesOperation extends 
AbstractAlterTableOperatio
     } else {
       boolean isFromMmTable = 
AcidUtils.isInsertOnlyTable(table.getParameters());
       Boolean isToMmTable = AcidUtils.isToInsertOnlyTable(table, 
desc.getProps());
+      boolean isToFullAcid = AcidUtils.isToFullAcid(table, desc.getProps());
       if (!isFromMmTable && BooleanUtils.isTrue(isToMmTable)) {
         if (!HiveConf.getBoolVar(context.getConf(), 
ConfVars.HIVE_MM_ALLOW_ORIGINALS)) {
           List<Task<?>> mmTasks = generateAddMmTasks(table, desc.getWriteId());
@@ -79,8 +83,13 @@ public class AlterTableSetPropertiesOperation extends 
AbstractAlterTableOperatio
             checkMmLb(table);
           }
         }
-      } else if (isFromMmTable && BooleanUtils.isFalse(isToMmTable)) {
-        throw new HiveException("Cannot convert an ACID table to non-ACID");
+      } else if (isFromMmTable) {
+        if (isToFullAcid) {
+          
table.getParameters().put(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES,
+                  DEFAULT_TRANSACTIONAL_PROPERTY);
+        } else if (BooleanUtils.isFalse(isToMmTable)) {
+          throw new HiveException("Cannot convert an ACID table to non-ACID");
+        }
       }
 
       // Converting to/from external table
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java 
b/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java
index a9c3bb5a827..2811763c062 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java
@@ -21,7 +21,10 @@ package org.apache.hadoop.hive.ql.io;
 import static 
org.apache.hadoop.hive.common.AcidConstants.SOFT_DELETE_PATH_SUFFIX;
 import static org.apache.hadoop.hive.common.AcidConstants.SOFT_DELETE_TABLE;
 import static org.apache.hadoop.hive.common.FileUtils.HIDDEN_FILES_PATH_FILTER;
+import static 
org.apache.hadoop.hive.metastore.TransactionalValidationListener.INSERTONLY_TRANSACTIONAL_PROPERTY;
+import static 
org.apache.hadoop.hive.metastore.TransactionalValidationListener.DEFAULT_TRANSACTIONAL_PROPERTY;
 import static org.apache.hadoop.hive.ql.exec.Utilities.COPY_KEYWORD;
+
 import static org.apache.hadoop.hive.ql.parse.CalcitePlanner.ASTSearcher;
 
 import java.io.FileNotFoundException;
@@ -55,6 +58,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.google.protobuf.InvalidProtocolBufferException;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hadoop.conf.Configuration;
@@ -74,6 +78,7 @@ import org.apache.hadoop.hive.common.ValidReaderWriteIdList;
 import org.apache.hadoop.hive.common.ValidTxnWriteIdList;
 import org.apache.hadoop.hive.common.ValidWriteIdList;
 import org.apache.hadoop.hive.common.TableName;
+import org.apache.hadoop.hive.conf.Constants;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hadoop.hive.metastore.LockComponentBuilder;
@@ -82,6 +87,7 @@ import org.apache.hadoop.hive.metastore.api.DataOperationType;
 import org.apache.hadoop.hive.metastore.api.LockComponent;
 import org.apache.hadoop.hive.metastore.api.LockType;
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
 import org.apache.hadoop.hive.metastore.api.TxnType;
 import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils;
 import org.apache.hadoop.hive.ql.Context;
@@ -474,11 +480,7 @@ public class AcidUtils {
    * @return true, if the tblProperties contains {@link 
AcidUtils#COMPACTOR_TABLE_PROPERTY}
    */
   public static boolean isCompactionTable(Properties tblProperties) {
-    if (tblProperties != null && 
tblProperties.containsKey(COMPACTOR_TABLE_PROPERTY) && tblProperties
-        .getProperty(COMPACTOR_TABLE_PROPERTY).equalsIgnoreCase("true")) {
-      return true;
-    }
-    return false;
+    return tblProperties != null && 
isCompactionTable(Maps.fromProperties(tblProperties));
   }
 
   /**
@@ -487,7 +489,7 @@ public class AcidUtils {
    * @return true, if the parameters contains {@link 
AcidUtils#COMPACTOR_TABLE_PROPERTY}
    */
   public static boolean isCompactionTable(Map<String, String> parameters) {
-    return Boolean.valueOf(parameters.getOrDefault(COMPACTOR_TABLE_PROPERTY, 
"false"));
+    return Boolean.parseBoolean(parameters.get(COMPACTOR_TABLE_PROPERTY));
   }
 
   /**
@@ -1927,11 +1929,7 @@ public class AcidUtils {
   }
 
   public static boolean isTablePropertyTransactional(Properties props) {
-    String resultStr = 
props.getProperty(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    if (resultStr == null) {
-      resultStr = 
props.getProperty(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.toUpperCase());
-    }
-    return resultStr != null && resultStr.equalsIgnoreCase("true");
+    return isTablePropertyTransactional(Maps.fromProperties(props));
   }
 
   public static boolean isTablePropertyTransactional(Map<String, String> 
parameters) {
@@ -1939,18 +1937,9 @@ public class AcidUtils {
     if (resultStr == null) {
       resultStr = 
parameters.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.toUpperCase());
     }
-    return resultStr != null && resultStr.equalsIgnoreCase("true");
+    return Boolean.parseBoolean(resultStr);
   }
 
-  public static boolean isTablePropertyTransactional(Configuration conf) {
-    String resultStr = 
conf.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    if (resultStr == null) {
-      resultStr = 
conf.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.toUpperCase());
-    }
-    return resultStr != null && resultStr.equalsIgnoreCase("true");
-  }
-
-
   /**
    * @param p - not null
    */
@@ -1967,12 +1956,16 @@ public class AcidUtils {
     return isTransactionalTable(table.getTblProps());
   }
 
+  public static boolean isTransactionalTable(Table table) {
+    return table != null && isTransactionalTable(table.getTTable());
+  }
+
+  public static boolean 
isTransactionalTable(org.apache.hadoop.hive.metastore.api.Table table) {
+    return table != null && isTransactionalTable(table.getParameters());
+  }
+
   public static boolean isTransactionalTable(Map<String, String> props) {
-    String tableIsTransactional = 
props.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    if (tableIsTransactional == null) {
-      tableIsTransactional = 
props.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.toUpperCase());
-    }
-    return tableIsTransactional != null && 
tableIsTransactional.equalsIgnoreCase("true");
+    return props != null && isTablePropertyTransactional(props);
   }
 
   public static boolean isTransactionalView(CreateMaterializedViewDesc view) {
@@ -1982,16 +1975,18 @@ public class AcidUtils {
     return isTransactionalTable(view.getTblProps());
   }
 
+  public static boolean isFullAcidTable(CreateTableDesc td) {
+    if (td == null || td.getTblProps() == null) {
+      return false;
+    }
+    return isFullAcidTable(td.getTblProps());
+  }
   /**
    * Should produce the same result as
    * {@link 
org.apache.hadoop.hive.metastore.txn.TxnUtils#isAcidTable(org.apache.hadoop.hive.metastore.api.Table)}
    */
   public static boolean isFullAcidTable(Table table) {
-    return isFullAcidTable(table == null ? null : table.getTTable());
-  }
-
-  public static boolean isTransactionalTable(Table table) {
-    return isTransactionalTable(table == null ? null : table.getTTable());
+    return table != null && isFullAcidTable(table.getTTable());
   }
 
   /**
@@ -1999,31 +1994,13 @@ public class AcidUtils {
    * {@link 
org.apache.hadoop.hive.metastore.txn.TxnUtils#isAcidTable(org.apache.hadoop.hive.metastore.api.Table)}
    */
   public static boolean 
isFullAcidTable(org.apache.hadoop.hive.metastore.api.Table table) {
-    return isTransactionalTable(table) &&
-        !isInsertOnlyTable(table.getParameters());
+    return table != null && isFullAcidTable(table.getParameters());
   }
 
   public static boolean isFullAcidTable(Map<String, String> params) {
     return isTransactionalTable(params) && !isInsertOnlyTable(params);
   }
 
-  public static boolean 
isTransactionalTable(org.apache.hadoop.hive.metastore.api.Table table) {
-    return table != null && table.getParameters() != null &&
-        isTablePropertyTransactional(table.getParameters());
-  }
-
-  public static boolean isFullAcidTable(CreateTableDesc td) {
-    if (td == null || td.getTblProps() == null) {
-      return false;
-    }
-    String tableIsTransactional = 
td.getTblProps().get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    if (tableIsTransactional == null) {
-      tableIsTransactional = 
td.getTblProps().get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.toUpperCase());
-    }
-    return tableIsTransactional != null && 
tableIsTransactional.equalsIgnoreCase("true") &&
-      !AcidUtils.isInsertOnlyTable(td.getTblProps());
-  }
-
   public static boolean isFullAcidScan(Configuration conf) {
     if (!HiveConf.getBoolVar(conf, ConfVars.HIVE_TRANSACTIONAL_TABLE_SCAN)) {
       return false;
@@ -2200,22 +2177,16 @@ public class AcidUtils {
    * @return true if table is an INSERT_ONLY table, false otherwise
    */
   public static boolean isInsertOnlyTable(Map<String, String> params) {
-    return isInsertOnlyTable(params, false);
+    String transactionalProp = 
params.get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES);
+    return 
INSERTONLY_TRANSACTIONAL_PROPERTY.equalsIgnoreCase(transactionalProp);
   }
+
   public static boolean isInsertOnlyTable(Table table) {
     return isTransactionalTable(table) && 
getAcidOperationalProperties(table).isInsertOnly();
   }
-
-  // TODO [MM gap]: CTAS may currently be broken. It used to work. See the old 
code, and why isCtas isn't used?
-  public static boolean isInsertOnlyTable(Map<String, String> params, boolean 
isCtas) {
-    String transactionalProp = 
params.get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES);
-    return (transactionalProp != null && 
"insert_only".equalsIgnoreCase(transactionalProp));
-  }
-
+  
   public static boolean isInsertOnlyTable(Properties params) {
-    String transactionalProp = params.getProperty(
-        hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES);
-    return (transactionalProp != null && 
"insert_only".equalsIgnoreCase(transactionalProp));
+    return isInsertOnlyTable(Maps.fromProperties(params));
   }
 
    /**
@@ -2240,13 +2211,15 @@ public class AcidUtils {
     if (transactional == null && tbl != null) {
       transactional = 
tbl.getParameters().get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
     }
-    boolean isSetToTxn = "true".equalsIgnoreCase(transactional);
+    boolean isSetToTxn = Boolean.parseBoolean(transactional);
     if (transactionalProp == null) {
       if (isSetToTxn || tbl == null) return false; // Assume the full ACID 
table.
       throw new RuntimeException("Cannot change '" + 
hive_metastoreConstants.TABLE_IS_TRANSACTIONAL
           + "' without '" + 
hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES + "'");
     }
-    if (!"insert_only".equalsIgnoreCase(transactionalProp)) return false; // 
Not MM.
+    if 
(!INSERTONLY_TRANSACTIONAL_PROPERTY.equalsIgnoreCase(transactionalProp)) {
+      return false; // Not MM.
+    }
     if (!isSetToTxn) {
       if (tbl == null) return true; // No table information yet; looks like it 
could be valid.
       throw new RuntimeException("Cannot set '"
@@ -2256,6 +2229,39 @@ public class AcidUtils {
     return true;
   }
 
+  public static Boolean isToFullAcid(Table table, Map<String, String> props) {
+    if (AcidUtils.isTransactionalTable(table)) {
+      String transactionalProp = 
props.get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES);
+
+      if (DEFAULT_TRANSACTIONAL_PROPERTY.equalsIgnoreCase(transactionalProp)) {
+        return canBeMadeAcid(table.getTableName(), table.getSd());
+      }
+    }
+    return false;
+  }
+
+  public static boolean canBeMadeAcid(String fullTableName, StorageDescriptor 
sd) {
+    return isAcidInputOutputFormat(fullTableName, sd) && sd.getSortColsSize() 
<= 0;
+  }
+  
+  private static boolean isAcidInputOutputFormat(String fullTableName, 
StorageDescriptor sd) {
+    if (sd.getInputFormat() == null || sd.getOutputFormat() == null) {
+      return false;
+    }
+    try {
+      return Class.forName(Constants.ORC_INPUT_FORMAT)
+                  .isAssignableFrom(Class.forName(sd.getInputFormat())) 
+            && Class.forName(Constants.ORC_OUTPUT_FORMAT)
+                  .isAssignableFrom(Class.forName(sd.getOutputFormat()));
+    
+    } catch (ClassNotFoundException e) {
+      //if a table is using some custom I/O format and it's not in the 
classpath, we won't mark
+      //the table for Acid, but today OrcInput/OutputFormat is the only Acid 
format
+      LOG.error("Could not determine if " + fullTableName + " can be made Acid 
due to: " + e.getMessage(), e);
+      return false;
+    }
+  }
+
   public static boolean isRemovedInsertOnlyTable(Set<String> removedSet) {
     boolean hasTxn = 
removedSet.contains(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL),
         hasProps = 
removedSet.contains(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES);
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java 
b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
index c3e7fb4a200..9b6c995bbd1 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
@@ -2456,8 +2456,7 @@ public class SemanticAnalyzer extends 
BaseSemanticAnalyzer {
             }
             try {
               CreateTableDesc tblDesc = qb.getTableDesc();
-              if (tblDesc != null && tblDesc.isTemporary() && AcidUtils
-                  .isInsertOnlyTable(tblDesc.getTblProps(), true)) {
+              if (tblDesc != null && tblDesc.isTemporary() && 
AcidUtils.isInsertOnlyTable(tblDesc.getTblProps())) {
                 fname = FileUtils.makeQualified(location, conf).toString();
               } else {
                 fname = 
ctx.getExtTmpPathRelTo(FileUtils.makeQualified(location, conf)).toString();
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/util/UpgradeTool.java 
b/ql/src/java/org/apache/hadoop/hive/ql/util/UpgradeTool.java
index e9e49a62701..67df6a7bcec 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/util/UpgradeTool.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/util/UpgradeTool.java
@@ -31,10 +31,8 @@ import org.apache.hadoop.fs.ContentSummary;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.LocatedFileStatus;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.fs.RemoteIterator;
 import org.apache.hadoop.hive.common.StatsSetupConst;
 import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
 import org.apache.hadoop.hive.metastore.IMetaStoreClient;
 import org.apache.hadoop.hive.metastore.RetryingMetaStoreClient;
 import org.apache.hadoop.hive.metastore.TableType;
@@ -43,18 +41,14 @@ import 
org.apache.hadoop.hive.metastore.api.EnvironmentContext;
 import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
 import org.apache.hadoop.hive.metastore.api.MetaException;
 import org.apache.hadoop.hive.metastore.api.Partition;
-import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
 import org.apache.hadoop.hive.metastore.api.Table;
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
 import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
-import org.apache.hadoop.hive.metastore.utils.FileUtils;
 import 
org.apache.hadoop.hive.metastore.utils.FileUtils.RemoteIteratorWithFilter;
 import org.apache.hadoop.hive.ql.io.AcidUtils;
 import org.apache.hadoop.hive.ql.io.BucketCodec;
-import org.apache.hadoop.hive.ql.lockmgr.HiveTxnManager;
 import org.apache.hadoop.hive.ql.metadata.Hive;
 import org.apache.hadoop.hive.ql.metadata.HiveException;
-import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hive.common.util.HiveVersionInfo;
 import org.apache.thrift.TException;
@@ -524,7 +518,7 @@ public class UpgradeTool {
      * ORC uses table props for settings so things like bucketing, I/O Format, 
etc should
      * be the same for each partition.
      */
-    boolean canBeMadeAcid = canBeMadeAcid(fullTableName, t.getSd());
+    boolean canBeMadeAcid = AcidUtils.canBeMadeAcid(fullTableName, t.getSd());
     if(t.getPartitionKeysSize() <= 0) {
       if(canBeMadeAcid) {
         convertToAcid.add("ALTER TABLE " + Warehouse.getQualifiedName(t) + " 
SET TBLPROPERTIES (" +
@@ -584,33 +578,8 @@ public class UpgradeTool {
       }
     }
   }
-  private static boolean canBeMadeAcid(String fullTableName, StorageDescriptor 
sd) {
-    return isAcidInputOutputFormat(fullTableName, sd) && sd.getSortColsSize() 
<= 0;
-  }
-  private static boolean isAcidInputOutputFormat(String fullTableName, 
StorageDescriptor sd) {
-    try {
-      Class inputFormatClass = sd.getInputFormat() == null ? null :
-          Class.forName(sd.getInputFormat());
-      Class outputFormatClass = sd.getOutputFormat() == null ? null :
-          Class.forName(sd.getOutputFormat());
 
-      if (inputFormatClass != null && outputFormatClass != null &&
-          Class.forName("org.apache.hadoop.hive.ql.io.AcidInputFormat")
-              .isAssignableFrom(inputFormatClass) &&
-          Class.forName("org.apache.hadoop.hive.ql.io.AcidOutputFormat")
-              .isAssignableFrom(outputFormatClass)) {
-        return true;
-      }
-    } catch (ClassNotFoundException e) {
-      //if a table is using some custom I/O format and it's not in the 
classpath, we won't mark
-      //the table for Acid, but today (Hive 3.1 and earlier) 
OrcInput/OutputFormat is the only
-      //Acid format
-      LOG.error("Could not determine if " + fullTableName +
-          " can be made Acid due to: " + e.getMessage(), e);
-      return false;
-    }
-    return false;
-  }
+
   private static void makeConvertTableScript(List<String> alterTableAcid, 
List<String> alterTableMm,
       String scriptLocation) throws IOException {
     if (alterTableAcid.isEmpty()) {
diff --git a/ql/src/test/queries/clientpositive/insert_only_to_acid_convert.q 
b/ql/src/test/queries/clientpositive/insert_only_to_acid_convert.q
new file mode 100644
index 00000000000..61ee7e41a13
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/insert_only_to_acid_convert.q
@@ -0,0 +1,31 @@
+--! qt:dataset:alltypesorc
+set hive.support.concurrency=true;
+set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
+set hive.mapred.mode=nonstrict;
+set hive.strict.checks.bucketing=true;
+set hive.enforce.bucketing=true;
+
+create table insert_only(col1 Int, col2 String) stored as orc  TBLPROPERTIES 
('transactional'='true','transactional_properties'='insert_only');
+insert into insert_only values(1,'hi'),(2,'hello');
+describe formatted insert_only;
+ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default');
+describe formatted insert_only;
+insert into insert_only values(1,'hi'),(2,'hello');
+select * from insert_only;
+
+create table insert_only_1(col1 Int, col2 String) stored as orc  TBLPROPERTIES 
('transactional'='true','transactional_properties'='insert_only');
+insert into insert_only_1 values(1,'hi'),(2,'hello');
+describe formatted insert_only_1;
+ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional_properties'='default');
+describe formatted insert_only_1;
+insert into insert_only_1 values(1,'hi'),(2,'hello');
+select * from insert_only_1;
+
+create table insert_only_part(a INT, b STRING) partitioned by (ds string) 
CLUSTERED BY(a) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES 
('transactional'='true', 'transactional_properties'='insert_only');
+insert into table insert_only_part partition (ds = 'today') select cint, 
cstring1 from alltypesorc where cint is not null order by cint limit 10;
+insert into table insert_only_part partition (ds = 'tomorrow') select cint, 
cstring1 from alltypesorc where cint is not null order by cint limit 10;
+describe formatted insert_only_part;
+ALTER TABLE insert_only_part SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default');
+describe formatted insert_only_part;
+select * from insert_only_part order by a, b, ds;
+
diff --git 
a/ql/src/test/results/clientpositive/llap/insert_only_to_acid_convert.q.out 
b/ql/src/test/results/clientpositive/llap/insert_only_to_acid_convert.q.out
new file mode 100644
index 00000000000..284e5d419a2
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/insert_only_to_acid_convert.q.out
@@ -0,0 +1,394 @@
+PREHOOK: query: create table insert_only(col1 Int, col2 String) stored as orc  
TBLPROPERTIES ('transactional'='true','transactional_properties'='insert_only')
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@insert_only
+POSTHOOK: query: create table insert_only(col1 Int, col2 String) stored as orc 
 TBLPROPERTIES ('transactional'='true','transactional_properties'='insert_only')
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@insert_only
+PREHOOK: query: insert into insert_only values(1,'hi'),(2,'hello')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@insert_only
+POSTHOOK: query: insert into insert_only values(1,'hi'),(2,'hello')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@insert_only
+POSTHOOK: Lineage: insert_only.col1 SCRIPT []
+POSTHOOK: Lineage: insert_only.col2 SCRIPT []
+PREHOOK: query: describe formatted insert_only
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only
+POSTHOOK: query: describe formatted insert_only
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only
+# col_name             data_type               comment             
+col1                   int                                         
+col2                   string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col1\":\"true\",\"col2\":\"true\"}}
+       bucketing_version       2                   
+       numFiles                1                   
+       numRows                 2                   
+       rawDataSize             182                 
+       totalSize               310                 
+       transactional           true                
+       transactional_properties        insert_only         
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           -1                       
+Bucket Columns:        []                       
+Sort Columns:          []                       
+Storage Desc Params:            
+       serialization.format    1                   
+PREHOOK: query: ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default')
+PREHOOK: type: ALTERTABLE_PROPERTIES
+PREHOOK: Input: default@insert_only
+PREHOOK: Output: default@insert_only
+POSTHOOK: query: ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default')
+POSTHOOK: type: ALTERTABLE_PROPERTIES
+POSTHOOK: Input: default@insert_only
+POSTHOOK: Output: default@insert_only
+PREHOOK: query: describe formatted insert_only
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only
+POSTHOOK: query: describe formatted insert_only
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only
+# col_name             data_type               comment             
+col1                   int                                         
+col2                   string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col1\":\"true\",\"col2\":\"true\"}}
+       bucketing_version       2                   
+#### A masked pattern was here ####
+       numFiles                1                   
+       numRows                 2                   
+       rawDataSize             182                 
+       totalSize               310                 
+       transactional           true                
+       transactional_properties        default             
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           -1                       
+Bucket Columns:        []                       
+Sort Columns:          []                       
+PREHOOK: query: insert into insert_only values(1,'hi'),(2,'hello')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@insert_only
+POSTHOOK: query: insert into insert_only values(1,'hi'),(2,'hello')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@insert_only
+POSTHOOK: Lineage: insert_only.col1 SCRIPT []
+POSTHOOK: Lineage: insert_only.col2 SCRIPT []
+PREHOOK: query: select * from insert_only
+PREHOOK: type: QUERY
+PREHOOK: Input: default@insert_only
+#### A masked pattern was here ####
+POSTHOOK: query: select * from insert_only
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@insert_only
+#### A masked pattern was here ####
+1      hi
+2      hello
+1      hi
+2      hello
+PREHOOK: query: create table insert_only_1(col1 Int, col2 String) stored as 
orc  TBLPROPERTIES 
('transactional'='true','transactional_properties'='insert_only')
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@insert_only_1
+POSTHOOK: query: create table insert_only_1(col1 Int, col2 String) stored as 
orc  TBLPROPERTIES 
('transactional'='true','transactional_properties'='insert_only')
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@insert_only_1
+PREHOOK: query: insert into insert_only_1 values(1,'hi'),(2,'hello')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@insert_only_1
+POSTHOOK: query: insert into insert_only_1 values(1,'hi'),(2,'hello')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@insert_only_1
+POSTHOOK: Lineage: insert_only_1.col1 SCRIPT []
+POSTHOOK: Lineage: insert_only_1.col2 SCRIPT []
+PREHOOK: query: describe formatted insert_only_1
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only_1
+POSTHOOK: query: describe formatted insert_only_1
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only_1
+# col_name             data_type               comment             
+col1                   int                                         
+col2                   string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col1\":\"true\",\"col2\":\"true\"}}
+       bucketing_version       2                   
+       numFiles                1                   
+       numRows                 2                   
+       rawDataSize             182                 
+       totalSize               310                 
+       transactional           true                
+       transactional_properties        insert_only         
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           -1                       
+Bucket Columns:        []                       
+Sort Columns:          []                       
+Storage Desc Params:            
+       serialization.format    1                   
+PREHOOK: query: ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional_properties'='default')
+PREHOOK: type: ALTERTABLE_PROPERTIES
+PREHOOK: Input: default@insert_only
+PREHOOK: Output: default@insert_only
+POSTHOOK: query: ALTER TABLE insert_only SET TBLPROPERTIES 
('transactional_properties'='default')
+POSTHOOK: type: ALTERTABLE_PROPERTIES
+POSTHOOK: Input: default@insert_only
+POSTHOOK: Output: default@insert_only
+PREHOOK: query: describe formatted insert_only_1
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only_1
+POSTHOOK: query: describe formatted insert_only_1
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only_1
+# col_name             data_type               comment             
+col1                   int                                         
+col2                   string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col1\":\"true\",\"col2\":\"true\"}}
+       bucketing_version       2                   
+       numFiles                1                   
+       numRows                 2                   
+       rawDataSize             182                 
+       totalSize               310                 
+       transactional           true                
+       transactional_properties        insert_only         
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           -1                       
+Bucket Columns:        []                       
+Sort Columns:          []                       
+Storage Desc Params:            
+       serialization.format    1                   
+PREHOOK: query: insert into insert_only_1 values(1,'hi'),(2,'hello')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@insert_only_1
+POSTHOOK: query: insert into insert_only_1 values(1,'hi'),(2,'hello')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@insert_only_1
+POSTHOOK: Lineage: insert_only_1.col1 SCRIPT []
+POSTHOOK: Lineage: insert_only_1.col2 SCRIPT []
+PREHOOK: query: select * from insert_only_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@insert_only_1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from insert_only_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@insert_only_1
+#### A masked pattern was here ####
+1      hi
+2      hello
+1      hi
+2      hello
+PREHOOK: query: create table insert_only_part(a INT, b STRING) partitioned by 
(ds string) CLUSTERED BY(a) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES 
('transactional'='true', 'transactional_properties'='insert_only')
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@insert_only_part
+POSTHOOK: query: create table insert_only_part(a INT, b STRING) partitioned by 
(ds string) CLUSTERED BY(a) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES 
('transactional'='true', 'transactional_properties'='insert_only')
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@insert_only_part
+PREHOOK: query: insert into table insert_only_part partition (ds = 'today') 
select cint, cstring1 from alltypesorc where cint is not null order by cint 
limit 10
+PREHOOK: type: QUERY
+PREHOOK: Input: default@alltypesorc
+PREHOOK: Output: default@insert_only_part@ds=today
+POSTHOOK: query: insert into table insert_only_part partition (ds = 'today') 
select cint, cstring1 from alltypesorc where cint is not null order by cint 
limit 10
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@alltypesorc
+POSTHOOK: Output: default@insert_only_part@ds=today
+POSTHOOK: Lineage: insert_only_part PARTITION(ds=today).a SIMPLE 
[(alltypesorc)alltypesorc.FieldSchema(name:cint, type:int, comment:null), ]
+POSTHOOK: Lineage: insert_only_part PARTITION(ds=today).b SIMPLE 
[(alltypesorc)alltypesorc.FieldSchema(name:cstring1, type:string, 
comment:null), ]
+PREHOOK: query: insert into table insert_only_part partition (ds = 'tomorrow') 
select cint, cstring1 from alltypesorc where cint is not null order by cint 
limit 10
+PREHOOK: type: QUERY
+PREHOOK: Input: default@alltypesorc
+PREHOOK: Output: default@insert_only_part@ds=tomorrow
+POSTHOOK: query: insert into table insert_only_part partition (ds = 
'tomorrow') select cint, cstring1 from alltypesorc where cint is not null order 
by cint limit 10
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@alltypesorc
+POSTHOOK: Output: default@insert_only_part@ds=tomorrow
+POSTHOOK: Lineage: insert_only_part PARTITION(ds=tomorrow).a SIMPLE 
[(alltypesorc)alltypesorc.FieldSchema(name:cint, type:int, comment:null), ]
+POSTHOOK: Lineage: insert_only_part PARTITION(ds=tomorrow).b SIMPLE 
[(alltypesorc)alltypesorc.FieldSchema(name:cstring1, type:string, 
comment:null), ]
+PREHOOK: query: describe formatted insert_only_part
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only_part
+POSTHOOK: query: describe formatted insert_only_part
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only_part
+# col_name             data_type               comment             
+a                      int                                         
+b                      string                                      
+                
+# Partition Information                 
+# col_name             data_type               comment             
+ds                     string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   {\"BASIC_STATS\":\"true\"}
+       bucketing_version       2                   
+       numFiles                4                   
+       numPartitions           2                   
+       numRows                 20                  
+       rawDataSize             2008                
+       totalSize               1920                
+       transactional           true                
+       transactional_properties        insert_only         
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           2                        
+Bucket Columns:        [a]                      
+Sort Columns:          []                       
+Storage Desc Params:            
+       serialization.format    1                   
+PREHOOK: query: ALTER TABLE insert_only_part SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default')
+PREHOOK: type: ALTERTABLE_PROPERTIES
+PREHOOK: Input: default@insert_only_part
+PREHOOK: Output: default@insert_only_part
+POSTHOOK: query: ALTER TABLE insert_only_part SET TBLPROPERTIES 
('transactional'='true','transactional_properties'='default')
+POSTHOOK: type: ALTERTABLE_PROPERTIES
+POSTHOOK: Input: default@insert_only_part
+POSTHOOK: Output: default@insert_only_part
+PREHOOK: query: describe formatted insert_only_part
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@insert_only_part
+POSTHOOK: query: describe formatted insert_only_part
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@insert_only_part
+# col_name             data_type               comment             
+a                      int                                         
+b                      string                                      
+                
+# Partition Information                 
+# col_name             data_type               comment             
+ds                     string                                      
+                
+# Detailed Table Information            
+Database:              default                  
+#### A masked pattern was here ####
+Retention:             0                        
+#### A masked pattern was here ####
+Table Type:            MANAGED_TABLE            
+Table Parameters:               
+       COLUMN_STATS_ACCURATE   {\"BASIC_STATS\":\"true\"}
+       bucketing_version       2                   
+#### A masked pattern was here ####
+       numFiles                4                   
+       numPartitions           2                   
+       numRows                 20                  
+       rawDataSize             2008                
+       totalSize               1920                
+       transactional           true                
+       transactional_properties        default             
+#### A masked pattern was here ####
+                
+# Storage Information           
+SerDe Library:         org.apache.hadoop.hive.ql.io.orc.OrcSerde        
+InputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcInputFormat  
+OutputFormat:          org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat        
 
+Compressed:            No                       
+Num Buckets:           2                        
+Bucket Columns:        [a]                      
+Sort Columns:          []                       
+PREHOOK: query: select * from insert_only_part order by a, b, ds
+PREHOOK: type: QUERY
+PREHOOK: Input: default@insert_only_part
+PREHOOK: Input: default@insert_only_part@ds=today
+PREHOOK: Input: default@insert_only_part@ds=tomorrow
+#### A masked pattern was here ####
+POSTHOOK: query: select * from insert_only_part order by a, b, ds
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@insert_only_part
+POSTHOOK: Input: default@insert_only_part@ds=today
+POSTHOOK: Input: default@insert_only_part@ds=tomorrow
+#### A masked pattern was here ####
+-1073279343    oj1YrV5Wa       today
+-1073279343    oj1YrV5Wa       tomorrow
+-1073051226    A34p7oRr2WvUJNf today
+-1073051226    A34p7oRr2WvUJNf tomorrow
+-1072910839    0iqrc5  today
+-1072910839    0iqrc5  tomorrow
+-1072081801    dPkN74F7        today
+-1072081801    dPkN74F7        tomorrow
+-1072076362    2uLyD28144vklju213J1mr  today
+-1072076362    2uLyD28144vklju213J1mr  tomorrow
+-1071480828    aw724t8c5558x2xneC624   today
+-1071480828    aw724t8c5558x2xneC624   tomorrow
+-1071363017    Anj0oF  today
+-1071363017    Anj0oF  tomorrow
+-1070883071    0ruyd6Y50JpdGRf6HqD     today
+-1070883071    0ruyd6Y50JpdGRf6HqD     tomorrow
+-1070551679    iUR3Q   today
+-1070551679    iUR3Q   tomorrow
+-1069736047    k17Am8uPHWk02cEf1jet    today
+-1069736047    k17Am8uPHWk02cEf1jet    tomorrow
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
index a5f5459b9fb..45655d83fd4 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
@@ -217,10 +217,10 @@ public final class TransactionalValidationListener 
extends MetaStorePreEventList
       }
     }
     checkSorted(newTable);
-    if(TxnUtils.isAcidTable(newTable) && !TxnUtils.isAcidTable(oldTable)) {
+    if (TxnUtils.isAcidTable(newTable) && 
!TxnUtils.isTransactionalTable(oldTable)) {
       /* we just made an existing table full acid which wasn't acid before and 
it passed all checks
       initialize the Write ID sequence so that we can handle assigning ROW_IDs 
to 'original'
-      files already present in the table. */
+      files already present in the table. Not needed if oldTable is 
insertOnly.*/
       TxnStore t = TxnUtils.getTxnStore(getConf());
       //For now assume no partition may have > 10M files.  Perhaps better to 
count them.
       t.seedWriteId(new SeedTableWriteIdsRequest(newTable.getDbName(),
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java
index e484a97d814..05fa4bce59d 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java
@@ -25,7 +25,6 @@ import 
org.apache.hadoop.hive.common.ValidCompactorWriteIdList;
 import org.apache.hadoop.hive.common.ValidReadTxnList;
 import org.apache.hadoop.hive.common.ValidTxnList;
 import org.apache.hadoop.hive.metastore.DatabaseProduct;
-import org.apache.hadoop.hive.metastore.TransactionalValidationListener;
 import org.apache.hadoop.hive.metastore.api.GetOpenTxnsResponse;
 import org.apache.hadoop.hive.metastore.api.MetaException;
 import org.apache.hadoop.hive.metastore.api.Table;
@@ -54,6 +53,8 @@ import java.util.stream.Collectors;
 
 import static org.apache.hadoop.hive.common.AcidConstants.SOFT_DELETE_TABLE;
 import static 
org.apache.hadoop.hive.metastore.DatabaseProduct.determineDatabaseProduct;
+import static 
org.apache.hadoop.hive.metastore.TransactionalValidationListener.INSERTONLY_TRANSACTIONAL_PROPERTY;
+import static 
org.apache.hadoop.hive.metastore.TransactionalValidationListener.DEFAULT_TRANSACTIONAL_PROPERTY;
 
 public class TxnUtils {
   private static final Logger LOG = LoggerFactory.getLogger(TxnUtils.class);
@@ -145,13 +146,7 @@ public class TxnUtils {
    * @return true if table is a transactional table, false otherwise
    */
   public static boolean isTransactionalTable(Table table) {
-    if (table == null) {
-      return false;
-    }
-    Map<String, String> parameters = table.getParameters();
-    if (parameters == null) return false;
-    String tableIsTransactional = 
parameters.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    return tableIsTransactional != null && 
tableIsTransactional.equalsIgnoreCase("true");
+    return table != null && isTransactionalTable(table.getParameters());
   }
 
   public static boolean isTransactionalTable(Map<String, String> parameters) {
@@ -159,7 +154,7 @@ public class TxnUtils {
       return false;
     }
     String tableIsTransactional = 
parameters.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
-    return tableIsTransactional != null && 
tableIsTransactional.equalsIgnoreCase("true");
+    return Boolean.parseBoolean(tableIsTransactional);
   }
 
   /**
@@ -167,15 +162,17 @@ public class TxnUtils {
    * org.apache.hadoop.hive.ql.io.AcidUtils#isAcidTable.
    */
   public static boolean isAcidTable(Table table) {
-    return TxnUtils.isTransactionalTable(table) &&
-      
TransactionalValidationListener.DEFAULT_TRANSACTIONAL_PROPERTY.equals(table.getParameters()
-      .get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES));
+    return table != null && isAcidTable(table.getParameters());
   }
 
   public static boolean isAcidTable(Map<String, String> parameters) {
-    return isTransactionalTable(parameters) &&
-            TransactionalValidationListener.DEFAULT_TRANSACTIONAL_PROPERTY.
-                    
equals(parameters.get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES));
+    return isTransactionalTable(parameters) && 
DEFAULT_TRANSACTIONAL_PROPERTY.equalsIgnoreCase(
+        
parameters.get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES));
+  }
+
+  public static boolean isInsertOnlyTable(Table table) {
+    return TxnUtils.isTransactionalTable(table) && 
INSERTONLY_TRANSACTIONAL_PROPERTY.equalsIgnoreCase(
+        
table.getParameters().get(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES));
   }
 
   public static boolean isTableSoftDeleteEnabled(Table table, boolean 
isSoftDelete) {

Reply via email to