HBASE-25299 Deprecate Scan#setRowPrefixFilter because of an unexpected behavior

Closes #2674

Signed-off-by: Guanghao Zhang <zghao@apache.org>
Signed-off-by: huaxiangsun <huaxiangsun@apache.org>
Signed-off-by: Viraj Jasani <vjasani@apache.org>
This commit is contained in:
tianhang 2020-11-24 19:31:03 +05:30 committed by Viraj Jasani
parent f221d11227
commit 390abb520c
No known key found for this signature in database
GPG Key ID: B3D6C0B41C8ADFD5
2 changed files with 48 additions and 0 deletions

View File

@ -383,6 +383,9 @@ public class Scan extends Query {
* <p>
* If the specified row does not exist, or the {@code inclusive} is {@code false}, the Scanner
* will start from the next closest row after the specified row.
* <p>
* <b>Note:</b> When use {@link #setRowPrefixFilter(byte[])}, the result might be unexpected.
* </p>
* @param startRow row to start scanner at or after
* @param inclusive whether we should include the start row when scan
* @return this
@ -447,7 +450,13 @@ public class Scan extends Query {
* after this method will yield undefined results.</b></p>
* @param rowPrefix the prefix all rows must start with. (Set <i>null</i> to remove the filter.)
* @return this
* @deprecated since 3.0.0. The scan result might be unexpected in some cases.
* e.g. startRow : "112" and rowPrefixFilter : "11"
* The Result of this scan might contains : "111"
* This method implements the filter by setting startRow and stopRow,
* but does not take care of the scenario where startRow has been set.
*/
@Deprecated
public Scan setRowPrefixFilter(byte[] rowPrefix) {
if (rowPrefix == null) {
withStartRow(HConstants.EMPTY_START_ROW);

View File

@ -206,6 +206,45 @@ public class TestScanRowPrefix extends FilterTestingCluster {
verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");
}
@Test
public void testRowPrefixFilterAndStartRow() throws IOException {
final TableName tableName = TableName.valueOf(name.getMethodName());
createTable(tableName,"F");
Table table = openTable(tableName);
final byte[][] rowkeys = {Bytes.toBytes("111"), Bytes.toBytes("112")};
final byte[] prefixFilter = Bytes.toBytes("11");
for (byte[] rowkey: rowkeys) {
Put p = new Put(rowkey);
p.addColumn(Bytes.toBytes("F"), Bytes.toBytes("f"), Bytes.toBytes("test value"));
table.put(p);
}
List<byte[]> expected0 = new ArrayList<>();
expected0.add(rowkeys[0]);
expected0.add(rowkeys[1]);
List<byte[]> expected1 = new ArrayList<>();
expected1.add(rowkeys[1]);
// ========
// First scan
// Set startRow before setRowPrefixFilter
Scan scan = new Scan();
scan.withStartRow(rowkeys[1]);
scan.setRowPrefixFilter(prefixFilter);
verifyScanResult(table, scan, expected0, "Set startRow before setRowPrefixFilter unexpected");
// ========
// Second scan
// Set startRow after setRowPrefixFilter
// The result is different from first scan
scan = new Scan();
scan.setRowPrefixFilter(prefixFilter);
scan.withStartRow(rowkeys[1]);
verifyScanResult(table, scan, expected1, "Set startRow after setRowPrefixFilter unexpected");
}
private void verifyScanResult(Table table, Scan scan, List<byte[]> expectedKeys, String message) {
List<byte[]> actualKeys = new ArrayList<>();
try {