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.rest; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertTrue; 023 024import java.io.ByteArrayInputStream; 025import java.io.StringWriter; 026import java.util.ArrayList; 027import java.util.Arrays; 028import java.util.Iterator; 029import java.util.List; 030import javax.xml.bind.JAXBContext; 031import javax.xml.bind.Marshaller; 032import javax.xml.bind.Unmarshaller; 033import org.apache.hadoop.hbase.CellUtil; 034import org.apache.hadoop.hbase.CompareOperator; 035import org.apache.hadoop.hbase.HBaseClassTestRule; 036import org.apache.hadoop.hbase.HBaseTestingUtility; 037import org.apache.hadoop.hbase.HColumnDescriptor; 038import org.apache.hadoop.hbase.HConstants; 039import org.apache.hadoop.hbase.HTableDescriptor; 040import org.apache.hadoop.hbase.KeyValue; 041import org.apache.hadoop.hbase.TableName; 042import org.apache.hadoop.hbase.client.Admin; 043import org.apache.hadoop.hbase.client.Delete; 044import org.apache.hadoop.hbase.client.Durability; 045import org.apache.hadoop.hbase.client.Put; 046import org.apache.hadoop.hbase.client.Scan; 047import org.apache.hadoop.hbase.client.Table; 048import org.apache.hadoop.hbase.filter.BinaryComparator; 049import org.apache.hadoop.hbase.filter.Filter; 050import org.apache.hadoop.hbase.filter.FilterList; 051import org.apache.hadoop.hbase.filter.FilterList.Operator; 052import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; 053import org.apache.hadoop.hbase.filter.InclusiveStopFilter; 054import org.apache.hadoop.hbase.filter.PageFilter; 055import org.apache.hadoop.hbase.filter.PrefixFilter; 056import org.apache.hadoop.hbase.filter.QualifierFilter; 057import org.apache.hadoop.hbase.filter.RegexStringComparator; 058import org.apache.hadoop.hbase.filter.RowFilter; 059import org.apache.hadoop.hbase.filter.SkipFilter; 060import org.apache.hadoop.hbase.filter.SubstringComparator; 061import org.apache.hadoop.hbase.filter.ValueFilter; 062import org.apache.hadoop.hbase.rest.client.Client; 063import org.apache.hadoop.hbase.rest.client.Cluster; 064import org.apache.hadoop.hbase.rest.client.Response; 065import org.apache.hadoop.hbase.rest.model.CellModel; 066import org.apache.hadoop.hbase.rest.model.CellSetModel; 067import org.apache.hadoop.hbase.rest.model.RowModel; 068import org.apache.hadoop.hbase.rest.model.ScannerModel; 069import org.apache.hadoop.hbase.testclassification.MediumTests; 070import org.apache.hadoop.hbase.testclassification.RestTests; 071import org.apache.hadoop.hbase.util.Bytes; 072import org.junit.AfterClass; 073import org.junit.BeforeClass; 074import org.junit.ClassRule; 075import org.junit.Test; 076import org.junit.experimental.categories.Category; 077import org.slf4j.Logger; 078import org.slf4j.LoggerFactory; 079 080@Category({RestTests.class, MediumTests.class}) 081public class TestScannersWithFilters { 082 083 @ClassRule 084 public static final HBaseClassTestRule CLASS_RULE = 085 HBaseClassTestRule.forClass(TestScannersWithFilters.class); 086 087 private static final Logger LOG = LoggerFactory.getLogger(TestScannersWithFilters.class); 088 089 private static final TableName TABLE = TableName.valueOf("TestScannersWithFilters"); 090 091 private static final byte [][] ROWS_ONE = { 092 Bytes.toBytes("testRowOne-0"), Bytes.toBytes("testRowOne-1"), 093 Bytes.toBytes("testRowOne-2"), Bytes.toBytes("testRowOne-3") 094 }; 095 096 private static final byte [][] ROWS_TWO = { 097 Bytes.toBytes("testRowTwo-0"), Bytes.toBytes("testRowTwo-1"), 098 Bytes.toBytes("testRowTwo-2"), Bytes.toBytes("testRowTwo-3") 099 }; 100 101 private static final byte [][] FAMILIES = { 102 Bytes.toBytes("testFamilyOne"), Bytes.toBytes("testFamilyTwo") 103 }; 104 105 private static final byte [][] QUALIFIERS_ONE = { 106 Bytes.toBytes("testQualifierOne-0"), Bytes.toBytes("testQualifierOne-1"), 107 Bytes.toBytes("testQualifierOne-2"), Bytes.toBytes("testQualifierOne-3") 108 }; 109 110 private static final byte [][] QUALIFIERS_TWO = { 111 Bytes.toBytes("testQualifierTwo-0"), Bytes.toBytes("testQualifierTwo-1"), 112 Bytes.toBytes("testQualifierTwo-2"), Bytes.toBytes("testQualifierTwo-3") 113 }; 114 115 private static final byte [][] VALUES = { 116 Bytes.toBytes("testValueOne"), Bytes.toBytes("testValueTwo") 117 }; 118 119 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 120 private static final HBaseRESTTestingUtility REST_TEST_UTIL = 121 new HBaseRESTTestingUtility(); 122 private static Client client; 123 private static JAXBContext context; 124 private static Marshaller marshaller; 125 private static Unmarshaller unmarshaller; 126 private static long numRows = (long) ROWS_ONE.length + ROWS_TWO.length; 127 private static long colsPerRow = (long) FAMILIES.length * QUALIFIERS_ONE.length; 128 129 @BeforeClass 130 public static void setUpBeforeClass() throws Exception { 131 TEST_UTIL.startMiniCluster(3); 132 REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); 133 context = JAXBContext.newInstance( 134 CellModel.class, 135 CellSetModel.class, 136 RowModel.class, 137 ScannerModel.class); 138 marshaller = context.createMarshaller(); 139 unmarshaller = context.createUnmarshaller(); 140 client = new Client(new Cluster().add("localhost", 141 REST_TEST_UTIL.getServletPort())); 142 Admin admin = TEST_UTIL.getAdmin(); 143 if (!admin.tableExists(TABLE)) { 144 HTableDescriptor htd = new HTableDescriptor(TABLE); 145 htd.addFamily(new HColumnDescriptor(FAMILIES[0])); 146 htd.addFamily(new HColumnDescriptor(FAMILIES[1])); 147 admin.createTable(htd); 148 Table table = TEST_UTIL.getConnection().getTable(TABLE); 149 // Insert first half 150 for(byte [] ROW : ROWS_ONE) { 151 Put p = new Put(ROW); 152 p.setDurability(Durability.SKIP_WAL); 153 for(byte [] QUALIFIER : QUALIFIERS_ONE) { 154 p.addColumn(FAMILIES[0], QUALIFIER, VALUES[0]); 155 } 156 table.put(p); 157 } 158 for(byte [] ROW : ROWS_TWO) { 159 Put p = new Put(ROW); 160 p.setDurability(Durability.SKIP_WAL); 161 for(byte [] QUALIFIER : QUALIFIERS_TWO) { 162 p.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]); 163 } 164 table.put(p); 165 } 166 167 // Insert second half (reverse families) 168 for(byte [] ROW : ROWS_ONE) { 169 Put p = new Put(ROW); 170 p.setDurability(Durability.SKIP_WAL); 171 for(byte [] QUALIFIER : QUALIFIERS_ONE) { 172 p.addColumn(FAMILIES[1], QUALIFIER, VALUES[0]); 173 } 174 table.put(p); 175 } 176 for(byte [] ROW : ROWS_TWO) { 177 Put p = new Put(ROW); 178 p.setDurability(Durability.SKIP_WAL); 179 for(byte [] QUALIFIER : QUALIFIERS_TWO) { 180 p.addColumn(FAMILIES[0], QUALIFIER, VALUES[1]); 181 } 182 table.put(p); 183 } 184 185 // Delete the second qualifier from all rows and families 186 for(byte [] ROW : ROWS_ONE) { 187 Delete d = new Delete(ROW); 188 d.addColumns(FAMILIES[0], QUALIFIERS_ONE[1]); 189 d.addColumns(FAMILIES[1], QUALIFIERS_ONE[1]); 190 table.delete(d); 191 } 192 for(byte [] ROW : ROWS_TWO) { 193 Delete d = new Delete(ROW); 194 d.addColumns(FAMILIES[0], QUALIFIERS_TWO[1]); 195 d.addColumns(FAMILIES[1], QUALIFIERS_TWO[1]); 196 table.delete(d); 197 } 198 colsPerRow -= 2; 199 200 // Delete the second rows from both groups, one column at a time 201 for(byte [] QUALIFIER : QUALIFIERS_ONE) { 202 Delete d = new Delete(ROWS_ONE[1]); 203 d.addColumns(FAMILIES[0], QUALIFIER); 204 d.addColumns(FAMILIES[1], QUALIFIER); 205 table.delete(d); 206 } 207 for(byte [] QUALIFIER : QUALIFIERS_TWO) { 208 Delete d = new Delete(ROWS_TWO[1]); 209 d.addColumns(FAMILIES[0], QUALIFIER); 210 d.addColumns(FAMILIES[1], QUALIFIER); 211 table.delete(d); 212 } 213 numRows -= 2; 214 table.close(); 215 } 216 } 217 218 @AfterClass 219 public static void tearDownAfterClass() throws Exception { 220 REST_TEST_UTIL.shutdownServletContainer(); 221 TEST_UTIL.shutdownMiniCluster(); 222 } 223 224 private static void verifyScan(Scan s, long expectedRows, long expectedKeys) 225 throws Exception { 226 ScannerModel model = ScannerModel.fromScan(s); 227 model.setBatch(Integer.MAX_VALUE); // fetch it all at once 228 StringWriter writer = new StringWriter(); 229 marshaller.marshal(model, writer); 230 LOG.debug(writer.toString()); 231 byte[] body = Bytes.toBytes(writer.toString()); 232 Response response = client.put("/" + TABLE + "/scanner", 233 Constants.MIMETYPE_XML, body); 234 assertEquals(201, response.getCode()); 235 String scannerURI = response.getLocation(); 236 assertNotNull(scannerURI); 237 238 // get a cell set 239 response = client.get(scannerURI, Constants.MIMETYPE_XML); 240 assertEquals(200, response.getCode()); 241 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); 242 CellSetModel cells = (CellSetModel) 243 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 244 245 int rows = cells.getRows().size(); 246 assertTrue("Scanned too many rows! Only expected " + expectedRows + 247 " total but scanned " + rows, expectedRows == rows); 248 for (RowModel row: cells.getRows()) { 249 int count = row.getCells().size(); 250 assertEquals("Expected " + expectedKeys + " keys per row but " + 251 "returned " + count, expectedKeys, count); 252 } 253 254 // delete the scanner 255 response = client.delete(scannerURI); 256 assertEquals(200, response.getCode()); 257 } 258 259 private static void verifyScanFull(Scan s, KeyValue [] kvs) 260 throws Exception { 261 ScannerModel model = ScannerModel.fromScan(s); 262 model.setBatch(Integer.MAX_VALUE); // fetch it all at once 263 StringWriter writer = new StringWriter(); 264 marshaller.marshal(model, writer); 265 LOG.debug(writer.toString()); 266 byte[] body = Bytes.toBytes(writer.toString()); 267 Response response = client.put("/" + TABLE + "/scanner", 268 Constants.MIMETYPE_XML, body); 269 assertEquals(201, response.getCode()); 270 String scannerURI = response.getLocation(); 271 assertNotNull(scannerURI); 272 273 // get a cell set 274 response = client.get(scannerURI, Constants.MIMETYPE_XML); 275 assertEquals(200, response.getCode()); 276 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); 277 CellSetModel cellSet = (CellSetModel) 278 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 279 280 // delete the scanner 281 response = client.delete(scannerURI); 282 assertEquals(200, response.getCode()); 283 284 int row = 0; 285 int idx = 0; 286 Iterator<RowModel> i = cellSet.getRows().iterator(); 287 for (boolean done = true; done; row++) { 288 done = i.hasNext(); 289 if (!done) break; 290 RowModel rowModel = i.next(); 291 List<CellModel> cells = rowModel.getCells(); 292 if (cells.isEmpty()) break; 293 assertTrue("Scanned too many keys! Only expected " + kvs.length + 294 " total but already scanned " + (cells.size() + idx), 295 kvs.length >= idx + cells.size()); 296 for (CellModel cell: cells) { 297 assertTrue("Row mismatch", 298 Bytes.equals(rowModel.getKey(), CellUtil.cloneRow(kvs[idx]))); 299 byte[][] split = CellUtil.parseColumn(cell.getColumn()); 300 assertTrue("Family mismatch", 301 Bytes.equals(split[0], CellUtil.cloneFamily(kvs[idx]))); 302 assertTrue("Qualifier mismatch", 303 Bytes.equals(split[1], CellUtil.cloneQualifier(kvs[idx]))); 304 assertTrue("Value mismatch", 305 Bytes.equals(cell.getValue(), CellUtil.cloneValue(kvs[idx]))); 306 idx++; 307 } 308 } 309 assertEquals("Expected " + kvs.length + " total keys but scanned " + idx, 310 kvs.length, idx); 311 } 312 313 private static void verifyScanNoEarlyOut(Scan s, long expectedRows, 314 long expectedKeys) throws Exception { 315 ScannerModel model = ScannerModel.fromScan(s); 316 model.setBatch(Integer.MAX_VALUE); // fetch it all at once 317 StringWriter writer = new StringWriter(); 318 marshaller.marshal(model, writer); 319 LOG.debug(writer.toString()); 320 byte[] body = Bytes.toBytes(writer.toString()); 321 Response response = client.put("/" + TABLE + "/scanner", 322 Constants.MIMETYPE_XML, body); 323 assertEquals(201, response.getCode()); 324 String scannerURI = response.getLocation(); 325 assertNotNull(scannerURI); 326 327 // get a cell set 328 response = client.get(scannerURI, Constants.MIMETYPE_XML); 329 assertEquals(200, response.getCode()); 330 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); 331 CellSetModel cellSet = (CellSetModel) 332 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 333 334 // delete the scanner 335 response = client.delete(scannerURI); 336 assertEquals(200, response.getCode()); 337 338 Iterator<RowModel> i = cellSet.getRows().iterator(); 339 int j = 0; 340 for (boolean done = true; done; j++) { 341 done = i.hasNext(); 342 if (!done) break; 343 RowModel rowModel = i.next(); 344 List<CellModel> cells = rowModel.getCells(); 345 if (cells.isEmpty()) break; 346 assertTrue("Scanned too many rows! Only expected " + expectedRows + 347 " total but already scanned " + (j+1), expectedRows > j); 348 assertEquals("Expected " + expectedKeys + " keys per row but " + 349 "returned " + cells.size(), expectedKeys, cells.size()); 350 } 351 assertEquals("Expected " + expectedRows + " rows but scanned " + j + 352 " rows", expectedRows, j); 353 } 354 355 @Test 356 public void testNoFilter() throws Exception { 357 // No filter 358 long expectedRows = numRows; 359 long expectedKeys = colsPerRow; 360 361 // Both families 362 Scan s = new Scan(); 363 verifyScan(s, expectedRows, expectedKeys); 364 365 // One family 366 s = new Scan(); 367 s.addFamily(FAMILIES[0]); 368 verifyScan(s, expectedRows, expectedKeys/2); 369 } 370 371 @Test 372 public void testPrefixFilter() throws Exception { 373 // Grab rows from group one (half of total) 374 long expectedRows = numRows / 2; 375 long expectedKeys = colsPerRow; 376 Scan s = new Scan(); 377 s.setFilter(new PrefixFilter(Bytes.toBytes("testRowOne"))); 378 verifyScan(s, expectedRows, expectedKeys); 379 } 380 381 @Test 382 public void testPageFilter() throws Exception { 383 // KVs in first 6 rows 384 KeyValue [] expectedKVs = { 385 // testRowOne-0 386 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 387 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 388 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 389 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 390 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 391 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 392 // testRowOne-2 393 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 394 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 395 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 396 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 397 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 398 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 399 // testRowOne-3 400 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 401 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 402 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 403 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 404 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 405 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 406 // testRowTwo-0 407 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 408 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 409 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 410 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 411 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 412 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 413 // testRowTwo-2 414 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 415 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 416 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 417 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 418 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 419 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 420 // testRowTwo-3 421 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 422 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 423 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 424 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 425 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 426 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]) 427 }; 428 429 // Grab all 6 rows 430 long expectedRows = 6; 431 long expectedKeys = colsPerRow; 432 Scan s = new Scan(); 433 s.setFilter(new PageFilter(expectedRows)); 434 verifyScan(s, expectedRows, expectedKeys); 435 s.setFilter(new PageFilter(expectedRows)); 436 verifyScanFull(s, expectedKVs); 437 438 // Grab first 4 rows (6 cols per row) 439 expectedRows = 4; 440 expectedKeys = colsPerRow; 441 s = new Scan(); 442 s.setFilter(new PageFilter(expectedRows)); 443 verifyScan(s, expectedRows, expectedKeys); 444 s.setFilter(new PageFilter(expectedRows)); 445 verifyScanFull(s, Arrays.copyOf(expectedKVs, 24)); 446 447 // Grab first 2 rows 448 expectedRows = 2; 449 expectedKeys = colsPerRow; 450 s = new Scan(); 451 s.setFilter(new PageFilter(expectedRows)); 452 verifyScan(s, expectedRows, expectedKeys); 453 s.setFilter(new PageFilter(expectedRows)); 454 verifyScanFull(s, Arrays.copyOf(expectedKVs, 12)); 455 456 // Grab first row 457 expectedRows = 1; 458 expectedKeys = colsPerRow; 459 s = new Scan(); 460 s.setFilter(new PageFilter(expectedRows)); 461 verifyScan(s, expectedRows, expectedKeys); 462 s.setFilter(new PageFilter(expectedRows)); 463 verifyScanFull(s, Arrays.copyOf(expectedKVs, 6)); 464 } 465 466 @Test 467 public void testInclusiveStopFilter() throws Exception { 468 // Grab rows from group one 469 470 // If we just use start/stop row, we get total/2 - 1 rows 471 long expectedRows = (numRows / 2) - 1; 472 long expectedKeys = colsPerRow; 473 Scan s = new Scan(Bytes.toBytes("testRowOne-0"), 474 Bytes.toBytes("testRowOne-3")); 475 verifyScan(s, expectedRows, expectedKeys); 476 477 // Now use start row with inclusive stop filter 478 expectedRows = numRows / 2; 479 s = new Scan(Bytes.toBytes("testRowOne-0")); 480 s.setFilter(new InclusiveStopFilter(Bytes.toBytes("testRowOne-3"))); 481 verifyScan(s, expectedRows, expectedKeys); 482 483 // Grab rows from group two 484 485 // If we just use start/stop row, we get total/2 - 1 rows 486 expectedRows = (numRows / 2) - 1; 487 expectedKeys = colsPerRow; 488 s = new Scan(Bytes.toBytes("testRowTwo-0"), 489 Bytes.toBytes("testRowTwo-3")); 490 verifyScan(s, expectedRows, expectedKeys); 491 492 // Now use start row with inclusive stop filter 493 expectedRows = numRows / 2; 494 s = new Scan(Bytes.toBytes("testRowTwo-0")); 495 s.setFilter(new InclusiveStopFilter(Bytes.toBytes("testRowTwo-3"))); 496 verifyScan(s, expectedRows, expectedKeys); 497 } 498 499 @Test 500 public void testQualifierFilter() throws Exception { 501 // Match two keys (one from each family) in half the rows 502 long expectedRows = numRows / 2; 503 long expectedKeys = 2; 504 Filter f = new QualifierFilter(CompareOperator.EQUAL, 505 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 506 Scan s = new Scan(); 507 s.setFilter(f); 508 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 509 510 // Match keys less than same qualifier 511 // Expect only two keys (one from each family) in half the rows 512 expectedRows = numRows / 2; 513 expectedKeys = 2; 514 f = new QualifierFilter(CompareOperator.LESS, 515 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 516 s = new Scan(); 517 s.setFilter(f); 518 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 519 520 // Match keys less than or equal 521 // Expect four keys (two from each family) in half the rows 522 expectedRows = numRows / 2; 523 expectedKeys = 4; 524 f = new QualifierFilter(CompareOperator.LESS_OR_EQUAL, 525 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 526 s = new Scan(); 527 s.setFilter(f); 528 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 529 530 // Match keys not equal 531 // Expect four keys (two from each family) 532 // Only look in first group of rows 533 expectedRows = numRows / 2; 534 expectedKeys = 4; 535 f = new QualifierFilter(CompareOperator.NOT_EQUAL, 536 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 537 s = new Scan(HConstants.EMPTY_START_ROW, Bytes.toBytes("testRowTwo")); 538 s.setFilter(f); 539 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 540 541 // Match keys greater or equal 542 // Expect four keys (two from each family) 543 // Only look in first group of rows 544 expectedRows = numRows / 2; 545 expectedKeys = 4; 546 f = new QualifierFilter(CompareOperator.GREATER_OR_EQUAL, 547 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 548 s = new Scan(HConstants.EMPTY_START_ROW, Bytes.toBytes("testRowTwo")); 549 s.setFilter(f); 550 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 551 552 // Match keys greater 553 // Expect two keys (one from each family) 554 // Only look in first group of rows 555 expectedRows = numRows / 2; 556 expectedKeys = 2; 557 f = new QualifierFilter(CompareOperator.GREATER, 558 new BinaryComparator(Bytes.toBytes("testQualifierOne-2"))); 559 s = new Scan(HConstants.EMPTY_START_ROW, Bytes.toBytes("testRowTwo")); 560 s.setFilter(f); 561 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 562 563 // Match keys not equal to 564 // Look across rows and fully validate the keys and ordering 565 // Expect varied numbers of keys, 4 per row in group one, 6 per row in 566 // group two 567 f = new QualifierFilter(CompareOperator.NOT_EQUAL, 568 new BinaryComparator(QUALIFIERS_ONE[2])); 569 s = new Scan(); 570 s.setFilter(f); 571 572 KeyValue [] kvs = { 573 // testRowOne-0 574 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 575 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 576 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 577 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 578 // testRowOne-2 579 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 580 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 581 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 582 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 583 // testRowOne-3 584 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 585 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 586 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 587 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 588 // testRowTwo-0 589 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 590 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 591 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 592 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 593 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 594 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 595 // testRowTwo-2 596 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 597 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 598 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 599 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 600 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 601 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 602 // testRowTwo-3 603 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 604 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 605 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 606 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 607 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 608 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 609 }; 610 verifyScanFull(s, kvs); 611 612 // Test across rows and groups with a regex 613 // Filter out "test*-2" 614 // Expect 4 keys per row across both groups 615 f = new QualifierFilter(CompareOperator.NOT_EQUAL, 616 new RegexStringComparator("test.+-2")); 617 s = new Scan(); 618 s.setFilter(f); 619 620 kvs = new KeyValue [] { 621 // testRowOne-0 622 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 623 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 624 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 625 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 626 // testRowOne-2 627 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 628 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 629 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 630 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 631 // testRowOne-3 632 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 633 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 634 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 635 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 636 // testRowTwo-0 637 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 638 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 639 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 640 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 641 // testRowTwo-2 642 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 643 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 644 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 645 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 646 // testRowTwo-3 647 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 648 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 649 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 650 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 651 }; 652 verifyScanFull(s, kvs); 653 } 654 655 @Test 656 public void testRowFilter() throws Exception { 657 // Match a single row, all keys 658 long expectedRows = 1; 659 long expectedKeys = colsPerRow; 660 Filter f = new RowFilter(CompareOperator.EQUAL, 661 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 662 Scan s = new Scan(); 663 s.setFilter(f); 664 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 665 666 // Match a two rows, one from each group, using regex 667 expectedRows = 2; 668 expectedKeys = colsPerRow; 669 f = new RowFilter(CompareOperator.EQUAL, 670 new RegexStringComparator("testRow.+-2")); 671 s = new Scan(); 672 s.setFilter(f); 673 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 674 675 // Match rows less than 676 // Expect all keys in one row 677 expectedRows = 1; 678 expectedKeys = colsPerRow; 679 f = new RowFilter(CompareOperator.LESS, 680 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 681 s = new Scan(); 682 s.setFilter(f); 683 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 684 685 // Match rows less than or equal 686 // Expect all keys in two rows 687 expectedRows = 2; 688 expectedKeys = colsPerRow; 689 f = new RowFilter(CompareOperator.LESS_OR_EQUAL, 690 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 691 s = new Scan(); 692 s.setFilter(f); 693 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 694 695 // Match rows not equal 696 // Expect all keys in all but one row 697 expectedRows = numRows - 1; 698 expectedKeys = colsPerRow; 699 f = new RowFilter(CompareOperator.NOT_EQUAL, 700 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 701 s = new Scan(); 702 s.setFilter(f); 703 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 704 705 // Match keys greater or equal 706 // Expect all keys in all but one row 707 expectedRows = numRows - 1; 708 expectedKeys = colsPerRow; 709 f = new RowFilter(CompareOperator.GREATER_OR_EQUAL, 710 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 711 s = new Scan(); 712 s.setFilter(f); 713 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 714 715 // Match keys greater 716 // Expect all keys in all but two rows 717 expectedRows = numRows - 2; 718 expectedKeys = colsPerRow; 719 f = new RowFilter(CompareOperator.GREATER, 720 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 721 s = new Scan(); 722 s.setFilter(f); 723 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 724 725 // Match rows not equal to testRowTwo-2 726 // Look across rows and fully validate the keys and ordering 727 // Should see all keys in all rows but testRowTwo-2 728 f = new RowFilter(CompareOperator.NOT_EQUAL, 729 new BinaryComparator(Bytes.toBytes("testRowOne-2"))); 730 s = new Scan(); 731 s.setFilter(f); 732 733 KeyValue [] kvs = { 734 // testRowOne-0 735 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 736 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 737 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 738 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 739 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 740 new KeyValue(ROWS_ONE[0], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 741 // testRowOne-3 742 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 743 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 744 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 745 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 746 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 747 new KeyValue(ROWS_ONE[3], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 748 // testRowTwo-0 749 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 750 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 751 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 752 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 753 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 754 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 755 // testRowTwo-2 756 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 757 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 758 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 759 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 760 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 761 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 762 // testRowTwo-3 763 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 764 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 765 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 766 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 767 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 768 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 769 }; 770 verifyScanFull(s, kvs); 771 772 // Test across rows and groups with a regex 773 // Filter out everything that doesn't match "*-2" 774 // Expect all keys in two rows 775 f = new RowFilter(CompareOperator.EQUAL, 776 new RegexStringComparator(".+-2")); 777 s = new Scan(); 778 s.setFilter(f); 779 780 kvs = new KeyValue [] { 781 // testRowOne-2 782 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 783 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), 784 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), 785 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[0], VALUES[0]), 786 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[2], VALUES[0]), 787 new KeyValue(ROWS_ONE[2], FAMILIES[1], QUALIFIERS_ONE[3], VALUES[0]), 788 // testRowTwo-2 789 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 790 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 791 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 792 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 793 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 794 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]) 795 }; 796 verifyScanFull(s, kvs); 797 } 798 799 @Test 800 public void testValueFilter() throws Exception { 801 // Match group one rows 802 long expectedRows = numRows / 2; 803 long expectedKeys = colsPerRow; 804 Filter f = new ValueFilter(CompareOperator.EQUAL, 805 new BinaryComparator(Bytes.toBytes("testValueOne"))); 806 Scan s = new Scan(); 807 s.setFilter(f); 808 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 809 810 // Match group two rows 811 expectedRows = numRows / 2; 812 expectedKeys = colsPerRow; 813 f = new ValueFilter(CompareOperator.EQUAL, 814 new BinaryComparator(Bytes.toBytes("testValueTwo"))); 815 s = new Scan(); 816 s.setFilter(f); 817 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 818 819 // Match all values using regex 820 expectedRows = numRows; 821 expectedKeys = colsPerRow; 822 f = new ValueFilter(CompareOperator.EQUAL, 823 new RegexStringComparator("testValue((One)|(Two))")); 824 s = new Scan(); 825 s.setFilter(f); 826 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 827 828 // Match values less than 829 // Expect group one rows 830 expectedRows = numRows / 2; 831 expectedKeys = colsPerRow; 832 f = new ValueFilter(CompareOperator.LESS, 833 new BinaryComparator(Bytes.toBytes("testValueTwo"))); 834 s = new Scan(); 835 s.setFilter(f); 836 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 837 838 // Match values less than or equal 839 // Expect all rows 840 expectedRows = numRows; 841 expectedKeys = colsPerRow; 842 f = new ValueFilter(CompareOperator.LESS_OR_EQUAL, 843 new BinaryComparator(Bytes.toBytes("testValueTwo"))); 844 s = new Scan(); 845 s.setFilter(f); 846 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 847 848 // Match values less than or equal 849 // Expect group one rows 850 expectedRows = numRows / 2; 851 expectedKeys = colsPerRow; 852 f = new ValueFilter(CompareOperator.LESS_OR_EQUAL, 853 new BinaryComparator(Bytes.toBytes("testValueOne"))); 854 s = new Scan(); 855 s.setFilter(f); 856 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 857 858 // Match values not equal 859 // Expect half the rows 860 expectedRows = numRows / 2; 861 expectedKeys = colsPerRow; 862 f = new ValueFilter(CompareOperator.NOT_EQUAL, 863 new BinaryComparator(Bytes.toBytes("testValueOne"))); 864 s = new Scan(); 865 s.setFilter(f); 866 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 867 868 // Match values greater or equal 869 // Expect all rows 870 expectedRows = numRows; 871 expectedKeys = colsPerRow; 872 f = new ValueFilter(CompareOperator.GREATER_OR_EQUAL, 873 new BinaryComparator(Bytes.toBytes("testValueOne"))); 874 s = new Scan(); 875 s.setFilter(f); 876 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 877 878 // Match values greater 879 // Expect half rows 880 expectedRows = numRows / 2; 881 expectedKeys = colsPerRow; 882 f = new ValueFilter(CompareOperator.GREATER, 883 new BinaryComparator(Bytes.toBytes("testValueOne"))); 884 s = new Scan(); 885 s.setFilter(f); 886 verifyScanNoEarlyOut(s, expectedRows, expectedKeys); 887 888 // Match values not equal to testValueOne 889 // Look across rows and fully validate the keys and ordering 890 // Should see all keys in all group two rows 891 f = new ValueFilter(CompareOperator.NOT_EQUAL, 892 new BinaryComparator(Bytes.toBytes("testValueOne"))); 893 s = new Scan(); 894 s.setFilter(f); 895 896 KeyValue [] kvs = { 897 // testRowTwo-0 898 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 899 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 900 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 901 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 902 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 903 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 904 // testRowTwo-2 905 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 906 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 907 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 908 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 909 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 910 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 911 // testRowTwo-3 912 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 913 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 914 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 915 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 916 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 917 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 918 }; 919 verifyScanFull(s, kvs); 920 } 921 922 @Test 923 public void testSkipFilter() throws Exception { 924 // Test for qualifier regex: "testQualifierOne-2" 925 // Should only get rows from second group, and all keys 926 Filter f = new SkipFilter(new QualifierFilter(CompareOperator.NOT_EQUAL, 927 new BinaryComparator(Bytes.toBytes("testQualifierOne-2")))); 928 Scan s = new Scan(); 929 s.setFilter(f); 930 931 KeyValue [] kvs = { 932 // testRowTwo-0 933 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 934 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 935 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 936 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 937 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 938 new KeyValue(ROWS_TWO[0], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 939 // testRowTwo-2 940 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 941 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 942 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 943 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 944 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 945 new KeyValue(ROWS_TWO[2], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 946 // testRowTwo-3 947 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 948 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), 949 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), 950 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[0], VALUES[1]), 951 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[2], VALUES[1]), 952 new KeyValue(ROWS_TWO[3], FAMILIES[1], QUALIFIERS_TWO[3], VALUES[1]), 953 }; 954 verifyScanFull(s, kvs); 955 } 956 957 @Test 958 public void testFilterList() throws Exception { 959 // Test getting a single row, single key using Row, Qualifier, and Value 960 // regular expression and substring filters 961 // Use must pass all 962 List<Filter> filters = new ArrayList<>(3); 963 filters.add(new RowFilter(CompareOperator.EQUAL, 964 new RegexStringComparator(".+-2"))); 965 filters.add(new QualifierFilter(CompareOperator.EQUAL, 966 new RegexStringComparator(".+-2"))); 967 filters.add(new ValueFilter(CompareOperator.EQUAL, 968 new SubstringComparator("One"))); 969 Filter f = new FilterList(Operator.MUST_PASS_ALL, filters); 970 Scan s = new Scan(); 971 s.addFamily(FAMILIES[0]); 972 s.setFilter(f); 973 KeyValue [] kvs = { 974 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]) 975 }; 976 verifyScanFull(s, kvs); 977 978 // Test getting everything with a MUST_PASS_ONE filter including row, qf, 979 // val, regular expression and substring filters 980 filters.clear(); 981 filters.add(new RowFilter(CompareOperator.EQUAL, 982 new RegexStringComparator(".+Two.+"))); 983 filters.add(new QualifierFilter(CompareOperator.EQUAL, 984 new RegexStringComparator(".+-2"))); 985 filters.add(new ValueFilter(CompareOperator.EQUAL, 986 new SubstringComparator("One"))); 987 f = new FilterList(Operator.MUST_PASS_ONE, filters); 988 s = new Scan(); 989 s.setFilter(f); 990 verifyScanNoEarlyOut(s, numRows, colsPerRow); 991 } 992 993 @Test 994 public void testFirstKeyOnlyFilter() throws Exception { 995 Scan s = new Scan(); 996 s.setFilter(new FirstKeyOnlyFilter()); 997 // Expected KVs, the first KV from each of the remaining 6 rows 998 KeyValue [] kvs = { 999 new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 1000 new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 1001 new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), 1002 new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 1003 new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), 1004 new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]) 1005 }; 1006 verifyScanFull(s, kvs); 1007 } 1008}