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