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

rongr 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 da7d534dac Avoid parsing query multiple times (#9202)
da7d534dac is described below

commit da7d534dacb40bfabab986383ea6502f794627fe
Author: Xiaotian (Jackie) Jiang <17555551+jackie-ji...@users.noreply.github.com>
AuthorDate: Tue Aug 16 11:29:06 2022 -0700

    Avoid parsing query multiple times (#9202)
    
    * Avoid compiling query multiple times
    
    * Include parseTimeNs in SqlNodeAndOptions
---
 .../broker/api/resources/PinotClientRequest.java   |  8 ++-
 .../broker/broker/helix/BaseBrokerStarter.java     |  2 +-
 .../requesthandler/BaseBrokerRequestHandler.java   | 34 ++++++-----
 .../requesthandler/BrokerRequestHandler.java       | 13 +++-
 .../BrokerRequestHandlerDelegate.java              | 71 ++++++++++++++++------
 .../MultiStageBrokerRequestHandler.java            | 30 +++++----
 .../apache/pinot/sql/parsers/CalciteSqlParser.java |  7 ++-
 .../pinot/sql/parsers/SqlNodeAndOptions.java       | 14 ++++-
 .../org/apache/pinot/query/QueryEnvironment.java   | 14 ++++-
 9 files changed, 135 insertions(+), 58 deletions(-)

diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/api/resources/PinotClientRequest.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/api/resources/PinotClientRequest.java
index 9bc1b466c0..5c7ce3299f 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/api/resources/PinotClientRequest.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/api/resources/PinotClientRequest.java
@@ -131,8 +131,8 @@ public class PinotClientRequest {
       if (!requestJson.has(Request.SQL)) {
         throw new IllegalStateException("Payload is missing the query string 
field 'sql'");
       }
-      BrokerResponse brokerResponse = executeSqlQuery((ObjectNode) 
requestJson, makeHttpIdentity(requestContext),
-          false);
+      BrokerResponse brokerResponse =
+          executeSqlQuery((ObjectNode) requestJson, 
makeHttpIdentity(requestContext), false);
       asyncResponse.resume(brokerResponse.toJsonString());
     } catch (Exception e) {
       LOGGER.error("Caught exception while processing POST request", e);
@@ -158,7 +158,8 @@ public class PinotClientRequest {
     switch (sqlType) {
       case DQL:
         try (RequestScope requestStatistics = 
Tracing.getTracer().createRequestScope()) {
-          return _requestHandler.handleRequest(sqlRequestJson, 
httpRequesterIdentity, requestStatistics);
+          return _requestHandler.handleRequest(sqlRequestJson, 
sqlNodeAndOptions, httpRequesterIdentity,
+              requestStatistics);
         }
       case DML:
         Map<String, String> headers = new HashMap<>();
@@ -170,6 +171,7 @@ public class PinotClientRequest {
             new UnsupportedOperationException("Unsupported SQL type - " + 
sqlType)));
     }
   }
+
   private static HttpRequesterIdentity 
makeHttpIdentity(org.glassfish.grizzly.http.server.Request context) {
     Multimap<String, String> headers = ArrayListMultimap.create();
     context.getHeaderNames().forEach(key -> 
context.getHeaders(key).forEach(value -> headers.put(key, value)));
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
index e3419f4544..98bb188ccf 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
@@ -284,7 +284,7 @@ public abstract class BaseBrokerStarter implements 
ServiceStartable {
     }
 
     _brokerRequestHandler = new 
BrokerRequestHandlerDelegate(singleStageBrokerRequestHandler,
-        multiStageBrokerRequestHandler);
+        multiStageBrokerRequestHandler, _brokerMetrics);
     _brokerRequestHandler.start();
     String controllerUrl = _brokerConf.getProperty(Broker.CONTROLLER_URL);
     if (controllerUrl != null) {
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
index 7ca62d1ac9..6afa20c95d 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
@@ -86,6 +86,7 @@ import org.apache.pinot.spi.utils.builder.TableNameBuilder;
 import org.apache.pinot.sql.FilterKind;
 import org.apache.pinot.sql.parsers.CalciteSqlCompiler;
 import org.apache.pinot.sql.parsers.CalciteSqlParser;
+import org.apache.pinot.sql.parsers.SqlNodeAndOptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -168,8 +169,8 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
   }
 
   @Override
-  public BrokerResponseNative handleRequest(JsonNode request, @Nullable 
RequesterIdentity requesterIdentity,
-      RequestContext requestContext)
+  public BrokerResponseNative handleRequest(JsonNode request, @Nullable 
SqlNodeAndOptions sqlNodeAndOptions,
+      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
       throws Exception {
     long requestId = _requestIdGenerator.incrementAndGet();
     requestContext.setBrokerId(_brokerId);
@@ -190,20 +191,28 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
     if (sql == null) {
       throw new BadQueryRequestException("Failed to find 'sql' in the request: 
" + request);
     }
-    return handleRequest(requestId, sql.asText(), request, requesterIdentity, 
requestContext);
+    String query = sql.asText();
+    requestContext.setQuery(query);
+    return handleRequest(requestId, query, sqlNodeAndOptions, request, 
requesterIdentity, requestContext);
   }
 
-  private BrokerResponseNative handleRequest(long requestId, String query, 
JsonNode request,
-      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
+  private BrokerResponseNative handleRequest(long requestId, String query,
+      @Nullable SqlNodeAndOptions sqlNodeAndOptions, JsonNode request, 
@Nullable RequesterIdentity requesterIdentity,
+      RequestContext requestContext)
       throws Exception {
     LOGGER.debug("SQL query for request {}: {}", requestId, query);
-    requestContext.setQuery(query);
 
     // Compile the request
     long compilationStartTimeNs = System.nanoTime();
     PinotQuery pinotQuery;
     try {
-      pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+      if (sqlNodeAndOptions != null) {
+        // Include parse time when the query is already parsed
+        compilationStartTimeNs -= sqlNodeAndOptions.getParseTimeNs();
+      } else {
+        sqlNodeAndOptions = CalciteSqlParser.compileToSqlNodeAndOptions(query);
+      }
+      pinotQuery = CalciteSqlParser.compileToPinotQuery(sqlNodeAndOptions);
     } catch (Exception e) {
       LOGGER.info("Caught exception while compiling SQL request {}: {}, {}", 
requestId, query, e.getMessage());
       
_brokerMetrics.addMeteredGlobalValue(BrokerMeter.REQUEST_COMPILATION_EXCEPTIONS,
 1);
@@ -244,8 +253,7 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
       return new 
BrokerResponseNative(QueryException.getException(QueryException.QUERY_EXECUTION_ERROR,
 e));
     }
 
-    String tableName =
-        getActualTableName(serverPinotQuery.getDataSource().getTableName(), 
_tableCache);
+    String tableName = 
getActualTableName(serverPinotQuery.getDataSource().getTableName(), 
_tableCache);
     serverPinotQuery.getDataSource().setTableName(tableName);
     String rawTableName = TableNameBuilder.extractRawTableName(tableName);
     requestContext.setTableName(rawTableName);
@@ -691,7 +699,6 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
       }
     }
 
-
     // Please keep the format as name=value comma-separated with no spaces
     // Please keep all the name value pairs together, then followed by the 
query. To add a new entry, please add it to
     // the end of existing pairs, but before the query.
@@ -702,9 +709,8 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
               + "{}/{}/{}/{}/{}/{}/{},consumingFreshnessTimeMs={},"
               + 
"servers={}/{},groupLimitReached={},brokerReduceTimeMs={},exceptions={},serverStats={},"
               + 
"offlineThreadCpuTimeNs(total/thread/sysActivity/resSer):{}/{}/{}/{},"
-              + 
"realtimeThreadCpuTimeNs(total/thread/sysActivity/resSer):{}/{}/{}/{},clientIp={}"
-              + ",query={}", requestId, tableName,
-          totalTimeMs, brokerResponse.getNumDocsScanned(), 
brokerResponse.getTotalDocs(),
+              + 
"realtimeThreadCpuTimeNs(total/thread/sysActivity/resSer):{}/{}/{}/{},clientIp={},query={}",
 requestId,
+          tableName, totalTimeMs, brokerResponse.getNumDocsScanned(), 
brokerResponse.getTotalDocs(),
           brokerResponse.getNumEntriesScannedInFilter(), 
brokerResponse.getNumEntriesScannedPostFilter(),
           brokerResponse.getNumSegmentsQueried(), 
brokerResponse.getNumSegmentsProcessed(),
           brokerResponse.getNumSegmentsMatched(), 
brokerResponse.getNumConsumingSegmentsQueried(),
@@ -779,7 +785,7 @@ public abstract class BaseBrokerRequestHandler implements 
BrokerRequestHandler {
       Preconditions.checkState(subqueryLiteral != null, "Second argument of 
IN_SUBQUERY must be a literal (subquery)");
       String subquery = subqueryLiteral.getStringValue();
       BrokerResponseNative response =
-          handleRequest(requestId, subquery, jsonRequest, requesterIdentity, 
requestContext);
+          handleRequest(requestId, subquery, null, jsonRequest, 
requesterIdentity, requestContext);
       if (response.getExceptionsSize() != 0) {
         throw new RuntimeException("Caught exception while executing subquery: 
" + subquery);
       }
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandler.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandler.java
index 93591dee71..799bfe8295 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandler.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandler.java
@@ -22,8 +22,9 @@ import com.fasterxml.jackson.databind.JsonNode;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
 import org.apache.pinot.broker.api.RequesterIdentity;
-import org.apache.pinot.common.response.BrokerResponse;
+import org.apache.pinot.common.response.broker.BrokerResponseNative;
 import org.apache.pinot.spi.trace.RequestContext;
+import org.apache.pinot.sql.parsers.SqlNodeAndOptions;
 
 
 @ThreadSafe
@@ -33,7 +34,13 @@ public interface BrokerRequestHandler {
 
   void shutDown();
 
-  BrokerResponse handleRequest(JsonNode request, @Nullable RequesterIdentity 
requesterIdentity,
-      RequestContext requestContext)
+  BrokerResponseNative handleRequest(JsonNode request, @Nullable 
SqlNodeAndOptions sqlNodeAndOptions,
+      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
       throws Exception;
+
+  default BrokerResponseNative handleRequest(JsonNode request, @Nullable 
RequesterIdentity requesterIdentity,
+      RequestContext requestContext)
+      throws Exception {
+    return handleRequest(request, null, requesterIdentity, requestContext);
+  }
 }
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandlerDelegate.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandlerDelegate.java
index 046e60c04f..ba22f3f481 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandlerDelegate.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandlerDelegate.java
@@ -22,9 +22,18 @@ import com.fasterxml.jackson.databind.JsonNode;
 import java.util.Map;
 import javax.annotation.Nullable;
 import org.apache.pinot.broker.api.RequesterIdentity;
-import org.apache.pinot.common.response.BrokerResponse;
+import org.apache.pinot.common.exception.QueryException;
+import org.apache.pinot.common.metrics.BrokerMeter;
+import org.apache.pinot.common.metrics.BrokerMetrics;
+import org.apache.pinot.common.response.broker.BrokerResponseNative;
+import org.apache.pinot.spi.exception.BadQueryRequestException;
 import org.apache.pinot.spi.trace.RequestContext;
-import org.apache.pinot.spi.utils.CommonConstants;
+import org.apache.pinot.spi.utils.CommonConstants.Broker.Request;
+import 
org.apache.pinot.spi.utils.CommonConstants.Broker.Request.QueryOptionKey;
+import org.apache.pinot.sql.parsers.CalciteSqlParser;
+import org.apache.pinot.sql.parsers.SqlNodeAndOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -34,20 +43,17 @@ import org.apache.pinot.spi.utils.CommonConstants;
  * {@see: @CommonConstant
  */
 public class BrokerRequestHandlerDelegate implements BrokerRequestHandler {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(BrokerRequestHandlerDelegate.class);
 
   private final BrokerRequestHandler _singleStageBrokerRequestHandler;
   private final MultiStageBrokerRequestHandler _multiStageWorkerRequestHandler;
+  private final BrokerMetrics _brokerMetrics;
 
-  private final boolean _isMultiStageQueryEngineEnabled;
-
-
-  public BrokerRequestHandlerDelegate(
-      BrokerRequestHandler singleStageBrokerRequestHandler,
-      @Nullable MultiStageBrokerRequestHandler multiStageWorkerRequestHandler
-  ) {
+  public BrokerRequestHandlerDelegate(BrokerRequestHandler 
singleStageBrokerRequestHandler,
+      @Nullable MultiStageBrokerRequestHandler multiStageWorkerRequestHandler, 
BrokerMetrics brokerMetrics) {
     _singleStageBrokerRequestHandler = singleStageBrokerRequestHandler;
     _multiStageWorkerRequestHandler = multiStageWorkerRequestHandler;
-    _isMultiStageQueryEngineEnabled = _multiStageWorkerRequestHandler != null;
+    _brokerMetrics = brokerMetrics;
   }
 
   @Override
@@ -71,18 +77,43 @@ public class BrokerRequestHandlerDelegate implements 
BrokerRequestHandler {
   }
 
   @Override
-  public BrokerResponse handleRequest(JsonNode request, @Nullable 
RequesterIdentity requesterIdentity,
-      RequestContext requestContext)
+  public BrokerResponseNative handleRequest(JsonNode request, @Nullable 
SqlNodeAndOptions sqlNodeAndOptions,
+      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
       throws Exception {
-    if (_isMultiStageQueryEngineEnabled && _multiStageWorkerRequestHandler != 
null) {
-      if (request.has("queryOptions")) {
-        Map<String, String> queryOptionMap = 
BaseBrokerRequestHandler.getOptionsFromJson(request, "queryOptions");
-        if (Boolean.parseBoolean(queryOptionMap.get(
-            
CommonConstants.Broker.Request.QueryOptionKey.USE_MULTISTAGE_ENGINE))) {
-          return _multiStageWorkerRequestHandler.handleRequest(request, 
requesterIdentity, requestContext);
-        }
+    if (sqlNodeAndOptions == null) {
+      JsonNode sql = request.get(Request.SQL);
+      if (sql == null) {
+        throw new BadQueryRequestException("Failed to find 'sql' in the 
request: " + request);
+      }
+      try {
+        sqlNodeAndOptions = 
CalciteSqlParser.compileToSqlNodeAndOptions(sql.asText());
+      } catch (Exception e) {
+        LOGGER.info("Caught exception while compiling SQL: {}, {}", 
sql.asText(), e.getMessage());
+        
_brokerMetrics.addMeteredGlobalValue(BrokerMeter.REQUEST_COMPILATION_EXCEPTIONS,
 1);
+        requestContext.setErrorCode(QueryException.SQL_PARSING_ERROR_CODE);
+        return new 
BrokerResponseNative(QueryException.getException(QueryException.SQL_PARSING_ERROR,
 e));
       }
     }
-    return _singleStageBrokerRequestHandler.handleRequest(request, 
requesterIdentity, requestContext);
+
+    if (_multiStageWorkerRequestHandler != null && 
useMultiStageEngine(request, sqlNodeAndOptions)) {
+      return _multiStageWorkerRequestHandler.handleRequest(request, 
sqlNodeAndOptions, requesterIdentity,
+          requestContext);
+    } else {
+      return _singleStageBrokerRequestHandler.handleRequest(request, 
sqlNodeAndOptions, requesterIdentity,
+          requestContext);
+    }
+  }
+
+  private boolean useMultiStageEngine(JsonNode request, SqlNodeAndOptions 
sqlNodeAndOptions) {
+    Map<String, String> optionsFromSql = sqlNodeAndOptions.getOptions();
+    if 
(Boolean.parseBoolean(optionsFromSql.get(QueryOptionKey.USE_MULTISTAGE_ENGINE)))
 {
+      return true;
+    }
+    if (request.has(Request.QUERY_OPTIONS)) {
+      Map<String, String> optionsFromRequest =
+          BaseBrokerRequestHandler.getOptionsFromJson(request, 
Request.QUERY_OPTIONS);
+      return 
Boolean.parseBoolean(optionsFromRequest.get(QueryOptionKey.USE_MULTISTAGE_ENGINE));
+    }
+    return false;
   }
 }
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
index 43adfd6045..babd76ab09 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
@@ -56,6 +56,8 @@ import org.apache.pinot.spi.env.PinotConfiguration;
 import org.apache.pinot.spi.exception.BadQueryRequestException;
 import org.apache.pinot.spi.trace.RequestContext;
 import org.apache.pinot.spi.utils.CommonConstants;
+import org.apache.pinot.sql.parsers.CalciteSqlParser;
+import org.apache.pinot.sql.parsers.SqlNodeAndOptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,8 +69,8 @@ public class MultiStageBrokerRequestHandler extends 
BaseBrokerRequestHandler {
   private final int _reducerPort;
 
   private final MailboxService<Mailbox.MailboxContent> _mailboxService;
-  private QueryEnvironment _queryEnvironment;
-  private QueryDispatcher _queryDispatcher;
+  private final QueryEnvironment _queryEnvironment;
+  private final QueryDispatcher _queryDispatcher;
 
   public MultiStageBrokerRequestHandler(PinotConfiguration config, 
BrokerRoutingManager routingManager,
       AccessControlFactory accessControlFactory, QueryQuotaManager 
queryQuotaManager, TableCache tableCache,
@@ -97,8 +99,8 @@ public class MultiStageBrokerRequestHandler extends 
BaseBrokerRequestHandler {
   }
 
   @Override
-  public BrokerResponseNative handleRequest(JsonNode request, @Nullable 
RequesterIdentity requesterIdentity,
-      RequestContext requestContext)
+  public BrokerResponseNative handleRequest(JsonNode request, @Nullable 
SqlNodeAndOptions sqlNodeAndOptions,
+      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
       throws Exception {
     long requestId = _requestIdGenerator.incrementAndGet();
     requestContext.setBrokerId(_brokerId);
@@ -118,23 +120,29 @@ public class MultiStageBrokerRequestHandler extends 
BaseBrokerRequestHandler {
     JsonNode sql = request.get(CommonConstants.Broker.Request.SQL);
     if (sql == null) {
       throw new BadQueryRequestException("Failed to find 'sql' in the request: 
" + request);
-    } else {
-      return handleSQLRequest(requestId, 
request.get(CommonConstants.Broker.Request.SQL).asText(), request,
-          requesterIdentity, requestContext);
     }
+    String query = sql.asText();
+    requestContext.setQuery(query);
+    return handleRequest(requestId, query, sqlNodeAndOptions, request, 
requesterIdentity, requestContext);
   }
 
-  private BrokerResponseNative handleSQLRequest(long requestId, String query, 
JsonNode request,
-      @Nullable RequesterIdentity requesterIdentity, RequestContext 
requestContext)
+  private BrokerResponseNative handleRequest(long requestId, String query,
+      @Nullable SqlNodeAndOptions sqlNodeAndOptions, JsonNode request, 
@Nullable RequesterIdentity requesterIdentity,
+      RequestContext requestContext)
       throws Exception {
     LOGGER.debug("SQL query for request {}: {}", requestId, query);
-    requestContext.setQuery(query);
 
     // Compile the request
     long compilationStartTimeNs = System.nanoTime();
     QueryPlan queryPlan;
     try {
-      queryPlan = _queryEnvironment.planQuery(query);
+      if (sqlNodeAndOptions != null) {
+        // Include parse time when the query is already parsed
+        compilationStartTimeNs -= sqlNodeAndOptions.getParseTimeNs();
+      } else {
+        sqlNodeAndOptions = CalciteSqlParser.compileToSqlNodeAndOptions(query);
+      }
+      queryPlan = _queryEnvironment.planQuery(query, sqlNodeAndOptions);
     } catch (Exception e) {
       LOGGER.info("Caught exception while compiling SQL request {}: {}, {}", 
requestId, query, e.getMessage());
       
_brokerMetrics.addMeteredGlobalValue(BrokerMeter.REQUEST_COMPILATION_EXCEPTIONS,
 1);
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
index 3f3cc1fd7b..e4bfd4a32a 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
@@ -107,6 +107,8 @@ public class CalciteSqlParser {
 
   public static SqlNodeAndOptions compileToSqlNodeAndOptions(String sql)
       throws SqlCompilationException {
+    long parseStartTimeNs = System.nanoTime();
+
     // Remove the comments from the query
     sql = removeComments(sql);
 
@@ -128,6 +130,7 @@ public class CalciteSqlParser {
       if (options.size() > 0) {
         sqlNodeAndOptions.setExtraOptions(extractOptionsMap(options));
       }
+      sqlNodeAndOptions.setParseTimeNs(System.nanoTime() - parseStartTimeNs);
       return sqlNodeAndOptions;
     } catch (Throwable e) {
       throw new SqlCompilationException("Caught exception while parsing query: 
" + sql, e);
@@ -171,8 +174,10 @@ public class CalciteSqlParser {
 
   public static PinotQuery compileToPinotQuery(String sql)
       throws SqlCompilationException {
-    SqlNodeAndOptions sqlNodeAndOptions = compileToSqlNodeAndOptions(sql);
+    return compileToPinotQuery(compileToSqlNodeAndOptions(sql));
+  }
 
+  public static PinotQuery compileToPinotQuery(SqlNodeAndOptions 
sqlNodeAndOptions) {
     // Compile Sql without OPTION statements.
     PinotQuery pinotQuery = 
compileSqlNodeToPinotQuery(sqlNodeAndOptions.getSqlNode());
 
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/SqlNodeAndOptions.java
 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/SqlNodeAndOptions.java
index 92b7183be0..e03caca1a7 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/SqlNodeAndOptions.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/SqlNodeAndOptions.java
@@ -28,6 +28,8 @@ public class SqlNodeAndOptions {
   // TODO: support option literals other than STRING
   private final Map<String, String> _options;
 
+  private long _parseTimeNs;
+
   public SqlNodeAndOptions(SqlNode sqlNode, PinotSqlType sqlType, Map<String, 
String> options) {
     _sqlNode = sqlNode;
     _sqlType = sqlType;
@@ -38,12 +40,20 @@ public class SqlNodeAndOptions {
     return _sqlNode;
   }
 
+  public PinotSqlType getSqlType() {
+    return _sqlType;
+  }
+
   public Map<String, String> getOptions() {
     return _options;
   }
 
-  public PinotSqlType getSqlType() {
-    return _sqlType;
+  public long getParseTimeNs() {
+    return _parseTimeNs;
+  }
+
+  public void setParseTimeNs(long parseTimeNs) {
+    _parseTimeNs = parseTimeNs;
   }
 
   public void setExtraOptions(Map<String, String> extractOptionsMap) {
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/QueryEnvironment.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/QueryEnvironment.java
index 7f6d43274e..516e6815d9 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/QueryEnvironment.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/QueryEnvironment.java
@@ -18,6 +18,7 @@
  */
 package org.apache.pinot.query;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.Collection;
 import java.util.Properties;
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
@@ -120,13 +121,14 @@ public class QueryEnvironment {
    * between reusing plannerImpl vs. create a new planner for each query.
    *
    * @param sqlQuery SQL query string.
+   * @param sqlNodeAndOptions parsed SQL query.
    * @return a dispatchable query plan
    */
-  public QueryPlan planQuery(String sqlQuery) {
+  public QueryPlan planQuery(String sqlQuery, SqlNodeAndOptions 
sqlNodeAndOptions) {
     PlannerContext plannerContext = new PlannerContext();
     try {
-      SqlNode parsed = parse(sqlQuery, plannerContext);
-      SqlNode validated = validate(parsed);
+      plannerContext.setOptions(sqlNodeAndOptions.getOptions());
+      SqlNode validated = validate(sqlNodeAndOptions.getSqlNode());
       RelRoot relation = toRelation(validated, plannerContext);
       RelNode optimized = optimize(relation, plannerContext);
       return toDispatchablePlan(optimized, plannerContext);
@@ -138,10 +140,16 @@ public class QueryEnvironment {
     }
   }
 
+  @VisibleForTesting
+  public QueryPlan planQuery(String sqlQuery) {
+    return planQuery(sqlQuery, 
CalciteSqlParser.compileToSqlNodeAndOptions(sqlQuery));
+  }
+
   // --------------------------------------------------------------------------
   // steps
   // --------------------------------------------------------------------------
 
+  @VisibleForTesting
   protected SqlNode parse(String query, PlannerContext plannerContext)
       throws Exception {
     // 1. invoke CalciteSqlParser to parse out SqlNode;


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

Reply via email to