Skip to content

Commit bd51dda

Browse files
author
Rong Rong
committed
[use SqlPhysicalPlan]
1 parent d9fd87c commit bd51dda

File tree

4 files changed

+63
-37
lines changed

4 files changed

+63
-37
lines changed

pinot-common/src/main/codegen/config.fmpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ data: {
526526
# List of extended statement syntax to add
527527
statementParserMethods: [
528528
"SqlInsertFromFile()"
529+
"SqlPhysicalExplain()"
529530
]
530531

531532
# List of custom function syntax to add

pinot-common/src/main/codegen/includes/parserImpls.ftl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,37 @@
1717
// under the License.
1818
-->
1919

20+
SqlNode SqlPhysicalExplain() :
21+
{
22+
SqlNode stmt;
23+
SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
24+
SqlExplain.Depth depth = SqlExplain.Depth.PHYSICAL;
25+
final SqlExplainFormat format;
26+
}
27+
{
28+
<EXPLAIN> <IMPLEMENTATION> <PLAN>
29+
[ detailLevel = ExplainDetailLevel() ]
30+
(
31+
LOOKAHEAD(2)
32+
<AS> <XML> { format = SqlExplainFormat.XML; }
33+
|
34+
LOOKAHEAD(2)
35+
<AS> <JSON> { format = SqlExplainFormat.JSON; }
36+
|
37+
<AS> <DOT_FORMAT> { format = SqlExplainFormat.DOT; }
38+
|
39+
{ format = SqlExplainFormat.TEXT; }
40+
)
41+
<FOR> stmt = SqlQueryOrDml() {
42+
return new SqlPhysicalExplain(getPos(),
43+
stmt,
44+
detailLevel.symbol(SqlParserPos.ZERO),
45+
depth.symbol(SqlParserPos.ZERO),
46+
format.symbol(SqlParserPos.ZERO),
47+
nDynamicParams);
48+
}
49+
}
50+
2051
private void DataFileDef(List<SqlNode> list) :
2152
{
2253
SqlParserPos pos;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.apache.pinot.sql.parsers.parser;
2+
3+
import org.apache.calcite.sql.SqlExplain;
4+
import org.apache.calcite.sql.SqlLiteral;
5+
import org.apache.calcite.sql.SqlNode;
6+
import org.apache.calcite.sql.parser.SqlParserPos;
7+
8+
9+
public class SqlPhysicalExplain extends SqlExplain {
10+
public SqlPhysicalExplain(SqlParserPos pos, SqlNode explicandum, SqlLiteral detailLevel, SqlLiteral depth,
11+
SqlLiteral format, int dynamicParameterCount) {
12+
super(pos, explicandum, detailLevel, depth, format, dynamicParameterCount);
13+
}
14+
}

pinot-query-planner/src/main/java/org/apache/pinot/query/QueryEnvironment.java

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.apache.pinot.query.type.TypeFactory;
7373
import org.apache.pinot.sql.parsers.CalciteSqlParser;
7474
import org.apache.pinot.sql.parsers.SqlNodeAndOptions;
75+
import org.apache.pinot.sql.parsers.parser.SqlPhysicalExplain;
7576

7677

7778
/**
@@ -163,7 +164,8 @@ public QueryPlannerResult planQuery(String sqlQuery, SqlNodeAndOptions sqlNodeAn
163164
// TODO: current code only assume one SubPlan per query, but we should support multiple SubPlans per query.
164165
// Each SubPlan should be able to run independently from Broker then set the results into the dependent
165166
// SubPlan for further processing.
166-
return getQueryPlannerResult(getQueryDispatchableSubPlan(relRoot, plannerContext, requestId), null);
167+
DispatchableSubPlan dispatchableSubPlan = planQueryDispatchable(relRoot, plannerContext, requestId);
168+
return new QueryPlannerResult(dispatchableSubPlan, null, dispatchableSubPlan.getTableNames());
167169
} catch (CalciteContextException e) {
168170
throw new RuntimeException("Error composing query plan for '" + sqlQuery
169171
+ "': " + e.getMessage() + "'", e);
@@ -186,27 +188,22 @@ public QueryPlannerResult planQuery(String sqlQuery, SqlNodeAndOptions sqlNodeAn
186188
*/
187189
public QueryPlannerResult explainQuery(String sqlQuery, SqlNodeAndOptions sqlNodeAndOptions, long requestId) {
188190
try (PlannerContext plannerContext = new PlannerContext(_config, _catalogReader, _typeFactory, _hepProgram)) {
189-
plannerContext.setOptions(sqlNodeAndOptions.getOptions());
190-
191191
SqlExplain explain = (SqlExplain) sqlNodeAndOptions.getSqlNode();
192-
SqlExplain.Depth planType = explain.getDepth();
193-
192+
plannerContext.setOptions(sqlNodeAndOptions.getOptions());
194193
RelRoot relRoot = planQueryLogical(explain.getExplicandum(), plannerContext);
195-
196-
// get the logical plan for query.
197-
if (planType == SqlExplain.Depth.LOGICAL) {
198-
String logicalPlan = getExplainQueryLogicalPlan(relRoot, explain);
199-
return getQueryPlannerResult(getQueryDispatchableSubPlan(relRoot, plannerContext, requestId), logicalPlan);
200-
}
201-
202-
// get the physical plan for query.
203-
if (planType == SqlExplain.Depth.PHYSICAL) {
204-
DispatchableSubPlan dispatchableSubPlan = getQueryDispatchableSubPlan(relRoot, plannerContext, requestId);
205-
return getQueryPlannerResult(dispatchableSubPlan, getExplainQueryPhysicalPlan(dispatchableSubPlan));
194+
if (explain instanceof SqlPhysicalExplain) {
195+
// get the physical plan for query.
196+
DispatchableSubPlan dispatchableSubPlan = planQueryDispatchable(relRoot, plannerContext, requestId);
197+
return new QueryPlannerResult(null, ExplainPlanPlanVisitor.explain(dispatchableSubPlan),
198+
dispatchableSubPlan.getTableNames());
199+
} else {
200+
// get the logical plan for query.
201+
SqlExplainFormat format = explain.getFormat() == null ? SqlExplainFormat.DOT : explain.getFormat();
202+
SqlExplainLevel level =
203+
explain.getDetailLevel() == null ? SqlExplainLevel.DIGEST_ATTRIBUTES : explain.getDetailLevel();
204+
Set<String> tableNames = RelToPlanNodeConverter.getTableNamesFromRelRoot(relRoot.rel);
205+
return new QueryPlannerResult(null, PlannerUtils.explainPlan(relRoot.rel, format, level), tableNames);
206206
}
207-
208-
// throwing exception for SqlExplain.Depth.TYPE
209-
throw new UnsupportedOperationException(String.format("'%s' Depth is not supported.", planType));
210207
} catch (Exception e) {
211208
throw new RuntimeException("Error explain query plan for: " + sqlQuery, e);
212209
}
@@ -338,33 +335,16 @@ private SubPlan toSubPlan(RelRoot relRoot) {
338335
QueryPlan queryPlan = pinotLogicalQueryPlanner.planQuery(relRoot);
339336
return pinotLogicalQueryPlanner.makePlan(queryPlan);
340337
}
341-
private DispatchableSubPlan getQueryDispatchableSubPlan(RelRoot relRoot, PlannerContext plannerContext,
338+
private DispatchableSubPlan planQueryDispatchable(RelRoot relRoot, PlannerContext plannerContext,
342339
long requestId) {
343340
SubPlan subPlanRoot = toSubPlan(relRoot);
344341

345-
// 6. construct a dispatchable query plan.
346342
PinotDispatchPlanner pinotDispatchPlanner =
347343
new PinotDispatchPlanner(plannerContext, _workerManager, requestId, _tableCache);
348344
pinotDispatchPlanner.createDispatchableSubPlan(subPlanRoot);
349345
return pinotDispatchPlanner.createDispatchableSubPlan(subPlanRoot);
350346
}
351347

352-
private QueryPlannerResult getQueryPlannerResult(DispatchableSubPlan dispatchableSubPlan, String plan) {
353-
return new QueryPlannerResult(dispatchableSubPlan, plan, dispatchableSubPlan.getTableNames());
354-
}
355-
356-
private String getExplainQueryPhysicalPlan(DispatchableSubPlan dispatchableSubPlan) {
357-
String physicalPlan = ExplainPlanPlanVisitor.explain(dispatchableSubPlan);
358-
return String.format("Physical Plan\n%s", physicalPlan);
359-
}
360-
361-
private String getExplainQueryLogicalPlan(RelRoot relRoot, SqlExplain explain) {
362-
SqlExplainFormat format = explain.getFormat() == null ? SqlExplainFormat.DOT : explain.getFormat();
363-
SqlExplainLevel level =
364-
explain.getDetailLevel() == null ? SqlExplainLevel.DIGEST_ATTRIBUTES : explain.getDetailLevel();
365-
return PlannerUtils.explainPlan(relRoot.rel, format, level);
366-
}
367-
368348
// --------------------------------------------------------------------------
369349
// utils
370350
// --------------------------------------------------------------------------

0 commit comments

Comments
 (0)