Index: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (revision 1497754) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (working copy) @@ -323,7 +323,11 @@ || kv.getMemstoreTS() > maxReadPointToTrackVersions) { // always include or it is not time yet to check whether it is OK // to purge deltes or not - return MatchCode.INCLUDE; + if (!isUserScan) { + // if this is a user scan (i.e. a "raw" scan), + // fall through to normal version and timerange checking. + return MatchCode.INCLUDE; + } } else if (keepDeletedCells) { if (timestamp < earliestPutTs) { // keeping delete rows, but there are no puts older than Index: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java (revision 1497754) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java (working copy) @@ -318,13 +318,56 @@ InternalScanner scan = region.getScanner(s); List kvs = new ArrayList(); scan.next(kvs); + assertEquals(8, kvs.size()); assertTrue(kvs.get(0).isDeleteFamily()); assertEquals(kvs.get(1).getValue(), T3); assertTrue(kvs.get(2).isDelete()); assertTrue(kvs.get(3).isDeleteType()); assertEquals(kvs.get(4).getValue(), T2); assertEquals(kvs.get(5).getValue(), T1); + // we have 3 CFs, so there are two more delete markers + assertTrue(kvs.get(6).isDeleteFamily()); + assertTrue(kvs.get(7).isDeleteFamily()); + // verify that raw scans honor the passed timerange + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(0, 1); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + // nothing in this interval, not even delete markers + assertTrue(kvs.isEmpty()); + + // filter new delete markers + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(0, ts+2); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + assertEquals(4, kvs.size()); + assertTrue(kvs.get(0).isDeleteFamily()); + assertEquals(kvs.get(1).getValue(), T1); + // we have 3 CFs + assertTrue(kvs.get(2).isDeleteFamily()); + assertTrue(kvs.get(3).isDeleteFamily()); + + // filter old delete markers + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(ts+3, ts+5); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + assertEquals(2, kvs.size()); + assertEquals(kvs.get(0).getValue(), T3); + assertTrue(kvs.get(1).isDelete()); + + HRegion.closeHRegion(region); }