HBASE-6562 Fake KVs are sometimes passed to filters

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1373650 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
larsh 2012-08-15 22:02:57 +00:00
parent 8d7218bf31
commit c3d1bb07f8
3 changed files with 95 additions and 2 deletions

View File

@ -1156,6 +1156,14 @@ public class KeyValue implements Writable, HeapSize {
HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG);
}
/**
* @return True if this is a "fake" KV created for internal seeking purposes,
* which should not be seen by user code
*/
public boolean isInternal() {
byte type = getType();
return type == Type.Minimum.code || type == Type.Maximum.code;
}
/**
* @param now Time to set into <code>this</code> IFF timestamp ==
* {@link HConstants#LATEST_TIMESTAMP} (else, its a noop).

View File

@ -3567,14 +3567,15 @@ public class HRegion implements HeapSize { // , Writable{
rpcCall.throwExceptionIfCallerDisconnected();
}
byte [] currentRow = peekRow();
KeyValue kv = this.storeHeap.peek();
byte [] currentRow = kv == null ? null : kv.getRow();
if (isStopRow(currentRow)) {
if (filter != null && filter.hasFilterRow()) {
filter.filterRow(results);
}
return false;
} else if (filterRowKey(currentRow)) {
} else if (kv != null && !kv.isInternal() && filterRowKey(currentRow)) {
nextRow(currentRow);
} else {
byte [] nextRow;

View File

@ -0,0 +1,84 @@
/*
* 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.
*/
package org.apache.hadoop.hbase.client;
import java.util.ArrayList;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.RegionScanner;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSUtils;
import org.junit.*;
import org.junit.experimental.categories.Category;
/**
* Make sure the fake KVs created internally are never user visible
* (not even to filters)
*/
@Category(SmallTests.class)
public class TestFakeKeyInFilter extends BinaryComparator {
protected static HBaseTestingUtility UTIL = new HBaseTestingUtility();
public TestFakeKeyInFilter() {
super(Bytes.toBytes("foo"));
}
@Override
public int compareTo(byte[] value, int offset, int length) {
if (value.length == 0) {
throw new RuntimeException("Found mysterious empty row");
}
return 0;
}
/**
* Simple way to verify the scenario.
* There are no KVs with an empty row key in the
* table, yet such a KV is presented to the filter.
*/
@Test
public void testForEmptyRowKey() throws Exception {
byte[] table = Bytes.toBytes("testForEmptyRowKey");
byte[] row = Bytes.toBytes("myRow");
byte[] cf = Bytes.toBytes("myFamily");
byte[] cq = Bytes.toBytes("myColumn");
HTableDescriptor desc = new HTableDescriptor(table);
desc.addFamily(new HColumnDescriptor(cf));
HRegionInfo hri = new HRegionInfo(desc.getName(), null, null);
HRegion region = HRegion.createHRegion(hri, FSUtils.getRootDir(UTIL.getConfiguration()), UTIL.getConfiguration(), desc);
Put put = new Put(row);
put.add(cf, cq, cq);
region.put(put);
region.flushcache();
Scan scan = new Scan();
scan.addColumn(cf, cq);
WritableByteArrayComparable comparable = new TestFakeKeyInFilter();
Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, comparable);
scan.setFilter(filter);
RegionScanner scanner = region.getScanner(scan);
scanner.next(new ArrayList<KeyValue>());
scanner.close();
region.close();
}
@org.junit.Rule
public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
}