You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ja...@apache.org on 2023/02/28 20:24:27 UTC

[pinot] branch master updated: Show correct query plan when prefetch is enabled (#10172)

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

jackie 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 ea6424e3d8 Show correct query plan when prefetch is enabled (#10172)
ea6424e3d8 is described below

commit ea6424e3d8dfb6ecca103a910b376dd2d0f0e62b
Author: Saurabh Dubey <sa...@gmail.com>
AuthorDate: Wed Mar 1 01:54:12 2023 +0530

    Show correct query plan when prefetch is enabled (#10172)
---
 .../org/apache/pinot/core/common/Operator.java     |  20 ++++
 .../AcquireReleaseColumnsSegmentOperator.java      |  13 ++-
 .../core/operator/InstanceResponseOperator.java    |   4 +-
 .../core/operator/filter/EmptyFilterOperator.java  |   6 ++
 .../operator/filter/MatchAllFilterOperator.java    |   6 ++
 .../query/executor/ServerQueryExecutorV1Impl.java  | 111 +++++++++------------
 .../pinot/queries/ExplainPlanQueriesTest.java      |  60 +++++++++--
 7 files changed, 146 insertions(+), 74 deletions(-)

diff --git a/pinot-core/src/main/java/org/apache/pinot/core/common/Operator.java b/pinot-core/src/main/java/org/apache/pinot/core/common/Operator.java
index f86caf9798..e8b812306d 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/common/Operator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/common/Operator.java
@@ -48,6 +48,26 @@ public interface Operator<T extends Block> {
   @Nullable
   String toExplainString();
 
+  default void prepareForExplainPlan(ExplainPlanRows explainPlanRows) {
+  }
+
+  default void explainPlan(ExplainPlanRows explainPlanRows, int[] globalId, int parentId) {
+    prepareForExplainPlan(explainPlanRows);
+    String explainPlanString = toExplainString();
+    if (explainPlanString != null) {
+      ExplainPlanRowData explainPlanRowData = new ExplainPlanRowData(explainPlanString, globalId[0], parentId);
+      parentId = globalId[0]++;
+      explainPlanRows.appendExplainPlanRowData(explainPlanRowData);
+    }
+
+    List<? extends Operator> children = getChildOperators();
+    for (Operator child : children) {
+      if (child != null) {
+        child.explainPlan(explainPlanRows, globalId, parentId);
+      }
+    }
+  }
+
   /**
    * Returns the index segment associated with the operator.
    */
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/AcquireReleaseColumnsSegmentOperator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/AcquireReleaseColumnsSegmentOperator.java
index 7a0c7f6b89..2b72292431 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/AcquireReleaseColumnsSegmentOperator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/AcquireReleaseColumnsSegmentOperator.java
@@ -20,6 +20,7 @@ package org.apache.pinot.core.operator;
 
 import java.util.Collections;
 import java.util.List;
+import org.apache.pinot.core.common.ExplainPlanRows;
 import org.apache.pinot.core.common.Operator;
 import org.apache.pinot.core.operator.blocks.results.BaseResultsBlock;
 import org.apache.pinot.core.plan.PlanNode;
@@ -54,12 +55,16 @@ public class AcquireReleaseColumnsSegmentOperator extends BaseOperator<BaseResul
     _fetchContext = fetchContext;
   }
 
+  public void materializeChildOperator() {
+    _childOperator = (Operator<BaseResultsBlock>) _planNode.run();
+  }
+
   /**
    * Runs the planNode to get the childOperator, and then proceeds with execution.
    */
   @Override
   protected BaseResultsBlock getNextBlock() {
-    _childOperator = (Operator<BaseResultsBlock>) _planNode.run();
+    materializeChildOperator();
     return _childOperator.nextBlock();
   }
 
@@ -81,6 +86,12 @@ public class AcquireReleaseColumnsSegmentOperator extends BaseOperator<BaseResul
     _indexSegment.release(_fetchContext);
   }
 
+  @Override
+  public void prepareForExplainPlan(ExplainPlanRows explainPlanRows) {
+    acquire();
+    materializeChildOperator();
+  }
+
   @Override
   public String toExplainString() {
     return EXPLAIN_NAME;
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/InstanceResponseOperator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/InstanceResponseOperator.java
index f77af356cb..75f6c46103 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/InstanceResponseOperator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/InstanceResponseOperator.java
@@ -126,13 +126,13 @@ public class InstanceResponseOperator extends BaseOperator<InstanceResponseBlock
     }
   }
 
-  protected void prefetchAll() {
+  public void prefetchAll() {
     for (int i = 0; i < _fetchContextSize; i++) {
       _indexSegments.get(i).prefetch(_fetchContexts.get(i));
     }
   }
 
-  protected void releaseAll() {
+  public void releaseAll() {
     for (int i = 0; i < _fetchContextSize; i++) {
       _indexSegments.get(i).release(_fetchContexts.get(i));
     }
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/EmptyFilterOperator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/EmptyFilterOperator.java
index 974eff26f4..66fe22b110 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/EmptyFilterOperator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/EmptyFilterOperator.java
@@ -20,6 +20,7 @@ package org.apache.pinot.core.operator.filter;
 
 import java.util.Collections;
 import java.util.List;
+import org.apache.pinot.core.common.ExplainPlanRows;
 import org.apache.pinot.core.common.Operator;
 import org.apache.pinot.core.operator.blocks.EmptyFilterBlock;
 import org.apache.pinot.core.operator.blocks.FilterBlock;
@@ -71,4 +72,9 @@ public final class EmptyFilterOperator extends BaseFilterOperator {
   public List<Operator> getChildOperators() {
     return Collections.emptyList();
   }
+
+  @Override
+  public void prepareForExplainPlan(ExplainPlanRows explainPlanRows) {
+    explainPlanRows.setHasEmptyFilter(true);
+  }
 }
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/MatchAllFilterOperator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/MatchAllFilterOperator.java
index 490851db8a..e4f5d9f662 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/MatchAllFilterOperator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/MatchAllFilterOperator.java
@@ -20,6 +20,7 @@ package org.apache.pinot.core.operator.filter;
 
 import java.util.Collections;
 import java.util.List;
+import org.apache.pinot.core.common.ExplainPlanRows;
 import org.apache.pinot.core.common.Operator;
 import org.apache.pinot.core.operator.blocks.FilterBlock;
 import org.apache.pinot.core.operator.docidsets.MatchAllDocIdSet;
@@ -63,4 +64,9 @@ public class MatchAllFilterOperator extends BaseFilterOperator {
   public String toExplainString() {
     return new StringBuilder(EXPLAIN_NAME).append("(docs:").append(_numDocs).append(')').toString();
   }
+
+  @Override
+  public void prepareForExplainPlan(ExplainPlanRows explainPlanRows) {
+    explainPlanRows.setHasMatchAllFilter(true);
+  }
 }
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/query/executor/ServerQueryExecutorV1Impl.java b/pinot-core/src/main/java/org/apache/pinot/core/query/executor/ServerQueryExecutorV1Impl.java
index 70cd3fa6ea..c227b7bd13 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/query/executor/ServerQueryExecutorV1Impl.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/query/executor/ServerQueryExecutorV1Impl.java
@@ -47,13 +47,12 @@ import org.apache.pinot.core.common.ExplainPlanRows;
 import org.apache.pinot.core.common.Operator;
 import org.apache.pinot.core.data.manager.InstanceDataManager;
 import org.apache.pinot.core.data.manager.realtime.RealtimeTableDataManager;
+import org.apache.pinot.core.operator.InstanceResponseOperator;
 import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
 import org.apache.pinot.core.operator.blocks.results.AggregationResultsBlock;
 import org.apache.pinot.core.operator.blocks.results.BaseResultsBlock;
 import org.apache.pinot.core.operator.blocks.results.ExplainResultsBlock;
 import org.apache.pinot.core.operator.blocks.results.ResultsBlockUtils;
-import org.apache.pinot.core.operator.filter.EmptyFilterOperator;
-import org.apache.pinot.core.operator.filter.MatchAllFilterOperator;
 import org.apache.pinot.core.plan.Plan;
 import org.apache.pinot.core.plan.maker.PlanMaker;
 import org.apache.pinot.core.query.aggregation.function.AggregationFunction;
@@ -416,7 +415,9 @@ public class ServerQueryExecutorV1Impl implements QueryExecutor {
       int[] operatorId = {3};
       ExplainPlanRows explainPlanRows = new ExplainPlanRows();
       // Get the segment explain plan for a single segment
-      getSegmentExplainPlanRowData(child, explainPlanRows, operatorId, 2);
+      if (child != null) {
+        child.explainPlan(explainPlanRows, operatorId, 2);
+      }
       int numRows = explainPlanRows.getExplainPlanRowData().size();
       if (numRows > 0) {
         operatorDepthToRowDataMap.putIfAbsent(numRows, new ArrayList<>());
@@ -456,72 +457,52 @@ public class ServerQueryExecutorV1Impl implements QueryExecutor {
     return operatorDepthToRowDataMap;
   }
 
-  /**
-   * Get the list of Explain Plan rows for a single segment
-   */
-  private static void getSegmentExplainPlanRowData(Operator node, ExplainPlanRows explainPlanRows, int[] globalId,
-      int parentId) {
-    if (node == null) {
-      return;
-    }
-
-    String explainPlanString = node.toExplainString();
-    if (explainPlanString != null) {
-      ExplainPlanRowData explainPlanRowData = new ExplainPlanRowData(explainPlanString, globalId[0], parentId);
-      parentId = globalId[0]++;
-      explainPlanRows.appendExplainPlanRowData(explainPlanRowData);
-      if (node instanceof EmptyFilterOperator) {
-        explainPlanRows.setHasEmptyFilter(true);
-      }
-      if (node instanceof MatchAllFilterOperator) {
-        explainPlanRows.setHasMatchAllFilter(true);
-      }
-    }
-
-    List<Operator> children = node.getChildOperators();
-    for (Operator child : children) {
-      getSegmentExplainPlanRowData(child, explainPlanRows, globalId, parentId);
-    }
-  }
-
   public static InstanceResponseBlock executeExplainQuery(Plan queryPlan, QueryContext queryContext) {
     ExplainResultsBlock explainResults = new ExplainResultsBlock();
-    List<? extends Operator> childOperators = queryPlan.getPlanNode().run().getChildOperators();
-    assert childOperators.size() == 1;
-    Operator root = childOperators.get(0);
-    Map<Integer, List<ExplainPlanRows>> operatorDepthToRowDataMap;
-    int numEmptyFilterSegments = 0;
-    int numMatchAllFilterSegments = 0;
-
-    // Get the list of unique explain plans
-    operatorDepthToRowDataMap = getAllSegmentsUniqueExplainPlanRowData(root);
-    List<ExplainPlanRows> listOfExplainPlans = new ArrayList<>();
-    operatorDepthToRowDataMap.forEach((key, value) -> listOfExplainPlans.addAll(value));
-
-    // Setup the combine root's explain string
-    explainResults.addOperator(root.toExplainString(), 2, 1);
-
-    // Walk through all the explain plans and create the entries in the explain plan output for each plan
-    for (ExplainPlanRows explainPlanRows : listOfExplainPlans) {
-      numEmptyFilterSegments +=
-          explainPlanRows.isHasEmptyFilter() ? explainPlanRows.getNumSegmentsMatchingThisPlan() : 0;
-      numMatchAllFilterSegments +=
-          explainPlanRows.isHasMatchAllFilter() ? explainPlanRows.getNumSegmentsMatchingThisPlan() : 0;
-      explainResults.addOperator(
-          String.format(ExplainPlanRows.PLAN_START_FORMAT, explainPlanRows.getNumSegmentsMatchingThisPlan()),
-          ExplainPlanRows.PLAN_START_IDS, ExplainPlanRows.PLAN_START_IDS);
-      for (ExplainPlanRowData explainPlanRowData : explainPlanRows.getExplainPlanRowData()) {
-        explainResults.addOperator(explainPlanRowData.getExplainPlanString(), explainPlanRowData.getOperatorId(),
-            explainPlanRowData.getParentId());
+    InstanceResponseOperator responseOperator = (InstanceResponseOperator) queryPlan.getPlanNode().run();
+
+    try {
+      responseOperator.prefetchAll();
+
+      List<? extends Operator> childOperators = queryPlan.getPlanNode().run().getChildOperators();
+      assert childOperators.size() == 1;
+      Operator root = childOperators.get(0);
+      Map<Integer, List<ExplainPlanRows>> operatorDepthToRowDataMap;
+      int numEmptyFilterSegments = 0;
+      int numMatchAllFilterSegments = 0;
+
+      // Get the list of unique explain plans
+      operatorDepthToRowDataMap = getAllSegmentsUniqueExplainPlanRowData(root);
+      List<ExplainPlanRows> listOfExplainPlans = new ArrayList<>();
+      operatorDepthToRowDataMap.forEach((key, value) -> listOfExplainPlans.addAll(value));
+
+      // Setup the combine root's explain string
+      explainResults.addOperator(root.toExplainString(), 2, 1);
+
+      // Walk through all the explain plans and create the entries in the explain plan output for each plan
+      for (ExplainPlanRows explainPlanRows : listOfExplainPlans) {
+        numEmptyFilterSegments +=
+            explainPlanRows.isHasEmptyFilter() ? explainPlanRows.getNumSegmentsMatchingThisPlan() : 0;
+        numMatchAllFilterSegments +=
+            explainPlanRows.isHasMatchAllFilter() ? explainPlanRows.getNumSegmentsMatchingThisPlan() : 0;
+        explainResults.addOperator(
+            String.format(ExplainPlanRows.PLAN_START_FORMAT, explainPlanRows.getNumSegmentsMatchingThisPlan()),
+            ExplainPlanRows.PLAN_START_IDS, ExplainPlanRows.PLAN_START_IDS);
+        for (ExplainPlanRowData explainPlanRowData : explainPlanRows.getExplainPlanRowData()) {
+          explainResults.addOperator(explainPlanRowData.getExplainPlanString(), explainPlanRowData.getOperatorId(),
+              explainPlanRowData.getParentId());
+        }
       }
-    }
 
-    InstanceResponseBlock instanceResponse = new InstanceResponseBlock(explainResults, queryContext);
-    instanceResponse.addMetadata(MetadataKey.EXPLAIN_PLAN_NUM_EMPTY_FILTER_SEGMENTS.getName(),
-        String.valueOf(numEmptyFilterSegments));
-    instanceResponse.addMetadata(MetadataKey.EXPLAIN_PLAN_NUM_MATCH_ALL_FILTER_SEGMENTS.getName(),
-        String.valueOf(numMatchAllFilterSegments));
-    return instanceResponse;
+      InstanceResponseBlock instanceResponse = new InstanceResponseBlock(explainResults, queryContext);
+      instanceResponse.addMetadata(MetadataKey.EXPLAIN_PLAN_NUM_EMPTY_FILTER_SEGMENTS.getName(),
+          String.valueOf(numEmptyFilterSegments));
+      instanceResponse.addMetadata(MetadataKey.EXPLAIN_PLAN_NUM_MATCH_ALL_FILTER_SEGMENTS.getName(),
+          String.valueOf(numMatchAllFilterSegments));
+      return instanceResponse;
+    } finally {
+      responseOperator.releaseAll();
+    }
   }
 
   /**
diff --git a/pinot-core/src/test/java/org/apache/pinot/queries/ExplainPlanQueriesTest.java b/pinot-core/src/test/java/org/apache/pinot/queries/ExplainPlanQueriesTest.java
index d74a81fa87..d876ea4f2f 100644
--- a/pinot-core/src/test/java/org/apache/pinot/queries/ExplainPlanQueriesTest.java
+++ b/pinot-core/src/test/java/org/apache/pinot/queries/ExplainPlanQueriesTest.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
@@ -143,6 +144,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
 
   private ServerMetrics _serverMetrics;
   private QueryExecutor _queryExecutor;
+  private QueryExecutor _queryExecutorWithPrefetchEnabled;
   private BrokerReduceService _brokerReduceService;
 
   @Override
@@ -319,13 +321,58 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     _queryExecutor = new ServerQueryExecutorV1Impl();
     _queryExecutor.init(new PinotConfiguration(queryExecutorConfig), instanceDataManager, _serverMetrics);
 
+    PinotConfiguration prefetchEnabledConf = new PinotConfiguration(queryExecutorConfig);
+    prefetchEnabledConf.setProperty(ServerQueryExecutorV1Impl.ENABLE_PREFETCH, "true");
+    _queryExecutorWithPrefetchEnabled = new ServerQueryExecutorV1Impl();
+    _queryExecutorWithPrefetchEnabled.init(prefetchEnabledConf, instanceDataManager, _serverMetrics);
+
     // Create the BrokerReduceService
     _brokerReduceService = new BrokerReduceService(new PinotConfiguration(
         Collections.singletonMap(CommonConstants.Broker.CONFIG_OF_MAX_REDUCE_THREADS_PER_QUERY, 2)));
   }
 
+  private ResultTable getPrefetchEnabledResulTable(ResultTable resultTable) {
+    // TODO does not work for cases where different segments have different plans (more than 1 PLAN_START rows)
+    List<Object[]> newRows = new ArrayList<>();
+    int acquireOpParentId = -1;
+
+    Iterator<Object[]> it = resultTable.getRows().iterator();
+    // After each PLAN_START, we need to add ACQUIRE_RELEASE_COLUMNS_SEGMENT (unles ALL_SEGMENTS_PRUNED_ON_SERVER),
+    // and all following op should have their ids incremented
+
+    while (it.hasNext()) {
+      Object[] row = it.next();
+      String op = row[0].toString();
+      newRows.add(row);
+      acquireOpParentId = Math.max(acquireOpParentId, (int) row[1]);
+      if (op.startsWith("PLAN_START")) {
+        newRows.add(new Object[]{"ACQUIRE_RELEASE_COLUMNS_SEGMENT", acquireOpParentId + 1, acquireOpParentId});
+        break;
+      }
+    }
+
+    while (it.hasNext()) {
+      Object[] row = it.next();
+      String op = row[0].toString();
+      newRows.add(new Object[]{row[0].toString(), ((int) row[1] + 1), ((int) row[2]) + 1});
+    }
+
+    return new ResultTable(resultTable.getDataSchema(), newRows);
+  }
+
   /** Checks the correctness of EXPLAIN PLAN output. */
   private void check(String query, ResultTable expected) {
+    check(query, expected, false);
+  }
+
+  private void check(String query, ResultTable expected, boolean checkPrefetchEnabled) {
+    checkWithQueryExecutor(query, expected, _queryExecutor);
+    if (checkPrefetchEnabled) {
+      checkWithQueryExecutor(query, getPrefetchEnabledResulTable(expected), _queryExecutorWithPrefetchEnabled);
+    }
+  }
+
+  private void checkWithQueryExecutor(String query, ResultTable expected, QueryExecutor queryExecutor) {
     BrokerRequest brokerRequest = CalciteSqlCompiler.compileToBrokerRequest(query);
 
     int segmentsForServer1 = _segmentNames.size() / 2;
@@ -343,10 +390,10 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     brokerRequest.getPinotQuery().getDataSource().setTableName(OFFLINE_TABLE_NAME);
     InstanceRequest instanceRequest1 = new InstanceRequest(0L, brokerRequest);
     instanceRequest1.setSearchSegments(indexSegmentsForServer1);
-    InstanceResponseBlock instanceResponse1 = _queryExecutor.execute(getQueryRequest(instanceRequest1), QUERY_RUNNERS);
+    InstanceResponseBlock instanceResponse1 = queryExecutor.execute(getQueryRequest(instanceRequest1), QUERY_RUNNERS);
     InstanceRequest instanceRequest2 = new InstanceRequest(0L, brokerRequest);
     instanceRequest2.setSearchSegments(indexSegmentsForServer2);
-    InstanceResponseBlock instanceResponse2 = _queryExecutor.execute(getQueryRequest(instanceRequest2), QUERY_RUNNERS);
+    InstanceResponseBlock instanceResponse2 = queryExecutor.execute(getQueryRequest(instanceRequest2), QUERY_RUNNERS);
 
     // Broker side
     // Use 2 Threads for 2 data-tables
@@ -401,7 +448,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     });
     result1.add(new Object[]{"DOC_ID_SET", 6, 5});
     result1.add(new Object[]{"FILTER_MATCH_ENTIRE_SEGMENT(docs:3)", 7, 6});
-    check(query1, new ResultTable(DATA_SCHEMA, result1));
+    check(query1, new ResultTable(DATA_SCHEMA, result1), true);
 
     String query2 = "EXPLAIN PLAN FOR SELECT 'mickey' FROM testTable";
     List<Object[]> result2 = new ArrayList<>();
@@ -414,7 +461,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     result2.add(new Object[]{"PROJECT()", 5, 4});
     result2.add(new Object[]{"DOC_ID_SET", 6, 5});
     result2.add(new Object[]{"FILTER_MATCH_ENTIRE_SEGMENT(docs:3)", 7, 6});
-    check(query2, new ResultTable(DATA_SCHEMA, result2));
+    check(query2, new ResultTable(DATA_SCHEMA, result2), true);
 
     String query3 = "EXPLAIN PLAN FOR SELECT invertedIndexCol1, noIndexCol1 FROM testTable LIMIT 100";
     List<Object[]> result3 = new ArrayList<>();
@@ -427,7 +474,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     result3.add(new Object[]{"PROJECT(invertedIndexCol1, noIndexCol1)", 5, 4});
     result3.add(new Object[]{"DOC_ID_SET", 6, 5});
     result3.add(new Object[]{"FILTER_MATCH_ENTIRE_SEGMENT(docs:3)", 7, 6});
-    check(query3, new ResultTable(DATA_SCHEMA, result3));
+    check(query3, new ResultTable(DATA_SCHEMA, result3), true);
 
     String query4 = "EXPLAIN PLAN FOR SELECT DISTINCT invertedIndexCol1, noIndexCol1 FROM testTable LIMIT 100";
     List<Object[]> result4 = new ArrayList<>();
@@ -440,7 +487,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
     result4.add(new Object[]{"PROJECT(invertedIndexCol1, noIndexCol1)", 5, 4});
     result4.add(new Object[]{"DOC_ID_SET", 6, 5});
     result4.add(new Object[]{"FILTER_MATCH_ENTIRE_SEGMENT(docs:3)", 7, 6});
-    check(query4, new ResultTable(DATA_SCHEMA, result4));
+    check(query4, new ResultTable(DATA_SCHEMA, result4), true);
   }
 
   @Test
@@ -2403,6 +2450,7 @@ public class ExplainPlanQueriesTest extends BaseQueriesTest {
   public void tearDown() {
     _brokerReduceService.shutDown();
     _queryExecutor.shutDown();
+    _queryExecutorWithPrefetchEnabled.shutDown();
     for (IndexSegment segment : _indexSegments) {
       segment.destroy();
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org