>From Vijay Sarathy <[email protected]>:
Vijay Sarathy has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17301 )
Change subject: PLEASE EDIT to provide a meaningful commit message! Add cost
and cardinality to explain
......................................................................
PLEASE EDIT to provide a meaningful commit message!
Add cost and cardinality to explain
Change-Id: I7b4a6c78dca3326f070e1dda888d774dc6100c0b
---
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainOnlyResultsPrinter.java
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
A
asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainResults.java
6 files changed, 130 insertions(+), 27 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/01/17301/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
index 9b9fd28..f9f34bf 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
@@ -86,7 +86,7 @@
public Pair<Double, Double>
visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Double arg)
throws AlgebricksException {
// Empty tuple source operator sends an empty tuple to downstream
operators.
- return new Pair<>(1.0, 1.0);
+ return new Pair<>(0.0, 0.0);
}
@Override
@@ -220,7 +220,7 @@
@Override
public Pair<Double, Double> visitDataScanOperator(DataSourceScanOperator
op, Double arg)
throws AlgebricksException {
- Pair<Double, Double> cardCost = new Pair<>(1.0, 1.0);
+ Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
if (anno.getValue() != null &&
anno.getKey().equals(OperatorAnnotations.OP_INPUT_CARDINALITY)) {
@@ -250,7 +250,7 @@
op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL,
exchCost);
op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
exchCost + cardCost.getSecond());
} else {
- op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL,
cardCost.getSecond());
+ op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL, 0.0);
op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
cardCost.getSecond());
}
op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
cardCost.getFirst());
@@ -305,12 +305,12 @@
private static Pair<Double, Double>
annotate(EstimatedCostComputationVisitor visitor, ILogicalOperator op,
Double arg) throws AlgebricksException {
if (op.getInputs().isEmpty()) {
- return new Pair<>(1.0, 1.0);
+ return new Pair<>(0.0, 0.0);
}
Pair<Double, Double> cardCost =
op.getInputs().get(0).getValue().accept(visitor, arg);
op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
cardCost.getFirst());
op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
cardCost.getSecond());
- op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL,
cardCost.getSecond());
+ op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL, 0.0);
return cardCost;
}
@@ -322,9 +322,9 @@
return operator.getInputs().get(0).getValue().accept(this, arg);
}
- // Visits an inner join operator, particularly, deals with the case the
join is a cartesian product.
+ // Visits an inner join operator.
private Pair<Double, Double> visitInnerJoin(InnerJoinOperator
joinOperator, Double arg) throws AlgebricksException {
- Pair<Double, Double> cardCost = new Pair<>(1.0, 1.0);
+ Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
ILogicalOperator left = joinOperator.getInputs().get(0).getValue();
ILogicalOperator right = joinOperator.getInputs().get(1).getValue();
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index adcdcb2..3a06329 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -35,6 +35,7 @@
import org.apache.asterix.algebra.base.ILangExpressionToPlanTranslatorFactory;
import org.apache.asterix.api.http.server.ResultUtil;
import org.apache.asterix.app.result.fields.ExplainOnlyResultsPrinter;
+import org.apache.asterix.app.result.fields.ExplainResults;
import org.apache.asterix.app.result.fields.SignaturePrinter;
import org.apache.asterix.common.api.INodeJobTracker;
import org.apache.asterix.common.api.IResponsePrinter;
@@ -85,6 +86,7 @@
import org.apache.hyracks.algebricks.compiler.api.ICompilerFactory;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
import
org.apache.hyracks.algebricks.core.algebra.expressions.ExpressionRuntimeProvider;
import
org.apache.hyracks.algebricks.core.algebra.expressions.IConflictingTypeResolver;
import
org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionEvalSizeComputer;
@@ -270,6 +272,10 @@
AlgebricksStringBuilderWriter buf = new
AlgebricksStringBuilderWriter(PlanPrettyPrinter.INIT_SIZE);
PlanPrettyPrinter.printPhysicalOps(plan, buf, 0, true);
output.out().write(buf.toString());
+ } else {
+ if (isQuery || isLoad) {
+ generateOptimizedLogicalPlan(plan,
output.config().getPlanFormat());
+ }
}
}
}
@@ -289,7 +295,22 @@
boolean printSignature = isQuery && requestParameters != null &&
requestParameters.isPrintSignature();
- if (printSignature && !isExplainOnly) { //explainOnly adds the
signature later
+ if (isExplainOnly) {
+ Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
+ double cost =
+ (double)
plan.getRoots().get(0).getValue().getAnnotations().get(OperatorAnnotations.OP_COST_TOTAL);
+ double cardinality = (double)
plan.getRoots().get(0).getValue().getAnnotations()
+ .get(OperatorAnnotations.OP_OUTPUT_CARDINALITY);
+ cardCost.setFirst(cardinality);
+ cardCost.setSecond(cost);
+ printPlanAsResult(metadataProvider, output, printer,
printSignature, cardCost);
+ if (!conf.is(SessionConfig.OOB_OPTIMIZED_LOGICAL_PLAN)) {
+ executionPlans.setOptimizedLogicalPlan(null);
+ }
+ return null;
+ }
+
+ if (printSignature) {
printer.addResultPrinter(SignaturePrinter.newInstance(executionPlans));
}
@@ -324,14 +345,6 @@
}
}
- if (isExplainOnly) {
- printPlanAsResult(metadataProvider, output, printer,
printSignature);
- if (!conf.is(SessionConfig.OOB_OPTIMIZED_LOGICAL_PLAN)) {
- executionPlans.setOptimizedLogicalPlan(null);
- }
- return null;
- }
-
if (isQuery && conf.is(SessionConfig.OOB_HYRACKS_JOB)) {
generateJob(spec);
}
@@ -339,13 +352,15 @@
}
private void printPlanAsResult(MetadataProvider metadataProvider,
SessionOutput output, IResponsePrinter printer,
- boolean printSignature) throws AlgebricksException {
+ boolean printSignature, Pair<Double, Double> cardCost) throws
AlgebricksException {
try {
if (printSignature) {
printer.addResultPrinter(SignaturePrinter.INSTANCE);
}
printer.addResultPrinter(new
ExplainOnlyResultsPrinter(metadataProvider.getApplicationContext(),
- executionPlans.getOptimizedLogicalPlan(), output));
+ new ExplainResults(cardCost.getFirst(),
cardCost.getSecond(),
+ executionPlans.getOptimizedLogicalPlan()),
+ output));
printer.printResults();
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
index cf535d9..dc83aa3 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
@@ -102,14 +102,26 @@
printField(pw, name, value, true);
}
+ public static void printField(PrintWriter pw, String name, double value) {
+ printField(pw, name, value, true);
+ }
+
public static void printField(PrintWriter pw, String name, String value,
boolean comma) {
printFieldInternal(pw, name, "\"" + value + "\"", comma);
}
+ public static void printFieldNoQuotes(PrintWriter pw, String name, String
value, boolean comma) {
+ printFieldInternal(pw, name, value, comma);
+ }
+
public static void printField(PrintWriter pw, String name, long value,
boolean comma) {
printFieldInternal(pw, name, String.valueOf(value), comma);
}
+ public static void printField(PrintWriter pw, String name, double value,
boolean comma) {
+ printFieldInternal(pw, name, String.valueOf(value), comma);
+ }
+
protected static void printFieldInternal(PrintWriter pw, String name,
String value, boolean comma) {
pw.print("\t\"");
pw.print(name);
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainOnlyResultsPrinter.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainOnlyResultsPrinter.java
index 1949e54..ab9039b 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainOnlyResultsPrinter.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainOnlyResultsPrinter.java
@@ -23,7 +23,6 @@
import org.apache.asterix.api.http.server.ResultUtil;
import org.apache.asterix.common.api.IApplicationContext;
import org.apache.asterix.common.api.IResponseFieldPrinter;
-import org.apache.asterix.translator.IStatementExecutor;
import org.apache.asterix.translator.SessionConfig;
import org.apache.asterix.translator.SessionOutput;
import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -31,12 +30,30 @@
public class ExplainOnlyResultsPrinter implements IResponseFieldPrinter {
private final IApplicationContext appCtx;
- private final String plan;
+ private final ExplainResults explainResults;
private final SessionOutput sessionOutput;
- public ExplainOnlyResultsPrinter(IApplicationContext appCtx, String plan,
SessionOutput sessionOutput) {
+ public enum ExplainOnlyResults {
+ CARDINALITY("cardinality"),
+ COST("cost"),
+ PLAN("plan");
+
+ private final String str;
+
+ ExplainOnlyResults(String str) {
+ this.str = str;
+ }
+
+ public String str() {
+ return str;
+ }
+ }
+
+ public ExplainOnlyResultsPrinter(IApplicationContext appCtx,
ExplainResults explainResults,
+ SessionOutput sessionOutput) {
+ super();
this.appCtx = appCtx;
- this.plan = plan;
+ this.explainResults = explainResults;
this.sessionOutput = sessionOutput;
}
@@ -44,7 +61,18 @@
public void print(PrintWriter pw) throws HyracksDataException {
boolean quoteResult = sessionOutput.config().getPlanFormat() ==
SessionConfig.PlanFormat.STRING;
sessionOutput.config().set(SessionConfig.FORMAT_QUOTE_RECORD,
quoteResult);
- ResultUtil.printResults(appCtx, plan, sessionOutput, new
IStatementExecutor.Stats(), null);
+ pw.print("\t\"");
+ pw.print(AbstractResultsPrinter.FIELD_NAME);
+ pw.print("\": [");
+ pw.print("\n\t{\n\t");
+ ResultUtil.printField(pw, ExplainOnlyResults.CARDINALITY.str(),
explainResults.getCardinality());
+ pw.print("\n\t");
+ ResultUtil.printField(pw, ExplainOnlyResults.COST.str(),
explainResults.getCost());
+ pw.print("\n\t");
+ ResultUtil.printFieldNoQuotes(pw, ExplainOnlyResults.PLAN.str(),
+ explainResults.getPlan().replaceAll("\n", "\n\t\t"), false);
+ pw.print("\n\t}");
+ pw.print("\n]");
}
@Override
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainResults.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainResults.java
new file mode 100755
index 0000000..1d3c388
--- /dev/null
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/fields/ExplainResults.java
@@ -0,0 +1,25 @@
+package org.apache.asterix.app.result.fields;
+
+public class ExplainResults {
+ private double cardinality;
+ private double cost;
+ private String plan;
+
+ public ExplainResults(double cardinality, double cost, String plan) {
+ this.cardinality = cardinality;
+ this.cost = cost;
+ this.plan = plan;
+ }
+
+ public double getCardinality() {
+ return cardinality;
+ }
+
+ public double getCost() {
+ return cost;
+ }
+
+ public String getPlan() {
+ return plan;
+ }
+}
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
index 14bac72..1d04a36 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
@@ -214,24 +214,28 @@
}
jsonGenerator.writeStringField("execution-mode",
op.getExecutionMode().toString());
+ String opCard = null;
+ String opCostLocal = null;
+ String opCostTotal = null;
for (Map.Entry<String, Object> anno :
op.getAnnotations().entrySet()) {
Object annotationVal = anno.getValue();
if (annotationVal != null) {
String annotation = anno.getKey();
switch (annotation) {
case OperatorAnnotations.OP_COST_LOCAL:
+ opCostLocal = annotationVal.toString();
+ break;
case OperatorAnnotations.OP_COST_TOTAL:
-
jsonGenerator.writeStringField(annotation.toLowerCase().replace('_', '-'),
- annotationVal.toString());
+ opCostTotal = annotationVal.toString();
break;
case OperatorAnnotations.OP_INPUT_CARDINALITY:
if (op.getOperatorTag() ==
LogicalOperatorTag.DATASOURCESCAN) {
- jsonGenerator.writeStringField(OP_CARDINALITY,
annotationVal.toString());
+ opCard = annotationVal.toString();
}
break;
case OperatorAnnotations.OP_OUTPUT_CARDINALITY:
if (op.getOperatorTag() !=
LogicalOperatorTag.DATASOURCESCAN) {
- jsonGenerator.writeStringField(OP_CARDINALITY,
annotationVal.toString());
+ opCard = annotationVal.toString();
}
break;
default:
@@ -239,6 +243,15 @@
}
}
}
+ if (opCard != null && opCostLocal != null && opCostTotal != null) {
+ jsonGenerator.writeObjectFieldStart("optimizer_estimates");
+ jsonGenerator.writeStringField(OP_CARDINALITY, opCard);
+
jsonGenerator.writeStringField(OperatorAnnotations.OP_COST_LOCAL.toLowerCase().replace('_',
'-'),
+ opCostLocal);
+
jsonGenerator.writeStringField(OperatorAnnotations.OP_COST_TOTAL.toLowerCase().replace('_',
'-'),
+ opCostTotal);
+ jsonGenerator.writeEndObject();
+ }
if (printInputs && !op.getInputs().isEmpty()) {
jsonGenerator.writeArrayFieldStart("inputs");
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17301
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I7b4a6c78dca3326f070e1dda888d774dc6100c0b
Gerrit-Change-Number: 17301
Gerrit-PatchSet: 1
Gerrit-Owner: Vijay Sarathy <[email protected]>
Gerrit-MessageType: newchange