001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import static org.apache.hadoop.hbase.HBaseTestingUtil.countRows; 021import static org.junit.Assert.assertArrayEquals; 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertNull; 024import static org.junit.Assert.assertSame; 025import static org.junit.Assert.assertTrue; 026import static org.junit.Assert.fail; 027 028import java.io.IOException; 029import java.util.ArrayList; 030import java.util.Arrays; 031import java.util.Collection; 032import java.util.Collections; 033import java.util.HashMap; 034import java.util.List; 035import java.util.Map; 036import org.apache.hadoop.conf.Configuration; 037import org.apache.hadoop.hbase.Cell; 038import org.apache.hadoop.hbase.CellUtil; 039import org.apache.hadoop.hbase.CompareOperator; 040import org.apache.hadoop.hbase.ExtendedCell; 041import org.apache.hadoop.hbase.HBaseClassTestRule; 042import org.apache.hadoop.hbase.HBaseTestingUtil; 043import org.apache.hadoop.hbase.HConstants; 044import org.apache.hadoop.hbase.HRegionLocation; 045import org.apache.hadoop.hbase.KeepDeletedCells; 046import org.apache.hadoop.hbase.PrivateCellUtil; 047import org.apache.hadoop.hbase.TableName; 048import org.apache.hadoop.hbase.TableNameTestRule; 049import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint; 050import org.apache.hadoop.hbase.filter.Filter; 051import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 052import org.apache.hadoop.hbase.filter.LongComparator; 053import org.apache.hadoop.hbase.filter.QualifierFilter; 054import org.apache.hadoop.hbase.filter.RegexStringComparator; 055import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 056import org.apache.hadoop.hbase.testclassification.ClientTests; 057import org.apache.hadoop.hbase.testclassification.LargeTests; 058import org.apache.hadoop.hbase.util.Bytes; 059import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 060import org.junit.AfterClass; 061import org.junit.ClassRule; 062import org.junit.Rule; 063import org.junit.Test; 064import org.junit.experimental.categories.Category; 065import org.junit.runner.RunWith; 066import org.junit.runners.Parameterized; 067import org.slf4j.Logger; 068import org.slf4j.LoggerFactory; 069 070/** 071 * Run tests that use the HBase clients; {@link Table}. Sets up the HBase mini cluster once at start 072 * and runs through all client tests. Each creates a table named for the method and does its stuff 073 * against that. Parameterized to run with different registry implementations. This class was split 074 * in three because it got too big when parameterized. Other classes are below. 075 * @see TestFromClientSide4 076 * @see TestFromClientSide5 077 */ 078// NOTE: Increment tests were moved to their own class, TestIncrementsFromClientSide. 079@Category({ LargeTests.class, ClientTests.class }) 080@SuppressWarnings("deprecation") 081@RunWith(Parameterized.class) 082public class TestFromClientSide extends FromClientSideBase { 083 private static final Logger LOG = LoggerFactory.getLogger(TestFromClientSide.class); 084 085 @ClassRule 086 public static final HBaseClassTestRule CLASS_RULE = 087 HBaseClassTestRule.forClass(TestFromClientSide.class); 088 @Rule 089 public TableNameTestRule name = new TableNameTestRule(); 090 091 // To keep the child classes happy. 092 TestFromClientSide() { 093 } 094 095 public TestFromClientSide(Class registry, int numHedgedReqs) throws Exception { 096 initialize(registry, numHedgedReqs, MultiRowMutationEndpoint.class); 097 } 098 099 @Parameterized.Parameters 100 public static Collection parameters() { 101 return Arrays.asList(new Object[][] { { MasterRegistry.class, 1 }, { MasterRegistry.class, 2 }, 102 { ZKConnectionRegistry.class, 1 } }); 103 } 104 105 @AfterClass 106 public static void tearDownAfterClass() throws Exception { 107 afterClass(); 108 } 109 110 /** 111 * Test append result when there are duplicate rpc request. 112 */ 113 @Test 114 public void testDuplicateAppend() throws Exception { 115 TableDescriptorBuilder builder = TEST_UTIL.createModifyableTableDescriptor(name.getTableName(), 116 ColumnFamilyDescriptorBuilder.DEFAULT_MIN_VERSIONS, 3, HConstants.FOREVER, 117 ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED); 118 Map<String, String> kvs = new HashMap<>(); 119 kvs.put(SleepAtFirstRpcCall.SLEEP_TIME_CONF_KEY, "2000"); 120 builder.setCoprocessor(CoprocessorDescriptorBuilder 121 .newBuilder(SleepAtFirstRpcCall.class.getName()).setPriority(1).setProperties(kvs).build()); 122 TEST_UTIL.createTable(builder.build(), new byte[][] { ROW }).close(); 123 124 Configuration c = new Configuration(TEST_UTIL.getConfiguration()); 125 c.setInt(HConstants.HBASE_CLIENT_PAUSE, 50); 126 // Client will retry because rpc timeout is small than the sleep time of first rpc call 127 c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500); 128 129 try (Connection connection = ConnectionFactory.createConnection(c); Table table = 130 connection.getTableBuilder(name.getTableName(), null).setOperationTimeout(3 * 1000).build()) { 131 Append append = new Append(ROW); 132 append.addColumn(HBaseTestingUtil.fam1, QUALIFIER, VALUE); 133 Result result = table.append(append); 134 135 // Verify expected result 136 Cell[] cells = result.rawCells(); 137 assertEquals(1, cells.length); 138 assertKey(cells[0], ROW, HBaseTestingUtil.fam1, QUALIFIER, VALUE); 139 140 // Verify expected result again 141 Result readResult = table.get(new Get(ROW)); 142 cells = readResult.rawCells(); 143 assertEquals(1, cells.length); 144 assertKey(cells[0], ROW, HBaseTestingUtil.fam1, QUALIFIER, VALUE); 145 } 146 } 147 148 /** 149 * Test batch append result when there are duplicate rpc request. 150 */ 151 @Test 152 public void testDuplicateBatchAppend() throws Exception { 153 TableDescriptorBuilder builder = TEST_UTIL.createModifyableTableDescriptor(name.getTableName(), 154 ColumnFamilyDescriptorBuilder.DEFAULT_MIN_VERSIONS, 3, HConstants.FOREVER, 155 ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED); 156 Map<String, String> kvs = new HashMap<>(); 157 kvs.put(SleepAtFirstRpcCall.SLEEP_TIME_CONF_KEY, "2000"); 158 builder.setCoprocessor(CoprocessorDescriptorBuilder 159 .newBuilder(SleepAtFirstRpcCall.class.getName()).setPriority(1).setProperties(kvs).build()); 160 TEST_UTIL.createTable(builder.build(), new byte[][] { ROW }).close(); 161 162 Configuration c = new Configuration(TEST_UTIL.getConfiguration()); 163 c.setInt(HConstants.HBASE_CLIENT_PAUSE, 50); 164 // Client will retry because rpc timeout is small than the sleep time of first rpc call 165 c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500); 166 167 try (Connection connection = ConnectionFactory.createConnection(c); Table table = 168 connection.getTableBuilder(name.getTableName(), null).setOperationTimeout(3 * 1000).build()) { 169 Append append = new Append(ROW); 170 append.addColumn(HBaseTestingUtil.fam1, QUALIFIER, VALUE); 171 172 // Batch append 173 Object[] results = new Object[1]; 174 table.batch(Collections.singletonList(append), results); 175 176 // Verify expected result 177 Cell[] cells = ((Result) results[0]).rawCells(); 178 assertEquals(1, cells.length); 179 assertKey(cells[0], ROW, HBaseTestingUtil.fam1, QUALIFIER, VALUE); 180 181 // Verify expected result again 182 Result readResult = table.get(new Get(ROW)); 183 cells = readResult.rawCells(); 184 assertEquals(1, cells.length); 185 assertKey(cells[0], ROW, HBaseTestingUtil.fam1, QUALIFIER, VALUE); 186 } 187 } 188 189 /** 190 * Basic client side validation of HBASE-4536 191 */ 192 @Test 193 public void testKeepDeletedCells() throws Exception { 194 final TableName tableName = name.getTableName(); 195 final byte[] FAMILY = Bytes.toBytes("family"); 196 final byte[] C0 = Bytes.toBytes("c0"); 197 198 final byte[] T1 = Bytes.toBytes("T1"); 199 final byte[] T2 = Bytes.toBytes("T2"); 200 final byte[] T3 = Bytes.toBytes("T3"); 201 202 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName) 203 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY) 204 .setKeepDeletedCells(KeepDeletedCells.TRUE).setMaxVersions(3).build()) 205 .build(); 206 TEST_UTIL.getAdmin().createTable(tableDescriptor); 207 try (Table h = TEST_UTIL.getConnection().getTable(tableName)) { 208 long ts = EnvironmentEdgeManager.currentTime(); 209 Put p = new Put(T1, ts); 210 p.addColumn(FAMILY, C0, T1); 211 h.put(p); 212 p = new Put(T1, ts + 2); 213 p.addColumn(FAMILY, C0, T2); 214 h.put(p); 215 p = new Put(T1, ts + 4); 216 p.addColumn(FAMILY, C0, T3); 217 h.put(p); 218 219 Delete d = new Delete(T1, ts + 3); 220 h.delete(d); 221 222 d = new Delete(T1, ts + 3); 223 d.addColumns(FAMILY, C0, ts + 3); 224 h.delete(d); 225 226 Get g = new Get(T1); 227 // does *not* include the delete 228 g.setTimeRange(0, ts + 3); 229 Result r = h.get(g); 230 assertArrayEquals(T2, r.getValue(FAMILY, C0)); 231 232 Scan s = new Scan().withStartRow(T1); 233 s.setTimeRange(0, ts + 3); 234 s.readAllVersions(); 235 ResultScanner scanner = h.getScanner(s); 236 ExtendedCell[] kvs = scanner.next().rawExtendedCells(); 237 assertArrayEquals(T2, CellUtil.cloneValue(kvs[0])); 238 assertArrayEquals(T1, CellUtil.cloneValue(kvs[1])); 239 scanner.close(); 240 241 s = new Scan().withStartRow(T1); 242 s.setRaw(true); 243 s.readAllVersions(); 244 scanner = h.getScanner(s); 245 kvs = scanner.next().rawExtendedCells(); 246 assertTrue(PrivateCellUtil.isDeleteFamily(kvs[0])); 247 assertArrayEquals(T3, CellUtil.cloneValue(kvs[1])); 248 assertTrue(CellUtil.isDelete(kvs[2])); 249 assertArrayEquals(T2, CellUtil.cloneValue(kvs[3])); 250 assertArrayEquals(T1, CellUtil.cloneValue(kvs[4])); 251 scanner.close(); 252 } 253 } 254 255 /** 256 * Basic client side validation of HBASE-10118 257 */ 258 @Test 259 public void testPurgeFutureDeletes() throws Exception { 260 final TableName tableName = name.getTableName(); 261 final byte[] ROW = Bytes.toBytes("row"); 262 final byte[] FAMILY = Bytes.toBytes("family"); 263 final byte[] COLUMN = Bytes.toBytes("column"); 264 final byte[] VALUE = Bytes.toBytes("value"); 265 266 try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) { 267 // future timestamp 268 long ts = EnvironmentEdgeManager.currentTime() * 2; 269 Put put = new Put(ROW, ts); 270 put.addColumn(FAMILY, COLUMN, VALUE); 271 table.put(put); 272 273 Get get = new Get(ROW); 274 Result result = table.get(get); 275 assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN)); 276 277 Delete del = new Delete(ROW); 278 del.addColumn(FAMILY, COLUMN, ts); 279 table.delete(del); 280 281 get = new Get(ROW); 282 result = table.get(get); 283 assertNull(result.getValue(FAMILY, COLUMN)); 284 285 // major compaction, purged future deletes 286 TEST_UTIL.getAdmin().flush(tableName); 287 TEST_UTIL.getAdmin().majorCompact(tableName); 288 289 // waiting for the major compaction to complete 290 TEST_UTIL.waitFor(6000, 291 () -> TEST_UTIL.getAdmin().getCompactionState(tableName) == CompactionState.NONE); 292 293 put = new Put(ROW, ts); 294 put.addColumn(FAMILY, COLUMN, VALUE); 295 table.put(put); 296 297 get = new Get(ROW); 298 result = table.get(get); 299 assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN)); 300 } 301 } 302 303 /** 304 * Verifies that getConfiguration returns the same Configuration object used to create the HTable 305 * instance. 306 */ 307 @Test 308 public void testGetConfiguration() throws Exception { 309 final TableName tableName = name.getTableName(); 310 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") }; 311 Configuration conf = TEST_UTIL.getConfiguration(); 312 try (Table table = TEST_UTIL.createTable(tableName, FAMILIES)) { 313 assertSame(conf, table.getConfiguration()); 314 } 315 } 316 317 /** 318 * Test from client side of an involved filter against a multi family that involves deletes. 319 */ 320 @Test 321 public void testWeirdCacheBehaviour() throws Exception { 322 final TableName tableName = name.getTableName(); 323 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("trans-blob"), Bytes.toBytes("trans-type"), 324 Bytes.toBytes("trans-date"), Bytes.toBytes("trans-tags"), Bytes.toBytes("trans-group") }; 325 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES)) { 326 String value = "this is the value"; 327 String value2 = "this is some other value"; 328 String keyPrefix1 = HBaseTestingUtil.getRandomUUID().toString(); 329 String keyPrefix2 = HBaseTestingUtil.getRandomUUID().toString(); 330 String keyPrefix3 = HBaseTestingUtil.getRandomUUID().toString(); 331 putRows(ht, 3, value, keyPrefix1); 332 putRows(ht, 3, value, keyPrefix2); 333 putRows(ht, 3, value, keyPrefix3); 334 putRows(ht, 3, value2, keyPrefix1); 335 putRows(ht, 3, value2, keyPrefix2); 336 putRows(ht, 3, value2, keyPrefix3); 337 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 338 System.out.println("Checking values for key: " + keyPrefix1); 339 assertEquals("Got back incorrect number of rows from scan", 3, 340 getNumberOfRows(keyPrefix1, value2, table)); 341 System.out.println("Checking values for key: " + keyPrefix2); 342 assertEquals("Got back incorrect number of rows from scan", 3, 343 getNumberOfRows(keyPrefix2, value2, table)); 344 System.out.println("Checking values for key: " + keyPrefix3); 345 assertEquals("Got back incorrect number of rows from scan", 3, 346 getNumberOfRows(keyPrefix3, value2, table)); 347 deleteColumns(ht, value2, keyPrefix1); 348 deleteColumns(ht, value2, keyPrefix2); 349 deleteColumns(ht, value2, keyPrefix3); 350 System.out.println("Starting important checks....."); 351 assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1, 0, 352 getNumberOfRows(keyPrefix1, value2, table)); 353 assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2, 0, 354 getNumberOfRows(keyPrefix2, value2, table)); 355 assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3, 0, 356 getNumberOfRows(keyPrefix3, value2, table)); 357 } 358 } 359 } 360 361 /** 362 * Test filters when multiple regions. It does counts. Needs eye-balling of logs to ensure that 363 * we're not scanning more regions that we're supposed to. Related to the TestFilterAcrossRegions 364 * over in the o.a.h.h.filter package. 365 */ 366 @Test 367 public void testFilterAcrossMultipleRegions() throws IOException { 368 final TableName tableName = name.getTableName(); 369 try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) { 370 int rowCount = TEST_UTIL.loadTable(t, FAMILY, false); 371 assertRowCount(t, rowCount); 372 // Split the table. Should split on a reasonable key; 'lqj' 373 List<HRegionLocation> regions = splitTable(t); 374 assertRowCount(t, rowCount); 375 // Get end key of first region. 376 byte[] endKey = regions.get(0).getRegion().getEndKey(); 377 // Count rows with a filter that stops us before passed 'endKey'. 378 // Should be count of rows in first region. 379 int endKeyCount = countRows(t, createScanWithRowFilter(endKey)); 380 assertTrue(endKeyCount < rowCount); 381 382 // How do I know I did not got to second region? Thats tough. Can't really 383 // do that in client-side region test. I verified by tracing in debugger. 384 // I changed the messages that come out when set to DEBUG so should see 385 // when scanner is done. Says "Finished with scanning..." with region name. 386 // Check that its finished in right region. 387 388 // New test. Make it so scan goes into next region by one and then two. 389 // Make sure count comes out right. 390 byte[] key = new byte[] { endKey[0], endKey[1], (byte) (endKey[2] + 1) }; 391 int plusOneCount = countRows(t, createScanWithRowFilter(key)); 392 assertEquals(endKeyCount + 1, plusOneCount); 393 key = new byte[] { endKey[0], endKey[1], (byte) (endKey[2] + 2) }; 394 int plusTwoCount = countRows(t, createScanWithRowFilter(key)); 395 assertEquals(endKeyCount + 2, plusTwoCount); 396 397 // New test. Make it so I scan one less than endkey. 398 key = new byte[] { endKey[0], endKey[1], (byte) (endKey[2] - 1) }; 399 int minusOneCount = countRows(t, createScanWithRowFilter(key)); 400 assertEquals(endKeyCount - 1, minusOneCount); 401 // For above test... study logs. Make sure we do "Finished with scanning.." 402 // in first region and that we do not fall into the next region. 403 404 key = new byte[] { 'a', 'a', 'a' }; 405 int countBBB = countRows(t, createScanWithRowFilter(key, null, CompareOperator.EQUAL)); 406 assertEquals(1, countBBB); 407 408 int countGreater = 409 countRows(t, createScanWithRowFilter(endKey, null, CompareOperator.GREATER_OR_EQUAL)); 410 // Because started at start of table. 411 assertEquals(0, countGreater); 412 countGreater = 413 countRows(t, createScanWithRowFilter(endKey, endKey, CompareOperator.GREATER_OR_EQUAL)); 414 assertEquals(rowCount - endKeyCount, countGreater); 415 } 416 } 417 418 @Test 419 public void testSuperSimple() throws Exception { 420 final TableName tableName = name.getTableName(); 421 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 422 Put put = new Put(ROW); 423 put.addColumn(FAMILY, QUALIFIER, VALUE); 424 ht.put(put); 425 Scan scan = new Scan(); 426 scan.addColumn(FAMILY, tableName.toBytes()); 427 ResultScanner scanner = ht.getScanner(scan); 428 Result result = scanner.next(); 429 assertNull("Expected null result", result); 430 scanner.close(); 431 } 432 } 433 434 @Test 435 public void testMaxKeyValueSize() throws Exception { 436 final TableName tableName = name.getTableName(); 437 Configuration conf = TEST_UTIL.getConfiguration(); 438 String oldMaxSize = conf.get(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY); 439 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 440 byte[] value = new byte[4 * 1024 * 1024]; 441 Put put = new Put(ROW); 442 put.addColumn(FAMILY, QUALIFIER, value); 443 ht.put(put); 444 445 try { 446 TEST_UTIL.getConfiguration().setInt(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, 447 2 * 1024 * 1024); 448 // Create new table so we pick up the change in Configuration. 449 try (Connection connection = 450 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) { 451 try (Table t = connection.getTable(TableName.valueOf(FAMILY))) { 452 put = new Put(ROW); 453 put.addColumn(FAMILY, QUALIFIER, value); 454 t.put(put); 455 } 456 } 457 fail("Inserting a too large KeyValue worked, should throw exception"); 458 } catch (Exception ignored) { 459 } 460 } 461 conf.set(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, oldMaxSize); 462 } 463 464 @Test 465 public void testFilters() throws Exception { 466 final TableName tableName = name.getTableName(); 467 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 468 byte[][] ROWS = makeN(ROW, 10); 469 byte[][] QUALIFIERS = 470 { Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"), 471 Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"), 472 Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"), 473 Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"), 474 Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>") }; 475 for (int i = 0; i < 10; i++) { 476 Put put = new Put(ROWS[i]); 477 put.setDurability(Durability.SKIP_WAL); 478 put.addColumn(FAMILY, QUALIFIERS[i], VALUE); 479 ht.put(put); 480 } 481 Scan scan = new Scan(); 482 scan.addFamily(FAMILY); 483 Filter filter = 484 new QualifierFilter(CompareOperator.EQUAL, new RegexStringComparator("col[1-5]")); 485 scan.setFilter(filter); 486 try (ResultScanner scanner = ht.getScanner(scan)) { 487 int expectedIndex = 1; 488 for (Result result : scanner) { 489 assertEquals(1, result.size()); 490 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[expectedIndex])); 491 assertTrue( 492 Bytes.equals(CellUtil.cloneQualifier(result.rawCells()[0]), QUALIFIERS[expectedIndex])); 493 expectedIndex++; 494 } 495 assertEquals(6, expectedIndex); 496 } 497 } 498 } 499 500 @Test 501 public void testFilterWithLongCompartor() throws Exception { 502 final TableName tableName = name.getTableName(); 503 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 504 byte[][] ROWS = makeN(ROW, 10); 505 byte[][] values = new byte[10][]; 506 for (int i = 0; i < 10; i++) { 507 values[i] = Bytes.toBytes(100L * i); 508 } 509 for (int i = 0; i < 10; i++) { 510 Put put = new Put(ROWS[i]); 511 put.setDurability(Durability.SKIP_WAL); 512 put.addColumn(FAMILY, QUALIFIER, values[i]); 513 ht.put(put); 514 } 515 Scan scan = new Scan(); 516 scan.addFamily(FAMILY); 517 Filter filter = new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.GREATER, 518 new LongComparator(500)); 519 scan.setFilter(filter); 520 try (ResultScanner scanner = ht.getScanner(scan)) { 521 int expectedIndex = 0; 522 for (Result result : scanner) { 523 assertEquals(1, result.size()); 524 assertTrue(Bytes.toLong(result.getValue(FAMILY, QUALIFIER)) > 500); 525 expectedIndex++; 526 } 527 assertEquals(4, expectedIndex); 528 } 529 } 530 } 531 532 @Test 533 public void testKeyOnlyFilter() throws Exception { 534 final TableName tableName = name.getTableName(); 535 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 536 byte[][] ROWS = makeN(ROW, 10); 537 byte[][] QUALIFIERS = 538 { Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"), 539 Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"), 540 Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"), 541 Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"), 542 Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>") }; 543 for (int i = 0; i < 10; i++) { 544 Put put = new Put(ROWS[i]); 545 put.setDurability(Durability.SKIP_WAL); 546 put.addColumn(FAMILY, QUALIFIERS[i], VALUE); 547 ht.put(put); 548 } 549 Scan scan = new Scan(); 550 scan.addFamily(FAMILY); 551 Filter filter = new KeyOnlyFilter(true); 552 scan.setFilter(filter); 553 try (ResultScanner scanner = ht.getScanner(scan)) { 554 int count = 0; 555 for (Result result : scanner) { 556 assertEquals(1, result.size()); 557 assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength()); 558 assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0]))); 559 count++; 560 } 561 assertEquals(10, count); 562 } 563 } 564 } 565 566 /** 567 * Test simple table and non-existent row cases. 568 */ 569 @Test 570 public void testSimpleMissing() throws Exception { 571 final TableName tableName = name.getTableName(); 572 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 573 byte[][] ROWS = makeN(ROW, 4); 574 575 // Try to get a row on an empty table 576 Get get = new Get(ROWS[0]); 577 Result result = ht.get(get); 578 assertEmptyResult(result); 579 580 get = new Get(ROWS[0]); 581 get.addFamily(FAMILY); 582 result = ht.get(get); 583 assertEmptyResult(result); 584 585 get = new Get(ROWS[0]); 586 get.addColumn(FAMILY, QUALIFIER); 587 result = ht.get(get); 588 assertEmptyResult(result); 589 590 Scan scan = new Scan(); 591 result = getSingleScanResult(ht, scan); 592 assertNullResult(result); 593 594 scan = new Scan().withStartRow(ROWS[0]); 595 result = getSingleScanResult(ht, scan); 596 assertNullResult(result); 597 598 scan = new Scan().withStartRow(ROWS[0]).withStopRow(ROWS[1]); 599 result = getSingleScanResult(ht, scan); 600 assertNullResult(result); 601 602 scan = new Scan(); 603 scan.addFamily(FAMILY); 604 result = getSingleScanResult(ht, scan); 605 assertNullResult(result); 606 607 scan = new Scan(); 608 scan.addColumn(FAMILY, QUALIFIER); 609 result = getSingleScanResult(ht, scan); 610 assertNullResult(result); 611 612 // Insert a row 613 614 Put put = new Put(ROWS[2]); 615 put.addColumn(FAMILY, QUALIFIER, VALUE); 616 ht.put(put); 617 618 // Try to get empty rows around it 619 620 get = new Get(ROWS[1]); 621 result = ht.get(get); 622 assertEmptyResult(result); 623 624 get = new Get(ROWS[0]); 625 get.addFamily(FAMILY); 626 result = ht.get(get); 627 assertEmptyResult(result); 628 629 get = new Get(ROWS[3]); 630 get.addColumn(FAMILY, QUALIFIER); 631 result = ht.get(get); 632 assertEmptyResult(result); 633 634 // Try to scan empty rows around it 635 636 scan = new Scan().withStartRow(ROWS[3]); 637 result = getSingleScanResult(ht, scan); 638 assertNullResult(result); 639 640 scan = new Scan().withStartRow(ROWS[0]).withStopRow(ROWS[2]); 641 result = getSingleScanResult(ht, scan); 642 assertNullResult(result); 643 644 // Make sure we can actually get the row 645 646 get = new Get(ROWS[2]); 647 result = ht.get(get); 648 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 649 650 get = new Get(ROWS[2]); 651 get.addFamily(FAMILY); 652 result = ht.get(get); 653 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 654 655 get = new Get(ROWS[2]); 656 get.addColumn(FAMILY, QUALIFIER); 657 result = ht.get(get); 658 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 659 660 // Make sure we can scan the row 661 662 scan = new Scan(); 663 result = getSingleScanResult(ht, scan); 664 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 665 666 scan = new Scan().withStartRow(ROWS[0]).withStopRow(ROWS[3]); 667 result = getSingleScanResult(ht, scan); 668 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 669 670 scan = new Scan().withStartRow(ROWS[2]).withStopRow(ROWS[3]); 671 result = getSingleScanResult(ht, scan); 672 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 673 } 674 } 675 676 /** 677 * Test basic puts, gets, scans, and deletes for a single row in a multiple family table. 678 */ 679 @SuppressWarnings("checkstyle:MethodLength") 680 @Test 681 public void testSingleRowMultipleFamily() throws Exception { 682 final TableName tableName = name.getTableName(); 683 byte[][] ROWS = makeN(ROW, 3); 684 byte[][] FAMILIES = makeNAscii(FAMILY, 10); 685 byte[][] QUALIFIERS = makeN(QUALIFIER, 10); 686 byte[][] VALUES = makeN(VALUE, 10); 687 688 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES)) { 689 //////////////////////////////////////////////////////////////////////////// 690 // Insert one column to one family 691 //////////////////////////////////////////////////////////////////////////// 692 693 Put put = new Put(ROWS[0]); 694 put.addColumn(FAMILIES[4], QUALIFIERS[0], VALUES[0]); 695 ht.put(put); 696 697 // Get the single column 698 getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 699 700 // Scan the single column 701 scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 702 703 // Get empty results around inserted column 704 getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 705 706 // Scan empty results around inserted column 707 scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 708 709 //////////////////////////////////////////////////////////////////////////// 710 // Flush memstore and run same tests from storefiles 711 //////////////////////////////////////////////////////////////////////////// 712 713 TEST_UTIL.flush(); 714 715 // Redo get and scan tests from storefile 716 getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 717 scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 718 getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 719 scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 720 721 //////////////////////////////////////////////////////////////////////////// 722 // Now, Test reading from memstore and storefiles at once 723 //////////////////////////////////////////////////////////////////////////// 724 725 // Insert multiple columns to two other families 726 put = new Put(ROWS[0]); 727 put.addColumn(FAMILIES[2], QUALIFIERS[2], VALUES[2]); 728 put.addColumn(FAMILIES[2], QUALIFIERS[4], VALUES[4]); 729 put.addColumn(FAMILIES[4], QUALIFIERS[4], VALUES[4]); 730 put.addColumn(FAMILIES[6], QUALIFIERS[6], VALUES[6]); 731 put.addColumn(FAMILIES[6], QUALIFIERS[7], VALUES[7]); 732 put.addColumn(FAMILIES[7], QUALIFIERS[7], VALUES[7]); 733 put.addColumn(FAMILIES[9], QUALIFIERS[0], VALUES[0]); 734 ht.put(put); 735 736 // Get multiple columns across multiple families and get empties around it 737 singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 738 739 // Scan multiple columns across multiple families and scan empties around it 740 singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 741 742 //////////////////////////////////////////////////////////////////////////// 743 // Flush the table again 744 //////////////////////////////////////////////////////////////////////////// 745 746 TEST_UTIL.flush(); 747 748 // Redo tests again 749 singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 750 singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 751 752 // Insert more data to memstore 753 put = new Put(ROWS[0]); 754 put.addColumn(FAMILIES[6], QUALIFIERS[5], VALUES[5]); 755 put.addColumn(FAMILIES[6], QUALIFIERS[8], VALUES[8]); 756 put.addColumn(FAMILIES[6], QUALIFIERS[9], VALUES[9]); 757 put.addColumn(FAMILIES[4], QUALIFIERS[3], VALUES[3]); 758 ht.put(put); 759 760 //////////////////////////////////////////////////////////////////////////// 761 // Delete a storefile column 762 //////////////////////////////////////////////////////////////////////////// 763 Delete delete = new Delete(ROWS[0]); 764 delete.addColumns(FAMILIES[6], QUALIFIERS[7]); 765 ht.delete(delete); 766 767 // Try to get deleted column 768 Get get = new Get(ROWS[0]); 769 get.addColumn(FAMILIES[6], QUALIFIERS[7]); 770 Result result = ht.get(get); 771 assertEmptyResult(result); 772 773 // Try to scan deleted column 774 Scan scan = new Scan(); 775 scan.addColumn(FAMILIES[6], QUALIFIERS[7]); 776 result = getSingleScanResult(ht, scan); 777 assertNullResult(result); 778 779 // Make sure we can still get a column before it and after it 780 get = new Get(ROWS[0]); 781 get.addColumn(FAMILIES[6], QUALIFIERS[6]); 782 result = ht.get(get); 783 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 784 785 get = new Get(ROWS[0]); 786 get.addColumn(FAMILIES[6], QUALIFIERS[8]); 787 result = ht.get(get); 788 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]); 789 790 // Make sure we can still scan a column before it and after it 791 scan = new Scan(); 792 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 793 result = getSingleScanResult(ht, scan); 794 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 795 796 scan = new Scan(); 797 scan.addColumn(FAMILIES[6], QUALIFIERS[8]); 798 result = getSingleScanResult(ht, scan); 799 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]); 800 801 //////////////////////////////////////////////////////////////////////////// 802 // Delete a memstore column 803 //////////////////////////////////////////////////////////////////////////// 804 delete = new Delete(ROWS[0]); 805 delete.addColumns(FAMILIES[6], QUALIFIERS[8]); 806 ht.delete(delete); 807 808 // Try to get deleted column 809 get = new Get(ROWS[0]); 810 get.addColumn(FAMILIES[6], QUALIFIERS[8]); 811 result = ht.get(get); 812 assertEmptyResult(result); 813 814 // Try to scan deleted column 815 scan = new Scan(); 816 scan.addColumn(FAMILIES[6], QUALIFIERS[8]); 817 result = getSingleScanResult(ht, scan); 818 assertNullResult(result); 819 820 // Make sure we can still get a column before it and after it 821 get = new Get(ROWS[0]); 822 get.addColumn(FAMILIES[6], QUALIFIERS[6]); 823 result = ht.get(get); 824 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 825 826 get = new Get(ROWS[0]); 827 get.addColumn(FAMILIES[6], QUALIFIERS[9]); 828 result = ht.get(get); 829 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 830 831 // Make sure we can still scan a column before it and after it 832 scan = new Scan(); 833 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 834 result = getSingleScanResult(ht, scan); 835 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 836 837 scan = new Scan(); 838 scan.addColumn(FAMILIES[6], QUALIFIERS[9]); 839 result = getSingleScanResult(ht, scan); 840 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 841 842 //////////////////////////////////////////////////////////////////////////// 843 // Delete joint storefile/memstore family 844 //////////////////////////////////////////////////////////////////////////// 845 846 delete = new Delete(ROWS[0]); 847 delete.addFamily(FAMILIES[4]); 848 ht.delete(delete); 849 850 // Try to get storefile column in deleted family 851 get = new Get(ROWS[0]); 852 get.addColumn(FAMILIES[4], QUALIFIERS[4]); 853 result = ht.get(get); 854 assertEmptyResult(result); 855 856 // Try to get memstore column in deleted family 857 get = new Get(ROWS[0]); 858 get.addColumn(FAMILIES[4], QUALIFIERS[3]); 859 result = ht.get(get); 860 assertEmptyResult(result); 861 862 // Try to get deleted family 863 get = new Get(ROWS[0]); 864 get.addFamily(FAMILIES[4]); 865 result = ht.get(get); 866 assertEmptyResult(result); 867 868 // Try to scan storefile column in deleted family 869 scan = new Scan(); 870 scan.addColumn(FAMILIES[4], QUALIFIERS[4]); 871 result = getSingleScanResult(ht, scan); 872 assertNullResult(result); 873 874 // Try to scan memstore column in deleted family 875 scan = new Scan(); 876 scan.addColumn(FAMILIES[4], QUALIFIERS[3]); 877 result = getSingleScanResult(ht, scan); 878 assertNullResult(result); 879 880 // Try to scan deleted family 881 scan = new Scan(); 882 scan.addFamily(FAMILIES[4]); 883 result = getSingleScanResult(ht, scan); 884 assertNullResult(result); 885 886 // Make sure we can still get another family 887 get = new Get(ROWS[0]); 888 get.addColumn(FAMILIES[2], QUALIFIERS[2]); 889 result = ht.get(get); 890 assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]); 891 892 get = new Get(ROWS[0]); 893 get.addColumn(FAMILIES[6], QUALIFIERS[9]); 894 result = ht.get(get); 895 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 896 897 // Make sure we can still scan another family 898 scan = new Scan(); 899 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 900 result = getSingleScanResult(ht, scan); 901 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 902 903 scan = new Scan(); 904 scan.addColumn(FAMILIES[6], QUALIFIERS[9]); 905 result = getSingleScanResult(ht, scan); 906 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 907 908 //////////////////////////////////////////////////////////////////////////// 909 // Flush everything and rerun delete tests 910 //////////////////////////////////////////////////////////////////////////// 911 912 TEST_UTIL.flush(); 913 914 // Try to get storefile column in deleted family 915 assertEmptyResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[4], QUALIFIERS[4]))); 916 917 // Try to get memstore column in deleted family 918 assertEmptyResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[4], QUALIFIERS[3]))); 919 920 // Try to get deleted family 921 assertEmptyResult(ht.get(new Get(ROWS[0]).addFamily(FAMILIES[4]))); 922 923 // Try to scan storefile column in deleted family 924 assertNullResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[4], QUALIFIERS[4]))); 925 926 // Try to scan memstore column in deleted family 927 assertNullResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[4], QUALIFIERS[3]))); 928 929 // Try to scan deleted family 930 assertNullResult(getSingleScanResult(ht, new Scan().addFamily(FAMILIES[4]))); 931 932 // Make sure we can still get another family 933 assertSingleResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[2], QUALIFIERS[2])), ROWS[0], 934 FAMILIES[2], QUALIFIERS[2], VALUES[2]); 935 936 assertSingleResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[6], QUALIFIERS[9])), ROWS[0], 937 FAMILIES[6], QUALIFIERS[9], VALUES[9]); 938 939 // Make sure we can still scan another family 940 assertSingleResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[6], QUALIFIERS[6])), 941 ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 942 943 assertSingleResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[6], QUALIFIERS[9])), 944 ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 945 } 946 } 947 948 @Test(expected = NullPointerException.class) 949 public void testNullTableName() throws IOException { 950 // Null table name (should NOT work) 951 TEST_UTIL.createTable(null, FAMILY); 952 fail("Creating a table with null name passed, should have failed"); 953 } 954 955 @Test(expected = IllegalArgumentException.class) 956 public void testNullFamilyName() throws IOException { 957 final TableName tableName = name.getTableName(); 958 959 // Null family (should NOT work) 960 TEST_UTIL.createTable(tableName, new byte[][] { null }); 961 fail("Creating a table with a null family passed, should fail"); 962 } 963 964 @Test 965 public void testNullRowAndQualifier() throws Exception { 966 final TableName tableName = name.getTableName(); 967 968 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 969 970 // Null row (should NOT work) 971 try { 972 Put put = new Put((byte[]) null); 973 put.addColumn(FAMILY, QUALIFIER, VALUE); 974 ht.put(put); 975 fail("Inserting a null row worked, should throw exception"); 976 } catch (Exception ignored) { 977 } 978 979 // Null qualifier (should work) 980 { 981 Put put = new Put(ROW); 982 put.addColumn(FAMILY, null, VALUE); 983 ht.put(put); 984 985 getTestNull(ht, ROW, FAMILY, VALUE); 986 987 scanTestNull(ht, ROW, FAMILY, VALUE); 988 989 Delete delete = new Delete(ROW); 990 delete.addColumns(FAMILY, null); 991 ht.delete(delete); 992 993 Get get = new Get(ROW); 994 Result result = ht.get(get); 995 assertEmptyResult(result); 996 } 997 } 998 } 999 1000 @Test 1001 public void testNullEmptyQualifier() throws Exception { 1002 final TableName tableName = name.getTableName(); 1003 1004 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 1005 1006 // Empty qualifier, byte[0] instead of null (should work) 1007 try { 1008 Put put = new Put(ROW); 1009 put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE); 1010 ht.put(put); 1011 1012 getTestNull(ht, ROW, FAMILY, VALUE); 1013 1014 scanTestNull(ht, ROW, FAMILY, VALUE); 1015 1016 // Flush and try again 1017 1018 TEST_UTIL.flush(); 1019 1020 getTestNull(ht, ROW, FAMILY, VALUE); 1021 1022 scanTestNull(ht, ROW, FAMILY, VALUE); 1023 1024 Delete delete = new Delete(ROW); 1025 delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY); 1026 ht.delete(delete); 1027 1028 Get get = new Get(ROW); 1029 Result result = ht.get(get); 1030 assertEmptyResult(result); 1031 1032 } catch (Exception e) { 1033 throw new IOException("Using a row with null qualifier should not throw exception"); 1034 } 1035 } 1036 } 1037 1038 @Test 1039 public void testNullValue() throws IOException { 1040 final TableName tableName = name.getTableName(); 1041 1042 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 1043 // Null value 1044 try { 1045 Put put = new Put(ROW); 1046 put.addColumn(FAMILY, QUALIFIER, null); 1047 ht.put(put); 1048 1049 Get get = new Get(ROW); 1050 get.addColumn(FAMILY, QUALIFIER); 1051 Result result = ht.get(get); 1052 assertSingleResult(result, ROW, FAMILY, QUALIFIER, null); 1053 1054 Scan scan = new Scan(); 1055 scan.addColumn(FAMILY, QUALIFIER); 1056 result = getSingleScanResult(ht, scan); 1057 assertSingleResult(result, ROW, FAMILY, QUALIFIER, null); 1058 1059 Delete delete = new Delete(ROW); 1060 delete.addColumns(FAMILY, QUALIFIER); 1061 ht.delete(delete); 1062 1063 get = new Get(ROW); 1064 result = ht.get(get); 1065 assertEmptyResult(result); 1066 1067 } catch (Exception e) { 1068 throw new IOException("Null values should be allowed, but threw exception"); 1069 } 1070 } 1071 } 1072 1073 @Test 1074 public void testNullQualifier() throws Exception { 1075 final TableName tableName = name.getTableName(); 1076 try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) { 1077 1078 // Work for Put 1079 Put put = new Put(ROW); 1080 put.addColumn(FAMILY, null, VALUE); 1081 table.put(put); 1082 1083 // Work for Get, Scan 1084 getTestNull(table, ROW, FAMILY, VALUE); 1085 scanTestNull(table, ROW, FAMILY, VALUE); 1086 1087 // Work for Delete 1088 Delete delete = new Delete(ROW); 1089 delete.addColumns(FAMILY, null); 1090 table.delete(delete); 1091 1092 Get get = new Get(ROW); 1093 Result result = table.get(get); 1094 assertEmptyResult(result); 1095 1096 // Work for Increment/Append 1097 Increment increment = new Increment(ROW); 1098 increment.addColumn(FAMILY, null, 1L); 1099 table.increment(increment); 1100 getTestNull(table, ROW, FAMILY, 1L); 1101 1102 table.incrementColumnValue(ROW, FAMILY, null, 1L); 1103 getTestNull(table, ROW, FAMILY, 2L); 1104 1105 delete = new Delete(ROW); 1106 delete.addColumns(FAMILY, null); 1107 table.delete(delete); 1108 1109 Append append = new Append(ROW); 1110 append.addColumn(FAMILY, null, VALUE); 1111 table.append(append); 1112 getTestNull(table, ROW, FAMILY, VALUE); 1113 1114 // Work for checkAndMutate using thenPut, thenMutate and thenDelete 1115 put = new Put(ROW); 1116 put.addColumn(FAMILY, null, Bytes.toBytes("checkAndPut")); 1117 table.put(put); 1118 table.checkAndMutate(ROW, FAMILY).ifEquals(VALUE).thenPut(put); 1119 1120 RowMutations mutate = new RowMutations(ROW); 1121 mutate.add(new Put(ROW).addColumn(FAMILY, null, Bytes.toBytes("checkAndMutate"))); 1122 table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndPut")).thenMutate(mutate); 1123 1124 delete = new Delete(ROW); 1125 delete.addColumns(FAMILY, null); 1126 table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndMutate")) 1127 .thenDelete(delete); 1128 } 1129 } 1130 1131 @Test 1132 @SuppressWarnings("checkstyle:MethodLength") 1133 public void testVersions() throws Exception { 1134 final TableName tableName = name.getTableName(); 1135 1136 long[] STAMPS = makeStamps(20); 1137 byte[][] VALUES = makeNAscii(VALUE, 20); 1138 1139 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 1140 1141 // Insert 4 versions of same column 1142 Put put = new Put(ROW); 1143 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1144 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1145 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1146 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1147 ht.put(put); 1148 1149 // Verify we can get each one properly 1150 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1151 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1152 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1153 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1154 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1155 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1156 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1157 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1158 1159 // Verify we don't accidentally get others 1160 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1161 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1162 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1163 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1164 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1165 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1166 1167 // Ensure maxVersions in query is respected 1168 Get get = new Get(ROW); 1169 get.addColumn(FAMILY, QUALIFIER); 1170 get.readVersions(2); 1171 Result result = ht.get(get); 1172 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1173 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1174 1175 Scan scan = new Scan().withStartRow(ROW); 1176 scan.addColumn(FAMILY, QUALIFIER); 1177 scan.readVersions(2); 1178 result = getSingleScanResult(ht, scan); 1179 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1180 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1181 1182 // Flush and redo 1183 1184 TEST_UTIL.flush(); 1185 1186 // Verify we can get each one properly 1187 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1188 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1189 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1190 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1191 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1192 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1193 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1194 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1195 1196 // Verify we don't accidentally get others 1197 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1198 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1199 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1200 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1201 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1202 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1203 1204 // Ensure maxVersions in query is respected 1205 get = new Get(ROW); 1206 get.addColumn(FAMILY, QUALIFIER); 1207 get.readVersions(2); 1208 result = ht.get(get); 1209 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1210 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1211 1212 scan = new Scan().withStartRow(ROW); 1213 scan.addColumn(FAMILY, QUALIFIER); 1214 scan.readVersions(2); 1215 result = getSingleScanResult(ht, scan); 1216 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1217 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1218 1219 // Add some memstore and retest 1220 1221 // Insert 4 more versions of same column and a dupe 1222 put = new Put(ROW); 1223 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 1224 put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 1225 put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1226 put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]); 1227 ht.put(put); 1228 1229 // Ensure maxVersions in query is respected 1230 get = new Get(ROW); 1231 get.addColumn(FAMILY, QUALIFIER); 1232 get.readAllVersions(); 1233 result = ht.get(get); 1234 assertNResult(result, ROW, FAMILY, QUALIFIER, 1235 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1236 STAMPS[8] }, 1237 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1238 VALUES[8] }, 1239 0, 7); 1240 1241 scan = new Scan().withStartRow(ROW); 1242 scan.addColumn(FAMILY, QUALIFIER); 1243 scan.readAllVersions(); 1244 result = getSingleScanResult(ht, scan); 1245 assertNResult(result, ROW, FAMILY, QUALIFIER, 1246 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1247 STAMPS[8] }, 1248 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1249 VALUES[8] }, 1250 0, 7); 1251 1252 get = new Get(ROW); 1253 get.readAllVersions(); 1254 result = ht.get(get); 1255 assertNResult(result, ROW, FAMILY, QUALIFIER, 1256 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1257 STAMPS[8] }, 1258 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1259 VALUES[8] }, 1260 0, 7); 1261 1262 scan = new Scan().withStartRow(ROW); 1263 scan.readAllVersions(); 1264 result = getSingleScanResult(ht, scan); 1265 assertNResult(result, ROW, FAMILY, QUALIFIER, 1266 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1267 STAMPS[8] }, 1268 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1269 VALUES[8] }, 1270 0, 7); 1271 1272 // Verify we can get each one properly 1273 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1274 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1275 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1276 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1277 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1278 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1279 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1280 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1281 1282 // Verify we don't accidentally get others 1283 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1284 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 1285 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1286 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 1287 1288 // Ensure maxVersions of table is respected 1289 1290 TEST_UTIL.flush(); 1291 1292 // Insert 4 more versions of same column and a dupe 1293 put = new Put(ROW); 1294 put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]); 1295 put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]); 1296 put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]); 1297 put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]); 1298 ht.put(put); 1299 1300 get = new Get(ROW); 1301 get.addColumn(FAMILY, QUALIFIER); 1302 get.readVersions(Integer.MAX_VALUE); 1303 result = ht.get(get); 1304 assertNResult(result, ROW, FAMILY, QUALIFIER, 1305 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 1306 STAMPS[11], STAMPS[13], STAMPS[15] }, 1307 new byte[][] { VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 1308 VALUES[11], VALUES[13], VALUES[15] }, 1309 0, 9); 1310 1311 scan = new Scan().withStartRow(ROW); 1312 scan.addColumn(FAMILY, QUALIFIER); 1313 scan.readVersions(Integer.MAX_VALUE); 1314 result = getSingleScanResult(ht, scan); 1315 assertNResult(result, ROW, FAMILY, QUALIFIER, 1316 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 1317 STAMPS[11], STAMPS[13], STAMPS[15] }, 1318 new byte[][] { VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 1319 VALUES[11], VALUES[13], VALUES[15] }, 1320 0, 9); 1321 1322 // Delete a version in the memstore and a version in a storefile 1323 Delete delete = new Delete(ROW); 1324 delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]); 1325 delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]); 1326 ht.delete(delete); 1327 1328 // Test that it's gone 1329 get = new Get(ROW); 1330 get.addColumn(FAMILY, QUALIFIER); 1331 get.readVersions(Integer.MAX_VALUE); 1332 result = ht.get(get); 1333 assertNResult(result, ROW, FAMILY, QUALIFIER, 1334 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 1335 STAMPS[9], STAMPS[13], STAMPS[15] }, 1336 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], 1337 VALUES[9], VALUES[13], VALUES[15] }, 1338 0, 9); 1339 1340 scan = new Scan().withStartRow(ROW); 1341 scan.addColumn(FAMILY, QUALIFIER); 1342 scan.readVersions(Integer.MAX_VALUE); 1343 result = getSingleScanResult(ht, scan); 1344 assertNResult(result, ROW, FAMILY, QUALIFIER, 1345 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 1346 STAMPS[9], STAMPS[13], STAMPS[15] }, 1347 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], 1348 VALUES[9], VALUES[13], VALUES[15] }, 1349 0, 9); 1350 } 1351 } 1352 1353 @Test 1354 @SuppressWarnings("checkstyle:MethodLength") 1355 public void testVersionLimits() throws Exception { 1356 final TableName tableName = name.getTableName(); 1357 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1358 int[] LIMITS = { 1, 3, 5 }; 1359 long[] STAMPS = makeStamps(10); 1360 byte[][] VALUES = makeNAscii(VALUE, 10); 1361 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, LIMITS)) { 1362 1363 // Insert limit + 1 on each family 1364 Put put = new Put(ROW); 1365 put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[0], VALUES[0]); 1366 put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[1], VALUES[1]); 1367 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[0], VALUES[0]); 1368 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[1], VALUES[1]); 1369 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[2], VALUES[2]); 1370 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[3], VALUES[3]); 1371 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[0], VALUES[0]); 1372 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[1], VALUES[1]); 1373 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[2], VALUES[2]); 1374 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[3], VALUES[3]); 1375 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[4], VALUES[4]); 1376 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[5], VALUES[5]); 1377 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[6], VALUES[6]); 1378 ht.put(put); 1379 1380 // Verify we only get the right number out of each 1381 1382 // Family0 1383 1384 Get get = new Get(ROW); 1385 get.addColumn(FAMILIES[0], QUALIFIER); 1386 get.readVersions(Integer.MAX_VALUE); 1387 Result result = ht.get(get); 1388 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1389 new byte[][] { VALUES[1] }, 0, 0); 1390 1391 get = new Get(ROW); 1392 get.addFamily(FAMILIES[0]); 1393 get.readVersions(Integer.MAX_VALUE); 1394 result = ht.get(get); 1395 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1396 new byte[][] { VALUES[1] }, 0, 0); 1397 1398 Scan scan = new Scan().withStartRow(ROW); 1399 scan.addColumn(FAMILIES[0], QUALIFIER); 1400 scan.readVersions(Integer.MAX_VALUE); 1401 result = getSingleScanResult(ht, scan); 1402 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1403 new byte[][] { VALUES[1] }, 0, 0); 1404 1405 scan = new Scan().withStartRow(ROW); 1406 scan.addFamily(FAMILIES[0]); 1407 scan.readVersions(Integer.MAX_VALUE); 1408 result = getSingleScanResult(ht, scan); 1409 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1410 new byte[][] { VALUES[1] }, 0, 0); 1411 1412 // Family1 1413 1414 get = new Get(ROW); 1415 get.addColumn(FAMILIES[1], QUALIFIER); 1416 get.readVersions(Integer.MAX_VALUE); 1417 result = ht.get(get); 1418 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1419 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1420 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1421 1422 get = new Get(ROW); 1423 get.addFamily(FAMILIES[1]); 1424 get.readVersions(Integer.MAX_VALUE); 1425 result = ht.get(get); 1426 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1427 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1428 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1429 1430 scan = new Scan().withStartRow(ROW); 1431 scan.addColumn(FAMILIES[1], QUALIFIER); 1432 scan.readVersions(Integer.MAX_VALUE); 1433 result = getSingleScanResult(ht, scan); 1434 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1435 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1436 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1437 1438 scan = new Scan().withStartRow(ROW); 1439 scan.addFamily(FAMILIES[1]); 1440 scan.readVersions(Integer.MAX_VALUE); 1441 result = getSingleScanResult(ht, scan); 1442 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1443 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1444 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1445 1446 // Family2 1447 1448 get = new Get(ROW); 1449 get.addColumn(FAMILIES[2], QUALIFIER); 1450 get.readVersions(Integer.MAX_VALUE); 1451 result = ht.get(get); 1452 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1453 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1454 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1455 1456 get = new Get(ROW); 1457 get.addFamily(FAMILIES[2]); 1458 get.readVersions(Integer.MAX_VALUE); 1459 result = ht.get(get); 1460 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1461 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1462 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1463 1464 scan = new Scan().withStartRow(ROW); 1465 scan.addColumn(FAMILIES[2], QUALIFIER); 1466 scan.readVersions(Integer.MAX_VALUE); 1467 result = getSingleScanResult(ht, scan); 1468 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1469 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1470 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1471 1472 scan = new Scan().withStartRow(ROW); 1473 scan.addFamily(FAMILIES[2]); 1474 scan.readVersions(Integer.MAX_VALUE); 1475 result = getSingleScanResult(ht, scan); 1476 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1477 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1478 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1479 1480 // Try all families 1481 1482 get = new Get(ROW); 1483 get.readVersions(Integer.MAX_VALUE); 1484 result = ht.get(get); 1485 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1486 1487 get = new Get(ROW); 1488 get.addFamily(FAMILIES[0]); 1489 get.addFamily(FAMILIES[1]); 1490 get.addFamily(FAMILIES[2]); 1491 get.readVersions(Integer.MAX_VALUE); 1492 result = ht.get(get); 1493 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1494 1495 get = new Get(ROW); 1496 get.addColumn(FAMILIES[0], QUALIFIER); 1497 get.addColumn(FAMILIES[1], QUALIFIER); 1498 get.addColumn(FAMILIES[2], QUALIFIER); 1499 get.readVersions(Integer.MAX_VALUE); 1500 result = ht.get(get); 1501 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1502 1503 scan = new Scan().withStartRow(ROW); 1504 scan.readVersions(Integer.MAX_VALUE); 1505 result = getSingleScanResult(ht, scan); 1506 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1507 1508 scan = new Scan().withStartRow(ROW); 1509 scan.readVersions(Integer.MAX_VALUE); 1510 scan.addFamily(FAMILIES[0]); 1511 scan.addFamily(FAMILIES[1]); 1512 scan.addFamily(FAMILIES[2]); 1513 result = getSingleScanResult(ht, scan); 1514 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1515 1516 scan = new Scan().withStartRow(ROW); 1517 scan.readVersions(Integer.MAX_VALUE); 1518 scan.addColumn(FAMILIES[0], QUALIFIER); 1519 scan.addColumn(FAMILIES[1], QUALIFIER); 1520 scan.addColumn(FAMILIES[2], QUALIFIER); 1521 result = getSingleScanResult(ht, scan); 1522 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1523 } 1524 } 1525 1526 @Test 1527 public void testDeleteFamilyVersion() throws Exception { 1528 try (Admin admin = TEST_UTIL.getAdmin()) { 1529 final TableName tableName = name.getTableName(); 1530 1531 byte[][] QUALIFIERS = makeNAscii(QUALIFIER, 1); 1532 byte[][] VALUES = makeN(VALUE, 5); 1533 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1534 1535 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) { 1536 1537 Put put = new Put(ROW); 1538 for (int q = 0; q < 1; q++) { 1539 for (int t = 0; t < 5; t++) { 1540 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1541 } 1542 } 1543 ht.put(put); 1544 admin.flush(tableName); 1545 1546 Delete delete = new Delete(ROW); 1547 delete.addFamilyVersion(FAMILY, ts[1]); // delete version '2000' 1548 delete.addFamilyVersion(FAMILY, ts[3]); // delete version '4000' 1549 ht.delete(delete); 1550 admin.flush(tableName); 1551 1552 for (int i = 0; i < 1; i++) { 1553 Get get = new Get(ROW); 1554 get.addColumn(FAMILY, QUALIFIERS[i]); 1555 get.readVersions(Integer.MAX_VALUE); 1556 Result result = ht.get(get); 1557 // verify version '1000'/'3000'/'5000' remains for all columns 1558 assertNResult(result, ROW, FAMILY, QUALIFIERS[i], new long[] { ts[0], ts[2], ts[4] }, 1559 new byte[][] { VALUES[0], VALUES[2], VALUES[4] }, 0, 2); 1560 } 1561 } 1562 } 1563 } 1564 1565 @Test 1566 public void testDeleteFamilyVersionWithOtherDeletes() throws Exception { 1567 final TableName tableName = name.getTableName(); 1568 1569 byte[][] QUALIFIERS = makeNAscii(QUALIFIER, 5); 1570 byte[][] VALUES = makeN(VALUE, 5); 1571 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1572 1573 try (Admin admin = TEST_UTIL.getAdmin(); 1574 Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) { 1575 Put put; 1576 Result result; 1577 Get get; 1578 Delete delete = null; 1579 1580 // 1. put on ROW 1581 put = new Put(ROW); 1582 for (int q = 0; q < 5; q++) { 1583 for (int t = 0; t < 5; t++) { 1584 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1585 } 1586 } 1587 ht.put(put); 1588 admin.flush(tableName); 1589 1590 // 2. put on ROWS[0] 1591 byte[] ROW2 = Bytes.toBytes("myRowForTest"); 1592 put = new Put(ROW2); 1593 for (int q = 0; q < 5; q++) { 1594 for (int t = 0; t < 5; t++) { 1595 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1596 } 1597 } 1598 ht.put(put); 1599 admin.flush(tableName); 1600 1601 // 3. delete on ROW 1602 delete = new Delete(ROW); 1603 // delete version <= 2000 of all columns 1604 // note: addFamily must be the first since it will mask 1605 // the subsequent other type deletes! 1606 delete.addFamily(FAMILY, ts[1]); 1607 // delete version '4000' of all columns 1608 delete.addFamilyVersion(FAMILY, ts[3]); 1609 // delete version <= 3000 of column 0 1610 delete.addColumns(FAMILY, QUALIFIERS[0], ts[2]); 1611 // delete version <= 5000 of column 2 1612 delete.addColumns(FAMILY, QUALIFIERS[2], ts[4]); 1613 // delete version 5000 of column 4 1614 delete.addColumn(FAMILY, QUALIFIERS[4], ts[4]); 1615 ht.delete(delete); 1616 admin.flush(tableName); 1617 1618 // 4. delete on ROWS[0] 1619 delete = new Delete(ROW2); 1620 delete.addFamilyVersion(FAMILY, ts[1]); // delete version '2000' 1621 delete.addFamilyVersion(FAMILY, ts[3]); // delete version '4000' 1622 ht.delete(delete); 1623 admin.flush(tableName); 1624 1625 // 5. check ROW 1626 get = new Get(ROW); 1627 get.addColumn(FAMILY, QUALIFIERS[0]); 1628 get.readVersions(Integer.MAX_VALUE); 1629 result = ht.get(get); 1630 assertNResult(result, ROW, FAMILY, QUALIFIERS[0], new long[] { ts[4] }, 1631 new byte[][] { VALUES[4] }, 0, 0); 1632 1633 get = new Get(ROW); 1634 get.addColumn(FAMILY, QUALIFIERS[1]); 1635 get.readVersions(Integer.MAX_VALUE); 1636 result = ht.get(get); 1637 assertNResult(result, ROW, FAMILY, QUALIFIERS[1], new long[] { ts[2], ts[4] }, 1638 new byte[][] { VALUES[2], VALUES[4] }, 0, 1); 1639 1640 get = new Get(ROW); 1641 get.addColumn(FAMILY, QUALIFIERS[2]); 1642 get.readVersions(Integer.MAX_VALUE); 1643 result = ht.get(get); 1644 assertEquals(0, result.size()); 1645 1646 get = new Get(ROW); 1647 get.addColumn(FAMILY, QUALIFIERS[3]); 1648 get.readVersions(Integer.MAX_VALUE); 1649 result = ht.get(get); 1650 assertNResult(result, ROW, FAMILY, QUALIFIERS[3], new long[] { ts[2], ts[4] }, 1651 new byte[][] { VALUES[2], VALUES[4] }, 0, 1); 1652 1653 get = new Get(ROW); 1654 get.addColumn(FAMILY, QUALIFIERS[4]); 1655 get.readVersions(Integer.MAX_VALUE); 1656 result = ht.get(get); 1657 assertNResult(result, ROW, FAMILY, QUALIFIERS[4], new long[] { ts[2] }, 1658 new byte[][] { VALUES[2] }, 0, 0); 1659 1660 // 6. check ROWS[0] 1661 for (int i = 0; i < 5; i++) { 1662 get = new Get(ROW2); 1663 get.addColumn(FAMILY, QUALIFIERS[i]); 1664 get.readVersions(Integer.MAX_VALUE); 1665 result = ht.get(get); 1666 // verify version '1000'/'3000'/'5000' remains for all columns 1667 assertNResult(result, ROW2, FAMILY, QUALIFIERS[i], new long[] { ts[0], ts[2], ts[4] }, 1668 new byte[][] { VALUES[0], VALUES[2], VALUES[4] }, 0, 2); 1669 } 1670 } 1671 } 1672 1673 @Test 1674 public void testDeleteWithFailed() throws Exception { 1675 final TableName tableName = name.getTableName(); 1676 1677 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1678 byte[][] VALUES = makeN(VALUE, 5); 1679 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1680 1681 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) { 1682 Put put = new Put(ROW); 1683 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); 1684 ht.put(put); 1685 1686 // delete wrong family 1687 Delete delete = new Delete(ROW); 1688 delete.addFamily(FAMILIES[1], ts[0]); 1689 ht.delete(delete); 1690 1691 Get get = new Get(ROW); 1692 get.addFamily(FAMILIES[0]); 1693 get.readAllVersions(); 1694 Result result = ht.get(get); 1695 assertTrue(Bytes.equals(result.getValue(FAMILIES[0], QUALIFIER), VALUES[0])); 1696 } 1697 } 1698 1699 @Test 1700 @SuppressWarnings("checkstyle:MethodLength") 1701 public void testDeletes() throws Exception { 1702 final TableName tableName = name.getTableName(); 1703 1704 byte[][] ROWS = makeNAscii(ROW, 6); 1705 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1706 byte[][] VALUES = makeN(VALUE, 5); 1707 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1708 1709 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) { 1710 1711 Put put = new Put(ROW); 1712 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); 1713 put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]); 1714 ht.put(put); 1715 1716 Delete delete = new Delete(ROW); 1717 delete.addFamily(FAMILIES[0], ts[0]); 1718 ht.delete(delete); 1719 1720 Get get = new Get(ROW); 1721 get.addFamily(FAMILIES[0]); 1722 get.readVersions(Integer.MAX_VALUE); 1723 Result result = ht.get(get); 1724 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1] }, 1725 new byte[][] { VALUES[1] }, 0, 0); 1726 1727 Scan scan = new Scan().withStartRow(ROW); 1728 scan.addFamily(FAMILIES[0]); 1729 scan.readVersions(Integer.MAX_VALUE); 1730 result = getSingleScanResult(ht, scan); 1731 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1] }, 1732 new byte[][] { VALUES[1] }, 0, 0); 1733 1734 // Test delete latest version 1735 put = new Put(ROW); 1736 put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); 1737 put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]); 1738 put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]); 1739 put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]); 1740 put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]); 1741 put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]); 1742 ht.put(put); 1743 1744 delete = new Delete(ROW); 1745 delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4] 1746 ht.delete(delete); 1747 1748 get = new Get(ROW); 1749 get.addColumn(FAMILIES[0], QUALIFIER); 1750 get.readVersions(Integer.MAX_VALUE); 1751 result = ht.get(get); 1752 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1753 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1754 1755 scan = new Scan().withStartRow(ROW); 1756 scan.addColumn(FAMILIES[0], QUALIFIER); 1757 scan.readVersions(Integer.MAX_VALUE); 1758 result = getSingleScanResult(ht, scan); 1759 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1760 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1761 1762 // Test for HBASE-1847 1763 delete = new Delete(ROW); 1764 delete.addColumn(FAMILIES[0], null); 1765 ht.delete(delete); 1766 1767 // Cleanup null qualifier 1768 delete = new Delete(ROW); 1769 delete.addColumns(FAMILIES[0], null); 1770 ht.delete(delete); 1771 1772 // Expected client behavior might be that you can re-put deleted values 1773 // But alas, this is not to be. We can't put them back in either case. 1774 1775 put = new Put(ROW); 1776 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); // 1000 1777 put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); // 5000 1778 ht.put(put); 1779 1780 // It used to be due to the internal implementation of Get, that 1781 // the Get() call would return ts[4] UNLIKE the Scan below. With 1782 // the switch to using Scan for Get this is no longer the case. 1783 get = new Get(ROW); 1784 get.addFamily(FAMILIES[0]); 1785 get.readVersions(Integer.MAX_VALUE); 1786 result = ht.get(get); 1787 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1788 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1789 1790 // The Scanner returns the previous values, the expected-naive-unexpected behavior 1791 1792 scan = new Scan().withStartRow(ROW); 1793 scan.addFamily(FAMILIES[0]); 1794 scan.readVersions(Integer.MAX_VALUE); 1795 result = getSingleScanResult(ht, scan); 1796 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1797 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1798 1799 // Test deleting an entire family from one row but not the other various ways 1800 1801 put = new Put(ROWS[0]); 1802 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1803 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1804 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1805 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1806 ht.put(put); 1807 1808 put = new Put(ROWS[1]); 1809 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1810 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1811 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1812 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1813 ht.put(put); 1814 1815 put = new Put(ROWS[2]); 1816 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1817 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1818 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1819 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1820 ht.put(put); 1821 1822 // Assert that above went in. 1823 get = new Get(ROWS[2]); 1824 get.addFamily(FAMILIES[1]); 1825 get.addFamily(FAMILIES[2]); 1826 get.readVersions(Integer.MAX_VALUE); 1827 result = ht.get(get); 1828 assertEquals("Expected 4 key but received " + result.size() + ": " + result, 4, 1829 result.size()); 1830 1831 delete = new Delete(ROWS[0]); 1832 delete.addFamily(FAMILIES[2]); 1833 ht.delete(delete); 1834 1835 delete = new Delete(ROWS[1]); 1836 delete.addColumns(FAMILIES[1], QUALIFIER); 1837 ht.delete(delete); 1838 1839 delete = new Delete(ROWS[2]); 1840 delete.addColumn(FAMILIES[1], QUALIFIER); 1841 delete.addColumn(FAMILIES[1], QUALIFIER); 1842 delete.addColumn(FAMILIES[2], QUALIFIER); 1843 ht.delete(delete); 1844 1845 get = new Get(ROWS[0]); 1846 get.addFamily(FAMILIES[1]); 1847 get.addFamily(FAMILIES[2]); 1848 get.readVersions(Integer.MAX_VALUE); 1849 result = ht.get(get); 1850 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1851 assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[] { ts[0], ts[1] }, 1852 new byte[][] { VALUES[0], VALUES[1] }, 0, 1); 1853 1854 scan = new Scan().withStartRow(ROWS[0]); 1855 scan.addFamily(FAMILIES[1]); 1856 scan.addFamily(FAMILIES[2]); 1857 scan.readVersions(Integer.MAX_VALUE); 1858 result = getSingleScanResult(ht, scan); 1859 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1860 assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[] { ts[0], ts[1] }, 1861 new byte[][] { VALUES[0], VALUES[1] }, 0, 1); 1862 1863 get = new Get(ROWS[1]); 1864 get.addFamily(FAMILIES[1]); 1865 get.addFamily(FAMILIES[2]); 1866 get.readVersions(Integer.MAX_VALUE); 1867 result = ht.get(get); 1868 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1869 1870 scan = new Scan().withStartRow(ROWS[1]); 1871 scan.addFamily(FAMILIES[1]); 1872 scan.addFamily(FAMILIES[2]); 1873 scan.readVersions(Integer.MAX_VALUE); 1874 result = getSingleScanResult(ht, scan); 1875 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1876 1877 get = new Get(ROWS[2]); 1878 get.addFamily(FAMILIES[1]); 1879 get.addFamily(FAMILIES[2]); 1880 get.readVersions(Integer.MAX_VALUE); 1881 result = ht.get(get); 1882 assertEquals(1, result.size()); 1883 assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER, new long[] { ts[2] }, 1884 new byte[][] { VALUES[2] }, 0, 0); 1885 1886 scan = new Scan().withStartRow(ROWS[2]); 1887 scan.addFamily(FAMILIES[1]); 1888 scan.addFamily(FAMILIES[2]); 1889 scan.readVersions(Integer.MAX_VALUE); 1890 result = getSingleScanResult(ht, scan); 1891 assertEquals(1, result.size()); 1892 assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER, new long[] { ts[2] }, 1893 new byte[][] { VALUES[2] }, 0, 0); 1894 1895 // Test if we delete the family first in one row (HBASE-1541) 1896 1897 delete = new Delete(ROWS[3]); 1898 delete.addFamily(FAMILIES[1]); 1899 ht.delete(delete); 1900 1901 put = new Put(ROWS[3]); 1902 put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]); 1903 ht.put(put); 1904 1905 put = new Put(ROWS[4]); 1906 put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]); 1907 put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]); 1908 ht.put(put); 1909 1910 get = new Get(ROWS[3]); 1911 get.addFamily(FAMILIES[1]); 1912 get.addFamily(FAMILIES[2]); 1913 get.readVersions(Integer.MAX_VALUE); 1914 result = ht.get(get); 1915 assertEquals("Expected 1 key but received " + result.size(), 1, result.size()); 1916 1917 get = new Get(ROWS[4]); 1918 get.addFamily(FAMILIES[1]); 1919 get.addFamily(FAMILIES[2]); 1920 get.readVersions(Integer.MAX_VALUE); 1921 result = ht.get(get); 1922 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1923 1924 scan = new Scan().withStartRow(ROWS[3]); 1925 scan.addFamily(FAMILIES[1]); 1926 scan.addFamily(FAMILIES[2]); 1927 scan.readVersions(Integer.MAX_VALUE); 1928 ResultScanner scanner = ht.getScanner(scan); 1929 result = scanner.next(); 1930 assertEquals("Expected 1 key but received " + result.size(), 1, result.size()); 1931 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3])); 1932 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0])); 1933 result = scanner.next(); 1934 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1935 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4])); 1936 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4])); 1937 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1])); 1938 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2])); 1939 scanner.close(); 1940 1941 // Add test of bulk deleting. 1942 for (int i = 0; i < 10; i++) { 1943 byte[] bytes = Bytes.toBytes(i); 1944 put = new Put(bytes); 1945 put.setDurability(Durability.SKIP_WAL); 1946 put.addColumn(FAMILIES[0], QUALIFIER, bytes); 1947 ht.put(put); 1948 } 1949 for (int i = 0; i < 10; i++) { 1950 byte[] bytes = Bytes.toBytes(i); 1951 get = new Get(bytes); 1952 get.addFamily(FAMILIES[0]); 1953 result = ht.get(get); 1954 assertEquals(1, result.size()); 1955 } 1956 ArrayList<Delete> deletes = new ArrayList<>(); 1957 for (int i = 0; i < 10; i++) { 1958 byte[] bytes = Bytes.toBytes(i); 1959 delete = new Delete(bytes); 1960 delete.addFamily(FAMILIES[0]); 1961 deletes.add(delete); 1962 } 1963 ht.delete(deletes); 1964 for (int i = 0; i < 10; i++) { 1965 byte[] bytes = Bytes.toBytes(i); 1966 get = new Get(bytes); 1967 get.addFamily(FAMILIES[0]); 1968 result = ht.get(get); 1969 assertTrue(result.isEmpty()); 1970 } 1971 } 1972 } 1973}