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