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.ByteBuffer; 026import java.util.regex.Pattern; 027import org.apache.hadoop.hbase.ByteBufferKeyValue; 028import org.apache.hadoop.hbase.Cell; 029import org.apache.hadoop.hbase.CompareOperator; 030import org.apache.hadoop.hbase.KeyValue; 031import org.apache.hadoop.hbase.testclassification.FilterTests; 032import org.apache.hadoop.hbase.testclassification.SmallTests; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.junit.jupiter.api.BeforeEach; 035import org.junit.jupiter.api.Tag; 036import org.junit.jupiter.api.Test; 037 038/** 039 * Tests the value filter 040 */ 041@Tag(FilterTests.TAG) 042@Tag(SmallTests.TAG) 043public class TestSingleColumnValueFilter { 044 045 private static final byte[] ROW = Bytes.toBytes("test"); 046 private static final byte[] COLUMN_FAMILY = Bytes.toBytes("test"); 047 private static final byte[] COLUMN_QUALIFIER = Bytes.toBytes("foo"); 048 private static final byte[] VAL_1 = Bytes.toBytes("a"); 049 private static final byte[] VAL_2 = Bytes.toBytes("ab"); 050 private static final byte[] VAL_3 = Bytes.toBytes("abc"); 051 private static final byte[] VAL_4 = Bytes.toBytes("abcd"); 052 private static final byte[] FULLSTRING_1 = 053 Bytes.toBytes("The quick brown fox jumps over the lazy dog."); 054 private static final byte[] FULLSTRING_2 = 055 Bytes.toBytes("The slow grey fox trips over the lazy dog."); 056 private static final String QUICK_SUBSTR = "quick"; 057 private static final String QUICK_REGEX = ".+quick.+"; 058 private static final Pattern QUICK_PATTERN = 059 Pattern.compile("QuIcK", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 060 061 Filter basicFilter; 062 Filter nullFilter; 063 Filter substrFilter; 064 Filter regexFilter; 065 Filter regexPatternFilter; 066 067 @BeforeEach 068 public void setUp() throws Exception { 069 basicFilter = basicFilterNew(); 070 nullFilter = nullFilterNew(); 071 substrFilter = substrFilterNew(); 072 regexFilter = regexFilterNew(); 073 regexPatternFilter = regexFilterNew(QUICK_PATTERN); 074 } 075 076 private Filter basicFilterNew() { 077 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 078 CompareOperator.GREATER_OR_EQUAL, VAL_2); 079 } 080 081 private Filter nullFilterNew() { 082 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.NOT_EQUAL, 083 new NullComparator()); 084 } 085 086 private Filter substrFilterNew() { 087 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 088 new SubstringComparator(QUICK_SUBSTR)); 089 } 090 091 private Filter regexFilterNew() { 092 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 093 new RegexStringComparator(QUICK_REGEX)); 094 } 095 096 private Filter regexFilterNew(Pattern pattern) { 097 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 098 new RegexStringComparator(pattern.pattern(), pattern.flags())); 099 } 100 101 @Test 102 public void testLongComparator() throws IOException { 103 Filter filter = new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 104 CompareOperator.GREATER, new LongComparator(100L)); 105 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(1L)); 106 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(cell), "less than"); 107 filter.reset(); 108 byte[] buffer = cell.getBuffer(); 109 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 110 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(c), "less than"); 111 filter.reset(); 112 113 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(100L)); 114 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(cell), "Equals 100"); 115 filter.reset(); 116 buffer = cell.getBuffer(); 117 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 118 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(c), "Equals 100"); 119 filter.reset(); 120 121 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(120L)); 122 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "include 120"); 123 filter.reset(); 124 buffer = cell.getBuffer(); 125 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 126 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "include 120"); 127 } 128 129 private void basicFilterTests(SingleColumnValueFilter filter) throws Exception { 130 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 131 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "basicFilter1"); 132 byte[] buffer = cell.getBuffer(); 133 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 134 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "basicFilter1"); 135 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3); 136 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "basicFilter2"); 137 buffer = cell.getBuffer(); 138 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 139 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "basicFilter2"); 140 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4); 141 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "basicFilter3"); 142 buffer = cell.getBuffer(); 143 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 144 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "basicFilter3"); 145 assertFalse(filter.filterRow(), "basicFilterNotNull"); 146 filter.reset(); 147 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 148 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(cell), "basicFilter4"); 149 buffer = cell.getBuffer(); 150 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 151 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(c), "basicFilter4"); 152 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 153 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(cell), "basicFilter4"); 154 buffer = cell.getBuffer(); 155 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 156 assertEquals(Filter.ReturnCode.NEXT_ROW, filter.filterCell(c), "basicFilter4"); 157 assertFalse(filter.filterAllRemaining(), "basicFilterAllRemaining"); 158 assertTrue(filter.filterRow(), "basicFilterNotNull"); 159 filter.reset(); 160 filter.setLatestVersionOnly(false); 161 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 162 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "basicFilter5"); 163 buffer = cell.getBuffer(); 164 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 165 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "basicFilter5"); 166 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 167 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "basicFilter5"); 168 buffer = cell.getBuffer(); 169 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 170 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "basicFilter5"); 171 assertFalse(filter.filterRow(), "basicFilterNotNull"); 172 } 173 174 private void nullFilterTests(Filter filter) throws Exception { 175 ((SingleColumnValueFilter) filter).setFilterIfMissing(true); 176 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 177 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "null1"); 178 byte[] buffer = cell.getBuffer(); 179 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 180 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "null1"); 181 assertFalse(filter.filterRow(), "null1FilterRow"); 182 filter.reset(); 183 cell = new KeyValue(ROW, COLUMN_FAMILY, Bytes.toBytes("qual2"), FULLSTRING_2); 184 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "null2"); 185 buffer = cell.getBuffer(); 186 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 187 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "null2"); 188 assertTrue(filter.filterRow(), "null2FilterRow"); 189 } 190 191 private void substrFilterTests(Filter filter) throws Exception { 192 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 193 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "substrTrue"); 194 byte[] buffer = cell.getBuffer(); 195 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 196 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "substrTrue"); 197 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_2); 198 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "substrFalse"); 199 buffer = cell.getBuffer(); 200 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 201 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "substrFalse"); 202 assertFalse(filter.filterAllRemaining(), "substrFilterAllRemaining"); 203 assertFalse(filter.filterRow(), "substrFilterNotNull"); 204 } 205 206 private void regexFilterTests(Filter filter) throws Exception { 207 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 208 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "regexTrue"); 209 byte[] buffer = cell.getBuffer(); 210 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 211 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "regexTrue"); 212 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_2); 213 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "regexFalse"); 214 buffer = cell.getBuffer(); 215 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 216 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "regexFalse"); 217 assertFalse(filter.filterAllRemaining(), "regexFilterAllRemaining"); 218 assertFalse(filter.filterRow(), "regexFilterNotNull"); 219 } 220 221 private void regexPatternFilterTests(Filter filter) throws Exception { 222 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 223 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(cell), "regexTrue"); 224 byte[] buffer = cell.getBuffer(); 225 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 226 assertEquals(Filter.ReturnCode.INCLUDE, filter.filterCell(c), "regexTrue"); 227 assertFalse(filter.filterAllRemaining(), "regexFilterAllRemaining"); 228 assertFalse(filter.filterRow(), "regexFilterNotNull"); 229 } 230 231 private Filter serializationTest(Filter filter) throws Exception { 232 // Decompose filter to bytes. 233 byte[] buffer = filter.toByteArray(); 234 235 // Recompose filter. 236 Filter newFilter = SingleColumnValueFilter.parseFrom(buffer); 237 return newFilter; 238 } 239 240 /** 241 * Tests identification of the stop row 242 */ 243 @Test 244 public void testStop() throws Exception { 245 basicFilterTests((SingleColumnValueFilter) basicFilter); 246 nullFilterTests(nullFilter); 247 substrFilterTests(substrFilter); 248 regexFilterTests(regexFilter); 249 regexPatternFilterTests(regexPatternFilter); 250 } 251 252 /** 253 * Tests serialization 254 */ 255 @Test 256 public void testSerialization() throws Exception { 257 Filter newFilter = serializationTest(basicFilter); 258 basicFilterTests((SingleColumnValueFilter) newFilter); 259 newFilter = serializationTest(nullFilter); 260 nullFilterTests(newFilter); 261 newFilter = serializationTest(substrFilter); 262 substrFilterTests(newFilter); 263 newFilter = serializationTest(regexFilter); 264 regexFilterTests(newFilter); 265 newFilter = serializationTest(regexPatternFilter); 266 regexPatternFilterTests(newFilter); 267 } 268 269}