Merge branch 'gerrit/mad-hatter'
Change-Id: I85867c451c84aaa94f008c6b718ab7805983c503
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/extension/ExtensionStatement.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/extension/ExtensionStatement.java
index 08f330b..1530849 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/extension/ExtensionStatement.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/extension/ExtensionStatement.java
@@ -34,6 +34,8 @@
return Kind.EXTENSION;
}
+ public abstract String getName();
+
/**
* Called when the {@code IStatementExecutor} encounters an extension statement.
* An implementation class should implement the actual processing of the statement in this method.
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
index e242258..417a130 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
@@ -22,6 +22,7 @@
import org.apache.asterix.common.api.ICommonRequestParameters;
import org.apache.asterix.om.base.IAObject;
+import org.apache.asterix.translator.IStatementExecutor.StatementProperties;
import org.apache.asterix.translator.IStatementExecutor.Stats;
import org.apache.hyracks.api.result.IResultSet;
@@ -45,6 +46,12 @@
Stats getStats();
/**
+ * @return a reference on which to write properties of executed queries (e.g. what kind of statement was parsed
+ * by the parser)
+ */
+ StatementProperties getStatementProperties();
+
+ /**
* @return a reference to write the metadata of executed queries
*/
IStatementExecutor.ResultMetadata getOutMetadata();
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
index c0cf8eb..083fa83 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
@@ -37,6 +37,7 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.metadata.DataverseName;
import org.apache.asterix.lang.common.base.IStatementRewriter;
+import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.statement.Query;
import org.apache.asterix.metadata.declared.MetadataProvider;
import org.apache.asterix.om.base.IAObject;
@@ -217,6 +218,38 @@
}
}
+ class StatementProperties implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ private Statement.Kind kind;
+ private String name;
+
+ public Statement.Kind getKind() {
+ return kind;
+ }
+
+ public void setKind(Statement.Kind kind) {
+ this.kind = kind;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isValid() {
+ return kind != null && (kind != Statement.Kind.EXTENSION || name != null);
+ }
+
+ @Override
+ public String toString() {
+ return Statement.Kind.EXTENSION == kind ? String.valueOf(name) : String.valueOf(kind);
+ }
+ }
+
/**
* Compiles and executes a list of statements
*
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
index b6ac3f1..47e897d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
@@ -155,7 +155,7 @@
long startTime = System.currentTimeMillis();
final IRequestParameters requestParameters = new RequestParameters(requestReference, query, resultSet,
new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE), new IStatementExecutor.Stats(),
- null, null, null, null, true);
+ new IStatementExecutor.StatementProperties(), null, null, null, null, true);
translator.compileAndExecute(hcc, requestParameters);
long endTime = System.currentTimeMillis();
duration = (endTime - startTime) / 1000.00;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
index 6953d1f..1b2b00d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
@@ -69,8 +69,9 @@
@Override
protected void executeStatement(IRequestReference requestReference, String statementsText,
- SessionOutput sessionOutput, ResultProperties resultProperties, IStatementExecutor.Stats stats,
- QueryServiceRequestParameters param, RequestExecutionState execution,
+ SessionOutput sessionOutput, ResultProperties resultProperties,
+ IStatementExecutor.StatementProperties statementProperties, IStatementExecutor.Stats stats,
+ QueryServiceRequestParameters param, RequestExecutionState executionState,
Map<String, String> optionalParameters, Map<String, byte[]> statementParameters,
ResponsePrinter responsePrinter, List<Warning> warnings) throws Exception {
// Running on NC -> send 'execute' message to CC
@@ -89,7 +90,7 @@
resultProperties.getNcToCcResultProperties(), param.getClientContextID(), handleUrl,
optionalParameters, statementParameters, param.isMultiStatement(), param.getProfileType(),
stmtCategoryRestrictionMask, requestReference);
- execution.start();
+ executionState.start();
ncMb.sendMessageToPrimaryCC(requestMsg);
try {
responseMsg = (ExecuteStatementResponseMessage) responseFuture.get(timeout, TimeUnit.MILLISECONDS);
@@ -103,11 +104,12 @@
cancelQuery(ncMb, ncCtx.getNodeId(), requestReference.getUuid(), param.getClientContextID(), hde, true);
throw hde;
}
- execution.end();
+ executionState.end();
} finally {
ncMb.deregisterMessageFuture(responseFuture.getFutureId());
}
+ updatePropertiesFromCC(statementProperties, responseMsg);
Throwable err = responseMsg.getError();
if (err != null) {
if (err instanceof Error) {
@@ -118,6 +120,8 @@
throw new Exception(err.toString(), err);
}
}
+ // if the was no error, we can set the result status to success
+ executionState.setStatus(ResultStatus.SUCCESS, HttpResponseStatus.OK);
updateStatsFromCC(stats, responseMsg);
if (hasResult(responseMsg)) {
responsePrinter.addResultPrinter(
@@ -151,14 +155,14 @@
}
@Override
- protected void handleExecuteStatementException(Throwable t, RequestExecutionState state,
+ protected void handleExecuteStatementException(Throwable t, RequestExecutionState executionState,
QueryServiceRequestParameters param) {
if (t instanceof TimeoutException // TODO(mblow): I don't think t can ever been an instance of TimeoutException
|| ExceptionUtils.matchingCause(t, candidate -> candidate instanceof IPCException)) {
GlobalConfig.ASTERIX_LOGGER.log(Level.WARN, t.toString(), t);
- state.setStatus(ResultStatus.FAILED, HttpResponseStatus.SERVICE_UNAVAILABLE);
+ executionState.setStatus(ResultStatus.FAILED, HttpResponseStatus.SERVICE_UNAVAILABLE);
} else {
- super.handleExecuteStatementException(t, state, param);
+ super.handleExecuteStatementException(t, executionState, param);
}
}
@@ -177,4 +181,13 @@
stats.setProcessedObjects(responseStats.getProcessedObjects());
stats.updateTotalWarningsCount(responseStats.getTotalWarningsCount());
}
+
+ private static void updatePropertiesFromCC(IStatementExecutor.StatementProperties statementProperties,
+ ExecuteStatementResponseMessage responseMsg) {
+ IStatementExecutor.StatementProperties responseStmtProps = responseMsg.getStatementProperties();
+ if (responseStmtProps != null) {
+ statementProperties.setKind(responseStmtProps.getKind());
+ statementProperties.setName(responseStmtProps.getName());
+ }
+ }
}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
index 6cf8454..9863f19 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
@@ -117,6 +117,7 @@
private ResultDelivery mode = ResultDelivery.IMMEDIATE;
private PlanFormat planFormat = PlanFormat.JSON;
private ProfileType profileType = ProfileType.COUNTS;
+ private Map<String, String> optionalParams = null;
private Map<String, JsonNode> statementParams = null;
private boolean pretty = false;
private boolean expressionTree = false;
@@ -220,6 +221,14 @@
this.planFormat = planFormat;
}
+ public Map<String, String> getOptionalParams() {
+ return optionalParams;
+ }
+
+ public void setOptionalParams(Map<String, String> optionalParams) {
+ this.optionalParams = optionalParams;
+ }
+
public Map<String, JsonNode> getStatementParams() {
return statementParams;
}
@@ -367,6 +376,7 @@
setHost(servlet.host(request));
setPath(servlet.servletPath(request));
String contentType = HttpUtil.getContentTypeOnly(request);
+ setOptionalParams(optionalParams);
try {
if (HttpUtil.ContentType.APPLICATION_JSON.equals(contentType)) {
setParamFromJSON(request, optionalParams);
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index 319d959..cb1d6cf 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -88,6 +88,7 @@
import org.apache.asterix.translator.SessionOutput;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.api.application.IServiceContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.exceptions.HyracksException;
import org.apache.hyracks.api.exceptions.Warning;
import org.apache.hyracks.control.common.controllers.CCConfig;
@@ -152,18 +153,18 @@
response.setStatus(HttpResponseStatus.OK);
}
- protected static final class RequestExecutionState {
+ protected static class RequestExecutionState {
private long execStart = -1;
private long execEnd = -1;
- private ResultStatus resultStatus = ResultStatus.SUCCESS;
- private HttpResponseStatus httpResponseStatus = HttpResponseStatus.OK;
+ private ResultStatus resultStatus = ResultStatus.FATAL;
+ private HttpResponseStatus httpResponseStatus = HttpResponseStatus.INTERNAL_SERVER_ERROR;
public void setStatus(ResultStatus resultStatus, HttpResponseStatus httpResponseStatus) {
this.resultStatus = resultStatus;
this.httpResponseStatus = httpResponseStatus;
}
- ResultStatus getResultStatus() {
+ public ResultStatus getResultStatus() {
return resultStatus;
}
@@ -187,9 +188,19 @@
}
}
- long duration() {
+ public long duration() {
return execEnd - execStart;
}
+
+ protected StringBuilder append(StringBuilder sb) {
+ return sb.append("ResultStatus: ").append(resultStatus.str()).append(" HTTPStatus: ")
+ .append(String.valueOf(httpResponseStatus));
+ }
+
+ @Override
+ public String toString() {
+ return append(new StringBuilder()).toString();
+ }
}
private static SessionOutput createSessionOutput(PrintWriter resultWriter) {
@@ -201,7 +212,12 @@
}
protected void setRequestParam(IServletRequest request, QueryServiceRequestParameters param,
- Map<String, String> optionalParams) throws IOException, AlgebricksException {
+ Function<IServletRequest, Map<String, String>> optionalParamProvider, RequestExecutionState executionState)
+ throws IOException, AlgebricksException {
+ Map<String, String> optionalParams = null;
+ if (optionalParamProvider != null) {
+ optionalParams = optionalParamProvider.apply(request);
+ }
param.setParameters(this, request, optionalParams);
}
@@ -248,22 +264,18 @@
long elapsedStart = System.nanoTime();
long errorCount = 1;
Stats stats = new Stats();
- RequestExecutionState execution = new RequestExecutionState();
List<Warning> warnings = new ArrayList<>();
Charset resultCharset = HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, request);
PrintWriter httpWriter = response.writer();
SessionOutput sessionOutput = createSessionOutput(httpWriter);
- QueryServiceRequestParameters param = newRequestParameters();
ResponsePrinter responsePrinter = new ResponsePrinter(sessionOutput);
ResultDelivery delivery = ResultDelivery.IMMEDIATE;
+ QueryServiceRequestParameters param = newRequestParameters();
+ RequestExecutionState executionState = newRequestExecutionState();
try {
// buffer the output until we are ready to set the status of the response message correctly
responsePrinter.begin();
- Map<String, String> optionalParams = null;
- if (optionalParamProvider != null) {
- optionalParams = optionalParamProvider.apply(request);
- }
- setRequestParam(request, param, optionalParams);
+ setRequestParam(request, param, optionalParamProvider, executionState);
if (forceReadOnly) {
param.setReadOnly(true);
}
@@ -278,27 +290,32 @@
if (param.isParseOnly()) {
ResultUtil.ParseOnlyResult parseOnlyResult = parseStatement(statementsText);
setAccessControlHeaders(request, response);
- response.setStatus(execution.getHttpStatus());
+ executionState.setStatus(ResultStatus.SUCCESS, HttpResponseStatus.OK);
+ response.setStatus(executionState.getHttpStatus());
responsePrinter.addResultPrinter(new ParseOnlyResultPrinter(parseOnlyResult));
} else {
Map<String, byte[]> statementParams = org.apache.asterix.app.translator.RequestParameters
.serializeParameterValues(param.getStatementParams());
setAccessControlHeaders(request, response);
- response.setStatus(execution.getHttpStatus());
stats.setProfileType(param.getProfileType());
- executeStatement(requestRef, statementsText, sessionOutput, resultProperties, stats, param, execution,
- optionalParams, statementParams, responsePrinter, warnings);
+ IStatementExecutor.StatementProperties statementProperties =
+ new IStatementExecutor.StatementProperties();
+ response.setStatus(HttpResponseStatus.OK);
+ executeStatement(requestRef, statementsText, sessionOutput, resultProperties, statementProperties,
+ stats, param, executionState, param.getOptionalParams(), statementParams, responsePrinter,
+ warnings);
+ executionState.setStatus(ResultStatus.SUCCESS, HttpResponseStatus.OK);
}
errorCount = 0;
} catch (Exception | TokenMgrError | org.apache.asterix.aqlplus.parser.TokenMgrError e) {
- handleExecuteStatementException(e, execution, param);
- response.setStatus(execution.getHttpStatus());
+ handleExecuteStatementException(e, executionState, param);
+ response.setStatus(executionState.getHttpStatus());
requestFailed(e, responsePrinter);
} finally {
- execution.finish();
+ executionState.finish();
}
responsePrinter.printResults();
- buildResponseFooters(elapsedStart, errorCount, stats, execution, resultCharset, responsePrinter, delivery);
+ buildResponseFooters(elapsedStart, errorCount, stats, executionState, resultCharset, responsePrinter, delivery);
responsePrinter.printFooters();
responsePrinter.end();
if (sessionOutput.out().checkError()) {
@@ -306,6 +323,10 @@
}
}
+ protected RequestExecutionState newRequestExecutionState() throws HyracksDataException {
+ return new RequestExecutionState();
+ }
+
protected void buildResponseHeaders(IRequestReference requestRef, SessionOutput sessionOutput,
QueryServiceRequestParameters param, ResponsePrinter responsePrinter, ResultDelivery delivery) {
responsePrinter.addHeaderPrinter(new RequestIdPrinter(requestRef.getUuid()));
@@ -322,7 +343,7 @@
}
protected void buildResponseResults(ResponsePrinter responsePrinter, SessionOutput sessionOutput,
- ExecutionPlans plans, List<Warning> warnings) {
+ ExecutionPlans plans, List<Warning> warnings) throws HyracksDataException {
responsePrinter.addResultPrinter(new PlansPrinter(plans, sessionOutput.config().getPlanFormat()));
if (!warnings.isEmpty()) {
List<ICodedMessage> codedWarnings = new ArrayList<>();
@@ -331,20 +352,21 @@
}
}
- protected void buildResponseFooters(long elapsedStart, long errorCount, Stats stats,
- RequestExecutionState execution, Charset resultCharset, ResponsePrinter responsePrinter,
+ protected ResponseMetrics buildResponseFooters(long elapsedStart, long errorCount, Stats stats,
+ RequestExecutionState executionState, Charset resultCharset, ResponsePrinter responsePrinter,
ResultDelivery delivery) {
if (ResultDelivery.ASYNC != delivery) {
// in case of ASYNC delivery, the status is printed by query translator
- responsePrinter.addFooterPrinter(new StatusPrinter(execution.getResultStatus()));
+ responsePrinter.addFooterPrinter(new StatusPrinter(executionState.getResultStatus()));
}
final ResponseMetrics metrics =
- ResponseMetrics.of(System.nanoTime() - elapsedStart, execution.duration(), stats.getCount(),
+ ResponseMetrics.of(System.nanoTime() - elapsedStart, executionState.duration(), stats.getCount(),
stats.getSize(), stats.getProcessedObjects(), errorCount, stats.getTotalWarningsCount());
responsePrinter.addFooterPrinter(new MetricsPrinter(metrics, resultCharset));
if (isPrintingProfile(stats)) {
responsePrinter.addFooterPrinter(new ProfilePrinter(stats.getJobProfile()));
}
+ return metrics;
}
protected void validateStatement(String statement) throws RuntimeDataException {
@@ -365,8 +387,9 @@
}
protected void executeStatement(IRequestReference requestReference, String statementsText,
- SessionOutput sessionOutput, ResultProperties resultProperties, Stats stats,
- QueryServiceRequestParameters param, RequestExecutionState execution,
+ SessionOutput sessionOutput, ResultProperties resultProperties,
+ IStatementExecutor.StatementProperties statementProperties, Stats stats,
+ QueryServiceRequestParameters param, RequestExecutionState executionState,
Map<String, String> optionalParameters, Map<String, byte[]> statementParameters,
ResponsePrinter responsePrinter, List<Warning> warnings) throws Exception {
IClusterManagementWork.ClusterState clusterState =
@@ -383,22 +406,23 @@
MetadataManager.INSTANCE.init();
IStatementExecutor translator = statementExecutorFactory.create((ICcApplicationContext) appCtx, statements,
sessionOutput, compilationProvider, componentProvider, responsePrinter);
- execution.start();
+ executionState.start();
Map<String, IAObject> stmtParams =
org.apache.asterix.app.translator.RequestParameters.deserializeParameterValues(statementParameters);
int stmtCategoryRestriction = org.apache.asterix.app.translator.RequestParameters
.getStatementCategoryRestrictionMask(param.isReadOnly());
- IRequestParameters requestParameters = new org.apache.asterix.app.translator.RequestParameters(requestReference,
- statementsText, getResultSet(), resultProperties, stats, null, param.getClientContextID(),
- optionalParameters, stmtParams, param.isMultiStatement(), stmtCategoryRestriction);
+ IRequestParameters requestParameters =
+ new org.apache.asterix.app.translator.RequestParameters(requestReference, statementsText,
+ getResultSet(), resultProperties, stats, statementProperties, null, param.getClientContextID(),
+ optionalParameters, stmtParams, param.isMultiStatement(), stmtCategoryRestriction);
translator.compileAndExecute(getHyracksClientConnection(), requestParameters);
- execution.end();
+ executionState.end();
translator.getWarnings(warnings, maxWarnings - warnings.size());
stats.updateTotalWarningsCount(parserTotalWarningsCount);
buildResponseResults(responsePrinter, sessionOutput, translator.getExecutionPlans(), warnings);
}
- protected void handleExecuteStatementException(Throwable t, RequestExecutionState state,
+ protected void handleExecuteStatementException(Throwable t, RequestExecutionState executionState,
QueryServiceRequestParameters param) {
if (t instanceof org.apache.asterix.aqlplus.parser.TokenMgrError || t instanceof TokenMgrError
|| t instanceof AlgebricksException) {
@@ -408,37 +432,37 @@
LOGGER.info(() -> "handleException: " + t.getMessage() + ": "
+ LogRedactionUtil.userData(param.toString()));
}
- state.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
+ executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
} else if (t instanceof HyracksException) {
HyracksException he = (HyracksException) t;
switch (he.getComponent() + he.getErrorCode()) {
case ASTERIX + REQUEST_TIMEOUT:
LOGGER.info(() -> "handleException: request execution timed out: "
+ LogRedactionUtil.userData(param.toString()));
- state.setStatus(ResultStatus.TIMEOUT, HttpResponseStatus.OK);
+ executionState.setStatus(ResultStatus.TIMEOUT, HttpResponseStatus.OK);
break;
case ASTERIX + REJECT_BAD_CLUSTER_STATE:
case ASTERIX + REJECT_NODE_UNREGISTERED:
LOGGER.warn(() -> "handleException: " + he.getMessage() + ": "
+ LogRedactionUtil.userData(param.toString()));
- state.setStatus(ResultStatus.FATAL, HttpResponseStatus.SERVICE_UNAVAILABLE);
+ executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.SERVICE_UNAVAILABLE);
break;
case ASTERIX + INVALID_REQ_PARAM_VAL:
case ASTERIX + INVALID_REQ_JSON_VAL:
case ASTERIX + NO_STATEMENT_PROVIDED:
case HYRACKS + JOB_REQUIREMENTS_EXCEED_CAPACITY:
- state.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
+ executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
break;
default:
LOGGER.warn(() -> "handleException: unexpected exception " + he.getMessage() + ": "
+ LogRedactionUtil.userData(param.toString()), he);
- state.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
+ executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
break;
}
} else {
LOGGER.warn(() -> "handleException: unexpected exception: " + LogRedactionUtil.userData(param.toString()),
t);
- state.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
+ executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
}
@@ -473,7 +497,7 @@
return new QueryServiceRequestParameters();
}
- private static boolean isPrintingProfile(IStatementExecutor.Stats stats) {
+ protected static boolean isPrintingProfile(IStatementExecutor.Stats stats) {
return stats.getProfileType() == Stats.ProfileType.FULL && stats.getJobProfile() != null;
}
}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
index 1cdf6f7..4fe6582 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
@@ -136,8 +136,8 @@
final RequestReference requestReference =
RequestReference.of(UUID.randomUUID().toString(), "CC", System.currentTimeMillis());
final IRequestParameters requestParameters = new RequestParameters(requestReference, statement, null,
- new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE), new IStatementExecutor.Stats(), null,
- null, null, statementParams, true);
+ new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE), new IStatementExecutor.Stats(),
+ new IStatementExecutor.StatementProperties(), null, null, null, statementParams, true);
translator.compileAndExecute(hcc, requestParameters);
executionPlans = translator.getExecutionPlans();
writer.flush();
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
index 94080da..149ed33 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
@@ -146,10 +146,12 @@
compilationProvider, storageComponentProvider, new ResponsePrinter(sessionOutput));
final IStatementExecutor.Stats stats = new IStatementExecutor.Stats();
stats.setProfileType(profileType);
+ final IStatementExecutor.StatementProperties statementProperties =
+ new IStatementExecutor.StatementProperties();
Map<String, IAObject> stmtParams = RequestParameters.deserializeParameterValues(statementParameters);
final IRequestParameters requestParameters = new RequestParameters(requestReference, statementsText, null,
- resultProperties, stats, outMetadata, clientContextID, optionalParameters, stmtParams,
- multiStatement, statementCategoryRestrictionMask);
+ resultProperties, stats, statementProperties, outMetadata, clientContextID, optionalParameters,
+ stmtParams, multiStatement, statementCategoryRestrictionMask);
translator.compileAndExecute(ccApp.getHcc(), requestParameters);
translator.getWarnings(warnings, maxWarnings - warnings.size());
stats.updateTotalWarningsCount(parserTotalWarningsCount);
@@ -157,6 +159,7 @@
responseMsg.setResult(outWriter.toString());
responseMsg.setMetadata(outMetadata);
responseMsg.setStats(stats);
+ responseMsg.setStatementProperties(statementProperties);
responseMsg.setExecutionPlans(translator.getExecutionPlans());
responseMsg.setWarnings(warnings);
} catch (AlgebricksException | HyracksException | TokenMgrError
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementResponseMessage.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementResponseMessage.java
index 58898cf..2cdede1 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementResponseMessage.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementResponseMessage.java
@@ -41,6 +41,8 @@
private IStatementExecutor.Stats stats;
+ private IStatementExecutor.StatementProperties statementProperties;
+
private Throwable error;
private ExecutionPlans executionPlans;
@@ -92,6 +94,14 @@
this.stats = stats;
}
+ public IStatementExecutor.StatementProperties getStatementProperties() {
+ return statementProperties;
+ }
+
+ public void setStatementProperties(IStatementExecutor.StatementProperties statementProperties) {
+ this.statementProperties = statementProperties;
+ }
+
public ExecutionPlans getExecutionPlans() {
return executionPlans;
}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 12fe09b..50f2e9f 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -308,6 +308,7 @@
final ResultDelivery resultDelivery = requestParameters.getResultProperties().getDelivery();
final long maxResultReads = requestParameters.getResultProperties().getMaxReads();
final Stats stats = requestParameters.getStats();
+ final StatementProperties statementProperties = requestParameters.getStatementProperties();
final ResultMetadata outMetadata = requestParameters.getOutMetadata();
final Map<String, IAObject> stmtParams = requestParameters.getStatementParameters();
warningCollector.setMaxWarnings(sessionConfig.getMaxWarnings());
@@ -324,7 +325,9 @@
metadataProvider.setOutputFile(outputFile);
IStatementRewriter stmtRewriter = rewriterFactory.createStatementRewriter();
rewriteStatement(stmt, stmtRewriter, metadataProvider); // Rewrite the statement's AST.
- switch (stmt.getKind()) {
+ Statement.Kind kind = stmt.getKind();
+ statementProperties.setKind(kind);
+ switch (kind) {
case SET:
handleSetStatement(stmt, config);
break;
@@ -443,12 +446,13 @@
// No op
break;
case EXTENSION:
- ((ExtensionStatement) stmt).handle(hcc, this, requestParameters, metadataProvider,
- resultSetIdCounter);
+ final ExtensionStatement extStmt = (ExtensionStatement) stmt;
+ statementProperties.setName(extStmt.getName());
+ extStmt.handle(hcc, this, requestParameters, metadataProvider, resultSetIdCounter);
break;
default:
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, stmt.getSourceLocation(),
- "Unexpected statement: " + stmt.getKind());
+ "Unexpected statement: " + kind);
}
}
} finally {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
index 90602e7..5ebc9ba 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
@@ -31,6 +31,7 @@
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.translator.IRequestParameters;
import org.apache.asterix.translator.IStatementExecutor;
+import org.apache.asterix.translator.IStatementExecutor.StatementProperties;
import org.apache.asterix.translator.IStatementExecutor.Stats;
import org.apache.asterix.translator.ResultProperties;
import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -49,6 +50,7 @@
private final IResultSet resultSet;
private final ResultProperties resultProperties;
private final Stats stats;
+ private final StatementProperties statementProperties;
private final Map<String, String> optionalParameters;
private final IStatementExecutor.ResultMetadata outMetadata;
private final String clientContextId;
@@ -58,22 +60,24 @@
private final String statement;
public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
- ResultProperties resultProperties, Stats stats, IStatementExecutor.ResultMetadata outMetadata,
- String clientContextId, Map<String, String> optionalParameters, Map<String, IAObject> statementParameters,
- boolean multiStatement) {
- this(requestReference, statement, resultSet, resultProperties, stats, outMetadata, clientContextId,
- optionalParameters, statementParameters, multiStatement, NO_CATEGORY_RESTRICTION_MASK);
+ ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
+ IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+ Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement) {
+ this(requestReference, statement, resultSet, resultProperties, stats, statementProperties, outMetadata,
+ clientContextId, optionalParameters, statementParameters, multiStatement, NO_CATEGORY_RESTRICTION_MASK);
}
public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
- ResultProperties resultProperties, Stats stats, IStatementExecutor.ResultMetadata outMetadata,
- String clientContextId, Map<String, String> optionalParameters, Map<String, IAObject> statementParameters,
- boolean multiStatement, int statementCategoryRestrictionMask) {
+ ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
+ IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+ Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement,
+ int statementCategoryRestrictionMask) {
this.requestReference = requestReference;
this.statement = statement;
this.resultSet = resultSet;
this.resultProperties = resultProperties;
this.stats = stats;
+ this.statementProperties = statementProperties;
this.outMetadata = outMetadata;
this.clientContextId = clientContextId;
this.optionalParameters = optionalParameters;
@@ -93,11 +97,16 @@
}
@Override
- public IStatementExecutor.Stats getStats() {
+ public Stats getStats() {
return stats;
}
@Override
+ public StatementProperties getStatementProperties() {
+ return statementProperties;
+ }
+
+ @Override
public Map<String, String> getOptionalParameters() {
return optionalParameters;
}
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
index 348b947..50e1155 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
@@ -70,8 +70,8 @@
verify(mockResponse, times(1)).setStatus(HttpResponseStatus.NOT_FOUND);
final RequestReference requestReference = RequestReference.of("1", "node1", System.currentTimeMillis());
- RequestParameters requestParameters =
- new RequestParameters(requestReference, "select 1", null, null, null, null, "1", null, null, true);
+ RequestParameters requestParameters = new RequestParameters(requestReference, "select 1", null, null, null,
+ null, null, "1", null, null, true);
ClientRequest request = new ClientRequest(requestParameters);
request.setJobId(new JobId(1));
request.markCancellable();
@@ -87,8 +87,8 @@
// Tests the case that the job cancellation hit some exception from Hyracks.
final RequestReference requestReference2 = RequestReference.of("2", "node1", System.currentTimeMillis());
- requestParameters =
- new RequestParameters(requestReference2, "select 1", null, null, null, null, "2", null, null, true);
+ requestParameters = new RequestParameters(requestReference2, "select 1", null, null, null, null, null, "2",
+ null, null, true);
ClientRequest request2 = new ClientRequest(requestParameters);
request2.setJobId(new JobId(2));
request2.markCancellable();
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
index 190b7b0..3895ec8 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
@@ -200,10 +200,12 @@
Charset resultCharset, OutputFormat fmt, String[] plans) throws Exception {
ExtractedResult extractedResult = new ExtractedResult();
final String resultStr = IOUtils.toString(resultStream, resultCharset);
+
+ LOGGER.debug("+++++++\n" + resultStr + "\n+++++++\n");
+
final ObjectNode result = OBJECT_READER.readValue(resultStr);
final boolean isJsonFormat = isJsonFormat(fmt);
- LOGGER.debug("+++++++\n" + result + "\n+++++++\n");
// if we have errors field in the results, we will always return it
checkForErrors(result);
final StringBuilder resultBuilder = new StringBuilder();
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 ed8f7f6..ff9f0ee 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
@@ -1461,7 +1461,6 @@
FilenameUtils.getExtension(ctx.getFile().getName()));
return executeQuery(fmt, statement, variableCtx, ctx, expectedResultFile, actualResultFile, queryCount,
numResultFiles, params, compare, uri);
-
}
private void polldynamic(TestCaseContext testCaseCtx, TestFileContext ctx, Map<String, Object> variableCtx,
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IRequestReference.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IRequestReference.java
index 8a25ed2..c7f8d30 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IRequestReference.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IRequestReference.java
@@ -42,4 +42,18 @@
* @return the time at which the request was received.
*/
long getTime();
+
+ /**
+ * Gets the user agent from which the request was received.
+ *
+ * @return user agent from which the request was received.
+ */
+ String getUserAgent();
+
+ /**
+ * Gets the remote address from which the request was received.
+ *
+ * @return remote address from which the request was received.
+ */
+ String getRemoteAddr();
}