Hi,
I've encountered an issue which is closely related to HBASE-2406, HBASE-2847
and HBASE-2256.
Scenario (see also unit test in attachment, tested against HBase
0.89.0-r1004203-3076) :
- put values in 3 columns (A, B and C) of the same column family at
timestamp 0.
- delete all versions of column B (using Delete.deleteColumns() )
- read columns A and C
- result : for column A a result is given, for column C not (the
alphabetical order is in play here!)
Now, if we would use any other (positive) timestamp instead of 0 or let
HBase fill in the timestamp, this problem does not arrise.
For my use-case I can work with timestamp 1 instead of 0. But it is a bit
strange that timestamp 0 gives different behavior than timestamp 1, and that
the alphabetical order of the columns makes a difference.
I'm not sure if this should just be added as extra info to HBASE-2406 or
should be put in a new jira-issue.
Regards,
Evert Arckens.
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class DeleteColumnsTest {
private HBaseTestingUtility TEST_UTIL;
private static byte[] cf = Bytes.toBytes("CF");
private static HTableInterface hTable;
private static HBaseAdmin admin;
private static String tableName = "TestTable";
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
TEST_UTIL = new HBaseTestingUtility();
TEST_UTIL.startMiniCluster(1);
Configuration configuration = TEST_UTIL.getConfiguration();
admin = new HBaseAdmin(configuration);
HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
tableDescriptor.addFamily(new HColumnDescriptor(cf,
HConstants.ALL_VERSIONS, "none", false, true,
HConstants.FOREVER, HColumnDescriptor.DEFAULT_BLOOMFILTER));
admin.createTable(tableDescriptor);
hTable = new HTable(configuration, tableName);
}
@After
public void tearDown() throws Exception {
TEST_UTIL.shutdownMiniCluster();
}
@Test
public void testDelete() throws Exception {
byte[] row = Bytes.toBytes("row1");
Put put = new Put(row);
byte[] colA = Bytes.toBytes("A");
put.add(cf, colA, 0L, Bytes.toBytes("value1"));
byte[] colB = Bytes.toBytes("B");
put.add(cf, colB, 0L, Bytes.toBytes("value2"));
byte[] colC = Bytes.toBytes("C");
put.add(cf, colC, 0L, Bytes.toBytes("value3"));
hTable.put(put);
Get get = new Get(row);
get.addColumn(cf, colA);
get.addColumn(cf, colB);
get.addColumn(cf, colC);
Result result = hTable.get(get);
Assert.assertEquals("value1", Bytes.toString(result.getValue(cf, colA)));
Assert.assertEquals("value2", Bytes.toString(result.getValue(cf, colB)));
Assert.assertEquals("value3", Bytes.toString(result.getValue(cf, colC)));
Delete delete = new Delete(row, -1, null);
delete.deleteColumns(cf, colB);
hTable.delete(delete);
get = new Get(row);
get.addColumn(cf, colA);
get.addColumn(cf, colB);
get.addColumn(cf, colC);
result = hTable.get(get);
Assert.assertEquals("value1", Bytes.toString(result.getValue(cf, colA)));
Assert.assertNull(Bytes.toString(result.getValue(cf, colB)));
Assert.assertEquals("value3", Bytes.toString(result.getValue(cf, colC)));
}
}