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