diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/UserScanQueryMatcher.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/UserScanQueryMatcher.java index 7501594..f9dd8bc 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/UserScanQueryMatcher.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/UserScanQueryMatcher.java @@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.filter.Filter.ReturnCode; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; import org.apache.hadoop.hbase.regionserver.ScanInfo; +import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; /** @@ -212,6 +213,9 @@ public abstract class UserScanQueryMatcher extends ScanQueryMatcher { case INCLUDE_AND_NEXT_COL: if (matchCode == MatchCode.INCLUDE) { matchCode = MatchCode.INCLUDE_AND_SEEK_NEXT_COL; + // Update column tracker to next column, It is similar to call ExplicitColumnTracker#doneWithColumn + // As we use the column hint from the tracker to seek to next cell + columns.getNextRowOrNextColumn(cell); } break; case INCLUDE_AND_SEEK_NEXT_ROW: diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilter.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilter.java index b28c23c..d35e3dc 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilter.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilter.java @@ -142,7 +142,8 @@ public class TestFilter { @Before public void setUp() throws Exception { HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("TestFilter")); - htd.addFamily(new HColumnDescriptor(FAMILIES[0])); + HColumnDescriptor family0 = new HColumnDescriptor(FAMILIES[0]).setVersions(100, 100); + htd.addFamily(family0); htd.addFamily(new HColumnDescriptor(FAMILIES[1])); htd.addFamily(new HColumnDescriptor(FAMILIES_1[0])); htd.addFamily(new HColumnDescriptor(FAMILIES_1[1])); @@ -1861,6 +1862,65 @@ public class TestFilter { } @Test + public void testLatestVersionFilterWithExplicitColumn() throws Exception { + // Add multiple versions + Put p = new Put(ROWS_ONE[0]); + p.setDurability(Durability.SKIP_WAL); + p.addColumn(FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]); + this.region.put(p); + p = new Put(ROWS_ONE[0]); + p.setDurability(Durability.SKIP_WAL); + p.addColumn(FAMILIES[0], QUALIFIERS_ONE[0], VALUES[1]); + this.region.put(p); + this.region.flush(true); + Scan s = new Scan(); + s.setFilter(new FilterBase() { + @Override + public ReturnCode filterCell(Cell c) throws IOException { + return ReturnCode.INCLUDE_AND_NEXT_COL; + } + }); + s.setMaxVersions(100); + s.addColumn(FAMILIES[0], QUALIFIERS_ONE[0]); + s.addColumn(FAMILIES[0], QUALIFIERS_ONE[1]); + s.addColumn(FAMILIES[0], QUALIFIERS_ONE[2]); + s.addColumn(FAMILIES[0], QUALIFIERS_ONE[3]); + s.addColumn(FAMILIES[0], QUALIFIERS_TWO[0]); + s.addColumn(FAMILIES[0], QUALIFIERS_TWO[1]); + s.addColumn(FAMILIES[0], QUALIFIERS_TWO[2]); + s.addColumn(FAMILIES[0], QUALIFIERS_TWO[3]); + KeyValue[] kvs = { + // testRowOne-0 + new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[1]), + new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), + new KeyValue(ROWS_ONE[0], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), + + // testRowOne-2 + new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), + new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), + new KeyValue(ROWS_ONE[2], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), + + // testRowOne-3 + new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[0], VALUES[0]), + new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[2], VALUES[0]), + new KeyValue(ROWS_ONE[3], FAMILIES[0], QUALIFIERS_ONE[3], VALUES[0]), + // testRowTwo-0 + new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), + new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), + new KeyValue(ROWS_TWO[0], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), + // testRowTwo-2 + new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), + new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), + new KeyValue(ROWS_TWO[2], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), + // testRowTwo-3 + new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]), + new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[2], VALUES[1]), + new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[3], VALUES[1]), }; + verifyScanFull(s, kvs); + + } + + @Test public void testColumnPaginationFilter() throws Exception { // Test that the filter skips multiple column versions. Put p = new Put(ROWS_ONE[0]);