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