>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

Reply via email to