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.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertNull; 023import static org.junit.Assert.assertSame; 024import static org.junit.Assert.assertTrue; 025import static org.junit.Assert.fail; 026 027import java.io.IOException; 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.Collections; 032import java.util.HashMap; 033import java.util.List; 034import java.util.Map; 035import org.apache.hadoop.conf.Configuration; 036import org.apache.hadoop.hbase.Cell; 037import org.apache.hadoop.hbase.CellUtil; 038import org.apache.hadoop.hbase.CompareOperator; 039import org.apache.hadoop.hbase.HBaseClassTestRule; 040import org.apache.hadoop.hbase.HBaseTestingUtility; 041import org.apache.hadoop.hbase.HColumnDescriptor; 042import org.apache.hadoop.hbase.HConstants; 043import org.apache.hadoop.hbase.HRegionLocation; 044import org.apache.hadoop.hbase.HTableDescriptor; 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 HTableDescriptor hdt = TEST_UTIL.createTableDescriptor(name.getTableName()); 116 Map<String, String> kvs = new HashMap<>(); 117 kvs.put(HConnectionTestingUtility.SleepAtFirstRpcCall.SLEEP_TIME_CONF_KEY, "2000"); 118 hdt.addCoprocessor(HConnectionTestingUtility.SleepAtFirstRpcCall.class.getName(), null, 1, kvs); 119 TEST_UTIL.createTable(hdt, new byte[][] { ROW }).close(); 120 121 Configuration c = new Configuration(TEST_UTIL.getConfiguration()); 122 c.setInt(HConstants.HBASE_CLIENT_PAUSE, 50); 123 // Client will retry because rpc timeout is small than the sleep time of first rpc call 124 c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500); 125 126 try (Connection connection = ConnectionFactory.createConnection(c)) { 127 try (Table t = connection.getTable(name.getTableName())) { 128 if (t instanceof HTable) { 129 HTable table = (HTable) t; 130 table.setOperationTimeout(3 * 1000); 131 132 Append append = new Append(ROW); 133 append.addColumn(HBaseTestingUtility.fam1, QUALIFIER, VALUE); 134 Result result = table.append(append); 135 136 // Verify expected result 137 Cell[] cells = result.rawCells(); 138 assertEquals(1, cells.length); 139 assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE); 140 141 // Verify expected result again 142 Result readResult = table.get(new Get(ROW)); 143 cells = readResult.rawCells(); 144 assertEquals(1, cells.length); 145 assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE); 146 } 147 } 148 } 149 } 150 151 /** 152 * Test batch append result when there are duplicate rpc request. 153 */ 154 @Test 155 public void testDuplicateBatchAppend() throws Exception { 156 HTableDescriptor hdt = TEST_UTIL.createTableDescriptor(name.getTableName()); 157 Map<String, String> kvs = new HashMap<>(); 158 kvs.put(HConnectionTestingUtility.SleepAtFirstRpcCall.SLEEP_TIME_CONF_KEY, "2000"); 159 hdt.addCoprocessor(HConnectionTestingUtility.SleepAtFirstRpcCall.class.getName(), null, 1, kvs); 160 TEST_UTIL.createTable(hdt, 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(HBaseTestingUtility.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, HBaseTestingUtility.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, HBaseTestingUtility.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 HColumnDescriptor hcd = 202 new HColumnDescriptor(FAMILY).setKeepDeletedCells(KeepDeletedCells.TRUE).setMaxVersions(3); 203 204 HTableDescriptor desc = new HTableDescriptor(tableName); 205 desc.addFamily(hcd); 206 TEST_UTIL.getAdmin().createTable(desc); 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(T1); 233 s.setTimeRange(0, ts + 3); 234 s.setMaxVersions(); 235 try (ResultScanner scanner = h.getScanner(s)) { 236 Cell[] kvs = scanner.next().rawCells(); 237 assertArrayEquals(T2, CellUtil.cloneValue(kvs[0])); 238 assertArrayEquals(T1, CellUtil.cloneValue(kvs[1])); 239 } 240 241 s = new Scan(T1); 242 s.setRaw(true); 243 s.setMaxVersions(); 244 try (ResultScanner scanner = h.getScanner(s)) { 245 Cell[] kvs = scanner.next().rawCells(); 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 } 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 = HBaseTestingUtility.getRandomUUID().toString(); 329 String keyPrefix2 = HBaseTestingUtility.getRandomUUID().toString(); 330 String keyPrefix3 = HBaseTestingUtility.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).getRegionInfo().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 = TEST_UTIL.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 = TEST_UTIL.countRows(t, createScanWithRowFilter(key)); 392 assertEquals(endKeyCount + 1, plusOneCount); 393 key = new byte[] { endKey[0], endKey[1], (byte) (endKey[2] + 2) }; 394 int plusTwoCount = TEST_UTIL.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 = TEST_UTIL.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 = 406 TEST_UTIL.countRows(t, createScanWithRowFilter(key, null, CompareOperator.EQUAL)); 407 assertEquals(1, countBBB); 408 409 int countGreater = TEST_UTIL.countRows(t, 410 createScanWithRowFilter(endKey, null, CompareOperator.GREATER_OR_EQUAL)); 411 // Because started at start of table. 412 assertEquals(0, countGreater); 413 countGreater = TEST_UTIL.countRows(t, 414 createScanWithRowFilter(endKey, endKey, CompareOperator.GREATER_OR_EQUAL)); 415 assertEquals(rowCount - endKeyCount, countGreater); 416 } 417 } 418 419 @Test 420 public void testSuperSimple() throws Exception { 421 final TableName tableName = name.getTableName(); 422 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 423 Put put = new Put(ROW); 424 put.addColumn(FAMILY, QUALIFIER, VALUE); 425 ht.put(put); 426 Scan scan = new Scan(); 427 scan.addColumn(FAMILY, tableName.toBytes()); 428 try (ResultScanner scanner = ht.getScanner(scan)) { 429 Result result = scanner.next(); 430 assertNull("Expected null result", result); 431 } 432 } 433 } 434 435 @Test 436 public void testMaxKeyValueSize() throws Exception { 437 final TableName tableName = name.getTableName(); 438 Configuration conf = TEST_UTIL.getConfiguration(); 439 String oldMaxSize = conf.get(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY); 440 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 441 byte[] value = new byte[4 * 1024 * 1024]; 442 Put put = new Put(ROW); 443 put.addColumn(FAMILY, QUALIFIER, value); 444 ht.put(put); 445 446 try { 447 TEST_UTIL.getConfiguration().setInt(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, 448 2 * 1024 * 1024); 449 // Create new table so we pick up the change in Configuration. 450 try (Connection connection = 451 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) { 452 try (Table t = connection.getTable(TableName.valueOf(FAMILY))) { 453 put = new Put(ROW); 454 put.addColumn(FAMILY, QUALIFIER, value); 455 t.put(put); 456 } 457 } 458 fail("Inserting a too large KeyValue worked, should throw exception"); 459 } catch (Exception ignored) { 460 } 461 } 462 conf.set(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, oldMaxSize); 463 } 464 465 @Test 466 public void testFilters() throws Exception { 467 final TableName tableName = name.getTableName(); 468 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 469 byte[][] ROWS = makeN(ROW, 10); 470 byte[][] QUALIFIERS = 471 { Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"), 472 Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"), 473 Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"), 474 Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"), 475 Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>") }; 476 for (int i = 0; i < 10; i++) { 477 Put put = new Put(ROWS[i]); 478 put.setDurability(Durability.SKIP_WAL); 479 put.addColumn(FAMILY, QUALIFIERS[i], VALUE); 480 ht.put(put); 481 } 482 Scan scan = new Scan(); 483 scan.addFamily(FAMILY); 484 Filter filter = 485 new QualifierFilter(CompareOperator.EQUAL, new RegexStringComparator("col[1-5]")); 486 scan.setFilter(filter); 487 try (ResultScanner scanner = ht.getScanner(scan)) { 488 int expectedIndex = 1; 489 for (Result result : scanner) { 490 assertEquals(1, result.size()); 491 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[expectedIndex])); 492 assertTrue( 493 Bytes.equals(CellUtil.cloneQualifier(result.rawCells()[0]), QUALIFIERS[expectedIndex])); 494 expectedIndex++; 495 } 496 assertEquals(6, expectedIndex); 497 } 498 } 499 } 500 501 @Test 502 public void testFilterWithLongCompartor() throws Exception { 503 final TableName tableName = name.getTableName(); 504 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 505 byte[][] ROWS = makeN(ROW, 10); 506 byte[][] values = new byte[10][]; 507 for (int i = 0; i < 10; i++) { 508 values[i] = Bytes.toBytes(100L * i); 509 } 510 for (int i = 0; i < 10; i++) { 511 Put put = new Put(ROWS[i]); 512 put.setDurability(Durability.SKIP_WAL); 513 put.addColumn(FAMILY, QUALIFIER, values[i]); 514 ht.put(put); 515 } 516 Scan scan = new Scan(); 517 scan.addFamily(FAMILY); 518 Filter filter = new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.GREATER, 519 new LongComparator(500)); 520 scan.setFilter(filter); 521 try (ResultScanner scanner = ht.getScanner(scan)) { 522 int expectedIndex = 0; 523 for (Result result : scanner) { 524 assertEquals(1, result.size()); 525 assertTrue(Bytes.toLong(result.getValue(FAMILY, QUALIFIER)) > 500); 526 expectedIndex++; 527 } 528 assertEquals(4, expectedIndex); 529 } 530 } 531 } 532 533 @Test 534 public void testKeyOnlyFilter() throws Exception { 535 final TableName tableName = name.getTableName(); 536 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 537 byte[][] ROWS = makeN(ROW, 10); 538 byte[][] QUALIFIERS = 539 { Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"), 540 Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"), 541 Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"), 542 Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"), 543 Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>") }; 544 for (int i = 0; i < 10; i++) { 545 Put put = new Put(ROWS[i]); 546 put.setDurability(Durability.SKIP_WAL); 547 put.addColumn(FAMILY, QUALIFIERS[i], VALUE); 548 ht.put(put); 549 } 550 Scan scan = new Scan(); 551 scan.addFamily(FAMILY); 552 Filter filter = new KeyOnlyFilter(true); 553 scan.setFilter(filter); 554 try (ResultScanner scanner = ht.getScanner(scan)) { 555 int count = 0; 556 for (Result result : scanner) { 557 assertEquals(1, result.size()); 558 assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength()); 559 assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0]))); 560 count++; 561 } 562 assertEquals(10, count); 563 } 564 } 565 } 566 567 /** 568 * Test simple table and non-existent row cases. 569 */ 570 @Test 571 public void testSimpleMissing() throws Exception { 572 final TableName tableName = name.getTableName(); 573 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 574 byte[][] ROWS = makeN(ROW, 4); 575 576 // Try to get a row on an empty table 577 Get get = new Get(ROWS[0]); 578 Result result = ht.get(get); 579 assertEmptyResult(result); 580 581 get = new Get(ROWS[0]); 582 get.addFamily(FAMILY); 583 result = ht.get(get); 584 assertEmptyResult(result); 585 586 get = new Get(ROWS[0]); 587 get.addColumn(FAMILY, QUALIFIER); 588 result = ht.get(get); 589 assertEmptyResult(result); 590 591 Scan scan = new Scan(); 592 result = getSingleScanResult(ht, scan); 593 assertNullResult(result); 594 595 scan = new Scan(ROWS[0]); 596 result = getSingleScanResult(ht, scan); 597 assertNullResult(result); 598 599 scan = new Scan(ROWS[0], ROWS[1]); 600 result = getSingleScanResult(ht, scan); 601 assertNullResult(result); 602 603 scan = new Scan(); 604 scan.addFamily(FAMILY); 605 result = getSingleScanResult(ht, scan); 606 assertNullResult(result); 607 608 scan = new Scan(); 609 scan.addColumn(FAMILY, QUALIFIER); 610 result = getSingleScanResult(ht, scan); 611 assertNullResult(result); 612 613 // Insert a row 614 615 Put put = new Put(ROWS[2]); 616 put.addColumn(FAMILY, QUALIFIER, VALUE); 617 ht.put(put); 618 619 // Try to get empty rows around it 620 621 get = new Get(ROWS[1]); 622 result = ht.get(get); 623 assertEmptyResult(result); 624 625 get = new Get(ROWS[0]); 626 get.addFamily(FAMILY); 627 result = ht.get(get); 628 assertEmptyResult(result); 629 630 get = new Get(ROWS[3]); 631 get.addColumn(FAMILY, QUALIFIER); 632 result = ht.get(get); 633 assertEmptyResult(result); 634 635 // Try to scan empty rows around it 636 637 scan = new Scan(ROWS[3]); 638 result = getSingleScanResult(ht, scan); 639 assertNullResult(result); 640 641 scan = new Scan(ROWS[0], ROWS[2]); 642 result = getSingleScanResult(ht, scan); 643 assertNullResult(result); 644 645 // Make sure we can actually get the row 646 647 get = new Get(ROWS[2]); 648 result = ht.get(get); 649 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 650 651 get = new Get(ROWS[2]); 652 get.addFamily(FAMILY); 653 result = ht.get(get); 654 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 655 656 get = new Get(ROWS[2]); 657 get.addColumn(FAMILY, QUALIFIER); 658 result = ht.get(get); 659 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 660 661 // Make sure we can scan the row 662 663 scan = new Scan(); 664 result = getSingleScanResult(ht, scan); 665 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 666 667 scan = new Scan(ROWS[0], ROWS[3]); 668 result = getSingleScanResult(ht, scan); 669 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 670 671 scan = new Scan(ROWS[2], ROWS[3]); 672 result = getSingleScanResult(ht, scan); 673 assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE); 674 } 675 } 676 677 /** 678 * Test basic puts, gets, scans, and deletes for a single row in a multiple family table. 679 */ 680 @SuppressWarnings("checkstyle:MethodLength") 681 @Test 682 public void testSingleRowMultipleFamily() throws Exception { 683 final TableName tableName = name.getTableName(); 684 byte[][] ROWS = makeN(ROW, 3); 685 byte[][] FAMILIES = makeNAscii(FAMILY, 10); 686 byte[][] QUALIFIERS = makeN(QUALIFIER, 10); 687 byte[][] VALUES = makeN(VALUE, 10); 688 689 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES)) { 690 //////////////////////////////////////////////////////////////////////////// 691 // Insert one column to one family 692 //////////////////////////////////////////////////////////////////////////// 693 694 Put put = new Put(ROWS[0]); 695 put.addColumn(FAMILIES[4], QUALIFIERS[0], VALUES[0]); 696 ht.put(put); 697 698 // Get the single column 699 getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 700 701 // Scan the single column 702 scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 703 704 // Get empty results around inserted column 705 getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 706 707 // Scan empty results around inserted column 708 scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 709 710 //////////////////////////////////////////////////////////////////////////// 711 // Flush memstore and run same tests from storefiles 712 //////////////////////////////////////////////////////////////////////////// 713 714 TEST_UTIL.flush(); 715 716 // Redo get and scan tests from storefile 717 getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 718 scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0); 719 getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 720 scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0); 721 722 //////////////////////////////////////////////////////////////////////////// 723 // Now, Test reading from memstore and storefiles at once 724 //////////////////////////////////////////////////////////////////////////// 725 726 // Insert multiple columns to two other families 727 put = new Put(ROWS[0]); 728 put.addColumn(FAMILIES[2], QUALIFIERS[2], VALUES[2]); 729 put.addColumn(FAMILIES[2], QUALIFIERS[4], VALUES[4]); 730 put.addColumn(FAMILIES[4], QUALIFIERS[4], VALUES[4]); 731 put.addColumn(FAMILIES[6], QUALIFIERS[6], VALUES[6]); 732 put.addColumn(FAMILIES[6], QUALIFIERS[7], VALUES[7]); 733 put.addColumn(FAMILIES[7], QUALIFIERS[7], VALUES[7]); 734 put.addColumn(FAMILIES[9], QUALIFIERS[0], VALUES[0]); 735 ht.put(put); 736 737 // Get multiple columns across multiple families and get empties around it 738 singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 739 740 // Scan multiple columns across multiple families and scan empties around it 741 singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 742 743 //////////////////////////////////////////////////////////////////////////// 744 // Flush the table again 745 //////////////////////////////////////////////////////////////////////////// 746 747 TEST_UTIL.flush(); 748 749 // Redo tests again 750 singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 751 singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES); 752 753 // Insert more data to memstore 754 put = new Put(ROWS[0]); 755 put.addColumn(FAMILIES[6], QUALIFIERS[5], VALUES[5]); 756 put.addColumn(FAMILIES[6], QUALIFIERS[8], VALUES[8]); 757 put.addColumn(FAMILIES[6], QUALIFIERS[9], VALUES[9]); 758 put.addColumn(FAMILIES[4], QUALIFIERS[3], VALUES[3]); 759 ht.put(put); 760 761 //////////////////////////////////////////////////////////////////////////// 762 // Delete a storefile column 763 //////////////////////////////////////////////////////////////////////////// 764 Delete delete = new Delete(ROWS[0]); 765 delete.addColumns(FAMILIES[6], QUALIFIERS[7]); 766 ht.delete(delete); 767 768 // Try to get deleted column 769 Get get = new Get(ROWS[0]); 770 get.addColumn(FAMILIES[6], QUALIFIERS[7]); 771 Result result = ht.get(get); 772 assertEmptyResult(result); 773 774 // Try to scan deleted column 775 Scan scan = new Scan(); 776 scan.addColumn(FAMILIES[6], QUALIFIERS[7]); 777 result = getSingleScanResult(ht, scan); 778 assertNullResult(result); 779 780 // Make sure we can still get a column before it and after it 781 get = new Get(ROWS[0]); 782 get.addColumn(FAMILIES[6], QUALIFIERS[6]); 783 result = ht.get(get); 784 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 785 786 get = new Get(ROWS[0]); 787 get.addColumn(FAMILIES[6], QUALIFIERS[8]); 788 result = ht.get(get); 789 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]); 790 791 // Make sure we can still scan a column before it and after it 792 scan = new Scan(); 793 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 794 result = getSingleScanResult(ht, scan); 795 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 796 797 scan = new Scan(); 798 scan.addColumn(FAMILIES[6], QUALIFIERS[8]); 799 result = getSingleScanResult(ht, scan); 800 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]); 801 802 //////////////////////////////////////////////////////////////////////////// 803 // Delete a memstore column 804 //////////////////////////////////////////////////////////////////////////// 805 delete = new Delete(ROWS[0]); 806 delete.addColumns(FAMILIES[6], QUALIFIERS[8]); 807 ht.delete(delete); 808 809 // Try to get deleted column 810 get = new Get(ROWS[0]); 811 get.addColumn(FAMILIES[6], QUALIFIERS[8]); 812 result = ht.get(get); 813 assertEmptyResult(result); 814 815 // Try to scan deleted column 816 scan = new Scan(); 817 scan.addColumn(FAMILIES[6], QUALIFIERS[8]); 818 result = getSingleScanResult(ht, scan); 819 assertNullResult(result); 820 821 // Make sure we can still get a column before it and after it 822 get = new Get(ROWS[0]); 823 get.addColumn(FAMILIES[6], QUALIFIERS[6]); 824 result = ht.get(get); 825 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 826 827 get = new Get(ROWS[0]); 828 get.addColumn(FAMILIES[6], QUALIFIERS[9]); 829 result = ht.get(get); 830 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 831 832 // Make sure we can still scan a column before it and after it 833 scan = new Scan(); 834 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 835 result = getSingleScanResult(ht, scan); 836 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 837 838 scan = new Scan(); 839 scan.addColumn(FAMILIES[6], QUALIFIERS[9]); 840 result = getSingleScanResult(ht, scan); 841 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 842 843 //////////////////////////////////////////////////////////////////////////// 844 // Delete joint storefile/memstore family 845 //////////////////////////////////////////////////////////////////////////// 846 847 delete = new Delete(ROWS[0]); 848 delete.addFamily(FAMILIES[4]); 849 ht.delete(delete); 850 851 // Try to get storefile column in deleted family 852 get = new Get(ROWS[0]); 853 get.addColumn(FAMILIES[4], QUALIFIERS[4]); 854 result = ht.get(get); 855 assertEmptyResult(result); 856 857 // Try to get memstore column in deleted family 858 get = new Get(ROWS[0]); 859 get.addColumn(FAMILIES[4], QUALIFIERS[3]); 860 result = ht.get(get); 861 assertEmptyResult(result); 862 863 // Try to get deleted family 864 get = new Get(ROWS[0]); 865 get.addFamily(FAMILIES[4]); 866 result = ht.get(get); 867 assertEmptyResult(result); 868 869 // Try to scan storefile column in deleted family 870 scan = new Scan(); 871 scan.addColumn(FAMILIES[4], QUALIFIERS[4]); 872 result = getSingleScanResult(ht, scan); 873 assertNullResult(result); 874 875 // Try to scan memstore column in deleted family 876 scan = new Scan(); 877 scan.addColumn(FAMILIES[4], QUALIFIERS[3]); 878 result = getSingleScanResult(ht, scan); 879 assertNullResult(result); 880 881 // Try to scan deleted family 882 scan = new Scan(); 883 scan.addFamily(FAMILIES[4]); 884 result = getSingleScanResult(ht, scan); 885 assertNullResult(result); 886 887 // Make sure we can still get another family 888 get = new Get(ROWS[0]); 889 get.addColumn(FAMILIES[2], QUALIFIERS[2]); 890 result = ht.get(get); 891 assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]); 892 893 get = new Get(ROWS[0]); 894 get.addColumn(FAMILIES[6], QUALIFIERS[9]); 895 result = ht.get(get); 896 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 897 898 // Make sure we can still scan another family 899 scan = new Scan(); 900 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 901 result = getSingleScanResult(ht, scan); 902 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 903 904 scan = new Scan(); 905 scan.addColumn(FAMILIES[6], QUALIFIERS[9]); 906 result = getSingleScanResult(ht, scan); 907 assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 908 909 //////////////////////////////////////////////////////////////////////////// 910 // Flush everything and rerun delete tests 911 //////////////////////////////////////////////////////////////////////////// 912 913 TEST_UTIL.flush(); 914 915 // Try to get storefile column in deleted family 916 assertEmptyResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[4], QUALIFIERS[4]))); 917 918 // Try to get memstore column in deleted family 919 assertEmptyResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[4], QUALIFIERS[3]))); 920 921 // Try to get deleted family 922 assertEmptyResult(ht.get(new Get(ROWS[0]).addFamily(FAMILIES[4]))); 923 924 // Try to scan storefile column in deleted family 925 assertNullResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[4], QUALIFIERS[4]))); 926 927 // Try to scan memstore column in deleted family 928 assertNullResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[4], QUALIFIERS[3]))); 929 930 // Try to scan deleted family 931 assertNullResult(getSingleScanResult(ht, new Scan().addFamily(FAMILIES[4]))); 932 933 // Make sure we can still get another family 934 assertSingleResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[2], QUALIFIERS[2])), ROWS[0], 935 FAMILIES[2], QUALIFIERS[2], VALUES[2]); 936 937 assertSingleResult(ht.get(new Get(ROWS[0]).addColumn(FAMILIES[6], QUALIFIERS[9])), ROWS[0], 938 FAMILIES[6], QUALIFIERS[9], VALUES[9]); 939 940 // Make sure we can still scan another family 941 assertSingleResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[6], QUALIFIERS[6])), 942 ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]); 943 944 assertSingleResult(getSingleScanResult(ht, new Scan().addColumn(FAMILIES[6], QUALIFIERS[9])), 945 ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]); 946 } 947 } 948 949 @Test(expected = NullPointerException.class) 950 public void testNullTableName() throws IOException { 951 // Null table name (should NOT work) 952 TEST_UTIL.createTable(null, FAMILY); 953 fail("Creating a table with null name passed, should have failed"); 954 } 955 956 @Test(expected = IllegalArgumentException.class) 957 public void testNullFamilyName() throws IOException { 958 final TableName tableName = name.getTableName(); 959 960 // Null family (should NOT work) 961 TEST_UTIL.createTable(tableName, new byte[][] { null }); 962 fail("Creating a table with a null family passed, should fail"); 963 } 964 965 @Test 966 public void testNullRowAndQualifier() throws Exception { 967 final TableName tableName = name.getTableName(); 968 969 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 970 971 // Null row (should NOT work) 972 try { 973 Put put = new Put((byte[]) null); 974 put.addColumn(FAMILY, QUALIFIER, VALUE); 975 ht.put(put); 976 fail("Inserting a null row worked, should throw exception"); 977 } catch (Exception ignored) { 978 } 979 980 // Null qualifier (should work) 981 { 982 Put put = new Put(ROW); 983 put.addColumn(FAMILY, null, VALUE); 984 ht.put(put); 985 986 getTestNull(ht, ROW, FAMILY, VALUE); 987 988 scanTestNull(ht, ROW, FAMILY, VALUE); 989 990 Delete delete = new Delete(ROW); 991 delete.addColumns(FAMILY, null); 992 ht.delete(delete); 993 994 Get get = new Get(ROW); 995 Result result = ht.get(get); 996 assertEmptyResult(result); 997 } 998 } 999 } 1000 1001 @Test 1002 public void testNullEmptyQualifier() throws Exception { 1003 final TableName tableName = name.getTableName(); 1004 1005 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 1006 1007 // Empty qualifier, byte[0] instead of null (should work) 1008 try { 1009 Put put = new Put(ROW); 1010 put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE); 1011 ht.put(put); 1012 1013 getTestNull(ht, ROW, FAMILY, VALUE); 1014 1015 scanTestNull(ht, ROW, FAMILY, VALUE); 1016 1017 // Flush and try again 1018 1019 TEST_UTIL.flush(); 1020 1021 getTestNull(ht, ROW, FAMILY, VALUE); 1022 1023 scanTestNull(ht, ROW, FAMILY, VALUE); 1024 1025 Delete delete = new Delete(ROW); 1026 delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY); 1027 ht.delete(delete); 1028 1029 Get get = new Get(ROW); 1030 Result result = ht.get(get); 1031 assertEmptyResult(result); 1032 1033 } catch (Exception e) { 1034 throw new IOException("Using a row with null qualifier should not throw exception"); 1035 } 1036 } 1037 } 1038 1039 @Test 1040 public void testNullValue() throws IOException { 1041 final TableName tableName = name.getTableName(); 1042 1043 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 1044 // Null value 1045 try { 1046 Put put = new Put(ROW); 1047 put.addColumn(FAMILY, QUALIFIER, null); 1048 ht.put(put); 1049 1050 Get get = new Get(ROW); 1051 get.addColumn(FAMILY, QUALIFIER); 1052 Result result = ht.get(get); 1053 assertSingleResult(result, ROW, FAMILY, QUALIFIER, null); 1054 1055 Scan scan = new Scan(); 1056 scan.addColumn(FAMILY, QUALIFIER); 1057 result = getSingleScanResult(ht, scan); 1058 assertSingleResult(result, ROW, FAMILY, QUALIFIER, null); 1059 1060 Delete delete = new Delete(ROW); 1061 delete.addColumns(FAMILY, QUALIFIER); 1062 ht.delete(delete); 1063 1064 get = new Get(ROW); 1065 result = ht.get(get); 1066 assertEmptyResult(result); 1067 1068 } catch (Exception e) { 1069 throw new IOException("Null values should be allowed, but threw exception"); 1070 } 1071 } 1072 } 1073 1074 @Test 1075 public void testNullQualifier() throws Exception { 1076 final TableName tableName = name.getTableName(); 1077 try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) { 1078 1079 // Work for Put 1080 Put put = new Put(ROW); 1081 put.addColumn(FAMILY, null, VALUE); 1082 table.put(put); 1083 1084 // Work for Get, Scan 1085 getTestNull(table, ROW, FAMILY, VALUE); 1086 scanTestNull(table, ROW, FAMILY, VALUE); 1087 1088 // Work for Delete 1089 Delete delete = new Delete(ROW); 1090 delete.addColumns(FAMILY, null); 1091 table.delete(delete); 1092 1093 Get get = new Get(ROW); 1094 Result result = table.get(get); 1095 assertEmptyResult(result); 1096 1097 // Work for Increment/Append 1098 Increment increment = new Increment(ROW); 1099 increment.addColumn(FAMILY, null, 1L); 1100 table.increment(increment); 1101 getTestNull(table, ROW, FAMILY, 1L); 1102 1103 table.incrementColumnValue(ROW, FAMILY, null, 1L); 1104 getTestNull(table, ROW, FAMILY, 2L); 1105 1106 delete = new Delete(ROW); 1107 delete.addColumns(FAMILY, null); 1108 table.delete(delete); 1109 1110 Append append = new Append(ROW); 1111 append.addColumn(FAMILY, null, VALUE); 1112 table.append(append); 1113 getTestNull(table, ROW, FAMILY, VALUE); 1114 1115 // Work for checkAndMutate using thenPut, thenMutate and thenDelete 1116 put = new Put(ROW); 1117 put.addColumn(FAMILY, null, Bytes.toBytes("checkAndPut")); 1118 table.put(put); 1119 table.checkAndMutate(ROW, FAMILY).ifEquals(VALUE).thenPut(put); 1120 1121 RowMutations mutate = new RowMutations(ROW); 1122 mutate.add(new Put(ROW).addColumn(FAMILY, null, Bytes.toBytes("checkAndMutate"))); 1123 table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndPut")).thenMutate(mutate); 1124 1125 delete = new Delete(ROW); 1126 delete.addColumns(FAMILY, null); 1127 table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndMutate")) 1128 .thenDelete(delete); 1129 } 1130 } 1131 1132 @Test 1133 @SuppressWarnings("checkstyle:MethodLength") 1134 public void testVersions() throws Exception { 1135 final TableName tableName = name.getTableName(); 1136 1137 long[] STAMPS = makeStamps(20); 1138 byte[][] VALUES = makeNAscii(VALUE, 20); 1139 1140 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 1141 1142 // Insert 4 versions of same column 1143 Put put = new Put(ROW); 1144 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1145 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1146 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1147 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1148 ht.put(put); 1149 1150 // Verify we can get each one properly 1151 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1152 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1153 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1154 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1155 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1156 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1157 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1158 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1159 1160 // Verify we don't accidentally get others 1161 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1162 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1163 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1164 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1165 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1166 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1167 1168 // Ensure maxVersions in query is respected 1169 Get get = new Get(ROW); 1170 get.addColumn(FAMILY, QUALIFIER); 1171 get.setMaxVersions(2); 1172 Result result = ht.get(get); 1173 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1174 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1175 1176 Scan scan = new Scan(ROW); 1177 scan.addColumn(FAMILY, QUALIFIER); 1178 scan.setMaxVersions(2); 1179 result = getSingleScanResult(ht, scan); 1180 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1181 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1182 1183 // Flush and redo 1184 1185 TEST_UTIL.flush(); 1186 1187 // Verify we can get each one properly 1188 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1189 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1190 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1191 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1192 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1193 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1194 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1195 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 1196 1197 // Verify we don't accidentally get others 1198 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1199 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1200 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1201 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1202 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 1203 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 1204 1205 // Ensure maxVersions in query is respected 1206 get = new Get(ROW); 1207 get.addColumn(FAMILY, QUALIFIER); 1208 get.setMaxVersions(2); 1209 result = ht.get(get); 1210 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1211 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1212 1213 scan = new Scan(ROW); 1214 scan.addColumn(FAMILY, QUALIFIER); 1215 scan.setMaxVersions(2); 1216 result = getSingleScanResult(ht, scan); 1217 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 1218 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 1219 1220 // Add some memstore and retest 1221 1222 // Insert 4 more versions of same column and a dupe 1223 put = new Put(ROW); 1224 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 1225 put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 1226 put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1227 put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]); 1228 ht.put(put); 1229 1230 // Ensure maxVersions in query is respected 1231 get = new Get(ROW); 1232 get.addColumn(FAMILY, QUALIFIER); 1233 get.setMaxVersions(); 1234 result = ht.get(get); 1235 assertNResult(result, ROW, FAMILY, QUALIFIER, 1236 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1237 STAMPS[8] }, 1238 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1239 VALUES[8] }, 1240 0, 7); 1241 1242 scan = new Scan(ROW); 1243 scan.addColumn(FAMILY, QUALIFIER); 1244 scan.setMaxVersions(); 1245 result = getSingleScanResult(ht, scan); 1246 assertNResult(result, ROW, FAMILY, QUALIFIER, 1247 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1248 STAMPS[8] }, 1249 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1250 VALUES[8] }, 1251 0, 7); 1252 1253 get = new Get(ROW); 1254 get.setMaxVersions(); 1255 result = ht.get(get); 1256 assertNResult(result, ROW, FAMILY, QUALIFIER, 1257 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1258 STAMPS[8] }, 1259 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1260 VALUES[8] }, 1261 0, 7); 1262 1263 scan = new Scan(ROW); 1264 scan.setMaxVersions(); 1265 result = getSingleScanResult(ht, scan); 1266 assertNResult(result, ROW, FAMILY, QUALIFIER, 1267 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], 1268 STAMPS[8] }, 1269 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], 1270 VALUES[8] }, 1271 0, 7); 1272 1273 // Verify we can get each one properly 1274 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1275 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1276 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1277 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1278 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 1279 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 1280 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 1281 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 1282 1283 // Verify we don't accidentally get others 1284 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1285 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 1286 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 1287 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 1288 1289 // Ensure maxVersions of table is respected 1290 1291 TEST_UTIL.flush(); 1292 1293 // Insert 4 more versions of same column and a dupe 1294 put = new Put(ROW); 1295 put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]); 1296 put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]); 1297 put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]); 1298 put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]); 1299 ht.put(put); 1300 1301 get = new Get(ROW); 1302 get.addColumn(FAMILY, QUALIFIER); 1303 get.setMaxVersions(Integer.MAX_VALUE); 1304 result = ht.get(get); 1305 assertNResult(result, ROW, FAMILY, QUALIFIER, 1306 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 1307 STAMPS[11], STAMPS[13], STAMPS[15] }, 1308 new byte[][] { VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 1309 VALUES[11], VALUES[13], VALUES[15] }, 1310 0, 9); 1311 1312 scan = new Scan(ROW); 1313 scan.addColumn(FAMILY, QUALIFIER); 1314 scan.setMaxVersions(Integer.MAX_VALUE); 1315 result = getSingleScanResult(ht, scan); 1316 assertNResult(result, ROW, FAMILY, QUALIFIER, 1317 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 1318 STAMPS[11], STAMPS[13], STAMPS[15] }, 1319 new byte[][] { VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 1320 VALUES[11], VALUES[13], VALUES[15] }, 1321 0, 9); 1322 1323 // Delete a version in the memstore and a version in a storefile 1324 Delete delete = new Delete(ROW); 1325 delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]); 1326 delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]); 1327 ht.delete(delete); 1328 1329 // Test that it's gone 1330 get = new Get(ROW); 1331 get.addColumn(FAMILY, QUALIFIER); 1332 get.setMaxVersions(Integer.MAX_VALUE); 1333 result = ht.get(get); 1334 assertNResult(result, ROW, FAMILY, QUALIFIER, 1335 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 1336 STAMPS[9], STAMPS[13], STAMPS[15] }, 1337 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], 1338 VALUES[9], VALUES[13], VALUES[15] }, 1339 0, 9); 1340 1341 scan = new Scan(ROW); 1342 scan.addColumn(FAMILY, QUALIFIER); 1343 scan.setMaxVersions(Integer.MAX_VALUE); 1344 result = getSingleScanResult(ht, scan); 1345 assertNResult(result, ROW, FAMILY, QUALIFIER, 1346 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 1347 STAMPS[9], STAMPS[13], STAMPS[15] }, 1348 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], 1349 VALUES[9], VALUES[13], VALUES[15] }, 1350 0, 9); 1351 } 1352 } 1353 1354 @Test 1355 @SuppressWarnings("checkstyle:MethodLength") 1356 public void testVersionLimits() throws Exception { 1357 final TableName tableName = name.getTableName(); 1358 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1359 int[] LIMITS = { 1, 3, 5 }; 1360 long[] STAMPS = makeStamps(10); 1361 byte[][] VALUES = makeNAscii(VALUE, 10); 1362 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, LIMITS)) { 1363 1364 // Insert limit + 1 on each family 1365 Put put = new Put(ROW); 1366 put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[0], VALUES[0]); 1367 put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[1], VALUES[1]); 1368 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[0], VALUES[0]); 1369 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[1], VALUES[1]); 1370 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[2], VALUES[2]); 1371 put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[3], VALUES[3]); 1372 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[0], VALUES[0]); 1373 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[1], VALUES[1]); 1374 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[2], VALUES[2]); 1375 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[3], VALUES[3]); 1376 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[4], VALUES[4]); 1377 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[5], VALUES[5]); 1378 put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[6], VALUES[6]); 1379 ht.put(put); 1380 1381 // Verify we only get the right number out of each 1382 1383 // Family0 1384 1385 Get get = new Get(ROW); 1386 get.addColumn(FAMILIES[0], QUALIFIER); 1387 get.setMaxVersions(Integer.MAX_VALUE); 1388 Result result = ht.get(get); 1389 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1390 new byte[][] { VALUES[1] }, 0, 0); 1391 1392 get = new Get(ROW); 1393 get.addFamily(FAMILIES[0]); 1394 get.setMaxVersions(Integer.MAX_VALUE); 1395 result = ht.get(get); 1396 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1397 new byte[][] { VALUES[1] }, 0, 0); 1398 1399 Scan scan = new Scan(ROW); 1400 scan.addColumn(FAMILIES[0], QUALIFIER); 1401 scan.setMaxVersions(Integer.MAX_VALUE); 1402 result = getSingleScanResult(ht, scan); 1403 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1404 new byte[][] { VALUES[1] }, 0, 0); 1405 1406 scan = new Scan(ROW); 1407 scan.addFamily(FAMILIES[0]); 1408 scan.setMaxVersions(Integer.MAX_VALUE); 1409 result = getSingleScanResult(ht, scan); 1410 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { STAMPS[1] }, 1411 new byte[][] { VALUES[1] }, 0, 0); 1412 1413 // Family1 1414 1415 get = new Get(ROW); 1416 get.addColumn(FAMILIES[1], QUALIFIER); 1417 get.setMaxVersions(Integer.MAX_VALUE); 1418 result = ht.get(get); 1419 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1420 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1421 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1422 1423 get = new Get(ROW); 1424 get.addFamily(FAMILIES[1]); 1425 get.setMaxVersions(Integer.MAX_VALUE); 1426 result = ht.get(get); 1427 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1428 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1429 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1430 1431 scan = new Scan(ROW); 1432 scan.addColumn(FAMILIES[1], QUALIFIER); 1433 scan.setMaxVersions(Integer.MAX_VALUE); 1434 result = getSingleScanResult(ht, scan); 1435 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1436 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1437 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1438 1439 scan = new Scan(ROW); 1440 scan.addFamily(FAMILIES[1]); 1441 scan.setMaxVersions(Integer.MAX_VALUE); 1442 result = getSingleScanResult(ht, scan); 1443 assertNResult(result, ROW, FAMILIES[1], QUALIFIER, 1444 new long[] { STAMPS[1], STAMPS[2], STAMPS[3] }, 1445 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1446 1447 // Family2 1448 1449 get = new Get(ROW); 1450 get.addColumn(FAMILIES[2], QUALIFIER); 1451 get.setMaxVersions(Integer.MAX_VALUE); 1452 result = ht.get(get); 1453 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1454 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1455 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1456 1457 get = new Get(ROW); 1458 get.addFamily(FAMILIES[2]); 1459 get.setMaxVersions(Integer.MAX_VALUE); 1460 result = ht.get(get); 1461 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1462 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1463 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1464 1465 scan = new Scan(ROW); 1466 scan.addColumn(FAMILIES[2], QUALIFIER); 1467 scan.setMaxVersions(Integer.MAX_VALUE); 1468 result = getSingleScanResult(ht, scan); 1469 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1470 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1471 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1472 1473 scan = new Scan(ROW); 1474 scan.addFamily(FAMILIES[2]); 1475 scan.setMaxVersions(Integer.MAX_VALUE); 1476 result = getSingleScanResult(ht, scan); 1477 assertNResult(result, ROW, FAMILIES[2], QUALIFIER, 1478 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6] }, 1479 new byte[][] { VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6] }, 0, 4); 1480 1481 // Try all families 1482 1483 get = new Get(ROW); 1484 get.setMaxVersions(Integer.MAX_VALUE); 1485 result = ht.get(get); 1486 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1487 1488 get = new Get(ROW); 1489 get.addFamily(FAMILIES[0]); 1490 get.addFamily(FAMILIES[1]); 1491 get.addFamily(FAMILIES[2]); 1492 get.setMaxVersions(Integer.MAX_VALUE); 1493 result = ht.get(get); 1494 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1495 1496 get = new Get(ROW); 1497 get.addColumn(FAMILIES[0], QUALIFIER); 1498 get.addColumn(FAMILIES[1], QUALIFIER); 1499 get.addColumn(FAMILIES[2], QUALIFIER); 1500 get.setMaxVersions(Integer.MAX_VALUE); 1501 result = ht.get(get); 1502 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1503 1504 scan = new Scan(ROW); 1505 scan.setMaxVersions(Integer.MAX_VALUE); 1506 result = getSingleScanResult(ht, scan); 1507 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1508 1509 scan = new Scan(ROW); 1510 scan.setMaxVersions(Integer.MAX_VALUE); 1511 scan.addFamily(FAMILIES[0]); 1512 scan.addFamily(FAMILIES[1]); 1513 scan.addFamily(FAMILIES[2]); 1514 result = getSingleScanResult(ht, scan); 1515 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1516 1517 scan = new Scan(ROW); 1518 scan.setMaxVersions(Integer.MAX_VALUE); 1519 scan.addColumn(FAMILIES[0], QUALIFIER); 1520 scan.addColumn(FAMILIES[1], QUALIFIER); 1521 scan.addColumn(FAMILIES[2], QUALIFIER); 1522 result = getSingleScanResult(ht, scan); 1523 assertEquals("Expected 9 keys but received " + result.size(), 9, result.size()); 1524 } 1525 } 1526 1527 @Test 1528 public void testDeleteFamilyVersion() throws Exception { 1529 try (Admin admin = TEST_UTIL.getAdmin()) { 1530 final TableName tableName = name.getTableName(); 1531 1532 byte[][] QUALIFIERS = makeNAscii(QUALIFIER, 1); 1533 byte[][] VALUES = makeN(VALUE, 5); 1534 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1535 1536 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) { 1537 1538 Put put = new Put(ROW); 1539 for (int q = 0; q < 1; q++) { 1540 for (int t = 0; t < 5; t++) { 1541 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1542 } 1543 } 1544 ht.put(put); 1545 admin.flush(tableName); 1546 1547 Delete delete = new Delete(ROW); 1548 delete.addFamilyVersion(FAMILY, ts[1]); // delete version '2000' 1549 delete.addFamilyVersion(FAMILY, ts[3]); // delete version '4000' 1550 ht.delete(delete); 1551 admin.flush(tableName); 1552 1553 for (int i = 0; i < 1; i++) { 1554 Get get = new Get(ROW); 1555 get.addColumn(FAMILY, QUALIFIERS[i]); 1556 get.setMaxVersions(Integer.MAX_VALUE); 1557 Result result = ht.get(get); 1558 // verify version '1000'/'3000'/'5000' remains for all columns 1559 assertNResult(result, ROW, FAMILY, QUALIFIERS[i], new long[] { ts[0], ts[2], ts[4] }, 1560 new byte[][] { VALUES[0], VALUES[2], VALUES[4] }, 0, 2); 1561 } 1562 } 1563 } 1564 } 1565 1566 @Test 1567 public void testDeleteFamilyVersionWithOtherDeletes() throws Exception { 1568 final TableName tableName = name.getTableName(); 1569 1570 byte[][] QUALIFIERS = makeNAscii(QUALIFIER, 5); 1571 byte[][] VALUES = makeN(VALUE, 5); 1572 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1573 1574 try (Admin admin = TEST_UTIL.getAdmin(); 1575 Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) { 1576 Put put; 1577 Result result = null; 1578 Get get = null; 1579 Delete delete = null; 1580 1581 // 1. put on ROW 1582 put = new Put(ROW); 1583 for (int q = 0; q < 5; q++) { 1584 for (int t = 0; t < 5; t++) { 1585 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1586 } 1587 } 1588 ht.put(put); 1589 admin.flush(tableName); 1590 1591 // 2. put on ROWS[0] 1592 byte[] ROW2 = Bytes.toBytes("myRowForTest"); 1593 put = new Put(ROW2); 1594 for (int q = 0; q < 5; q++) { 1595 for (int t = 0; t < 5; t++) { 1596 put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]); 1597 } 1598 } 1599 ht.put(put); 1600 admin.flush(tableName); 1601 1602 // 3. delete on ROW 1603 delete = new Delete(ROW); 1604 // delete version <= 2000 of all columns 1605 // note: addFamily must be the first since it will mask 1606 // the subsequent other type deletes! 1607 delete.addFamily(FAMILY, ts[1]); 1608 // delete version '4000' of all columns 1609 delete.addFamilyVersion(FAMILY, ts[3]); 1610 // delete version <= 3000 of column 0 1611 delete.addColumns(FAMILY, QUALIFIERS[0], ts[2]); 1612 // delete version <= 5000 of column 2 1613 delete.addColumns(FAMILY, QUALIFIERS[2], ts[4]); 1614 // delete version 5000 of column 4 1615 delete.addColumn(FAMILY, QUALIFIERS[4], ts[4]); 1616 ht.delete(delete); 1617 admin.flush(tableName); 1618 1619 // 4. delete on ROWS[0] 1620 delete = new Delete(ROW2); 1621 delete.addFamilyVersion(FAMILY, ts[1]); // delete version '2000' 1622 delete.addFamilyVersion(FAMILY, ts[3]); // delete version '4000' 1623 ht.delete(delete); 1624 admin.flush(tableName); 1625 1626 // 5. check ROW 1627 get = new Get(ROW); 1628 get.addColumn(FAMILY, QUALIFIERS[0]); 1629 get.setMaxVersions(Integer.MAX_VALUE); 1630 result = ht.get(get); 1631 assertNResult(result, ROW, FAMILY, QUALIFIERS[0], new long[] { ts[4] }, 1632 new byte[][] { VALUES[4] }, 0, 0); 1633 1634 get = new Get(ROW); 1635 get.addColumn(FAMILY, QUALIFIERS[1]); 1636 get.setMaxVersions(Integer.MAX_VALUE); 1637 result = ht.get(get); 1638 assertNResult(result, ROW, FAMILY, QUALIFIERS[1], new long[] { ts[2], ts[4] }, 1639 new byte[][] { VALUES[2], VALUES[4] }, 0, 1); 1640 1641 get = new Get(ROW); 1642 get.addColumn(FAMILY, QUALIFIERS[2]); 1643 get.setMaxVersions(Integer.MAX_VALUE); 1644 result = ht.get(get); 1645 assertEquals(0, result.size()); 1646 1647 get = new Get(ROW); 1648 get.addColumn(FAMILY, QUALIFIERS[3]); 1649 get.setMaxVersions(Integer.MAX_VALUE); 1650 result = ht.get(get); 1651 assertNResult(result, ROW, FAMILY, QUALIFIERS[3], new long[] { ts[2], ts[4] }, 1652 new byte[][] { VALUES[2], VALUES[4] }, 0, 1); 1653 1654 get = new Get(ROW); 1655 get.addColumn(FAMILY, QUALIFIERS[4]); 1656 get.setMaxVersions(Integer.MAX_VALUE); 1657 result = ht.get(get); 1658 assertNResult(result, ROW, FAMILY, QUALIFIERS[4], new long[] { ts[2] }, 1659 new byte[][] { VALUES[2] }, 0, 0); 1660 1661 // 6. check ROWS[0] 1662 for (int i = 0; i < 5; i++) { 1663 get = new Get(ROW2); 1664 get.addColumn(FAMILY, QUALIFIERS[i]); 1665 get.readVersions(Integer.MAX_VALUE); 1666 result = ht.get(get); 1667 // verify version '1000'/'3000'/'5000' remains for all columns 1668 assertNResult(result, ROW2, FAMILY, QUALIFIERS[i], new long[] { ts[0], ts[2], ts[4] }, 1669 new byte[][] { VALUES[0], VALUES[2], VALUES[4] }, 0, 2); 1670 } 1671 } 1672 } 1673 1674 @Test 1675 public void testDeleteWithFailed() throws Exception { 1676 final TableName tableName = name.getTableName(); 1677 1678 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1679 byte[][] VALUES = makeN(VALUE, 5); 1680 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1681 1682 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) { 1683 Put put = new Put(ROW); 1684 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); 1685 ht.put(put); 1686 1687 // delete wrong family 1688 Delete delete = new Delete(ROW); 1689 delete.addFamily(FAMILIES[1], ts[0]); 1690 ht.delete(delete); 1691 1692 Get get = new Get(ROW); 1693 get.addFamily(FAMILIES[0]); 1694 get.readAllVersions(); 1695 Result result = ht.get(get); 1696 assertTrue(Bytes.equals(result.getValue(FAMILIES[0], QUALIFIER), VALUES[0])); 1697 } 1698 } 1699 1700 @Test 1701 @SuppressWarnings("checkstyle:MethodLength") 1702 public void testDeletes() throws Exception { 1703 final TableName tableName = name.getTableName(); 1704 1705 byte[][] ROWS = makeNAscii(ROW, 6); 1706 byte[][] FAMILIES = makeNAscii(FAMILY, 3); 1707 byte[][] VALUES = makeN(VALUE, 5); 1708 long[] ts = { 1000, 2000, 3000, 4000, 5000 }; 1709 1710 try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) { 1711 1712 Put put = new Put(ROW); 1713 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); 1714 put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]); 1715 ht.put(put); 1716 1717 Delete delete = new Delete(ROW); 1718 delete.addFamily(FAMILIES[0], ts[0]); 1719 ht.delete(delete); 1720 1721 Get get = new Get(ROW); 1722 get.addFamily(FAMILIES[0]); 1723 get.setMaxVersions(Integer.MAX_VALUE); 1724 Result result = ht.get(get); 1725 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1] }, 1726 new byte[][] { VALUES[1] }, 0, 0); 1727 1728 Scan scan = new Scan(ROW); 1729 scan.addFamily(FAMILIES[0]); 1730 scan.setMaxVersions(Integer.MAX_VALUE); 1731 result = getSingleScanResult(ht, scan); 1732 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1] }, 1733 new byte[][] { VALUES[1] }, 0, 0); 1734 1735 // Test delete latest version 1736 put = new Put(ROW); 1737 put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); 1738 put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]); 1739 put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]); 1740 put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]); 1741 put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]); 1742 put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]); 1743 ht.put(put); 1744 1745 delete = new Delete(ROW); 1746 delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4] 1747 ht.delete(delete); 1748 1749 get = new Get(ROW); 1750 get.addColumn(FAMILIES[0], QUALIFIER); 1751 get.setMaxVersions(Integer.MAX_VALUE); 1752 result = ht.get(get); 1753 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1754 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1755 1756 scan = new Scan(ROW); 1757 scan.addColumn(FAMILIES[0], QUALIFIER); 1758 scan.setMaxVersions(Integer.MAX_VALUE); 1759 result = getSingleScanResult(ht, scan); 1760 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1761 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1762 1763 // Test for HBASE-1847 1764 delete = new Delete(ROW); 1765 delete.addColumn(FAMILIES[0], null); 1766 ht.delete(delete); 1767 1768 // Cleanup null qualifier 1769 delete = new Delete(ROW); 1770 delete.addColumns(FAMILIES[0], null); 1771 ht.delete(delete); 1772 1773 // Expected client behavior might be that you can re-put deleted values 1774 // But alas, this is not to be. We can't put them back in either case. 1775 1776 put = new Put(ROW); 1777 put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); // 1000 1778 put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); // 5000 1779 ht.put(put); 1780 1781 // It used to be due to the internal implementation of Get, that 1782 // the Get() call would return ts[4] UNLIKE the Scan below. With 1783 // the switch to using Scan for Get this is no longer the case. 1784 get = new Get(ROW); 1785 get.addFamily(FAMILIES[0]); 1786 get.setMaxVersions(Integer.MAX_VALUE); 1787 result = ht.get(get); 1788 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1789 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1790 1791 // The Scanner returns the previous values, the expected-naive-unexpected behavior 1792 1793 scan = new Scan(ROW); 1794 scan.addFamily(FAMILIES[0]); 1795 scan.setMaxVersions(Integer.MAX_VALUE); 1796 result = getSingleScanResult(ht, scan); 1797 assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1], ts[2], ts[3] }, 1798 new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2); 1799 1800 // Test deleting an entire family from one row but not the other various ways 1801 1802 put = new Put(ROWS[0]); 1803 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1804 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1805 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1806 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1807 ht.put(put); 1808 1809 put = new Put(ROWS[1]); 1810 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1811 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1812 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1813 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1814 ht.put(put); 1815 1816 put = new Put(ROWS[2]); 1817 put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]); 1818 put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]); 1819 put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]); 1820 put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]); 1821 ht.put(put); 1822 1823 // Assert that above went in. 1824 get = new Get(ROWS[2]); 1825 get.addFamily(FAMILIES[1]); 1826 get.addFamily(FAMILIES[2]); 1827 get.setMaxVersions(Integer.MAX_VALUE); 1828 result = ht.get(get); 1829 assertEquals("Expected 4 key but received " + result.size() + ": " + result, 4, 1830 result.size()); 1831 1832 delete = new Delete(ROWS[0]); 1833 delete.addFamily(FAMILIES[2]); 1834 ht.delete(delete); 1835 1836 delete = new Delete(ROWS[1]); 1837 delete.addColumns(FAMILIES[1], QUALIFIER); 1838 ht.delete(delete); 1839 1840 delete = new Delete(ROWS[2]); 1841 delete.addColumn(FAMILIES[1], QUALIFIER); 1842 delete.addColumn(FAMILIES[1], QUALIFIER); 1843 delete.addColumn(FAMILIES[2], QUALIFIER); 1844 ht.delete(delete); 1845 1846 get = new Get(ROWS[0]); 1847 get.addFamily(FAMILIES[1]); 1848 get.addFamily(FAMILIES[2]); 1849 get.setMaxVersions(Integer.MAX_VALUE); 1850 result = ht.get(get); 1851 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1852 assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[] { ts[0], ts[1] }, 1853 new byte[][] { VALUES[0], VALUES[1] }, 0, 1); 1854 1855 scan = new Scan(ROWS[0]); 1856 scan.addFamily(FAMILIES[1]); 1857 scan.addFamily(FAMILIES[2]); 1858 scan.setMaxVersions(Integer.MAX_VALUE); 1859 result = getSingleScanResult(ht, scan); 1860 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1861 assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[] { ts[0], ts[1] }, 1862 new byte[][] { VALUES[0], VALUES[1] }, 0, 1); 1863 1864 get = new Get(ROWS[1]); 1865 get.addFamily(FAMILIES[1]); 1866 get.addFamily(FAMILIES[2]); 1867 get.setMaxVersions(Integer.MAX_VALUE); 1868 result = ht.get(get); 1869 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1870 1871 scan = new Scan(ROWS[1]); 1872 scan.addFamily(FAMILIES[1]); 1873 scan.addFamily(FAMILIES[2]); 1874 scan.setMaxVersions(Integer.MAX_VALUE); 1875 result = getSingleScanResult(ht, scan); 1876 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1877 1878 get = new Get(ROWS[2]); 1879 get.addFamily(FAMILIES[1]); 1880 get.addFamily(FAMILIES[2]); 1881 get.setMaxVersions(Integer.MAX_VALUE); 1882 result = ht.get(get); 1883 assertEquals(1, result.size()); 1884 assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER, new long[] { ts[2] }, 1885 new byte[][] { VALUES[2] }, 0, 0); 1886 1887 scan = new Scan(ROWS[2]); 1888 scan.addFamily(FAMILIES[1]); 1889 scan.addFamily(FAMILIES[2]); 1890 scan.setMaxVersions(Integer.MAX_VALUE); 1891 result = getSingleScanResult(ht, scan); 1892 assertEquals(1, result.size()); 1893 assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER, new long[] { ts[2] }, 1894 new byte[][] { VALUES[2] }, 0, 0); 1895 1896 // Test if we delete the family first in one row (HBASE-1541) 1897 1898 delete = new Delete(ROWS[3]); 1899 delete.addFamily(FAMILIES[1]); 1900 ht.delete(delete); 1901 1902 put = new Put(ROWS[3]); 1903 put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]); 1904 ht.put(put); 1905 1906 put = new Put(ROWS[4]); 1907 put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]); 1908 put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]); 1909 ht.put(put); 1910 1911 get = new Get(ROWS[3]); 1912 get.addFamily(FAMILIES[1]); 1913 get.addFamily(FAMILIES[2]); 1914 get.setMaxVersions(Integer.MAX_VALUE); 1915 result = ht.get(get); 1916 assertEquals("Expected 1 key but received " + result.size(), 1, result.size()); 1917 1918 get = new Get(ROWS[4]); 1919 get.addFamily(FAMILIES[1]); 1920 get.addFamily(FAMILIES[2]); 1921 get.setMaxVersions(Integer.MAX_VALUE); 1922 result = ht.get(get); 1923 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1924 1925 scan = new Scan(ROWS[3]); 1926 scan.addFamily(FAMILIES[1]); 1927 scan.addFamily(FAMILIES[2]); 1928 scan.setMaxVersions(Integer.MAX_VALUE); 1929 try (ResultScanner scanner = ht.getScanner(scan)) { 1930 result = scanner.next(); 1931 assertEquals("Expected 1 key but received " + result.size(), 1, result.size()); 1932 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3])); 1933 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0])); 1934 result = scanner.next(); 1935 assertEquals("Expected 2 keys but received " + result.size(), 2, result.size()); 1936 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4])); 1937 assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4])); 1938 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1])); 1939 assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2])); 1940 } 1941 1942 // Add test of bulk deleting. 1943 for (int i = 0; i < 10; i++) { 1944 byte[] bytes = Bytes.toBytes(i); 1945 put = new Put(bytes); 1946 put.setDurability(Durability.SKIP_WAL); 1947 put.addColumn(FAMILIES[0], QUALIFIER, bytes); 1948 ht.put(put); 1949 } 1950 for (int i = 0; i < 10; i++) { 1951 byte[] bytes = Bytes.toBytes(i); 1952 get = new Get(bytes); 1953 get.addFamily(FAMILIES[0]); 1954 result = ht.get(get); 1955 assertEquals(1, result.size()); 1956 } 1957 ArrayList<Delete> deletes = new ArrayList<>(); 1958 for (int i = 0; i < 10; i++) { 1959 byte[] bytes = Bytes.toBytes(i); 1960 delete = new Delete(bytes); 1961 delete.addFamily(FAMILIES[0]); 1962 deletes.add(delete); 1963 } 1964 ht.delete(deletes); 1965 for (int i = 0; i < 10; i++) { 1966 byte[] bytes = Bytes.toBytes(i); 1967 get = new Get(bytes); 1968 get.addFamily(FAMILIES[0]); 1969 result = ht.get(get); 1970 assertTrue(result.isEmpty()); 1971 } 1972 } 1973 } 1974}