1 | /* | |
2 | * Copyright OpenSearch Contributors | |
3 | * SPDX-License-Identifier: Apache-2.0 | |
4 | */ | |
5 | ||
6 | ||
7 | package org.opensearch.sql.executor; | |
8 | ||
9 | import com.google.common.collect.ImmutableMap; | |
10 | import java.util.ArrayList; | |
11 | import java.util.List; | |
12 | import java.util.Map; | |
13 | import java.util.function.Consumer; | |
14 | import java.util.function.Function; | |
15 | import java.util.stream.Collectors; | |
16 | import org.apache.commons.lang3.tuple.Pair; | |
17 | import org.opensearch.sql.ast.tree.Sort; | |
18 | import org.opensearch.sql.executor.ExecutionEngine.ExplainResponse; | |
19 | import org.opensearch.sql.executor.ExecutionEngine.ExplainResponseNode; | |
20 | import org.opensearch.sql.expression.Expression; | |
21 | import org.opensearch.sql.planner.physical.AggregationOperator; | |
22 | import org.opensearch.sql.planner.physical.DedupeOperator; | |
23 | import org.opensearch.sql.planner.physical.EvalOperator; | |
24 | import org.opensearch.sql.planner.physical.FilterOperator; | |
25 | import org.opensearch.sql.planner.physical.LimitOperator; | |
26 | import org.opensearch.sql.planner.physical.PhysicalPlan; | |
27 | import org.opensearch.sql.planner.physical.PhysicalPlanNodeVisitor; | |
28 | import org.opensearch.sql.planner.physical.ProjectOperator; | |
29 | import org.opensearch.sql.planner.physical.RareTopNOperator; | |
30 | import org.opensearch.sql.planner.physical.RemoveOperator; | |
31 | import org.opensearch.sql.planner.physical.RenameOperator; | |
32 | import org.opensearch.sql.planner.physical.SortOperator; | |
33 | import org.opensearch.sql.planner.physical.ValuesOperator; | |
34 | import org.opensearch.sql.planner.physical.WindowOperator; | |
35 | import org.opensearch.sql.storage.TableScanOperator; | |
36 | ||
37 | /** | |
38 | * Visitor that explains a physical plan to JSON format. | |
39 | */ | |
40 | public class Explain extends PhysicalPlanNodeVisitor<ExplainResponseNode, Object> | |
41 | implements Function<PhysicalPlan, ExplainResponse> { | |
42 | ||
43 | @Override | |
44 | public ExplainResponse apply(PhysicalPlan plan) { | |
45 |
1
1. apply : replaced return value with null for org/opensearch/sql/executor/Explain::apply → KILLED |
return new ExplainResponse(plan.accept(this, null)); |
46 | } | |
47 | ||
48 | @Override | |
49 | public ExplainResponseNode visitProject(ProjectOperator node, Object context) { | |
50 |
2
1. lambda$visitProject$0 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitProject : replaced return value with null for org/opensearch/sql/executor/Explain::visitProject → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
51 | "fields", node.getProjectList().toString()))); | |
52 | } | |
53 | ||
54 | @Override | |
55 | public ExplainResponseNode visitFilter(FilterOperator node, Object context) { | |
56 |
2
1. lambda$visitFilter$1 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitFilter : replaced return value with null for org/opensearch/sql/executor/Explain::visitFilter → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
57 | "conditions", node.getConditions().toString()))); | |
58 | } | |
59 | ||
60 | @Override | |
61 | public ExplainResponseNode visitSort(SortOperator node, Object context) { | |
62 |
2
1. lambda$visitSort$2 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitSort : replaced return value with null for org/opensearch/sql/executor/Explain::visitSort → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
63 | "sortList", describeSortList(node.getSortList())))); | |
64 | } | |
65 | ||
66 | @Override | |
67 | public ExplainResponseNode visitTableScan(TableScanOperator node, Object context) { | |
68 |
2
1. lambda$visitTableScan$3 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitTableScan : replaced return value with null for org/opensearch/sql/executor/Explain::visitTableScan → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
69 | "request", node.toString()))); | |
70 | } | |
71 | ||
72 | @Override | |
73 | public ExplainResponseNode visitAggregation(AggregationOperator node, Object context) { | |
74 |
2
1. lambda$visitAggregation$4 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitAggregation : replaced return value with null for org/opensearch/sql/executor/Explain::visitAggregation → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
75 | "aggregators", node.getAggregatorList().toString(), | |
76 | "groupBy", node.getGroupByExprList().toString()))); | |
77 | } | |
78 | ||
79 | @Override | |
80 | public ExplainResponseNode visitWindow(WindowOperator node, Object context) { | |
81 |
2
1. lambda$visitWindow$5 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitWindow : replaced return value with null for org/opensearch/sql/executor/Explain::visitWindow → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
82 | "function", node.getWindowFunction().toString(), | |
83 | "definition", ImmutableMap.of( | |
84 | "partitionBy", node.getWindowDefinition().getPartitionByList().toString(), | |
85 | "sortList", describeSortList(node.getWindowDefinition().getSortList()))))); | |
86 | } | |
87 | ||
88 | @Override | |
89 | public ExplainResponseNode visitRename(RenameOperator node, Object context) { | |
90 | Map<String, String> renameMappingDescription = | |
91 | node.getMapping() | |
92 | .entrySet() | |
93 | .stream() | |
94 | .collect(Collectors.toMap( | |
95 |
1
1. lambda$visitRename$6 : replaced return value with "" for org/opensearch/sql/executor/Explain::lambda$visitRename$6 → KILLED |
e -> e.getKey().toString(), |
96 |
1
1. lambda$visitRename$7 : replaced return value with "" for org/opensearch/sql/executor/Explain::lambda$visitRename$7 → KILLED |
e -> e.getValue().toString())); |
97 | ||
98 |
2
1. lambda$visitRename$8 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitRename : replaced return value with null for org/opensearch/sql/executor/Explain::visitRename → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
99 | "mapping", renameMappingDescription))); | |
100 | } | |
101 | ||
102 | @Override | |
103 | public ExplainResponseNode visitRemove(RemoveOperator node, Object context) { | |
104 |
2
1. lambda$visitRemove$9 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitRemove : replaced return value with null for org/opensearch/sql/executor/Explain::visitRemove → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
105 | "removeList", node.getRemoveList().toString()))); | |
106 | } | |
107 | ||
108 | @Override | |
109 | public ExplainResponseNode visitEval(EvalOperator node, Object context) { | |
110 |
2
1. lambda$visitEval$10 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitEval : replaced return value with null for org/opensearch/sql/executor/Explain::visitEval → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
111 | "expressions", convertPairListToMap(node.getExpressionList())))); | |
112 | } | |
113 | ||
114 | @Override | |
115 | public ExplainResponseNode visitDedupe(DedupeOperator node, Object context) { | |
116 |
2
1. lambda$visitDedupe$11 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitDedupe : replaced return value with null for org/opensearch/sql/executor/Explain::visitDedupe → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
117 | "dedupeList", node.getDedupeList().toString(), | |
118 | "allowedDuplication", node.getAllowedDuplication(), | |
119 | "keepEmpty", node.getKeepEmpty(), | |
120 | "consecutive", node.getConsecutive()))); | |
121 | } | |
122 | ||
123 | @Override | |
124 | public ExplainResponseNode visitRareTopN(RareTopNOperator node, Object context) { | |
125 |
2
1. lambda$visitRareTopN$12 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitRareTopN : replaced return value with null for org/opensearch/sql/executor/Explain::visitRareTopN → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
126 | "commandType", node.getCommandType(), | |
127 | "noOfResults", node.getNoOfResults(), | |
128 | "fields", node.getFieldExprList().toString(), | |
129 | "groupBy", node.getGroupByExprList().toString() | |
130 | ))); | |
131 | } | |
132 | ||
133 | @Override | |
134 | public ExplainResponseNode visitValues(ValuesOperator node, Object context) { | |
135 |
2
1. lambda$visitValues$13 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitValues : replaced return value with null for org/opensearch/sql/executor/Explain::visitValues → KILLED |
return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( |
136 | "values", node.getValues()))); | |
137 | } | |
138 | ||
139 | @Override | |
140 | public ExplainResponseNode visitLimit(LimitOperator node, Object context) { | |
141 |
2
1. lambda$visitLimit$14 : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setDescription → KILLED 2. visitLimit : replaced return value with null for org/opensearch/sql/executor/Explain::visitLimit → KILLED |
return explain(node, context, explanNode -> explanNode.setDescription(ImmutableMap.of( |
142 | "limit", node.getLimit(), "offset", node.getOffset()))); | |
143 | } | |
144 | ||
145 | protected ExplainResponseNode explain(PhysicalPlan node, Object context, | |
146 | Consumer<ExplainResponseNode> doExplain) { | |
147 | ExplainResponseNode explainNode = new ExplainResponseNode(getOperatorName(node)); | |
148 | ||
149 | List<ExplainResponseNode> children = new ArrayList<>(); | |
150 | for (PhysicalPlan child : node.getChild()) { | |
151 | children.add(child.accept(this, context)); | |
152 | } | |
153 |
1
1. explain : removed call to org/opensearch/sql/executor/ExecutionEngine$ExplainResponseNode::setChildren → KILLED |
explainNode.setChildren(children); |
154 | ||
155 |
1
1. explain : removed call to java/util/function/Consumer::accept → KILLED |
doExplain.accept(explainNode); |
156 |
1
1. explain : replaced return value with null for org/opensearch/sql/executor/Explain::explain → KILLED |
return explainNode; |
157 | } | |
158 | ||
159 | private String getOperatorName(PhysicalPlan node) { | |
160 |
1
1. getOperatorName : replaced return value with "" for org/opensearch/sql/executor/Explain::getOperatorName → KILLED |
return node.getClass().getSimpleName(); |
161 | } | |
162 | ||
163 | private <T, U> Map<String, String> convertPairListToMap(List<Pair<T, U>> pairs) { | |
164 |
1
1. convertPairListToMap : replaced return value with Collections.emptyMap for org/opensearch/sql/executor/Explain::convertPairListToMap → KILLED |
return pairs.stream() |
165 | .collect(Collectors.toMap( | |
166 |
1
1. lambda$convertPairListToMap$15 : replaced return value with "" for org/opensearch/sql/executor/Explain::lambda$convertPairListToMap$15 → KILLED |
p -> p.getLeft().toString(), |
167 |
1
1. lambda$convertPairListToMap$16 : replaced return value with "" for org/opensearch/sql/executor/Explain::lambda$convertPairListToMap$16 → KILLED |
p -> p.getRight().toString())); |
168 | } | |
169 | ||
170 | private Map<String, Map<String, String>> describeSortList( | |
171 | List<Pair<Sort.SortOption, Expression>> sortList) { | |
172 |
1
1. describeSortList : replaced return value with Collections.emptyMap for org/opensearch/sql/executor/Explain::describeSortList → KILLED |
return sortList.stream() |
173 | .collect(Collectors.toMap( | |
174 |
1
1. lambda$describeSortList$17 : replaced return value with "" for org/opensearch/sql/executor/Explain::lambda$describeSortList$17 → KILLED |
p -> p.getRight().toString(), |
175 |
1
1. lambda$describeSortList$18 : replaced return value with Collections.emptyMap for org/opensearch/sql/executor/Explain::lambda$describeSortList$18 → KILLED |
p -> ImmutableMap.of( |
176 | "sortOrder", p.getLeft().getSortOrder().toString(), | |
177 | "nullOrder", p.getLeft().getNullOrder().toString()))); | |
178 | } | |
179 | ||
180 | } | |
Mutations | ||
45 |
1.1 |
|
50 |
1.1 2.2 |
|
56 |
1.1 2.2 |
|
62 |
1.1 2.2 |
|
68 |
1.1 2.2 |
|
74 |
1.1 2.2 |
|
81 |
1.1 2.2 |
|
95 |
1.1 |
|
96 |
1.1 |
|
98 |
1.1 2.2 |
|
104 |
1.1 2.2 |
|
110 |
1.1 2.2 |
|
116 |
1.1 2.2 |
|
125 |
1.1 2.2 |
|
135 |
1.1 2.2 |
|
141 |
1.1 2.2 |
|
153 |
1.1 |
|
155 |
1.1 |
|
156 |
1.1 |
|
160 |
1.1 |
|
164 |
1.1 |
|
166 |
1.1 |
|
167 |
1.1 |
|
172 |
1.1 |
|
174 |
1.1 |
|
175 |
1.1 |