diff --git a/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetastoreTransformer.java b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetastoreTransformer.java index 802ce4e70ed..ad7736de0cd 100644 --- a/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetastoreTransformer.java +++ b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetastoreTransformer.java @@ -1332,6 +1332,26 @@ public void testTransformerAlterTable() throws Exception { } } + @Test + public void testTransformerAlterTableWithoutLocationChangeDoesntValidateLocation() throws Exception { + try { + resetHMSClient(); + String dbName = "dbalter"; + String tblName = "test_alter_mgd_table"; + TableType type = TableType.MANAGED_TABLE; + Map tProps = new HashMap<>(); + tProps.put("DBNAME", dbName); + tProps.put("TBLNAME", tblName); + tProps.put("TBLTYPE", type); + tProps.put("LOCATION", wh.getAbsolutePath().concat(File.separator).concat(dbName).concat(File.separator).concat(tblName)); + createTableWithCapabilities(tProps); + client.alter_table(dbName, tblName, client.getTable(dbName, tblName)); + } finally { + resetHMSClient(); + } + } + + @Test public void testTransformerDatabase() throws Exception { try { diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetastoreDefaultTransformer.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetastoreDefaultTransformer.java index 5283e07d3b9..a8de6bab15b 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetastoreDefaultTransformer.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetastoreDefaultTransformer.java @@ -24,20 +24,20 @@ import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES; import static org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.EXTERNAL_TABLE_PURGE; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; 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.utils.FileUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -648,7 +648,7 @@ public Table transformAlterTable(Table table, List processorCapabilities tableLocation = Path.getPathWithoutSchemeAndAuthority(new Path(table.getSd().getLocation())); } whRootPath = Path.getPathWithoutSchemeAndAuthority(hmsHandler.getWh().getWhRoot()); - if (tableLocation != null && !FileUtils.isSubdirectory(whRootPath.toString(), tableLocation.toString())) { + if (tableLocation != null && tableLocationChanged(table) && !FileUtils.isSubdirectory(whRootPath.toString(), tableLocation.toString())) { throw new MetaException( "A managed table's location needs to be under the hive warehouse root directory," + "table:" + table.getTableName() + ",location:" + tableLocation + ",Hive warehouse:" + whRootPath); @@ -660,7 +660,7 @@ public Table transformAlterTable(Table table, List processorCapabilities whRootPath = Path.getPathWithoutSchemeAndAuthority(hmsHandler.getWh().getWhRoot()); if (tableLocation != null) { LOG.debug("Table is an EXTERNAL TABLE:tableLocation={}, whroot={}", tableLocation, whRootPath); - if (FileUtils.isSubdirectory(whRootPath.toString(), tableLocation.toString())) { + if (tableLocationChanged(table) && FileUtils.isSubdirectory(whRootPath.toString(), tableLocation.toString())) { throw new MetaException( "An external table's location should not be located within managed warehouse root directory," + "table:" + table.getTableName() + ",location:" + tableLocation + ",Hive managed warehouse:" + whRootPath); @@ -673,6 +673,21 @@ public Table transformAlterTable(Table table, List processorCapabilities return table; } + private boolean tableLocationChanged(Table alteredTable) throws MetaException { + if (!alteredTable.isSetSd() || alteredTable.getSd().getLocation() == null) { + return false; + } + try { + Table currentTable = hmsHandler.get_table_core(alteredTable.getCatName(), alteredTable.getDbName(), alteredTable.getTableName()); + if (!currentTable.isSetSd() || currentTable.getSd().getLocation() == null) { + return false; + } + return !currentTable.getSd().getLocation().equals(alteredTable.getSd().getLocation()); + } catch (NoSuchObjectException e) { + return false; + } + } + /** * Alter location of the database depending on whether or not the processor has ACID capabilities. */