This is an automated email from the ASF dual-hosted git repository.

richardstartin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new a46b05f8f6 print explain plan when integration test query fails to 
ease debugging (#10057)
a46b05f8f6 is described below

commit a46b05f8f6fc5b380cb54e83b4dad3f9adfaff90
Author: Richard Startin <richardstar...@apache.org>
AuthorDate: Thu Jan 5 09:36:42 2023 +0000

    print explain plan when integration test query fails to ease debugging 
(#10057)
---
 .../tests/ClusterIntegrationTestUtils.java         | 67 ++++++++++++++++++----
 1 file changed, 56 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..e8f4d143e2 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
@@ -41,6 +41,7 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Random;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -625,7 +626,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 +646,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 +670,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 +686,47 @@ 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);
+    Map<Integer, String> nodesById = new TreeMap<>();
+    JsonNode rows = explainPlanForResponse.get("resultTable").get("rows");
+    int[] parentMapping = new int[rows.size()];
+    for (int i = 0; i < rows.size(); i++) {
+      JsonNode row = rows.get(i);
+      int id = row.get(1).asInt();
+      if (id > 0) {
+        parentMapping[id] = row.get(2).asInt();
+      }
+      nodesById.put(id, row.get(0).asText());
+    }
+    int[] depths = new int[rows.size()];
+    for (Map.Entry<Integer, String> pair : nodesById.entrySet()) {
+      int depth = 0;
+      int id = pair.getKey();
+      int parentId = id;
+      while (parentId > 0) {
+        depth++;
+        parentId = parentMapping[parentId];
+      }
+      if (id > 0) {
+        depths[id] = depth;
+      }
+    }
+    StringBuilder explainPlan = new StringBuilder();
+    for (Map.Entry<Integer, String> pair : nodesById.entrySet()) {
+      explainPlan.append('\n');
+      int id = pair.getKey();
+      for (int i = 0; id > 0 && i < depths[id]; i++) {
+        explainPlan.append('\t');
+      }
+      explainPlan.append(pair.getValue());
+    }
+    return explainPlan.toString();
+  }
+
   private static int getH2ExpectedValues(Set<String> expectedValues, 
List<String> expectedOrderByValues,
       ResultSet h2ResultSet, ResultSetMetaData h2MetaData, Collection<String> 
orderByColumns)
       throws SQLException {
@@ -753,15 +800,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 +871,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-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to