diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index 60175137ad2c..40158dc5ddc8 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -1428,7 +1428,10 @@ public static ClientProtos.Result toResult(final Result result, boolean encodeTa ExtendedCell[] cells = ClientInternalHelper.getExtendedRawCells(result); if (cells == null || cells.length == 0) { - return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; + ClientProtos.Result emptyResult = result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; + return result.getMetrics() == null + ? emptyResult + : emptyResult.toBuilder().setMetrics(toQueryMetrics(result.getMetrics())).build(); } ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); @@ -1468,7 +1471,12 @@ public static ClientProtos.Result toResult(final boolean existence, boolean stal public static ClientProtos.Result toResultNoData(final Result result) { if (result.getExists() != null) return toResult(result.getExists(), result.isStale()); int size = result.size(); - if (size == 0) return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; + if (size == 0) { + ClientProtos.Result emptyResult = result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; + return result.getMetrics() == null + ? emptyResult + : emptyResult.toBuilder().setMetrics(toQueryMetrics(result.getMetrics())).build(); + } ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); builder.setAssociatedCellCount(size); builder.setStale(result.isStale()); @@ -1506,7 +1514,7 @@ public static Result toResult(final ClientProtos.Result proto, boolean decodeTag } List values = proto.getCellList(); - if (values.isEmpty()) { + if (values.isEmpty() && !proto.hasMetrics()) { return proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT; } @@ -1564,9 +1572,14 @@ public static Result toResult(final ClientProtos.Result proto, final CellScanner } } - Result r = (cells == null || cells.isEmpty()) - ? (proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT) - : Result.create(cells, null, proto.getStale()); + Result r; + if (cells == null || cells.isEmpty()) { + r = proto.hasMetrics() + ? Result.create(EMPTY_CELL_ARRAY, null, proto.getStale()) + : (proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT); + } else { + r = Result.create(cells, null, proto.getStale()); + } if (proto.hasMetrics()) { r.setMetrics(toQueryMetrics(proto.getMetrics())); diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/shaded/protobuf/TestProtobufUtil.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/shaded/protobuf/TestProtobufUtil.java index 6326bf7fd77e..f6a55eda0c2e 100644 --- a/hbase-client/src/test/java/org/apache/hadoop/hbase/shaded/protobuf/TestProtobufUtil.java +++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/shaded/protobuf/TestProtobufUtil.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; @@ -43,6 +44,8 @@ import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.Increment; import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.QueryMetrics; +import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.SlowLogParams; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.testclassification.SmallTests; @@ -132,6 +135,35 @@ public void testGet() throws IOException { assertEquals(getBuilder.build(), ProtobufUtil.toGet(get)); } + @Test + public void testEmptyResultWithQueryMetrics() throws IOException { + long blockBytesScanned = 123L; + Result result = Result.create(Collections.emptyList()); + result.setMetrics(new QueryMetrics(blockBytesScanned)); + + for (ClientProtos.Result proto : List.of(ProtobufUtil.toResult(result), + ProtobufUtil.toResultNoData(result))) { + assertTrue(proto.hasMetrics()); + assertEquals(blockBytesScanned, proto.getMetrics().getBlockBytesScanned()); + + Result roundTrip = ProtobufUtil.toResult(proto); + assertNotNull(roundTrip.getMetrics()); + assertEquals(blockBytesScanned, roundTrip.getMetrics().getBlockBytesScanned()); + + roundTrip = ProtobufUtil.toResult(proto, + PrivateCellUtil.createExtendedCellScanner(Collections. emptyList())); + assertNotNull(roundTrip.getMetrics()); + assertEquals(blockBytesScanned, roundTrip.getMetrics().getBlockBytesScanned()); + } + + ClientProtos.Result emptyProto = ClientProtos.Result.getDefaultInstance(); + assertNull(ProtobufUtil.toResult(emptyProto).getMetrics()); + assertNull(ProtobufUtil + .toResult(emptyProto, + PrivateCellUtil.createExtendedCellScanner(Collections. emptyList())) + .getMetrics()); + } + /** * Test Delete Mutate conversions. * @throws IOException if the conversion to a {@link Delete} or a