diff --git a/hcatalog/webhcat/java-client/src/main/java/org/apache/hive/hcatalog/api/HCatClientHMSImpl.java b/hcatalog/webhcat/java-client/src/main/java/org/apache/hive/hcatalog/api/HCatClientHMSImpl.java index 64375bc..2299fac 100644 --- a/hcatalog/webhcat/java-client/src/main/java/org/apache/hive/hcatalog/api/HCatClientHMSImpl.java +++ b/hcatalog/webhcat/java-client/src/main/java/org/apache/hive/hcatalog/api/HCatClientHMSImpl.java @@ -24,10 +24,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import com.google.common.base.Function; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.common.ObjectPair; @@ -603,11 +606,11 @@ private void dropPartitionsIteratively(String dbName, String tableName, public void dropPartitions(String dbName, String tableName, Map partitionSpec, boolean ifExists, boolean deleteData) throws HCatException { - LOG.info("HCatClient dropPartitions(db=" + dbName + ",table=" + tableName + ", partitionSpec: ["+ partitionSpec + "])."); + LOG.info("HCatClient dropPartitions(db=" + dbName + ",table=" + tableName + ", partitionSpec: [" + partitionSpec + "])."); try { dbName = checkDB(dbName); Table table = hmsClient.getTable(dbName, tableName); - + checkValidPartitionKeys(table, partitionSpec); if (hiveConfig.getBoolVar(HiveConf.ConfVars.METASTORE_CLIENT_DROP_PARTITIONS_WITH_EXPRESSIONS)) { try { dropPartitionsUsingExpressions(table, partitionSpec, ifExists, deleteData); @@ -635,6 +638,36 @@ public void dropPartitions(String dbName, String tableName, } } + private static Set getPartKeyNames(Table table) { + return Sets.newHashSet( + Iterables.transform(table.getPartitionKeys(), new Function() { + @Override + public String apply(FieldSchema partKeySchema) { + return partKeySchema.getName().toLowerCase(); + } + }) + ); + } + + private static void checkValidPartitionKeys(Table table, Map partSpec) + throws IllegalArgumentException { + Set partKeyNames = getPartKeyNames(table); + Set specifiedPartKeys = Sets.newHashSet( + Iterables.transform(partSpec.keySet(), new Function() { + @Override + public String apply(String input) { + return input.toLowerCase(); + } + }) + ); + + if (!partKeyNames.containsAll(specifiedPartKeys)) { + throw new IllegalArgumentException( + "Bad partitionSpec " + partSpec + " specified for " + table.getDbName() + "." + table.getTableName() + + ". Could not find part-key(s): " + Sets.difference(specifiedPartKeys, partKeyNames)); + } + } + @Override public void dropPartitions(String dbName, String tableName, Map partitionSpec, boolean ifExists) throws HCatException { diff --git a/hcatalog/webhcat/java-client/src/test/java/org/apache/hive/hcatalog/api/TestHCatClient.java b/hcatalog/webhcat/java-client/src/test/java/org/apache/hive/hcatalog/api/TestHCatClient.java index eb21a0f..c3a5b5c 100644 --- a/hcatalog/webhcat/java-client/src/test/java/org/apache/hive/hcatalog/api/TestHCatClient.java +++ b/hcatalog/webhcat/java-client/src/test/java/org/apache/hive/hcatalog/api/TestHCatClient.java @@ -804,6 +804,53 @@ public void testDropPartitionsWithPartialSpec() throws Exception { assertTrue("Unexpected exception! " + unexpected.getMessage(), false); } } + @Test + public void testDropPartitionsWithBadPartitionSpec() throws Exception { + try { + HCatClient client = HCatClient.create(new Configuration(hcatConf)); + final String dbName = "myDb"; + final String tableName = "myTable"; + + client.dropDatabase(dbName, true, HCatClient.DropDBMode.CASCADE); + + client.createDatabase(HCatCreateDBDesc.create(dbName).build()); + List columnSchema = Arrays.asList(new HCatFieldSchema("foo", Type.INT, ""), + new HCatFieldSchema("bar", Type.STRING, "")); + + List partitionSchema = Arrays.asList(new HCatFieldSchema("dt", Type.STRING, ""), + new HCatFieldSchema("grid", Type.STRING, "")); + + HCatTable table = new HCatTable(dbName, tableName).cols(columnSchema).partCols(partitionSchema); + client.createTable(HCatCreateTableDesc.create(table, false).build()); + + // Verify that the table was created successfully. + table = client.getTable(dbName, tableName); + assertNotNull("Table couldn't be queried for. ", table); + + Map partitionSpec = new HashMap(); + partitionSpec.put("grid", "AB"); + partitionSpec.put("dt", "2011_12_31"); + client.addPartition(HCatAddPartitionDesc.create(new HCatPartition(table, partitionSpec, "")).build()); + + Map badPartitionSpec = new HashMap(); + badPartitionSpec.put("non_partition_key", "2012_01_01"); + + try { + client.dropPartitions(dbName, tableName, badPartitionSpec, true); + fail("Dropping partitions using a non-partition-key should cause an IllegalArgumentException."); + } + catch (IllegalArgumentException ignore) { + LOG.info("Received exception as expected: " + ignore); + } + + // Clean-up. + client.dropDatabase(dbName, false, HCatClient.DropDBMode.CASCADE); + } + catch (Exception unexpected) { + LOG.error("Unexpected exception!", unexpected); + assertTrue("Unexpected exception! " + unexpected.getMessage(), false); + } + } private void startReplicationTargetMetaStoreIfRequired() throws Exception { if (!isReplicationTargetHCatRunning) {