[email protected] has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/3056
Change subject: parse-only implementation with testing framework.
......................................................................
parse-only implementation with testing framework.
Change-Id: I8b94f5da144f664fb488d37bee4673b6ff5646f7
---
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java
A
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
M
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
M
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
A
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ParseOnlyTest.java
A
asterixdb/asterix-app/src/test/resources/parseonly/queries_sqlpp/named_01.1.query.sqlpp
A asterixdb/asterix-app/src/test/resources/runtimets/only_parseonly.xml
A
asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.1.parse.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.2.parse.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.2.adm
A asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
A
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
A
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
16 files changed, 582 insertions(+), 63 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/56/3056/1
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java
index 9844900..9d923ec 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java
@@ -50,7 +50,8 @@
ERRORS("errors"),
METRICS("metrics"),
PLANS("plans"),
- WARNINGS("warnings");
+ WARNINGS("warnings"),
+ PARSEVALS("parsevals");
private final String str;
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
new file mode 100644
index 0000000..cd101ad
--- /dev/null
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
@@ -0,0 +1,61 @@
+package org.apache.asterix.api.http.server;
+
+import org.apache.asterix.lang.sqlpp.parser.ParseValues;
+import org.apache.asterix.translator.SessionConfig;
+import org.apache.hyracks.util.JSONUtil;
+
+public class ParseValuesJsonPrintUtils {
+
+ private static final String EXTERNAL_VARIABLE_LBL = "externalVariables";
+
+ public static String asJson(ParseValues parseValues) {
+ final StringBuilder output = new StringBuilder();
+ appendOutputPrefix(output);
+ appendNonNull(output, EXTERNAL_VARIABLE_LBL,
parseValues.toStringDebug());
+ appendOutputPostfix(output);
+ return output.toString();
+ }
+
+ private static void appendNonNull(StringBuilder builder, String lbl,
String value) {
+ //TODO: The format is string. Should we use JSON?
+
+ SessionConfig.PlanFormat format = SessionConfig.PlanFormat.STRING;
+
+ if (value != null) {
+ printFieldPrefix(builder, lbl);
+ switch (format) {
+ case JSON:
+ //TODO: No support for JSON currently.
+ break;
+ case STRING:
+ JSONUtil.quoteAndEscape(builder, value);
+ break;
+ default:
+ throw new IllegalStateException("Unrecognized plan format:
" + format);
+ }
+ printFieldPostfix(builder);
+ }
+ }
+
+ //TODO: Refactor to remove code duplication from
ExecutionPlansJsonPrintUtil
+ private static void appendOutputPrefix(StringBuilder builder) {
+ builder.append("{");
+ }
+
+ private static void printFieldPrefix(StringBuilder builder, String lbl) {
+ builder.append("\"" + lbl + "\": ");
+ }
+
+ private static void printFieldPostfix(StringBuilder builder) {
+ builder.append(",");
+ }
+
+ private static void appendOutputPostfix(StringBuilder builder) {
+ // remove extra comma if needed
+ if (builder.length() > 1) {
+ builder.deleteCharAt(builder.length() - 1);
+ }
+ builder.append("}");
+ }
+
+}
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 534cafb..01a70c1 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
@@ -46,23 +46,14 @@
import org.apache.asterix.compiler.provider.ILangCompilationProvider;
import org.apache.asterix.lang.aql.parser.TokenMgrError;
import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.Statement;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.lang.sqlpp.visitor.NamedParameterVisitor;
+
import org.apache.asterix.metadata.MetadataManager;
import org.apache.asterix.om.base.IAObject;
-import org.apache.asterix.translator.ExecutionPlans;
-import org.apache.asterix.translator.ExecutionPlansJsonPrintUtil;
-import org.apache.asterix.translator.IRequestParameters;
-import org.apache.asterix.translator.IStatementExecutor;
+import org.apache.asterix.translator.*;
import org.apache.asterix.translator.IStatementExecutor.ResultDelivery;
import org.apache.asterix.translator.IStatementExecutor.Stats;
-import org.apache.asterix.translator.IStatementExecutorContext;
-import org.apache.asterix.translator.IStatementExecutorFactory;
-import org.apache.asterix.translator.ResultProperties;
-import org.apache.asterix.translator.SessionConfig;
-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.HyracksException;
@@ -73,6 +64,9 @@
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+
+import org.apache.asterix.lang.sqlpp.parser.ParseValueParser;
+import org.apache.asterix.lang.sqlpp.parser.ParseValues;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
@@ -510,29 +504,6 @@
return "http://" + host + path + handlePath(delivery);
}
- protected void parseOnlyStatement(String statementsText,
QueryServiceRequestParameters param,
- SessionOutput sessionOutput) throws CompilationException {
- assert (param.isMultiStatement() == false);
- try {
- IParser parser =
compilationProvider.getParserFactory().createParser(statementsText);
- List<Statement> statements = parser.parse();
- Set<VariableExpr> extVars = new HashSet<>();
-
- NamedParameterVisitor erv = new NamedParameterVisitor();
- for (Statement st : statements) {
- st.accept(erv, extVars);
- }
- for (VariableExpr extVarRef : extVars) {
-
sessionOutput.out().println(SqlppVariableUtil.toUserDefinedName(extVarRef.getVar().getValue()));
- }
-
- } catch (CompilationException ce) {
- System.out.println("Compilation Exception happened");
- throw ce;
- }
-
- }
-
private void handleRequest(IServletRequest request, IServletResponse
response) throws IOException {
QueryServiceRequestParameters param = getRequestParameters(request);
LOGGER.info("handleRequest: {}", param);
@@ -567,30 +538,53 @@
String statementsText = param.getStatement() + ";";
+ RequestExecutionState execution = new RequestExecutionState();
if (param.isParseOnly()) {
try {
- parseOnlyStatement(statementsText, param, sessionOutput);
- } catch (CompilationException ce) {
+ parseStatement(statementsText, param, sessionOutput); //is
cousin of executeStatement
+ // CORS
+ if (request.getHeader("Origin") != null) {
+ response.setHeader("Access-Control-Allow-Origin",
request.getHeader("Origin"));
+ }
+ response.setHeader("Access-Control-Allow-Headers", "Origin,
X-Requested-With, Content-Type, Accept");
+
+ response.setStatus(HttpResponseStatus.OK);
+ if (ResultDelivery.IMMEDIATE == delivery ||
ResultDelivery.DEFERRED == delivery) {
+ ResultUtil.printStatus(sessionOutput,
execution.getResultStatus());
+ }
+ if (!warnings.isEmpty()) {
+ printWarnings(sessionOutput.out(), warnings);
+ }
+ errorCount = 0;
+ } catch (CompilationException e) {
//TODO: figure out what to do with compilation error
//TODO: invoke the already backed exception handling
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("handleException: {}: {}", ce.getMessage(),
param, ce);
+ LOGGER.debug("handleException: {}: {}", e.getMessage(),
param, e);
} else {
- LOGGER.info("handleException: {}: {}", ce.getMessage(),
param);
- sessionOutput.out()
- .print(ce.getMessage() + ";" +
ce.getLocalizedMessage() + ";" + ce.getSourceLocation());
+ LOGGER.info("handleException: {}: {}", e.getMessage(),
param);
+ //sessionOutput.out()
+ // .print(e.getMessage() + ";" +
e.getLocalizedMessage() + ";" + e.getSourceLocation());
+ }
+ handleExecuteStatementException(e, execution, param); //hope
this is generic enough to do its thing.
+ response.setStatus(execution.getHttpStatus());
+ printError(sessionOutput.out(), e);
+ ResultUtil.printStatus(sessionOutput,
execution.getResultStatus());
+ if (!warnings.isEmpty()) {
+ printWarnings(sessionOutput.out(), warnings);
}
} finally {
// make sure that we stop buffering and return the result to
the http response
sessionOutput.release();
- //TODO: make sure we are exiting the function from here.
}
+ printMetrics(sessionOutput.out(), System.nanoTime() -
elapsedStart, execution.duration(), stats.getCount(),
+ stats.getSize(), stats.getProcessedObjects(), errorCount,
warnings.size());
} else {
- RequestExecutionState execution = new RequestExecutionState();
+
try {
Map<String, String> optionalParams = null;
if (optionalParamProvider != null) {
@@ -631,6 +625,23 @@
if (sessionOutput.out().checkError()) {
LOGGER.warn("Error flushing output writer");
}
+ }
+
+ protected void parseStatement(String statementsText,
QueryServiceRequestParameters param,
+ SessionOutput sessionOutput) throws CompilationException {
+ //assert (param.isMultiStatement() == false);
+ try {
+ //IParser parser =
compilationProvider.getParserFactory().createParser(statementsText);
+ IParserFactory factory = compilationProvider.getParserFactory();
+ ParseValueParser parser = new ParseValueParser(factory,
statementsText);
+ parser.parse();
+ printParseValues(sessionOutput, parser.getParseValues());
+
+ } catch (CompilationException ce) {
+ System.out.println("Compilation Exception happened");
+ throw ce;
+ }
+
}
protected void executeStatement(String statementsText, SessionOutput
sessionOutput,
@@ -703,6 +714,18 @@
ResultUtil.printWarnings(pw, warnings);
}
+ protected void printParseValues(SessionOutput output, ParseValues
parseValues) {
+ final PrintWriter pw = output.out();
+ pw.print("\t\"");
+ pw.print(ResultFields.PARSEVALS.str());
+ pw.print("\":");
+
+ pw.print(ParseValuesJsonPrintUtils.asJson(parseValues));
+
+ pw.print(",\n");
+
+ }
+
protected void printExecutionPlans(SessionOutput output, ExecutionPlans
executionPlans) {
final PrintWriter pw = output.out();
pw.print("\t\"");
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 412cf03..e71c2d9 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
@@ -55,7 +55,8 @@
TYPE("type"),
ERRORS("errors"),
PLANS("plans"),
- WARNINGS("warnings");
+ WARNINGS("warnings"),
+ PARSEVALS("parsevals");
private static final Map<String, ResultField> fields = new HashMap<>();
@@ -90,6 +91,11 @@
public static InputStream extractMetrics(InputStream resultStream) throws
Exception {
return extract(resultStream, EnumSet.of(ResultField.METRICS));
}
+
+ public static InputStream extractParseResults(InputStream resultStream)
throws Exception {
+ return extract(resultStream, EnumSet.of(ResultField.PARSEVALS));
+ }
+
public static String extractHandle(InputStream resultStream) throws
Exception {
String result = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
@@ -165,6 +171,7 @@
case STATUS:
case TYPE:
case PLANS:
+ case PARSEVALS:
case WARNINGS:
resultBuilder.append(OBJECT_MAPPER.writeValueAsString(fieldValue));
break;
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 9f4f248..1af04ad 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
@@ -37,16 +37,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -80,6 +71,7 @@
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
@@ -153,6 +145,7 @@
public static final String DELIVERY_IMMEDIATE = "immediate";
public static final String DIAGNOSE = "diagnose";
private static final String METRICS_QUERY_TYPE = "metrics";
+ private static final String PARSE_QUERY_TYPE = "parse";
private static final HashMap<Integer, ITestServer> runningTestServers =
new HashMap<>();
private static Map<String, InetSocketAddress> ncEndPoints;
@@ -596,6 +589,8 @@
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(),
@@ -607,9 +602,21 @@
}
HttpUriRequest method = jsonEncoded ? constructPostMethodJson(str,
uri, "statement", newParams)
: constructPostMethodUrl(str, uri, "statement", newParams);
+
+ //HttpEntityEnclosingRequest method =
+ // (HttpEntityEnclosingRequest) (jsonEncoded ?
constructPostMethodJson(str, uri, "statement", newParams)
+ // : constructPostMethodUrl(str, uri, "statement",
newParams));
+
+
+ //final String entity = EntityUtils.toString(method.getEntity());
+ //System.out.println(entity);
+
// Set accepted output response type
method.setHeader("Origin", uri.getScheme() + uri.getAuthority());
method.setHeader("Accept", OutputFormat.CLEAN_JSON.mimeType());
+
+ //System.out.println("The method = " + method.toString());
+ //HttpResponse response = executeHttpRequest((HttpUriRequest) method);
HttpResponse response = executeHttpRequest(method);
if (responseCodeValidator != null) {
checkResponse(response, responseCodeValidator);
@@ -889,6 +896,7 @@
break;
case "query":
case "async":
+ case "parse":
case "deferred":
case "metrics":
// isDmlRecoveryTest: insert Crash and Recovery
@@ -1219,17 +1227,39 @@
if (DELIVERY_IMMEDIATE.equals(delivery)) {
resultStream =
executeQueryService(statement, fmt, uri, params,
isJsonEncoded, null, isCancellable(reqType));
- resultStream = METRICS_QUERY_TYPE.equals(reqType) ?
ResultExtractor.extractMetrics(resultStream)
- : ResultExtractor.extract(resultStream);
+ //String res = IOUtils.toString(resultStream,
StandardCharsets.UTF_8);
+ //EnumSet<ResultExtractor.ResultField> resultFields = new
EnumSet<ResultExtractor.ResultField>();
+ //resultFields.add(ResultExtractor.ResultField.PARSEVALS);
+
+ switch(reqType){
+
+ case METRICS_QUERY_TYPE:
+ resultStream =
ResultExtractor.extractMetrics(resultStream);
+ break;
+ case PARSE_QUERY_TYPE:
+ resultStream =
ResultExtractor.extractParseResults(resultStream);
+ break;
+ default:
+ resultStream = ResultExtractor.extract(resultStream);
+ break;
+
+ }
+ //resultStream = METRICS_QUERY_TYPE.equals(reqType) ?
ResultExtractor.extractMetrics(resultStream)
+ // : ResultExtractor.extract(resultStream);
+ //String res1 = IOUtils.toString(resultStream,
StandardCharsets.UTF_8);
+
} else {
String handleVar = getHandleVariable(statement);
resultStream = executeQueryService(statement, fmt, uri,
upsertParam(params, "mode", ParameterTypeEnum.STRING,
delivery), isJsonEncoded);
+ //String res = IOUtils.toString(resultStream,
StandardCharsets.UTF_8);
String handle = ResultExtractor.extractHandle(resultStream);
Assert.assertNotNull("no handle for " + reqType + " test " +
testFile.toString(), handleVar);
variableCtx.put(handleVar, toQueryServiceHandle(handle));
}
if (actualResultFile == null) {
+ String namex = testFile.getName();
+
if (testFile.getName().startsWith(DIAGNOSE)) {
LOGGER.info("Diagnostic output: {}",
IOUtils.toString(resultStream, StandardCharsets.UTF_8));
} else {
@@ -1237,6 +1267,7 @@
+ ", filectxs.size: " + numResultFiles);
}
} else {
+ //String res = IOUtils.toString(resultStream,
StandardCharsets.UTF_8);
writeOutputToFile(actualResultFile, resultStream);
if (expectedResultFile == null) {
if (reqType.equals("store")) {
@@ -1490,10 +1521,17 @@
while (m.find()) {
final Parameter param = new Parameter();
String name = m.group("name");
- param.setName(name);
+ if (name.equals("parse")) {
+ String newname= "parse-only";
+ param.setName(newname);
+ }
+ else {
+ param.setName(name);
+ }
String value = m.group("value");
param.setValue(value);
String type = m.group("type");
+
if (type != null) {
try {
param.setType(ParameterTypeEnum.fromValue(type.toLowerCase()));
@@ -1628,6 +1666,11 @@
executeTestFile(testCaseCtx, ctx, variableCtx,
statement, isDmlRecoveryTest, pb, cUnit,
queryCount, expectedResultFileCtxs, testFile,
actualPath);
}
+ else
+ {
+ executeTestFile(testCaseCtx, ctx, variableCtx,
statement, isDmlRecoveryTest, pb, cUnit,
+ queryCount, expectedResultFileCtxs, testFile,
actualPath);
+ }
} catch (TestLoop loop) {
// rewind the iterator until we find our target
while (!ctx.getFile().getName().equals(loop.getTarget())) {
diff --git
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ParseOnlyTest.java
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ParseOnlyTest.java
new file mode 100644
index 0000000..73f98a0
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ParseOnlyTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.test.runtime;
+
+
+import java.util.Collection;
+
+
+import org.apache.asterix.test.common.TestExecutor;
+
+
+import org.apache.asterix.testframework.context.TestCaseContext;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+
+//TODO: eventually dummy test should come here
+
+@RunWith(Parameterized.class)
+public class ParseOnlyTest {
+
+
+ protected static final String TEST_CONFIG_FILE_NAME =
"src/main/resources/cc.conf";
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ LangExecutionUtil.tearDown();
+ }
+
+ @Parameters(name = "ParseOnlyTest {index}: {0}")
+ public static Collection<Object[]> tests() throws Exception {
+ return LangExecutionUtil.tests("only.xml", "testsuite_parseonly.xml");
+ }
+
+ protected TestCaseContext tcCtx;
+
+ public ParseOnlyTest(TestCaseContext tcCtx) {
+ this.tcCtx = tcCtx;
+ }
+
+ @Test
+ public void test() throws Exception {
+ LangExecutionUtil.test(tcCtx);
+ }
+
+}
diff --git
a/asterixdb/asterix-app/src/test/resources/parseonly/queries_sqlpp/named_01.1.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/parseonly/queries_sqlpp/named_01.1.query.sqlpp
new file mode 100644
index 0000000..a8c05a7
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/parseonly/queries_sqlpp/named_01.1.query.sqlpp
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description : Test named statement parameters with json encoded request
+ * Expected Res : Success
+ * Date : Jun 2018
+ */
+
+-- param parse:string=true
+
+// requesttype=application/json
+
+// param $p_null:json=null
+// param $p_bool:json=true
+// param $p_int:json=42
+// param $p_dec:json=42.5
+// param $p_dbl:json=42.5e2
+// param $p_str:json="hello"
+// param $p_arr:json=["99",100,{"a":null},null,true]
+// param $p_obj:json={"a":[1,2,3]}
+
+{
+ "t1": {
+ "p_null": $p_null,
+ "p_bool": $p_bool,
+ "p_int": $p_int,
+ "p_dec": $p_dec,
+ "p_dbl": $p_dbl,
+ "p_str": $p_str,
+ "p_arr": $p_arr,
+ "p_obj": $p_obj
+ },
+
+ "t2": {
+ "p_null_type": $p_null is null,
+ "p_bool_type": is_boolean($p_bool),
+ "p_int_type": is_number($p_int),
+ "p_dec_type": is_number($p_dec),
+ "p_dbl_type": is_number($p_dbl),
+ "p_str_type": is_string($p_str),
+ "p_arr_type": is_array($p_arr),
+ "p_obj_type": is_object($p_obj)
+ },
+
+ "t3": [ $p_null, $p_bool, $p_int, $p_dec, $p_dbl, $p_str, $p_arr, $p_obj ]
+}
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/only_parseonly.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/only_parseonly.xml
new file mode 100644
index 0000000..e1b94d7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/only_parseonly.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ ! Licensed to the Apache Software Foundation (ASF) under one
+ ! or more contributor license agreements. See the NOTICE file
+ ! distributed with this work for additional information
+ ! regarding copyright ownership. The ASF licenses this file
+ ! to you under the Apache License, Version 2.0 (the
+ ! "License"); you may not use this file except in compliance
+ ! with the License. You may obtain a copy of the License at
+ !
+ ! http://www.apache.org/licenses/LICENSE-2.0
+ !
+ ! Unless required by applicable law or agreed to in writing,
+ ! software distributed under the License is distributed on an
+ ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ! KIND, either express or implied. See the License for the
+ ! specific language governing permissions and limitations
+ ! under the License.
+ !-->
+<test-suite xmlns="urn:xml.testframework.asterix.apache.org"
ResultOffsetPath="results" QueryOffsetPath="queries"
QueryFileExtension=".sqlpp">
+ <test-group name="parseonly">
+ </test-group>
+</test-suite>
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.1.parse.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.1.parse.sqlpp
new file mode 100644
index 0000000..cf43e64
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.1.parse.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description : Test named statement parameters with json encoded request
+ * Expected Res : Success
+ * Date : Jun 2018
+ */
+
+-- param parse:string=true
+
+select count(*) from ChirpUsers where name=$qname;
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.2.parse.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.2.parse.sqlpp
new file mode 100644
index 0000000..a8c05a7
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/parseonly/001/named_01.2.parse.sqlpp
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description : Test named statement parameters with json encoded request
+ * Expected Res : Success
+ * Date : Jun 2018
+ */
+
+-- param parse:string=true
+
+// requesttype=application/json
+
+// param $p_null:json=null
+// param $p_bool:json=true
+// param $p_int:json=42
+// param $p_dec:json=42.5
+// param $p_dbl:json=42.5e2
+// param $p_str:json="hello"
+// param $p_arr:json=["99",100,{"a":null},null,true]
+// param $p_obj:json={"a":[1,2,3]}
+
+{
+ "t1": {
+ "p_null": $p_null,
+ "p_bool": $p_bool,
+ "p_int": $p_int,
+ "p_dec": $p_dec,
+ "p_dbl": $p_dbl,
+ "p_str": $p_str,
+ "p_arr": $p_arr,
+ "p_obj": $p_obj
+ },
+
+ "t2": {
+ "p_null_type": $p_null is null,
+ "p_bool_type": is_boolean($p_bool),
+ "p_int_type": is_number($p_int),
+ "p_dec_type": is_number($p_dec),
+ "p_dbl_type": is_number($p_dbl),
+ "p_str_type": is_string($p_str),
+ "p_arr_type": is_array($p_arr),
+ "p_obj_type": is_object($p_obj)
+ },
+
+ "t3": [ $p_null, $p_bool, $p_int, $p_dec, $p_dbl, $p_str, $p_arr, $p_obj ]
+}
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.1.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.1.adm
new file mode 100644
index 0000000..4d06619
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.1.adm
@@ -0,0 +1 @@
+{"externalVariables":"[?qname,]"}
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.2.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.2.adm
new file mode 100644
index 0000000..decacc0
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/parseonly/001/named_01.2.adm
@@ -0,0 +1 @@
+{"externalVariables":"[?p_obj,?p_null,?p_bool,?p_dbl,?p_int,?p_str,?p_arr,?p_dec,]"}
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
new file mode 100644
index 0000000..a6d945f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ! Copyright 2017-2018 Couchbase, Inc.
+ !-->
+<test-suite xmlns="urn:xml.testframework.asterix.apache.org"
ResultOffsetPath="results" QueryOffsetPath="queries"
+ QueryFileExtension=".sqlpp">
+ <test-group name="parseonly">
+ <test-case FilePath="parseonly">
+ <compilation-unit name="001">
+ <output-dir compare="Text">001</output-dir>
+ </compilation-unit>
+ </test-case>
+ </test-group>
+</test-suite>
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
new file mode 100644
index 0000000..14770b4
--- /dev/null
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.parser;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
+import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.sqlpp.visitor.NamedParameterVisitor;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ParseValueParser {
+ private final IParserFactory parserFactory;
+ private final ParseValues parseValues;
+ private final Set<VariableExpr> extVars;
+ private final String statementsText;
+ private IParser parser;
+
+ public ParseValueParser(IParserFactory parserFactory, String
statementsText) {
+ this.statementsText = statementsText;
+ this.parserFactory = parserFactory;
+ this.extVars = new HashSet<>();
+ this.parseValues = new ParseValues();
+
+ }
+
+ public List<Statement> parse() throws CompilationException {
+ parser = parserFactory.createParser(statementsText);
+ List<Statement> statements = parser.parse();
+ NamedParameterVisitor erv = new NamedParameterVisitor();
+ for (Statement st : statements) {
+ st.accept(erv, extVars);
+ }
+ parseValues.setExternalVariables(extVars);
+ return statements;
+
+ }
+
+ public ParseValues getParseValues() {
+ return parseValues;
+ }
+
+ public String toStringDebug() {
+ return parseValues.toStringDebug();
+
+ }
+
+}
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
new file mode 100644
index 0000000..f71359e
--- /dev/null
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.parser;
+
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class ParseValues implements Serializable {
+ private Set<VariableExpr> externalVariables;
+ private String extVarsSerialized;
+ public Set<VariableExpr> getExternalVariables() {
+ return externalVariables;
+ }
+
+ public void setExternalVariables(Set<VariableExpr> extVars) {
+ this.externalVariables = extVars;
+ }
+
+ public String toStringDebug() {
+ extVarsSerialized = "[";
+
+ for (VariableExpr extVarRef : externalVariables) {
+ extVarsSerialized +=
SqlppVariableUtil.toUserDefinedName(extVarRef.getVar().getValue()) + ",";
+ }
+ extVarsSerialized += "]";
+
+ return extVarsSerialized;
+
+ }
+
+}
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
index 14dfaeb..7b9994e 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
@@ -18,14 +18,11 @@
*/
package org.apache.asterix.lang.sqlpp.util;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.clause.GroupbyClause;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
@@ -35,6 +32,7 @@
import org.apache.asterix.lang.sqlpp.clause.FromClause;
import org.apache.asterix.lang.sqlpp.clause.FromTerm;
import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.NamedParameterVisitor;
public class SqlppVariableUtil {
--
To view, visit https://asterix-gerrit.ics.uci.edu/3056
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8b94f5da144f664fb488d37bee4673b6ff5646f7
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: [email protected]