diff --git metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java index 68fc270..0bd7f87 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java @@ -282,21 +282,37 @@ public class HiveAlterHandler implements AlterHandler { throw new AlreadyExistsException("Partition already exists:" + dbname + "." + name + "." + new_part.getValues()); } + tbl = msdb.getTable(dbname, name); if (tbl == null) { throw new InvalidObjectException( - "Unable to rename partition because table or database do not exist"); + "Unable to rename partition because table or database do not exist"); } - try { - destPath = new Path(wh.getTablePath(msdb.getDatabase(dbname), name), - Warehouse.makePartName(tbl.getPartitionKeys(), new_part.getValues())); - destPath = constructRenamedPartitionPath(destPath, new_part); - } catch (NoSuchObjectException e) { - LOG.debug(e); - throw new InvalidOperationException( + + Path tablePath = null; + // if it is an EXTERNAL_TABLE, the table's location is in StorageDescriptor + if (tbl.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) { + // rablePath is the parent of Partition path + tablePath = new Path(oldPart.getSd().getLocation()); + for (int i = 0; i < part_vals.size(); i++) { + tablePath = tablePath.getParent(); + } + } else { + // if it is NOT an EXTERNAL_TABLE, the table's location could be get from Warehouse + try { + tablePath = wh.getTablePath(msdb.getDatabase(dbname), name); + } catch (NoSuchObjectException e) { + LOG.debug(e); + throw new InvalidOperationException( "Unable to change partition or table. Database " + dbname + " does not exist" - + " Check metastore logs for detailed stack." + e.getMessage()); + + " Check metastore logs for detailed stack." + e.getMessage()); + } } + LOG.info("tbl TableType: " + tbl.getTableType()); + LOG.info("tablePath: " + tablePath); + destPath = new Path(tablePath, Warehouse.makePartName( + tbl.getPartitionKeys(), new_part.getValues())); + destPath = constructRenamedPartitionPath(destPath, new_part); if (destPath != null) { newPartLoc = destPath.toString(); oldPartLoc = oldPart.getSd().getLocation(); diff --git ql/src/test/queries/clientpositive/rename_external_partition_location.q ql/src/test/queries/clientpositive/rename_external_partition_location.q new file mode 100644 index 0000000..ff73e20 --- /dev/null +++ ql/src/test/queries/clientpositive/rename_external_partition_location.q @@ -0,0 +1,16 @@ + +dfs -mkdir ${system:test.tmp.dir}/ex_table; + +CREATE EXTERNAL TABLE ex_table ( key INT, value STRING) + PARTITIONED BY (part STRING) + STORED AS textfile + LOCATION 'file:${system:test.tmp.dir}/ex_table'; + +INSERT OVERWRITE TABLE ex_table PARTITION (part='part1') +SELECT key, value FROM src WHERE key < 10; + +dfs -cat ${system:test.tmp.dir}/ex_table/part=part1/000000_0; + +ALTER TABLE ex_table PARTITION (part='part1') RENAME TO PARTITION (part='part2'); + +dfs -cat ${system:test.tmp.dir}/ex_table/part=part2/000000_0; diff --git ql/src/test/results/clientpositive/rename_external_partition_location.q.out ql/src/test/results/clientpositive/rename_external_partition_location.q.out new file mode 100644 index 0000000..1d7b849 --- /dev/null +++ ql/src/test/results/clientpositive/rename_external_partition_location.q.out @@ -0,0 +1,55 @@ +PREHOOK: query: CREATE EXTERNAL TABLE ex_table ( key INT, value STRING) + PARTITIONED BY (part STRING) + STORED AS textfile +#### A masked pattern was here #### +PREHOOK: type: CREATETABLE +POSTHOOK: query: CREATE EXTERNAL TABLE ex_table ( key INT, value STRING) + PARTITIONED BY (part STRING) + STORED AS textfile +#### A masked pattern was here #### +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@ex_table +PREHOOK: query: INSERT OVERWRITE TABLE ex_table PARTITION (part='part1') +SELECT key, value FROM src WHERE key < 10 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: default@ex_table@part=part1 +POSTHOOK: query: INSERT OVERWRITE TABLE ex_table PARTITION (part='part1') +SELECT key, value FROM src WHERE key < 10 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: default@ex_table@part=part1 +POSTHOOK: Lineage: ex_table PARTITION(part=part1).key EXPRESSION [(src)src.FieldSchema(name:key, type:string, comment:default), ] +POSTHOOK: Lineage: ex_table PARTITION(part=part1).value SIMPLE [(src)src.FieldSchema(name:value, type:string, comment:default), ] +0val_0 +4val_4 +8val_8 +0val_0 +0val_0 +5val_5 +5val_5 +2val_2 +5val_5 +9val_9 +PREHOOK: query: ALTER TABLE ex_table PARTITION (part='part1') RENAME TO PARTITION (part='part2') +PREHOOK: type: ALTERTABLE_RENAMEPART +PREHOOK: Input: default@ex_table +PREHOOK: Output: default@ex_table@part=part1 +POSTHOOK: query: ALTER TABLE ex_table PARTITION (part='part1') RENAME TO PARTITION (part='part2') +POSTHOOK: type: ALTERTABLE_RENAMEPART +POSTHOOK: Input: default@ex_table +POSTHOOK: Input: default@ex_table@part=part1 +POSTHOOK: Output: default@ex_table@part=part1 +POSTHOOK: Output: default@ex_table@part=part2 +POSTHOOK: Lineage: ex_table PARTITION(part=part1).key EXPRESSION [(src)src.FieldSchema(name:key, type:string, comment:default), ] +POSTHOOK: Lineage: ex_table PARTITION(part=part1).value SIMPLE [(src)src.FieldSchema(name:value, type:string, comment:default), ] +0val_0 +4val_4 +8val_8 +0val_0 +0val_0 +5val_5 +5val_5 +2val_2 +5val_5 +9val_9