[NO ISSUE][API] Return Plan as Result For Explain
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Return optimized logical plan in the results field
on explain only requests.
- Default plan format to string in test framework.
Change-Id: I615dca6267b925fffd8ab995f0fd0546a0d889b6
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2823
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
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 ca96a96..d57be82 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
@@ -104,6 +104,7 @@
import org.apache.hyracks.api.client.IHyracksClientConnection;
import org.apache.hyracks.api.client.NodeControllerInfo;
import org.apache.hyracks.api.config.IOptionType;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.exceptions.HyracksException;
import org.apache.hyracks.api.exceptions.SourceLocation;
import org.apache.hyracks.api.job.JobId;
@@ -199,6 +200,7 @@
final boolean isLoad = statement != null && statement.getKind() == Statement.Kind.LOAD;
final SourceLocation sourceLoc =
query != null ? query.getSourceLocation() : statement != null ? statement.getSourceLocation() : null;
+ final boolean isExplainOnly = isQuery && query.isExplain();
SessionConfig conf = output.config();
if (isQuery && !conf.is(SessionConfig.FORMAT_ONLY_PHYSICAL_OPS)
@@ -245,7 +247,7 @@
ICompiler compiler = compilerFactory.createCompiler(plan, metadataProvider, t.getVarCounter());
if (conf.isOptimize()) {
compiler.optimize();
- if (conf.is(SessionConfig.OOB_OPTIMIZED_LOGICAL_PLAN)) {
+ if (conf.is(SessionConfig.OOB_OPTIMIZED_LOGICAL_PLAN) || isExplainOnly) {
if (conf.is(SessionConfig.FORMAT_ONLY_PHYSICAL_OPS)) {
// For Optimizer tests.
AlgebricksAppendable buffer = new AlgebricksAppendable(output.out());
@@ -257,16 +259,12 @@
}
}
}
- if (isQuery && query.isExplain()) {
- try {
- LogicalOperatorPrettyPrintVisitor pvisitor = new LogicalOperatorPrettyPrintVisitor();
- PlanPrettyPrinter.printPlan(plan, pvisitor, 0);
- ResultUtil.printResults(metadataProvider.getApplicationContext(), pvisitor.get().toString(), output,
- new Stats(), null);
- return null;
- } catch (IOException e) {
- throw new AlgebricksException(e);
+ if (isExplainOnly) {
+ printPlanAsResult(metadataProvider, output);
+ if (!conf.is(SessionConfig.OOB_OPTIMIZED_LOGICAL_PLAN)) {
+ executionPlans.setOptimizedLogicalPlan(null);
}
+ return null;
}
if (!conf.isGenerateJobSpec()) {
@@ -308,6 +306,18 @@
return spec;
}
+ private void printPlanAsResult(MetadataProvider metadataProvider, SessionOutput output) throws AlgebricksException {
+ final SessionConfig conf = output.config();
+ boolean quoteResult = output.config().getPlanFormat() == SessionConfig.PlanFormat.STRING;
+ conf.set(SessionConfig.FORMAT_QUOTE_RECORD, quoteResult);
+ try {
+ ResultUtil.printResults(metadataProvider.getApplicationContext(), executionPlans.getOptimizedLogicalPlan(),
+ output, new Stats(), null);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
protected PhysicalOptimizationConfig getPhysicalOptimizationConfig(CompilerProperties compilerProperties,
Map<String, Object> querySpecificConfig, SourceLocation sourceLoc) throws AlgebricksException {
int frameSize = compilerProperties.getFrameSize();
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
index a6d2da9..2602917 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
@@ -192,8 +192,6 @@
public void print(String record) throws HyracksDataException {
printPrefix();
- // TODO(tillw) evil hack
- quoteRecord = true;
displayRecord(record);
printPostfix();
}
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 5aff17f..73b3e70 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -114,6 +114,7 @@
protected static final Logger LOGGER = LogManager.getLogger();
private static final String AQL = "aql";
private static final String SQLPP = "sqlpp";
+ private static final String DEFAULT_PLAN_FORMAT = "string";
// see
// https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184
private static final long MAX_URL_LENGTH = 2000l;
@@ -585,6 +586,8 @@
public InputStream executeQueryService(String str, OutputFormat fmt, URI uri, List<Parameter> params,
boolean jsonEncoded, Predicate<Integer> responseCodeValidator, boolean cancellable) throws Exception {
List<Parameter> newParams = upsertParam(params, "format", ParameterTypeEnum.STRING, fmt.mimeType());
+ newParams = upsertParam(newParams, QueryServiceServlet.Parameter.PLAN_FORMAT.str(), ParameterTypeEnum.STRING,
+ DEFAULT_PLAN_FORMAT);
final Optional<String> maxReadsOptional = extractMaxResultReads(str);
if (maxReadsOptional.isPresent()) {
newParams = upsertParam(newParams, QueryServiceServlet.Parameter.MAX_RESULT_READS.str(),