Skip to content

Commit 6c9d5c1

Browse files
author
Daniel Roudnitsky
committed
HBASE-29672 Handle runtime comparison failures during filtering gracefully
1 parent bab3df9 commit 6c9d5c1

File tree

9 files changed

+270
-24
lines changed

9 files changed

+270
-24
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/ColumnValueFilter.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,16 @@ public ReturnCode filterCell(Cell c) throws IOException {
121121
* @return true means cell should be filtered out, included otherwise.
122122
*/
123123
private boolean compareValue(final CompareOperator op, final ByteArrayComparable comparator,
124-
final Cell cell) {
124+
final Cell cell) throws IOException {
125125
if (op == CompareOperator.NO_OP) {
126126
return true;
127127
}
128-
int compareResult = PrivateCellUtil.compareValue(cell, comparator);
129-
return CompareFilter.compare(op, compareResult);
128+
try {
129+
int compareResult = PrivateCellUtil.compareValue(cell, comparator);
130+
return CompareFilter.compare(op, compareResult);
131+
} catch (RuntimeException e) {
132+
throw CompareFilter.wrapInHBaseIOException(e, comparator);
133+
}
130134
}
131135

132136
/**

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/CompareFilter.java

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.Objects;
2323
import org.apache.hadoop.hbase.Cell;
2424
import org.apache.hadoop.hbase.CompareOperator;
25+
import org.apache.hadoop.hbase.DoNotRetryIOException;
26+
import org.apache.hadoop.hbase.HBaseIOException;
2527
import org.apache.hadoop.hbase.PrivateCellUtil;
2628
import org.apache.hadoop.hbase.util.Bytes;
2729
import org.apache.yetus.audience.InterfaceAudience;
@@ -80,41 +82,71 @@ public boolean filterRowKey(Cell cell) throws IOException {
8082
return false;
8183
}
8284

85+
/**
86+
* RuntimeException when applying a comparator indicates a code bug or misconfigured
87+
* filter/comparator, we wrap it in `HBaseIOException` to provide a clear exception message/stack
88+
* trace and prevent propagating a runtime exception up the call stack (which would lead to
89+
* unexpected throwable at RpcServer layer and a complicated unclear remote exception on the client)
90+
*/
91+
public static HBaseIOException wrapInHBaseIOException(RuntimeException e,
92+
ByteArrayComparable comparator) {
93+
String msg =
94+
String.format("Runtime exception occurred when applying comparator %s during filtering",
95+
comparator.getClass().getSimpleName());
96+
return new HBaseIOException(msg, e);
97+
}
98+
8399
protected boolean compareRow(final CompareOperator op, final ByteArrayComparable comparator,
84-
final Cell cell) {
100+
final Cell cell) throws IOException {
85101
if (op == CompareOperator.NO_OP) {
86102
return true;
87103
}
88-
int compareResult = PrivateCellUtil.compareRow(cell, comparator);
89-
return compare(op, compareResult);
104+
try {
105+
int compareResult = PrivateCellUtil.compareRow(cell, comparator);
106+
return compare(op, compareResult);
107+
} catch (RuntimeException e) {
108+
throw wrapInHBaseIOException(e, comparator);
109+
}
90110
}
91111

92112
protected boolean compareFamily(final CompareOperator op, final ByteArrayComparable comparator,
93-
final Cell cell) {
113+
final Cell cell) throws IOException {
94114
if (op == CompareOperator.NO_OP) {
95115
return true;
96116
}
97-
int compareResult = PrivateCellUtil.compareFamily(cell, comparator);
98-
return compare(op, compareResult);
117+
try {
118+
int compareResult = PrivateCellUtil.compareFamily(cell, comparator);
119+
return compare(op, compareResult);
120+
} catch (RuntimeException e) {
121+
throw wrapInHBaseIOException(e, comparator);
122+
}
99123
}
100124

101125
protected boolean compareQualifier(final CompareOperator op, final ByteArrayComparable comparator,
102-
final Cell cell) {
126+
final Cell cell) throws IOException {
103127
// We do not call through to the non-deprecated method for perf reasons.
104128
if (op == CompareOperator.NO_OP) {
105129
return true;
106130
}
107-
int compareResult = PrivateCellUtil.compareQualifier(cell, comparator);
108-
return compare(op, compareResult);
131+
try {
132+
int compareResult = PrivateCellUtil.compareQualifier(cell, comparator);
133+
return compare(op, compareResult);
134+
} catch (RuntimeException e) {
135+
throw wrapInHBaseIOException(e, comparator);
136+
}
109137
}
110138

111139
protected boolean compareValue(final CompareOperator op, final ByteArrayComparable comparator,
112-
final Cell cell) {
140+
final Cell cell) throws IOException {
113141
if (op == CompareOperator.NO_OP) {
114142
return true;
115143
}
116-
int compareResult = PrivateCellUtil.compareValue(cell, comparator);
117-
return compare(op, compareResult);
144+
try {
145+
int compareResult = PrivateCellUtil.compareValue(cell, comparator);
146+
return compare(op, compareResult);
147+
} catch (RuntimeException e) {
148+
throw wrapInHBaseIOException(e, comparator);
149+
}
118150
}
119151

120152
static boolean compare(final CompareOperator op, int compareResult) {

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/DependentColumnFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.hadoop.hbase.Cell;
2727
import org.apache.hadoop.hbase.CellUtil;
2828
import org.apache.hadoop.hbase.CompareOperator;
29+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2930
import org.apache.hadoop.hbase.exceptions.DeserializationException;
3031
import org.apache.hadoop.hbase.util.Bytes;
3132
import org.apache.yetus.audience.InterfaceAudience;
@@ -117,7 +118,7 @@ public boolean filterAllRemaining() {
117118
}
118119

119120
@Override
120-
public ReturnCode filterCell(final Cell c) {
121+
public ReturnCode filterCell(final Cell c) throws IOException {
121122
// Check if the column and qualifier match
122123
if (!CellUtil.matchingColumn(c, this.columnFamily, this.columnQualifier)) {
123124
// include non-matches for the time being, they'll be discarded afterwards

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FamilyFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import org.apache.hadoop.hbase.Cell;
2323
import org.apache.hadoop.hbase.CompareOperator;
24+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2425
import org.apache.hadoop.hbase.exceptions.DeserializationException;
2526
import org.apache.yetus.audience.InterfaceAudience;
2627

@@ -56,7 +57,7 @@ public FamilyFilter(final CompareOperator op, final ByteArrayComparable familyCo
5657
}
5758

5859
@Override
59-
public ReturnCode filterCell(final Cell c) {
60+
public ReturnCode filterCell(final Cell c) throws IOException {
6061
int familyLength = c.getFamilyLength();
6162
if (familyLength > 0) {
6263
if (compareFamily(getCompareOperator(), this.comparator, c)) {

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/QualifierFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import org.apache.hadoop.hbase.Cell;
2323
import org.apache.hadoop.hbase.CompareOperator;
24+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2425
import org.apache.hadoop.hbase.exceptions.DeserializationException;
2526
import org.apache.yetus.audience.InterfaceAudience;
2627

@@ -53,7 +54,7 @@ public QualifierFilter(final CompareOperator op, final ByteArrayComparable quali
5354
}
5455

5556
@Override
56-
public ReturnCode filterCell(final Cell c) {
57+
public ReturnCode filterCell(final Cell c) throws IOException {
5758
if (compareQualifier(getCompareOperator(), this.comparator, c)) {
5859
return ReturnCode.SKIP;
5960
}

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/RowFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import org.apache.hadoop.hbase.Cell;
2323
import org.apache.hadoop.hbase.CompareOperator;
24+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2425
import org.apache.hadoop.hbase.exceptions.DeserializationException;
2526
import org.apache.yetus.audience.InterfaceAudience;
2627

@@ -67,7 +68,7 @@ public ReturnCode filterCell(final Cell v) {
6768
}
6869

6970
@Override
70-
public boolean filterRowKey(Cell firstRowCell) {
71+
public boolean filterRowKey(Cell firstRowCell) throws IOException {
7172
if (compareRow(getCompareOperator(), this.comparator, firstRowCell)) {
7273
this.filterOutRow = true;
7374
}

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.hadoop.hbase.Cell;
2424
import org.apache.hadoop.hbase.CellUtil;
2525
import org.apache.hadoop.hbase.CompareOperator;
26+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2627
import org.apache.hadoop.hbase.PrivateCellUtil;
2728
import org.apache.hadoop.hbase.exceptions.DeserializationException;
2829
import org.apache.hadoop.hbase.util.Bytes;
@@ -147,7 +148,7 @@ public boolean filterRowKey(Cell cell) throws IOException {
147148
}
148149

149150
@Override
150-
public ReturnCode filterCell(final Cell c) {
151+
public ReturnCode filterCell(final Cell c) throws IOException {
151152
// System.out.println("REMOVE KEY=" + keyValue.toString() + ", value=" +
152153
// Bytes.toString(keyValue.getValue()));
153154
if (this.matchedColumn) {
@@ -168,9 +169,13 @@ public ReturnCode filterCell(final Cell c) {
168169
return ReturnCode.INCLUDE;
169170
}
170171

171-
private boolean filterColumnValue(final Cell cell) {
172-
int compareResult = PrivateCellUtil.compareValue(cell, this.comparator);
173-
return CompareFilter.compare(this.op, compareResult);
172+
private boolean filterColumnValue(final Cell cell) throws IOException {
173+
try {
174+
int compareResult = PrivateCellUtil.compareValue(cell, this.comparator);
175+
return CompareFilter.compare(this.op, compareResult);
176+
} catch (RuntimeException e) {
177+
throw CompareFilter.wrapInHBaseIOException(e, this.comparator);
178+
}
174179
}
175180

176181
@Override

hbase-client/src/main/java/org/apache/hadoop/hbase/filter/ValueFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import org.apache.hadoop.hbase.Cell;
2323
import org.apache.hadoop.hbase.CompareOperator;
24+
import org.apache.hadoop.hbase.DoNotRetryIOException;
2425
import org.apache.hadoop.hbase.exceptions.DeserializationException;
2526
import org.apache.yetus.audience.InterfaceAudience;
2627

@@ -54,7 +55,7 @@ public ValueFilter(final CompareOperator valueCompareOp,
5455
}
5556

5657
@Override
57-
public ReturnCode filterCell(final Cell c) {
58+
public ReturnCode filterCell(final Cell c) throws IOException {
5859
if (compareValue(getCompareOperator(), this.comparator, c)) {
5960
return ReturnCode.SKIP;
6061
}

0 commit comments

Comments
 (0)