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