diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/TableDeleteFamilyHandler.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/TableDeleteFamilyHandler.java index 285d36d..7428340 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/TableDeleteFamilyHandler.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/TableDeleteFamilyHandler.java @@ -27,6 +27,7 @@ import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.Server; import org.apache.hadoop.hbase.executor.EventType; +import org.apache.hadoop.hbase.InvalidFamilyOperationException; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.master.MasterCoprocessorHost; import org.apache.hadoop.hbase.master.MasterFileSystem; @@ -52,6 +53,11 @@ public class TableDeleteFamilyHandler extends TableEventHandler { super.prepareWithTableLock(); HTableDescriptor htd = getTableDescriptor(); this.familyName = hasColumnFamily(htd, familyName); + + if (htd.getColumnFamilies().length == 1) { + throw new InvalidFamilyOperationException("Family '" + Bytes.toString(familyName) + + "' is the only column family in the table, so it cannot be deleted"); + } } @Override diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java index 62fe4df..b7a3116 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java @@ -1111,10 +1111,10 @@ public class TestAdmin1 { @Test (timeout=300000) public void testEnableDisableAddColumnDeleteColumn() throws Exception { ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL); - TableName tableName = TableName.valueOf("testMasterAdmin"); + TableName tableName = TableName.valueOf("testEnableDisableAddColumnDeleteColumn"); TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close(); while (!ZKTableStateClientSideReader.isEnabledTable(zkw, - TableName.valueOf("testMasterAdmin"))) { + TableName.valueOf("testEnableDisableAddColumnDeleteColumn"))) { Thread.sleep(10); } this.admin.disableTable(tableName); @@ -1134,4 +1134,33 @@ public class TestAdmin1 { this.admin.disableTable(tableName); this.admin.deleteTable(tableName); } + + @Test (timeout=300000) + public void testDeleteLastColumnFamily() throws Exception { + TableName tableName = TableName.valueOf("testDeleteLastColumnFamily"); + TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close(); + while (!this.admin.isTableEnabled(TableName.valueOf("testDeleteLastColumnFamily"))) { + Thread.sleep(10); + } + + // test for enabled table + try { + this.admin.deleteColumn(tableName, HConstants.CATALOG_FAMILY); + fail("Should have failed to delete the only column family of a table"); + } catch (InvalidFamilyOperationException ex) { + // expected + } + + // test for disabled table + this.admin.disableTable(tableName); + + try { + this.admin.deleteColumn(tableName, HConstants.CATALOG_FAMILY); + fail("Should have failed to delete the only column family of a table"); + } catch (InvalidFamilyOperationException ex) { + // expected + } + + this.admin.deleteTable(tableName); + } }