diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/filter/NullComparator.java hbase-client/src/main/java/org/apache/hadoop/hbase/filter/NullComparator.java index 6597294..6f9ca11 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/filter/NullComparator.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/filter/NullComparator.java @@ -56,7 +56,7 @@ public class NullComparator extends ByteArrayComparable { @Override public int compareTo(byte[] value, int offset, int length) { - throw new UnsupportedOperationException(); + return compareTo(value); } /** diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterWithNullComparator.java hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterWithNullComparator.java new file mode 100644 index 0000000..3434bd9 --- /dev/null +++ hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterWithNullComparator.java @@ -0,0 +1,107 @@ +package org.apache.hadoop.hbase.filter; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable + * law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.MediumTests; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Test {@link NullComparator} when it is combined with {@link SingleColumnValueFilter}. Expected + * result is that rows without the column qualifier are filtered out from the scan (HBASE-10848). + */ +@Category(MediumTests.class) +public class TestFilterWithNullComparator { + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + private static final byte[] TABLE_NAME = Bytes.toBytes("test"); + + private static final byte[] FAMILY = Bytes.toBytes("a"); + + private static final byte[] QUALIFIER_FOO = Bytes.toBytes("foo"); + private static final byte[] QUALIFIER_BAR = Bytes.toBytes("bar"); + + private HTable htable; + + @BeforeClass + public static void setUpClass() throws Exception { + TEST_UTIL.startMiniCluster(1); + } + + @AfterClass + public static void tearDownClass() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Before + public void setUp() throws IOException { + htable = TEST_UTIL.createTable(TABLE_NAME, FAMILY); + } + + public void tearDown() throws IOException { + TEST_UTIL.deleteTable(TABLE_NAME); + } + + @Test + public void testScanWithFilterUsingNullComparator() throws IOException { + /* Given */ + List puts = new ArrayList(); + Put put = new Put(Bytes.toBytes("1")); + put.add(FAMILY, QUALIFIER_FOO, Bytes.toBytes("a")); + puts.add(put); + + put = new Put(Bytes.toBytes("2")); + put.add(FAMILY, QUALIFIER_FOO, Bytes.toBytes("b")); + put.add(FAMILY, QUALIFIER_BAR, Bytes.toBytes("c")); + puts.add(put); + + put = new Put(Bytes.toBytes("3")); + put.add(FAMILY, QUALIFIER_BAR, Bytes.toBytes("c")); + puts.add(put); + htable.put(puts); + + /* When */ + SingleColumnValueFilter filter = + new SingleColumnValueFilter(FAMILY, QUALIFIER_FOO, CompareOp.NOT_EQUAL, + new NullComparator()); + filter.setFilterIfMissing(true); + Scan scan = new Scan(); + scan.setFilter(filter); + + /* Then */ + ResultScanner result = htable.getScanner(scan); + Iterator it = result.iterator(); + int count = 0; + while (it.hasNext()) { + it.next(); + count++; + } + Assert.assertEquals(2, count); + } +}