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.filter; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.nio.charset.StandardCharsets; 026import java.util.ArrayList; 027import java.util.List; 028import java.util.regex.Pattern; 029import org.apache.hadoop.hbase.CompareOperator; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.testclassification.MediumTests; 032import org.apache.hadoop.hbase.testclassification.RegionServerTests; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.junit.After; 035import org.junit.Before; 036import org.junit.ClassRule; 037import org.junit.Test; 038import org.junit.experimental.categories.Category; 039 040/** 041 * This class tests ParseFilter.java It tests the entire work flow from when a string is given by 042 * the user and how it is parsed to construct the corresponding Filter object 043 */ 044@Category({ RegionServerTests.class, MediumTests.class }) 045public class TestParseFilter { 046 047 @ClassRule 048 public static final HBaseClassTestRule CLASS_RULE = 049 HBaseClassTestRule.forClass(TestParseFilter.class); 050 051 ParseFilter f; 052 Filter filter; 053 054 @Before 055 public void setUp() throws Exception { 056 f = new ParseFilter(); 057 } 058 059 @After 060 public void tearDown() throws Exception { 061 // Nothing to do. 062 } 063 064 @Test 065 public void testKeyOnlyFilter() throws IOException { 066 String filterString = "KeyOnlyFilter()"; 067 doTestFilter(filterString, KeyOnlyFilter.class); 068 069 String filterString2 = "KeyOnlyFilter ('') "; 070 byte[] filterStringAsByteArray2 = Bytes.toBytes(filterString2); 071 try { 072 filter = f.parseFilterString(filterStringAsByteArray2); 073 assertTrue(false); 074 } catch (IllegalArgumentException e) { 075 System.out.println(e.getMessage()); 076 } 077 } 078 079 @Test 080 public void testFirstKeyOnlyFilter() throws IOException { 081 String filterString = " FirstKeyOnlyFilter( ) "; 082 doTestFilter(filterString, FirstKeyOnlyFilter.class); 083 084 String filterString2 = " FirstKeyOnlyFilter ('') "; 085 byte[] filterStringAsByteArray2 = Bytes.toBytes(filterString2); 086 try { 087 filter = f.parseFilterString(filterStringAsByteArray2); 088 assertTrue(false); 089 } catch (IllegalArgumentException e) { 090 System.out.println(e.getMessage()); 091 } 092 } 093 094 @Test 095 public void testPrefixFilter() throws IOException { 096 String filterString = " PrefixFilter('row' ) "; 097 PrefixFilter prefixFilter = doTestFilter(filterString, PrefixFilter.class); 098 byte[] prefix = prefixFilter.getPrefix(); 099 assertEquals("row", new String(prefix, StandardCharsets.UTF_8)); 100 101 filterString = " PrefixFilter(row)"; 102 try { 103 doTestFilter(filterString, PrefixFilter.class); 104 assertTrue(false); 105 } catch (IllegalArgumentException e) { 106 System.out.println(e.getMessage()); 107 } 108 } 109 110 @Test 111 public void testColumnPrefixFilter() throws IOException { 112 String filterString = " ColumnPrefixFilter('qualifier' ) "; 113 ColumnPrefixFilter columnPrefixFilter = doTestFilter(filterString, ColumnPrefixFilter.class); 114 byte[] columnPrefix = columnPrefixFilter.getPrefix(); 115 assertEquals("qualifier", new String(columnPrefix, StandardCharsets.UTF_8)); 116 } 117 118 @Test 119 public void testMultipleColumnPrefixFilter() throws IOException { 120 String filterString = " MultipleColumnPrefixFilter('qualifier1', 'qualifier2' ) "; 121 MultipleColumnPrefixFilter multipleColumnPrefixFilter = 122 doTestFilter(filterString, MultipleColumnPrefixFilter.class); 123 byte[][] prefixes = multipleColumnPrefixFilter.getPrefix(); 124 assertEquals("qualifier1", new String(prefixes[0], StandardCharsets.UTF_8)); 125 assertEquals("qualifier2", new String(prefixes[1], StandardCharsets.UTF_8)); 126 } 127 128 @Test 129 public void testColumnCountGetFilter() throws IOException { 130 String filterString = " ColumnCountGetFilter(4)"; 131 ColumnCountGetFilter columnCountGetFilter = 132 doTestFilter(filterString, ColumnCountGetFilter.class); 133 int limit = columnCountGetFilter.getLimit(); 134 assertEquals(4, limit); 135 136 filterString = " ColumnCountGetFilter('abc')"; 137 try { 138 doTestFilter(filterString, ColumnCountGetFilter.class); 139 assertTrue(false); 140 } catch (IllegalArgumentException e) { 141 System.out.println(e.getMessage()); 142 } 143 144 filterString = " ColumnCountGetFilter(2147483648)"; 145 try { 146 doTestFilter(filterString, ColumnCountGetFilter.class); 147 assertTrue(false); 148 } catch (IllegalArgumentException e) { 149 System.out.println(e.getMessage()); 150 } 151 } 152 153 @Test 154 public void testPageFilter() throws IOException { 155 String filterString = " PageFilter(4)"; 156 PageFilter pageFilter = doTestFilter(filterString, PageFilter.class); 157 long pageSize = pageFilter.getPageSize(); 158 assertEquals(4, pageSize); 159 160 filterString = " PageFilter('123')"; 161 try { 162 doTestFilter(filterString, PageFilter.class); 163 assertTrue(false); 164 } catch (IllegalArgumentException e) { 165 System.out.println("PageFilter needs an int as an argument"); 166 } 167 } 168 169 @Test 170 public void testColumnPaginationFilter() throws IOException { 171 String filterString = "ColumnPaginationFilter(4, 6)"; 172 ColumnPaginationFilter columnPaginationFilter = 173 doTestFilter(filterString, ColumnPaginationFilter.class); 174 int limit = columnPaginationFilter.getLimit(); 175 assertEquals(4, limit); 176 int offset = columnPaginationFilter.getOffset(); 177 assertEquals(6, offset); 178 179 filterString = " ColumnPaginationFilter('124')"; 180 try { 181 doTestFilter(filterString, ColumnPaginationFilter.class); 182 assertTrue(false); 183 } catch (IllegalArgumentException e) { 184 System.out.println("ColumnPaginationFilter needs two arguments"); 185 } 186 187 filterString = " ColumnPaginationFilter('4' , '123a')"; 188 try { 189 doTestFilter(filterString, ColumnPaginationFilter.class); 190 assertTrue(false); 191 } catch (IllegalArgumentException e) { 192 System.out.println("ColumnPaginationFilter needs two ints as arguments"); 193 } 194 195 filterString = " ColumnPaginationFilter('4' , '-123')"; 196 try { 197 doTestFilter(filterString, ColumnPaginationFilter.class); 198 assertTrue(false); 199 } catch (IllegalArgumentException e) { 200 System.out.println("ColumnPaginationFilter arguments should not be negative"); 201 } 202 } 203 204 @Test 205 public void testInclusiveStopFilter() throws IOException { 206 String filterString = "InclusiveStopFilter ('row 3')"; 207 InclusiveStopFilter inclusiveStopFilter = doTestFilter(filterString, InclusiveStopFilter.class); 208 byte[] stopRowKey = inclusiveStopFilter.getStopRowKey(); 209 assertEquals("row 3", new String(stopRowKey, StandardCharsets.UTF_8)); 210 } 211 212 @Test 213 public void testTimestampsFilter() throws IOException { 214 String filterString = "TimestampsFilter(9223372036854775806, 6)"; 215 TimestampsFilter timestampsFilter = doTestFilter(filterString, TimestampsFilter.class); 216 List<Long> timestamps = timestampsFilter.getTimestamps(); 217 assertEquals(2, timestamps.size()); 218 assertEquals(Long.valueOf(6), timestamps.get(0)); 219 220 filterString = "TimestampsFilter()"; 221 timestampsFilter = doTestFilter(filterString, TimestampsFilter.class); 222 timestamps = timestampsFilter.getTimestamps(); 223 assertEquals(0, timestamps.size()); 224 225 filterString = "TimestampsFilter(9223372036854775808, 6)"; 226 try { 227 doTestFilter(filterString, ColumnPaginationFilter.class); 228 assertTrue(false); 229 } catch (IllegalArgumentException e) { 230 System.out.println("Long Argument was too large"); 231 } 232 233 filterString = "TimestampsFilter(-45, 6)"; 234 try { 235 doTestFilter(filterString, ColumnPaginationFilter.class); 236 assertTrue(false); 237 } catch (IllegalArgumentException e) { 238 System.out.println("Timestamp Arguments should not be negative"); 239 } 240 } 241 242 @Test 243 public void testRowFilter() throws IOException { 244 String filterString = "RowFilter ( =, 'binary:regionse')"; 245 RowFilter rowFilter = doTestFilter(filterString, RowFilter.class); 246 assertEquals(CompareOperator.EQUAL, rowFilter.getCompareOperator()); 247 assertTrue(rowFilter.getComparator() instanceof BinaryComparator); 248 BinaryComparator binaryComparator = (BinaryComparator) rowFilter.getComparator(); 249 assertEquals("regionse", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 250 } 251 252 @Test 253 public void testFamilyFilter() throws IOException { 254 String filterString = "FamilyFilter(>=, 'binaryprefix:pre')"; 255 FamilyFilter familyFilter = doTestFilter(filterString, FamilyFilter.class); 256 assertEquals(CompareOperator.GREATER_OR_EQUAL, familyFilter.getCompareOperator()); 257 assertTrue(familyFilter.getComparator() instanceof BinaryPrefixComparator); 258 BinaryPrefixComparator binaryPrefixComparator = 259 (BinaryPrefixComparator) familyFilter.getComparator(); 260 assertEquals("pre", new String(binaryPrefixComparator.getValue(), StandardCharsets.UTF_8)); 261 } 262 263 @Test 264 public void testQualifierFilter() throws IOException { 265 String filterString = "QualifierFilter(=, 'regexstring:pre*')"; 266 QualifierFilter qualifierFilter = doTestFilter(filterString, QualifierFilter.class); 267 assertEquals(CompareOperator.EQUAL, qualifierFilter.getCompareOperator()); 268 assertTrue(qualifierFilter.getComparator() instanceof RegexStringComparator); 269 RegexStringComparator regexStringComparator = 270 (RegexStringComparator) qualifierFilter.getComparator(); 271 assertEquals("pre*", new String(regexStringComparator.getValue(), StandardCharsets.UTF_8)); 272 } 273 274 @Test 275 public void testQualifierFilterNoCase() throws IOException { 276 String filterString = "QualifierFilter(=, 'regexstringnocase:pre*')"; 277 QualifierFilter qualifierFilter = doTestFilter(filterString, QualifierFilter.class); 278 assertEquals(CompareOperator.EQUAL, qualifierFilter.getCompareOperator()); 279 assertTrue(qualifierFilter.getComparator() instanceof RegexStringComparator); 280 RegexStringComparator regexStringComparator = 281 (RegexStringComparator) qualifierFilter.getComparator(); 282 assertEquals("pre*", new String(regexStringComparator.getValue(), StandardCharsets.UTF_8)); 283 int regexComparatorFlags = regexStringComparator.getEngine().getFlags(); 284 assertEquals(Pattern.CASE_INSENSITIVE | Pattern.DOTALL, regexComparatorFlags); 285 } 286 287 @Test 288 public void testValueFilter() throws IOException { 289 String filterString = "ValueFilter(!=, 'substring:pre')"; 290 ValueFilter valueFilter = doTestFilter(filterString, ValueFilter.class); 291 assertEquals(CompareOperator.NOT_EQUAL, valueFilter.getCompareOperator()); 292 assertTrue(valueFilter.getComparator() instanceof SubstringComparator); 293 SubstringComparator substringComparator = (SubstringComparator) valueFilter.getComparator(); 294 assertEquals("pre", new String(substringComparator.getValue(), StandardCharsets.UTF_8)); 295 } 296 297 @Test 298 public void testColumnRangeFilter() throws IOException { 299 String filterString = "ColumnRangeFilter('abc', true, 'xyz', false)"; 300 ColumnRangeFilter columnRangeFilter = doTestFilter(filterString, ColumnRangeFilter.class); 301 assertEquals("abc", new String(columnRangeFilter.getMinColumn(), StandardCharsets.UTF_8)); 302 assertEquals("xyz", new String(columnRangeFilter.getMaxColumn(), StandardCharsets.UTF_8)); 303 assertTrue(columnRangeFilter.isMinColumnInclusive()); 304 assertFalse(columnRangeFilter.isMaxColumnInclusive()); 305 } 306 307 @Test 308 public void testDependentColumnFilter() throws IOException { 309 String filterString = "DependentColumnFilter('family', 'qualifier', true, =, 'binary:abc')"; 310 DependentColumnFilter dependentColumnFilter = 311 doTestFilter(filterString, DependentColumnFilter.class); 312 assertEquals("family", new String(dependentColumnFilter.getFamily(), StandardCharsets.UTF_8)); 313 assertEquals("qualifier", 314 new String(dependentColumnFilter.getQualifier(), StandardCharsets.UTF_8)); 315 assertTrue(dependentColumnFilter.getDropDependentColumn()); 316 assertEquals(CompareOperator.EQUAL, dependentColumnFilter.getCompareOperator()); 317 assertTrue(dependentColumnFilter.getComparator() instanceof BinaryComparator); 318 BinaryComparator binaryComparator = (BinaryComparator) dependentColumnFilter.getComparator(); 319 assertEquals("abc", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 320 } 321 322 @Test 323 public void testSingleColumnValueFilter() throws IOException { 324 String filterString = 325 "SingleColumnValueFilter " + "('family', 'qualifier', >=, 'binary:a', true, false)"; 326 SingleColumnValueFilter singleColumnValueFilter = 327 doTestFilter(filterString, SingleColumnValueFilter.class); 328 assertEquals("family", new String(singleColumnValueFilter.getFamily(), StandardCharsets.UTF_8)); 329 assertEquals("qualifier", 330 new String(singleColumnValueFilter.getQualifier(), StandardCharsets.UTF_8)); 331 assertEquals(CompareOperator.GREATER_OR_EQUAL, singleColumnValueFilter.getCompareOperator()); 332 assertTrue(singleColumnValueFilter.getComparator() instanceof BinaryComparator); 333 BinaryComparator binaryComparator = (BinaryComparator) singleColumnValueFilter.getComparator(); 334 assertEquals("a", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 335 assertTrue(singleColumnValueFilter.getFilterIfMissing()); 336 assertFalse(singleColumnValueFilter.getLatestVersionOnly()); 337 338 filterString = "SingleColumnValueFilter ('family', 'qualifier', >, 'binaryprefix:a')"; 339 singleColumnValueFilter = doTestFilter(filterString, SingleColumnValueFilter.class); 340 assertEquals("family", new String(singleColumnValueFilter.getFamily(), StandardCharsets.UTF_8)); 341 assertEquals("qualifier", 342 new String(singleColumnValueFilter.getQualifier(), StandardCharsets.UTF_8)); 343 assertEquals(CompareOperator.GREATER, singleColumnValueFilter.getCompareOperator()); 344 assertTrue(singleColumnValueFilter.getComparator() instanceof BinaryPrefixComparator); 345 BinaryPrefixComparator binaryPrefixComparator = 346 (BinaryPrefixComparator) singleColumnValueFilter.getComparator(); 347 assertEquals("a", new String(binaryPrefixComparator.getValue(), StandardCharsets.UTF_8)); 348 assertFalse(singleColumnValueFilter.getFilterIfMissing()); 349 assertTrue(singleColumnValueFilter.getLatestVersionOnly()); 350 } 351 352 @Test 353 public void testSingleColumnValueExcludeFilter() throws IOException { 354 String filterString = 355 "SingleColumnValueExcludeFilter ('family', 'qualifier', <, 'binaryprefix:a')"; 356 SingleColumnValueExcludeFilter singleColumnValueExcludeFilter = 357 doTestFilter(filterString, SingleColumnValueExcludeFilter.class); 358 assertEquals(CompareOperator.LESS, singleColumnValueExcludeFilter.getCompareOperator()); 359 assertEquals("family", 360 new String(singleColumnValueExcludeFilter.getFamily(), StandardCharsets.UTF_8)); 361 assertEquals("qualifier", 362 new String(singleColumnValueExcludeFilter.getQualifier(), StandardCharsets.UTF_8)); 363 assertEquals("a", new String(singleColumnValueExcludeFilter.getComparator().getValue(), 364 StandardCharsets.UTF_8)); 365 assertFalse(singleColumnValueExcludeFilter.getFilterIfMissing()); 366 assertTrue(singleColumnValueExcludeFilter.getLatestVersionOnly()); 367 368 filterString = "SingleColumnValueExcludeFilter " 369 + "('family', 'qualifier', <=, 'binaryprefix:a', true, false)"; 370 singleColumnValueExcludeFilter = 371 doTestFilter(filterString, SingleColumnValueExcludeFilter.class); 372 assertEquals("family", 373 new String(singleColumnValueExcludeFilter.getFamily(), StandardCharsets.UTF_8)); 374 assertEquals("qualifier", 375 new String(singleColumnValueExcludeFilter.getQualifier(), StandardCharsets.UTF_8)); 376 assertEquals(CompareOperator.LESS_OR_EQUAL, 377 singleColumnValueExcludeFilter.getCompareOperator()); 378 assertTrue(singleColumnValueExcludeFilter.getComparator() instanceof BinaryPrefixComparator); 379 BinaryPrefixComparator binaryPrefixComparator = 380 (BinaryPrefixComparator) singleColumnValueExcludeFilter.getComparator(); 381 assertEquals("a", new String(binaryPrefixComparator.getValue(), StandardCharsets.UTF_8)); 382 assertTrue(singleColumnValueExcludeFilter.getFilterIfMissing()); 383 assertFalse(singleColumnValueExcludeFilter.getLatestVersionOnly()); 384 } 385 386 @Test 387 public void testSkipFilter() throws IOException { 388 String filterString = "SKIP ValueFilter( =, 'binary:0')"; 389 SkipFilter skipFilter = doTestFilter(filterString, SkipFilter.class); 390 assertTrue(skipFilter.getFilter() instanceof ValueFilter); 391 ValueFilter valueFilter = (ValueFilter) skipFilter.getFilter(); 392 393 assertEquals(CompareOperator.EQUAL, valueFilter.getCompareOperator()); 394 assertTrue(valueFilter.getComparator() instanceof BinaryComparator); 395 BinaryComparator binaryComparator = (BinaryComparator) valueFilter.getComparator(); 396 assertEquals("0", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 397 } 398 399 @Test 400 public void testWhileFilter() throws IOException { 401 String filterString = " WHILE RowFilter ( !=, 'binary:row1')"; 402 WhileMatchFilter whileMatchFilter = doTestFilter(filterString, WhileMatchFilter.class); 403 assertTrue(whileMatchFilter.getFilter() instanceof RowFilter); 404 RowFilter rowFilter = (RowFilter) whileMatchFilter.getFilter(); 405 406 assertEquals(CompareOperator.NOT_EQUAL, rowFilter.getCompareOperator()); 407 assertTrue(rowFilter.getComparator() instanceof BinaryComparator); 408 BinaryComparator binaryComparator = (BinaryComparator) rowFilter.getComparator(); 409 assertEquals("row1", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 410 } 411 412 @Test 413 public void testCompoundFilter1() throws IOException { 414 String filterString = " (PrefixFilter ('realtime')AND FirstKeyOnlyFilter())"; 415 FilterList filterList = doTestFilter(filterString, FilterList.class); 416 ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters(); 417 418 assertTrue(filters.get(0) instanceof PrefixFilter); 419 assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter); 420 PrefixFilter PrefixFilter = (PrefixFilter) filters.get(0); 421 byte[] prefix = PrefixFilter.getPrefix(); 422 assertEquals("realtime", new String(prefix, StandardCharsets.UTF_8)); 423 FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1); 424 } 425 426 @Test 427 public void testCompoundFilter2() throws IOException { 428 String filterString = "(PrefixFilter('realtime') AND QualifierFilter (>=, 'binary:e'))" 429 + "OR FamilyFilter (=, 'binary:qualifier') "; 430 FilterList filterList = doTestFilter(filterString, FilterList.class); 431 ArrayList<Filter> filterListFilters = (ArrayList<Filter>) filterList.getFilters(); 432 assertTrue(filterListFilters.get(0) instanceof FilterList); 433 assertTrue(filterListFilters.get(1) instanceof FamilyFilter); 434 assertEquals(FilterList.Operator.MUST_PASS_ONE, filterList.getOperator()); 435 436 filterList = (FilterList) filterListFilters.get(0); 437 FamilyFilter familyFilter = (FamilyFilter) filterListFilters.get(1); 438 439 filterListFilters = (ArrayList<Filter>) filterList.getFilters(); 440 assertTrue(filterListFilters.get(0) instanceof PrefixFilter); 441 assertTrue(filterListFilters.get(1) instanceof QualifierFilter); 442 assertEquals(FilterList.Operator.MUST_PASS_ALL, filterList.getOperator()); 443 444 assertEquals(CompareOperator.EQUAL, familyFilter.getCompareOperator()); 445 assertTrue(familyFilter.getComparator() instanceof BinaryComparator); 446 BinaryComparator binaryComparator = (BinaryComparator) familyFilter.getComparator(); 447 assertEquals("qualifier", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 448 449 PrefixFilter prefixFilter = (PrefixFilter) filterListFilters.get(0); 450 byte[] prefix = prefixFilter.getPrefix(); 451 assertEquals("realtime", new String(prefix, StandardCharsets.UTF_8)); 452 453 QualifierFilter qualifierFilter = (QualifierFilter) filterListFilters.get(1); 454 assertEquals(CompareOperator.GREATER_OR_EQUAL, qualifierFilter.getCompareOperator()); 455 assertTrue(qualifierFilter.getComparator() instanceof BinaryComparator); 456 binaryComparator = (BinaryComparator) qualifierFilter.getComparator(); 457 assertEquals("e", new String(binaryComparator.getValue(), StandardCharsets.UTF_8)); 458 } 459 460 @Test 461 public void testCompoundFilter3() throws IOException { 462 String filterString = " ColumnPrefixFilter ('realtime')AND " 463 + "FirstKeyOnlyFilter() OR SKIP FamilyFilter(=, 'substring:hihi')"; 464 FilterList filterList = doTestFilter(filterString, FilterList.class); 465 ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters(); 466 467 assertTrue(filters.get(0) instanceof FilterList); 468 assertTrue(filters.get(1) instanceof SkipFilter); 469 470 filterList = (FilterList) filters.get(0); 471 SkipFilter skipFilter = (SkipFilter) filters.get(1); 472 473 filters = (ArrayList<Filter>) filterList.getFilters(); 474 assertTrue(filters.get(0) instanceof ColumnPrefixFilter); 475 assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter); 476 477 ColumnPrefixFilter columnPrefixFilter = (ColumnPrefixFilter) filters.get(0); 478 byte[] columnPrefix = columnPrefixFilter.getPrefix(); 479 assertEquals("realtime", new String(columnPrefix, StandardCharsets.UTF_8)); 480 481 FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1); 482 483 assertTrue(skipFilter.getFilter() instanceof FamilyFilter); 484 FamilyFilter familyFilter = (FamilyFilter) skipFilter.getFilter(); 485 486 assertEquals(CompareOperator.EQUAL, familyFilter.getCompareOperator()); 487 assertTrue(familyFilter.getComparator() instanceof SubstringComparator); 488 SubstringComparator substringComparator = (SubstringComparator) familyFilter.getComparator(); 489 assertEquals("hihi", new String(substringComparator.getValue(), StandardCharsets.UTF_8)); 490 } 491 492 @Test 493 public void testCompoundFilter4() throws IOException { 494 String filterString = " ColumnPrefixFilter ('realtime') OR " 495 + "FirstKeyOnlyFilter() OR SKIP FamilyFilter(=, 'substring:hihi')"; 496 FilterList filterList = doTestFilter(filterString, FilterList.class); 497 ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters(); 498 499 assertTrue(filters.get(0) instanceof ColumnPrefixFilter); 500 assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter); 501 assertTrue(filters.get(2) instanceof SkipFilter); 502 503 ColumnPrefixFilter columnPrefixFilter = (ColumnPrefixFilter) filters.get(0); 504 FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1); 505 SkipFilter skipFilter = (SkipFilter) filters.get(2); 506 507 byte[] columnPrefix = columnPrefixFilter.getPrefix(); 508 assertEquals("realtime", new String(columnPrefix, StandardCharsets.UTF_8)); 509 510 assertTrue(skipFilter.getFilter() instanceof FamilyFilter); 511 FamilyFilter familyFilter = (FamilyFilter) skipFilter.getFilter(); 512 513 assertEquals(CompareOperator.EQUAL, familyFilter.getCompareOperator()); 514 assertTrue(familyFilter.getComparator() instanceof SubstringComparator); 515 SubstringComparator substringComparator = (SubstringComparator) familyFilter.getComparator(); 516 assertEquals("hihi", new String(substringComparator.getValue(), StandardCharsets.UTF_8)); 517 } 518 519 @Test 520 public void testCompoundFilter5() throws IOException { 521 String filterStr = "(ValueFilter(!=, 'substring:pre'))"; 522 ValueFilter valueFilter = doTestFilter(filterStr, ValueFilter.class); 523 assertTrue(valueFilter.getComparator() instanceof SubstringComparator); 524 525 filterStr = "(ValueFilter(>=,'binary:x') AND (ValueFilter(<=,'binary:y')))" 526 + " OR ValueFilter(=,'binary:ab')"; 527 filter = f.parseFilterString(filterStr); 528 assertTrue(filter instanceof FilterList); 529 List<Filter> list = ((FilterList) filter).getFilters(); 530 assertEquals(2, list.size()); 531 assertTrue(list.get(0) instanceof FilterList); 532 assertTrue(list.get(1) instanceof ValueFilter); 533 } 534 535 @Test 536 public void testIncorrectCompareOperator() throws IOException { 537 String filterString = "RowFilter ('>>' , 'binary:region')"; 538 try { 539 doTestFilter(filterString, RowFilter.class); 540 assertTrue(false); 541 } catch (IllegalArgumentException e) { 542 System.out.println("Incorrect compare operator >>"); 543 } 544 } 545 546 @Test 547 public void testIncorrectComparatorType() throws IOException { 548 String filterString = "RowFilter ('>=' , 'binaryoperator:region')"; 549 try { 550 doTestFilter(filterString, RowFilter.class); 551 assertTrue(false); 552 } catch (IllegalArgumentException e) { 553 System.out.println("Incorrect comparator type: binaryoperator"); 554 } 555 556 filterString = "RowFilter ('>=' 'regexstring:pre*')"; 557 try { 558 doTestFilter(filterString, RowFilter.class); 559 assertTrue(false); 560 } catch (IllegalArgumentException e) { 561 System.out.println("RegexStringComparator can only be used with EQUAL or NOT_EQUAL"); 562 } 563 564 filterString = "SingleColumnValueFilter" 565 + " ('family', 'qualifier', '>=', 'substring:a', 'true', 'false')')"; 566 try { 567 doTestFilter(filterString, RowFilter.class); 568 assertTrue(false); 569 } catch (IllegalArgumentException e) { 570 System.out.println("SubtringComparator can only be used with EQUAL or NOT_EQUAL"); 571 } 572 } 573 574 @Test 575 public void testPrecedence1() throws IOException { 576 String filterString = 577 " (PrefixFilter ('realtime')AND FirstKeyOnlyFilter()" + " OR KeyOnlyFilter())"; 578 FilterList filterList = doTestFilter(filterString, FilterList.class); 579 580 ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters(); 581 582 assertTrue(filters.get(0) instanceof FilterList); 583 assertTrue(filters.get(1) instanceof KeyOnlyFilter); 584 585 filterList = (FilterList) filters.get(0); 586 filters = (ArrayList<Filter>) filterList.getFilters(); 587 588 assertTrue(filters.get(0) instanceof PrefixFilter); 589 assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter); 590 591 PrefixFilter prefixFilter = (PrefixFilter) filters.get(0); 592 byte[] prefix = prefixFilter.getPrefix(); 593 assertEquals("realtime", new String(prefix, StandardCharsets.UTF_8)); 594 } 595 596 @Test 597 public void testPrecedence2() throws IOException { 598 String filterString = 599 " PrefixFilter ('realtime')AND SKIP FirstKeyOnlyFilter()" + "OR KeyOnlyFilter()"; 600 FilterList filterList = doTestFilter(filterString, FilterList.class); 601 ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters(); 602 603 assertTrue(filters.get(0) instanceof FilterList); 604 assertTrue(filters.get(1) instanceof KeyOnlyFilter); 605 606 filterList = (FilterList) filters.get(0); 607 filters = (ArrayList<Filter>) filterList.getFilters(); 608 609 assertTrue(filters.get(0) instanceof PrefixFilter); 610 assertTrue(filters.get(1) instanceof SkipFilter); 611 612 PrefixFilter prefixFilter = (PrefixFilter) filters.get(0); 613 byte[] prefix = prefixFilter.getPrefix(); 614 assertEquals("realtime", new String(prefix, StandardCharsets.UTF_8)); 615 616 SkipFilter skipFilter = (SkipFilter) filters.get(1); 617 assertTrue(skipFilter.getFilter() instanceof FirstKeyOnlyFilter); 618 } 619 620 @Test 621 public void testUnescapedQuote1() throws IOException { 622 String filterString = "InclusiveStopFilter ('row''3')"; 623 InclusiveStopFilter inclusiveStopFilter = doTestFilter(filterString, InclusiveStopFilter.class); 624 byte[] stopRowKey = inclusiveStopFilter.getStopRowKey(); 625 assertEquals("row'3", new String(stopRowKey, StandardCharsets.UTF_8)); 626 } 627 628 @Test 629 public void testUnescapedQuote2() throws IOException { 630 String filterString = "InclusiveStopFilter ('row''3''')"; 631 InclusiveStopFilter inclusiveStopFilter = doTestFilter(filterString, InclusiveStopFilter.class); 632 byte[] stopRowKey = inclusiveStopFilter.getStopRowKey(); 633 assertEquals("row'3'", new String(stopRowKey, StandardCharsets.UTF_8)); 634 } 635 636 @Test 637 public void testUnescapedQuote3() throws IOException { 638 String filterString = " InclusiveStopFilter ('''')"; 639 InclusiveStopFilter inclusiveStopFilter = doTestFilter(filterString, InclusiveStopFilter.class); 640 byte[] stopRowKey = inclusiveStopFilter.getStopRowKey(); 641 assertEquals("'", new String(stopRowKey, StandardCharsets.UTF_8)); 642 } 643 644 @Test 645 public void testIncorrectFilterString() throws IOException { 646 String filterString = "()"; 647 byte[] filterStringAsByteArray = Bytes.toBytes(filterString); 648 try { 649 filter = f.parseFilterString(filterStringAsByteArray); 650 assertTrue(false); 651 } catch (IllegalArgumentException e) { 652 System.out.println(e.getMessage()); 653 } 654 } 655 656 @Test 657 public void testCorrectFilterString() throws IOException { 658 String filterString = "(FirstKeyOnlyFilter())"; 659 FirstKeyOnlyFilter firstKeyOnlyFilter = doTestFilter(filterString, FirstKeyOnlyFilter.class); 660 } 661 662 @Test 663 public void testRegisterFilter() { 664 ParseFilter.registerFilter("MyFilter", "some.class"); 665 666 assertTrue(f.getSupportedFilters().contains("MyFilter")); 667 } 668 669 private <T extends Filter> T doTestFilter(String filterString, Class<T> clazz) 670 throws IOException { 671 byte[] filterStringAsByteArray = Bytes.toBytes(filterString); 672 filter = f.parseFilterString(filterStringAsByteArray); 673 assertEquals(clazz, filter.getClass()); 674 return clazz.cast(filter); 675 } 676 677 @Test 678 public void testColumnValueFilter() throws IOException { 679 String filterString = "ColumnValueFilter ('family', 'qualifier', <, 'binaryprefix:value')"; 680 ColumnValueFilter cvf = doTestFilter(filterString, ColumnValueFilter.class); 681 assertEquals("family", new String(cvf.getFamily(), StandardCharsets.UTF_8)); 682 assertEquals("qualifier", new String(cvf.getQualifier(), StandardCharsets.UTF_8)); 683 assertEquals(CompareOperator.LESS, cvf.getCompareOperator()); 684 assertTrue(cvf.getComparator() instanceof BinaryPrefixComparator); 685 assertEquals("value", new String(cvf.getComparator().getValue(), StandardCharsets.UTF_8)); 686 } 687}