diff --git standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java index 69f6ed570e..7e615ed817 100644 --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java @@ -26,6 +26,7 @@ import org.apache.hadoop.hive.metastore.events.AlterPartitionEvent; import org.apache.hadoop.hive.metastore.events.AlterTableEvent; import org.apache.hadoop.hive.metastore.messaging.EventMessage; +import org.apache.hadoop.hive.metastore.txn.TxnUtils; import org.apache.hadoop.hive.metastore.utils.FileUtils; import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils; import org.slf4j.Logger; @@ -811,6 +812,9 @@ void alterTableUpdateTableColumnStats(RawStore msdb, Table oldTable, Table newTa ColumnStatistics colStats = null; boolean updateColumnStats = !newDbName.equals(dbName) || !newTableName.equals(tableName) || !MetaStoreUtils.columnsIncludedByNameType(oldCols, newCols); + // Don't bother in the case of ACID conversion. + updateColumnStats = updateColumnStats + && (TxnUtils.isAcidTable(oldTable) == TxnUtils.isAcidTable(newTable)); if (updateColumnStats) { List oldColNames = new ArrayList<>(oldCols.size()); for (FieldSchema oldCol : oldCols) { diff --git standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java index 8af164efc9..8e6c6d2586 100644 --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -4113,7 +4113,8 @@ public Table alterTable(String catName, String dbname, String name, Table newTab oldt.setDatabase(newt.getDatabase()); oldt.setTableName(normalizeIdentifier(newt.getTableName())); boolean isTxn = TxnUtils.isTransactionalTable(newTable); - if (isTxn && areTxnStatsSupported) { + boolean isToTxn = isTxn && !TxnUtils.isTransactionalTable(oldt.getParameters()); + if (!isToTxn && isTxn && areTxnStatsSupported) { // Transactional table is altered without a txn. Make sure there are no changes to the flag. String errorMsg = verifyStatsChangeCtx(oldt.getParameters(), newTable.getParameters(), newTable.getWriteId(), queryValidWriteIds, false); @@ -4121,7 +4122,6 @@ public Table alterTable(String catName, String dbname, String name, Table newTab throw new MetaException(errorMsg); } } - boolean isToTxn = isTxn && !TxnUtils.isTransactionalTable(oldt.getParameters()); oldt.setParameters(newt.getParameters()); oldt.setOwner(newt.getOwner()); oldt.setOwnerType(newt.getOwnerType()); @@ -4143,12 +4143,11 @@ public Table alterTable(String catName, String dbname, String name, Table newTab oldt.setRewriteEnabled(newt.isRewriteEnabled()); // If transactional, update the stats state for the current Stats updater query. - // Don't update for conversion to acid - it doesn't modify stats but passes in qVWIds. - // The fact that it doesn't update stats is verified above. + // Set stats invalid for ACID conversion; it doesn't pass in the write ID. if (isTxn) { - if (!areTxnStatsSupported) { + if (!areTxnStatsSupported || isToTxn) { StatsSetupConst.setBasicStatsState(oldt.getParameters(), StatsSetupConst.FALSE); - } else if (queryValidWriteIds != null && (!isToTxn || newTable.getWriteId() > 0)) { + } else if (queryValidWriteIds != null && newTable.getWriteId() > 0) { // Check concurrent INSERT case and set false to the flag. if (!isCurrentStatsValidForTheQuery(oldt, queryValidWriteIds, true)) { StatsSetupConst.setBasicStatsState(oldt.getParameters(), StatsSetupConst.FALSE); diff --git standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java index aac58110f9..bd202edb91 100644 --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnUtils.java @@ -221,6 +221,7 @@ public static boolean isTransactionalTable(Table table) { return false; } Map parameters = table.getParameters(); + if (parameters == null) return false; String tableIsTransactional = parameters.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL); return tableIsTransactional != null && tableIsTransactional.equalsIgnoreCase("true"); } diff --git standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java index 881648035c..93b2f23e62 100644 --- standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java +++ standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java @@ -64,7 +64,7 @@ public void testAlterTableAddColNotUpdateStats() throws MetaException, InvalidOb } @Test - public void testAlterTableDelColUpdateStats() throws MetaException, InvalidObjectException, NoSuchObjectException { + public void testAlterTableDelColUpdateStats() throws Exception { FieldSchema col1 = new FieldSchema("col1", "string", "col1 comment"); FieldSchema col2 = new FieldSchema("col2", "string", "col2 comment"); FieldSchema col3 = new FieldSchema("col3", "string", "col3 comment"); @@ -85,7 +85,13 @@ public void testAlterTableDelColUpdateStats() throws MetaException, InvalidObjec RawStore msdb = Mockito.mock(RawStore.class); HiveAlterHandler handler = new HiveAlterHandler(); handler.setConf(conf); - handler.alterTableUpdateTableColumnStats(msdb, oldTable, newTable, null, null); + try { + handler.alterTableUpdateTableColumnStats(msdb, oldTable, newTable, null, null); + } catch (Throwable t) { + System.err.println(t); + t.printStackTrace(System.err); + throw t; + } Mockito.verify(msdb, Mockito.times(1)).getTableColumnStatistics( getDefaultCatalog(conf), oldTable.getDbName(), oldTable.getTableName(), Arrays.asList("col1", "col2", "col3", "col4") );