You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ri...@apache.org on 2023/01/04 18:45:42 UTC
[pinot] 01/01: print explain plan when integration test query fails to ease debugging
This is an automated email from the ASF dual-hosted git repository.
richardstartin pushed a commit to branch explain-plan-on-error
in repository https://gitbox.apache.org/repos/asf/pinot.git
commit 54e58e1971e56fd57adb5a9fd81bb0b9265e29ff
Author: Richard Startin <ri...@apache.org>
AuthorDate: Wed Jan 4 18:44:47 2023 +0000
print explain plan when integration test query fails to ease debugging
---
.../tests/ClusterIntegrationTestUtils.java | 38 +++++++++++++++-------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/pinot-integration-test-base/src/test/java/org/apache/pinot/integration/tests/ClusterIntegrationTestUtils.java b/pinot-integration-test-base/src/test/java/org/apache/pinot/integration/tests/ClusterIntegrationTestUtils.java
index 52a27b4772..c5b88f4138 100644
--- a/pinot-integration-test-base/src/test/java/org/apache/pinot/integration/tests/ClusterIntegrationTestUtils.java
+++ b/pinot-integration-test-base/src/test/java/org/apache/pinot/integration/tests/ClusterIntegrationTestUtils.java
@@ -625,7 +625,8 @@ public class ClusterIntegrationTestUtils {
if (h2Value == null) {
if (pinotNumRecordsSelected != 0) {
throw new RuntimeException("No record selected in H2 but " + pinotNumRecordsSelected
- + " records selected in Pinot");
+ + " records selected in Pinot, explain plan: " + getExplainPlan(pinotQuery, brokerUrl, headers,
+ extraJsonProperties));
}
// Skip further comparison
@@ -644,8 +645,10 @@ public class ClusterIntegrationTestUtils {
// Fuzzy compare expected value and actual value
boolean error = fuzzyCompare(h2Value, brokerValue, connectionValue);
if (error) {
- throw new RuntimeException("Value: " + c + " does not match, expected: " + h2Value
- + ", got broker value: " + brokerValue + ", got client value:" + connectionValue);
+ throw new RuntimeException(
+ "Value: " + c + " does not match, expected: " + h2Value + ", got broker value: " + brokerValue
+ + ", got client value:" + connectionValue + ", explain plan: " + getExplainPlan(pinotQuery,
+ brokerUrl, headers, extraJsonProperties));
}
}
} else {
@@ -666,8 +669,10 @@ public class ClusterIntegrationTestUtils {
String connectionValue = resultTableResultSet.getString(i, c);
boolean error = fuzzyCompare(h2Value, brokerValue, connectionValue);
if (error) {
- throw new RuntimeException("Value: " + c + " does not match, expected: " + h2Value
- + ", got broker value: " + brokerValue + ", got client value:" + connectionValue);
+ throw new RuntimeException(
+ "Value: " + c + " does not match, expected: " + h2Value + ", got broker value: " + brokerValue
+ + ", got client value:" + connectionValue + ", explain plan: " + getExplainPlan(pinotQuery,
+ brokerUrl, headers, extraJsonProperties));
}
}
if (!h2ResultSet.next()) {
@@ -680,6 +685,19 @@ public class ClusterIntegrationTestUtils {
}
}
+ private static String getExplainPlan(String pinotQuery, String brokerUrl, @Nullable Map<String, String> headers,
+ @Nullable Map<String, String> extraJsonProperties)
+ throws Exception {
+ JsonNode explainPlanForResponse =
+ ClusterTest.postQuery("explain plan for " + pinotQuery, brokerUrl, headers, extraJsonProperties);
+ StringBuilder explainPlan = new StringBuilder();
+ JsonNode rows = explainPlanForResponse.get("resultTable").get("rows");
+ for (int i = 0; i < rows.size(); i++) {
+ explainPlan.append(rows.get(i).get(0).asText()).append("\n");
+ }
+ return explainPlan.toString();
+ }
+
private static int getH2ExpectedValues(Set<String> expectedValues, List<String> expectedOrderByValues,
ResultSet h2ResultSet, ResultSetMetaData h2MetaData, Collection<String> orderByColumns)
throws SQLException {
@@ -753,15 +771,13 @@ public class ClusterIntegrationTestUtils {
private static void comparePinotResultsWithExpectedValues(Set<String> expectedValues,
List<String> expectedOrderByValues, org.apache.pinot.client.ResultSet connectionResultSet,
- Set<String> orderByColumns, String pinotQuery, String h2Query, int h2NumRows,
- long pinotNumRecordsSelected) {
+ Set<String> orderByColumns, String pinotQuery, String h2Query, int h2NumRows, long pinotNumRecordsSelected) {
int pinotNumRows = connectionResultSet.getRowCount();
// No record selected in H2
if (h2NumRows == 0) {
if (pinotNumRows != 0) {
- throw new RuntimeException(
- "No record selected in H2 but number of records selected in Pinot: " + pinotNumRows);
+ throw new RuntimeException("No record selected in H2 but number of records selected in Pinot: " + pinotNumRows);
}
if (pinotNumRecordsSelected != 0) {
@@ -826,8 +842,8 @@ public class ClusterIntegrationTestUtils {
String actualOrderByValue = actualOrderByValueBuilder.toString();
// Check actual value in expected values set, skip comparison if query response is truncated by limit
if ((!isLimitSet || limit > h2NumRows) && !expectedValues.contains(actualValue)) {
- throw new RuntimeException("Selection result returned in Pinot but not in H2: " + actualValue
- + ", " + expectedValues);
+ throw new RuntimeException(
+ "Selection result returned in Pinot but not in H2: " + actualValue + ", " + expectedValues);
}
if (!orderByColumns.isEmpty()) {
// Check actual group value is the same as expected group value in the same order.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org