Merge branch 'gerrit/cheshire-cat'
Change-Id: Id09b95763801f6cd9d81cb35b42cd0a6541a21e2
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 c348b14..ce6e10d 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
@@ -396,13 +396,13 @@
handleAdapterDropStatement(metadataProvider, stmt);
break;
case CREATE_FUNCTION:
- handleCreateFunctionStatement(metadataProvider, stmt, stmtRewriter);
+ handleCreateFunctionStatement(metadataProvider, stmt, stmtRewriter, requestParameters);
break;
case FUNCTION_DROP:
handleFunctionDropStatement(metadataProvider, stmt);
break;
case CREATE_LIBRARY:
- handleCreateLibraryStatement(metadataProvider, stmt, hcc);
+ handleCreateLibraryStatement(metadataProvider, stmt, hcc, requestParameters);
break;
case LIBRARY_DROP:
handleLibraryDropStatement(metadataProvider, stmt, hcc);
@@ -2406,7 +2406,7 @@
}
public void handleCreateFunctionStatement(MetadataProvider metadataProvider, Statement stmt,
- IStatementRewriter stmtRewriter) throws Exception {
+ IStatementRewriter stmtRewriter, IRequestParameters requestParameters) throws Exception {
CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
FunctionSignature signature = cfs.getFunctionSignature();
metadataProvider.validateDatabaseObjectName(signature.getDataverseName(), signature.getName(),
@@ -2425,7 +2425,7 @@
lockUtil.createFunctionBegin(lockManager, metadataProvider.getLocks(), dataverseName, signature.getName(),
libraryDataverseName, libraryName);
try {
- doCreateFunction(metadataProvider, cfs, signature, stmtRewriter);
+ doCreateFunction(metadataProvider, cfs, signature, stmtRewriter, requestParameters);
} finally {
metadataProvider.getLocks().unlock();
metadataProvider.setDefaultDataverse(activeDataverse);
@@ -2433,7 +2433,8 @@
}
protected void doCreateFunction(MetadataProvider metadataProvider, CreateFunctionStatement cfs,
- FunctionSignature functionSignature, IStatementRewriter stmtRewriter) throws Exception {
+ FunctionSignature functionSignature, IStatementRewriter stmtRewriter, IRequestParameters requestParameters)
+ throws Exception {
DataverseName dataverseName = functionSignature.getDataverseName();
SourceLocation sourceLoc = cfs.getSourceLocation();
MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
@@ -2826,21 +2827,22 @@
}
protected void handleCreateLibraryStatement(MetadataProvider metadataProvider, Statement stmt,
- IHyracksClientConnection hcc) throws Exception {
+ IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
CreateLibraryStatement cls = (CreateLibraryStatement) stmt;
DataverseName dataverseName = getActiveDataverseName(cls.getDataverseName());
String libraryName = cls.getLibraryName();
String libraryHash = cls.getHash();
lockUtil.createLibraryBegin(lockManager, metadataProvider.getLocks(), dataverseName, libraryName);
try {
- doCreateLibrary(metadataProvider, dataverseName, libraryName, libraryHash, cls, hcc);
+ doCreateLibrary(metadataProvider, dataverseName, libraryName, libraryHash, cls, hcc, requestParameters);
} finally {
metadataProvider.getLocks().unlock();
}
}
- private void doCreateLibrary(MetadataProvider metadataProvider, DataverseName dataverseName, String libraryName,
- String libraryHash, CreateLibraryStatement cls, IHyracksClientConnection hcc) throws Exception {
+ protected void doCreateLibrary(MetadataProvider metadataProvider, DataverseName dataverseName, String libraryName,
+ String libraryHash, CreateLibraryStatement cls, IHyracksClientConnection hcc,
+ IRequestParameters requestParameters) throws Exception {
JobUtils.ProgressState progress = ProgressState.NO_PROGRESS;
boolean prepareJobSuccessful = false;
JobSpecification abortJobSpec = null;
@@ -3068,6 +3070,10 @@
if (synonym != null) {
if (css.getIfNotExists()) {
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
+ if (warningCollector.shouldWarn()) {
+ warningCollector
+ .warn(Warning.of(css.getSourceLocation(), ErrorCode.SYNONYM_EXISTS, synonymName));
+ }
return;
}
throw new CompilationException(ErrorCode.SYNONYM_EXISTS, css.getSourceLocation(), synonymName);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ComparisonException.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ComparisonException.java
index da5c8f6..cb437f0 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ComparisonException.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ComparisonException.java
@@ -24,4 +24,8 @@
public ComparisonException(String message) {
super(message);
}
+
+ public ComparisonException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
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 b8524c0..3cc6353 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
@@ -33,6 +33,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.Reader;
import java.io.StringWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -163,6 +164,8 @@
private static final Pattern HANDLE_VARIABLE_PATTERN = Pattern.compile("handlevariable=(\\w+)");
private static final Pattern RESULT_VARIABLE_PATTERN = Pattern.compile("resultvariable=(\\w+)");
private static final Pattern COMPARE_UNORDERED_ARRAY_PATTERN = Pattern.compile("compareunorderedarray=(\\w+)");
+ private static final Pattern IGNORE_EXTRA_FIELDS_PATTERN = Pattern.compile("ignoreextrafields=(\\w+)");
+ private static final Pattern PRETTIFY_JSON_PATTERN = Pattern.compile("prettifyjsonresult=(\\w+)");
private static final Pattern BODY_REF_PATTERN = Pattern.compile("bodyref=(.*)", Pattern.MULTILINE);
private static final Pattern MACRO_PARAM_PATTERN =
Pattern.compile("macro (?<name>[\\w-$]+)=(?<value>.*)", Pattern.MULTILINE);
@@ -275,10 +278,12 @@
if (expectedFile.getName().endsWith(".ignore")) {
return; //skip the comparison
}
+ boolean prettifyJsonResult = statement == null ? false : getPrettifyJsonResult(statement);
try (BufferedReader readerExpected =
new BufferedReader(new InputStreamReader(new FileInputStream(expectedFile), UTF_8));
- BufferedReader readerActual =
- new BufferedReader(new InputStreamReader(new FileInputStream(actualFile), actualEncoding))) {
+ Reader rawReaderActual = new InputStreamReader(new FileInputStream(actualFile), actualEncoding);
+ BufferedReader readerActual = new BufferedReader(
+ prettifyJsonResult ? TestHelper.asPrettyJson(rawReaderActual) : rawReaderActual)) {
if (ComparisonEnum.BINARY.equals(compare)) {
if (!IOUtils.contentEquals(new FileInputStream(actualFile), new FileInputStream(expectedFile))) {
throw new Exception("Result for " + scriptFile + ": actual file did not match expected result");
@@ -291,8 +296,7 @@
runScriptAndCompareWithResultRegexAdm(scriptFile, readerExpected, readerActual);
return;
} else if (actualFile.toString().endsWith(".regexjson")) {
- boolean compareUnorderedArray = statement != null && getCompareUnorderedArray(statement);
- runScriptAndCompareWithResultRegexJson(scriptFile, readerExpected, readerActual, compareUnorderedArray);
+ runScriptAndCompareWithResultRegexJson(scriptFile, readerExpected, readerActual, statement);
return;
} else if (actualFile.toString().endsWith(".unorderedtxt")) {
runScriptAndCompareWithResultUnorderedLinesText(scriptFile, readerExpected, readerActual);
@@ -546,24 +550,28 @@
}
private static void runScriptAndCompareWithResultRegexJson(File scriptFile, BufferedReader readerExpected,
- BufferedReader readerActual, boolean compareUnorderedArray) throws ComparisonException, IOException {
+ BufferedReader readerActual, String statement) throws ComparisonException, IOException {
+
+ boolean compareUnorderedArray = statement != null && getCompareUnorderedArray(statement);
+ boolean ignoreExtraFields = statement != null && getIgnoreExtraFields(statement);
+
JsonNode expectedJson, actualJson;
try {
expectedJson = SINGLE_JSON_NODE_READER.readTree(readerExpected);
} catch (JsonProcessingException e) {
- throw new ComparisonException("Invalid expected JSON for: " + scriptFile);
+ throw new ComparisonException("Invalid expected JSON for: " + scriptFile, e);
}
try {
actualJson = SINGLE_JSON_NODE_READER.readTree(readerActual);
} catch (JsonProcessingException e) {
- throw new ComparisonException("Invalid actual JSON for: " + scriptFile);
+ throw new ComparisonException("Invalid actual JSON for: " + scriptFile, e);
}
if (expectedJson == null) {
throw new ComparisonException("No expected result for: " + scriptFile);
} else if (actualJson == null) {
throw new ComparisonException("No actual result for: " + scriptFile);
}
- if (!TestHelper.equalJson(expectedJson, actualJson, compareUnorderedArray)) {
+ if (!TestHelper.equalJson(expectedJson, actualJson, compareUnorderedArray, ignoreExtraFields, false, null)) {
throw new ComparisonException("Result for " + scriptFile + " didn't match the expected JSON"
+ "\nexpected result:\n" + expectedJson + "\nactual result:\n" + actualJson);
}
@@ -1756,6 +1764,16 @@
return matcher.find() && Boolean.parseBoolean(matcher.group(1));
}
+ protected static boolean getIgnoreExtraFields(String statement) {
+ final Matcher matcher = IGNORE_EXTRA_FIELDS_PATTERN.matcher(statement);
+ return matcher.find() && Boolean.parseBoolean(matcher.group(1));
+ }
+
+ protected static boolean getPrettifyJsonResult(String statement) {
+ final Matcher matcher = PRETTIFY_JSON_PATTERN.matcher(statement);
+ return matcher.find() && Boolean.parseBoolean(matcher.group(1));
+ }
+
protected static String replaceVarRef(String statement, Map<String, Object> variableCtx) {
String tmpStmt = statement;
Matcher variableReferenceMatcher = VARIABLE_REF_PATTERN.matcher(tmpStmt);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
index 137efdb..24ca072 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
@@ -23,6 +23,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
import java.util.BitSet;
import java.util.Collections;
import java.util.Enumeration;
@@ -41,10 +44,13 @@
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.hyracks.util.file.FileUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -52,9 +58,29 @@
public final class TestHelper {
+ private static final Logger LOGGER = LogManager.getLogger();
private static final String TEST_DIR_BASE_PATH = System.getProperty("user.dir") + File.separator + "target";
private static final String[] TEST_DIRS = new String[] { "txnLogDir", "IODevice", "spill_area", "config" };
+ private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
+ private static final ObjectWriter PRETTY_SORTED_WRITER;
+
+ static {
+ SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+ SORTED_MAPPER.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
+ PRETTY_SORTED_WRITER = SORTED_MAPPER.writerWithDefaultPrettyPrinter();
+ }
+
+ public static Reader asPrettyJson(final Reader rawJson) throws IOException {
+ try {
+ StringWriter sw = new StringWriter();
+ PRETTY_SORTED_WRITER.writeValue(sw, SORTED_MAPPER.readTree(rawJson));
+ return new StringReader(sw.toString());
+ } finally {
+ IOUtils.closeQuietly(rawJson);
+ }
+ }
+
public static boolean isInPrefixList(List<String> prefixList, String s) {
for (String s2 : prefixList) {
if (s.startsWith(s2)) {
@@ -141,7 +167,8 @@
return RequestParameters.deserializeParameterValues(RequestParameters.serializeParameterValues(stmtParams));
}
- public static boolean equalJson(JsonNode expectedJson, JsonNode actualJson, boolean compareUnorderedArray) {
+ public static boolean equalJson(JsonNode expectedJson, JsonNode actualJson, boolean compareUnorderedArray,
+ boolean ignoreExtraFields, boolean withinUnorderedComparison, String context) {
if (expectedJson == actualJson) {
return true;
}
@@ -151,29 +178,50 @@
}
if ((expectedJson.isMissingNode() && !actualJson.isMissingNode())
|| (!expectedJson.isMissingNode() && actualJson.isMissingNode())) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("missing node mismatch: expected={} actual={} context={}", expectedJson, actualJson,
+ context);
+ }
return false;
}
// both are not null
if (isRegexField(expectedJson)) {
String expectedRegex = expectedJson.asText();
- String actualAsString = actualJson.isValueNode() ? actualJson.asText() : actualJson.toString();
+ String actualAsString = stringify(actualJson);
expectedRegex = expectedRegex.substring(2, expectedRegex.length() - 1);
- return actualAsString.matches(expectedRegex);
+ final boolean matches = actualAsString.matches(expectedRegex);
+ if (!matches && !withinUnorderedComparison) {
+ LOGGER.info("regex mismatch: expected={} actual={} context={}", expectedRegex, actualAsString, context);
+ }
+ return matches;
} else if (expectedJson.getNodeType() != actualJson.getNodeType()) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("node type mismatch: expected={}({}) actual={}({})", stringify(expectedJson),
+ expectedJson.getNodeType(), stringify(actualJson), actualJson.getNodeType());
+ }
return false;
} else if (expectedJson.isArray() && actualJson.isArray()) {
ArrayNode expectedArray = (ArrayNode) expectedJson;
ArrayNode actualArray = (ArrayNode) actualJson;
if (expectedArray.size() != actualArray.size()) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("array size mismatch: expected={} actual={}", stringify(expectedArray),
+ stringify(actualArray));
+ }
return false;
}
- return compareUnorderedArray ? compareUnordered(expectedArray, actualArray)
- : compareOrdered(expectedArray, actualArray);
+ return compareUnorderedArray ? compareUnordered(expectedArray, actualArray, ignoreExtraFields)
+ : compareOrdered(expectedArray, actualArray, ignoreExtraFields);
} else if (expectedJson.isObject() && actualJson.isObject()) {
// assumes no duplicates in field names
ObjectNode expectedObject = (ObjectNode) expectedJson;
ObjectNode actualObject = (ObjectNode) actualJson;
- if (expectedObject.size() != actualObject.size()) {
+ if (!ignoreExtraFields && expectedObject.size() != actualObject.size()
+ || (ignoreExtraFields && expectedObject.size() > actualObject.size())) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("object size mismatch: expected={} actual={} context={}", stringify(expectedObject),
+ stringify(actualObject), context);
+ }
return false;
}
Iterator<Map.Entry<String, JsonNode>> expectedFields = expectedObject.fields();
@@ -182,41 +230,62 @@
while (expectedFields.hasNext()) {
expectedField = expectedFields.next();
actualFieldValue = actualObject.get(expectedField.getKey());
- if (actualFieldValue == null
- || !equalJson(expectedField.getValue(), actualFieldValue, compareUnorderedArray)) {
+ if (actualFieldValue == null) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("actual field value null: expected name={} expected value={}",
+ expectedField.getKey(), expectedField.getValue().asText());
+ }
+ return false;
+ }
+ if (!equalJson(expectedField.getValue(), actualFieldValue, compareUnorderedArray, ignoreExtraFields,
+ withinUnorderedComparison, expectedField.getKey())) {
return false;
}
}
return true;
}
// value node
- String expectedAsString = expectedJson.isValueNode() ? expectedJson.asText() : expectedJson.toString();
- String actualAsString = actualJson.isValueNode() ? actualJson.asText() : actualJson.toString();
- return expectedAsString.equals(actualAsString);
+ String expectedAsString = stringify(expectedJson);
+ String actualAsString = stringify(actualJson);
+ if (!expectedAsString.equals(actualAsString)) {
+ if (!withinUnorderedComparison) {
+ LOGGER.info("value node mismatch: expected={} actual={} context={}", expectedAsString, actualAsString,
+ context);
+ }
+ return false;
+ }
+ return true;
}
- private static boolean compareUnordered(ArrayNode expectedArray, ArrayNode actualArray) {
+ private static String stringify(JsonNode jsonNode) {
+ return jsonNode == null ? null : (jsonNode.isValueNode() ? jsonNode.asText() : jsonNode.toString());
+ }
+
+ private static boolean compareUnordered(ArrayNode expectedArray, ArrayNode actualArray, boolean ignoreExtraFields) {
BitSet alreadyMatched = new BitSet(actualArray.size());
for (int i = 0; i < expectedArray.size(); i++) {
boolean found = false;
JsonNode expectedElement = expectedArray.get(i);
for (int k = 0; k < actualArray.size(); k++) {
- if (!alreadyMatched.get(k) && equalJson(expectedElement, actualArray.get(k), true)) {
+ if (!alreadyMatched.get(k) && equalJson(expectedElement, actualArray.get(k), true, ignoreExtraFields,
+ true, stringify(actualArray))) {
alreadyMatched.set(k);
found = true;
break;
}
}
if (!found) {
+ LOGGER.info("unordered array comparison failed; expected={} actual={}", expectedArray, actualArray);
return false;
}
}
return true;
}
- private static boolean compareOrdered(ArrayNode expectedArray, ArrayNode actualArray) {
+ private static boolean compareOrdered(ArrayNode expectedArray, ArrayNode actualArray, boolean ignoreExtraFields) {
for (int i = 0, size = expectedArray.size(); i < size; i++) {
- if (!equalJson(expectedArray.get(i), actualArray.get(i), false)) {
+ if (!equalJson(expectedArray.get(i), actualArray.get(i), false, ignoreExtraFields, false,
+ stringify(actualArray))) {
return false;
}
}
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
index 0c13cdf..434b368 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
@@ -164,7 +164,7 @@
ResultExtractor.extract(resultStream, StandardCharsets.UTF_8, TestCaseContext.OutputFormat.ADM));
}
- boolean eq = TestHelper.equalJson(sqlResult, sqlppResult, false);
+ boolean eq = TestHelper.equalJson(sqlResult, sqlppResult, false, false, false, null);
File sqlResultFile = writeResult(sqlResult, testcaseId, "sql", testcaseDescription);
File sqlppResultFile = writeResult(sqlppResult, testcaseId, "sqlpp", testcaseDescription);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
index 08577ae..729c5d5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
@@ -22,4 +22,5 @@
* Expected Result : Success
* Date : 7th September 2016
*/
+--prettifyjsonresult=true
/admin/cluster
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
index c309110..58fa336 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
@@ -22,4 +22,5 @@
* Expected Result : Positive
* Date : 8th September 2016
*/
+--prettifyjsonresult=true
/admin/diagnostics
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
index 12288a4..d98e4e8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
@@ -16,4 +16,5 @@
* specific language governing permissions and limitations
* under the License.
*/
+--prettifyjsonresult=true
nc:asterix_nc1 /admin/net
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.query.sqlpp
new file mode 100644
index 0000000..932661c9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.query.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.
+ */
+
+/**
+ * Test that scalar sum() produces correct output type
+ */
+
+select array_sum(array_reverse(lst))
+let lst = (
+ from range(1, 3) r
+ select value int32(to_string(r))
+)
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/sum/scalar_sum_type/scalar_sum_type.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/sum/scalar_sum_type/scalar_sum_type.1.query.sqlpp
new file mode 100644
index 0000000..361a59b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/sum/scalar_sum_type/scalar_sum_type.1.query.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.
+ */
+
+/**
+ * Test that scalar sum() produces correct output type
+ */
+
+select strict_sum(array_reverse(lst))
+let lst = (
+ from range(1, 3) r
+ select value int32(to_string(r))
+)
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
index 4a53aed..1a63ce7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
@@ -16,4 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
+//prettifyjsonresult=true
+
nc:asterix_nc2 /admin/storage
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
index 74ebe94..53d75bc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
@@ -16,4 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
+//prettifyjsonresult=true
+
nc:asterix_nc1:19004 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.query.sqlpp
new file mode 100644
index 0000000..110eefd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+with t as (select r, [r*10,r*10+1] ra from range(1, 2) r)
+select *
+from t unnest t.ra
+order by ra
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.adm
new file mode 100644
index 0000000..d9b1127
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/sum/scalar_sum_type/scalar_sum_type.1.adm
@@ -0,0 +1 @@
+{ "$1": 6 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/sum/scalar_sum_type/scalar_sum_type.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/sum/scalar_sum_type/scalar_sum_type.1.adm
new file mode 100644
index 0000000..d9b1127
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/sum/scalar_sum_type/scalar_sum_type.1.adm
@@ -0,0 +1 @@
+{ "$1": 6 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
index d0138cb..56a6051 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
@@ -1,3 +1 @@
-1
-
-
+1
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.adm
new file mode 100644
index 0000000..6b71814
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/unnest/ASTERIXDB-2844_unnest_syntax/ASTERIXDB-2844_unnest_syntax.1.adm
@@ -0,0 +1,4 @@
+{ "t": { "r": 1, "ra": [ 10, 11 ] }, "ra": 10 }
+{ "t": { "r": 1, "ra": [ 10, 11 ] }, "ra": 11 }
+{ "t": { "r": 2, "ra": [ 20, 21 ] }, "ra": 20 }
+{ "t": { "r": 2, "ra": [ 20, 21 ] }, "ra": 21 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 1d7f09e..2cdf027 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -834,6 +834,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="aggregate">
+ <compilation-unit name="sum/scalar_sum_type">
+ <output-dir compare="Text">sum/scalar_sum_type</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="aggregate">
<compilation-unit name="scalar_var">
<output-dir compare="Text">scalar_var</output-dir>
</compilation-unit>
@@ -2097,6 +2102,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="aggregate-sql">
+ <compilation-unit name="sum/scalar_sum_type">
+ <output-dir compare="Text">sum/scalar_sum_type</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="aggregate-sql">
<compilation-unit name="scalar_var">
<output-dir compare="Text">scalar_var</output-dir>
</compilation-unit>
@@ -14089,6 +14099,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="unnest">
+ <compilation-unit name="ASTERIXDB-2844_unnest_syntax">
+ <output-dir compare="Text">ASTERIXDB-2844_unnest_syntax</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="unnest">
<compilation-unit name="left-outer-unnest">
<output-dir compare="Text">left-outer-unnest</output-dir>
</compilation-unit>
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 2089658..4dac902 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -4411,12 +4411,12 @@
UnnestClause UnnestClause(UnnestType unnestType) throws ParseException :
{
Token startToken = null;
- Expression rightExpr;
- VariableExpr rightVar;
+ Expression rightExpr = null;
+ VariableExpr rightVar = null;
VariableExpr posVar = null;
}
{
- (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable()) (<AT> posVar = Variable())?
+ (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
{
if (rightVar == null) {
rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
index 699ad74..0ab5c7b 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
@@ -133,6 +133,11 @@
@Override
public MetadataTransactionContext beginTransaction() throws RemoteException {
+ try {
+ INSTANCE.init();
+ } catch (HyracksDataException e) {
+ throw new ACIDException(e);
+ }
TxnId txnId = createTxnId();
metadataNode.beginTransaction(txnId);
return new MetadataTransactionContext(txnId);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 268c1f6..63573a1 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -1832,6 +1832,11 @@
addFunction(NEGINF_IF, DoubleIfTypeComputer.INSTANCE, true);
// Aggregate Functions
+ ScalarVersionOfAggregateResultType scalarNumericSumTypeComputer =
+ new ScalarVersionOfAggregateResultType(NumericSumAggTypeComputer.INSTANCE);
+ ScalarVersionOfAggregateResultType scalarMinMaxTypeComputer =
+ new ScalarVersionOfAggregateResultType(MinMaxAggTypeComputer.INSTANCE);
+
addPrivateFunction(LISTIFY, OrderedListConstructorTypeComputer.INSTANCE, true);
addFunction(SCALAR_ARRAYAGG, ScalarArrayAggTypeComputer.INSTANCE, true);
addFunction(MAX, MinMaxAggTypeComputer.INSTANCE, true);
@@ -1877,7 +1882,7 @@
// SUM
addFunction(SUM, NumericSumAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SUM, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SUM, scalarNumericSumTypeComputer, true);
addPrivateFunction(LOCAL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
addPrivateFunction(INTERMEDIATE_SUM, NumericSumAggTypeComputer.INSTANCE, true);
addPrivateFunction(GLOBAL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
@@ -1893,8 +1898,8 @@
addPrivateFunction(SERIAL_INTERMEDIATE_SQL_AVG, LocalAvgTypeComputer.INSTANCE, true);
addFunction(SCALAR_AVG, NullableDoubleTypeComputer.INSTANCE, true);
addFunction(SCALAR_COUNT, AInt64TypeComputer.INSTANCE, true);
- addFunction(SCALAR_MAX, ScalarVersionOfAggregateResultType.INSTANCE, true);
- addFunction(SCALAR_MIN, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_MAX, scalarMinMaxTypeComputer, true);
+ addFunction(SCALAR_MIN, scalarMinMaxTypeComputer, true);
addPrivateFunction(INTERMEDIATE_AVG, LocalAvgTypeComputer.INSTANCE, true);
addFunction(SCALAR_STDDEV_SAMP, NullableDoubleTypeComputer.INSTANCE, true);
addPrivateFunction(INTERMEDIATE_STDDEV_SAMP, LocalSingleVarStatisticsTypeComputer.INSTANCE, true);
@@ -1935,7 +1940,7 @@
// SQL SUM
addFunction(SQL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SQL_SUM, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SQL_SUM, scalarNumericSumTypeComputer, true);
addPrivateFunction(LOCAL_SQL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
addPrivateFunction(INTERMEDIATE_SQL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
addPrivateFunction(GLOBAL_SQL_SUM, NumericSumAggTypeComputer.INSTANCE, true);
@@ -1959,8 +1964,8 @@
addPrivateFunction(GLOBAL_SQL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
addFunction(SCALAR_SQL_AVG, NullableDoubleTypeComputer.INSTANCE, true);
addFunction(SCALAR_SQL_COUNT, AInt64TypeComputer.INSTANCE, true);
- addFunction(SCALAR_SQL_MAX, ScalarVersionOfAggregateResultType.INSTANCE, true);
- addFunction(SCALAR_SQL_MIN, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SQL_MAX, scalarMinMaxTypeComputer, true);
+ addFunction(SCALAR_SQL_MIN, scalarMinMaxTypeComputer, true);
addPrivateFunction(INTERMEDIATE_SQL_AVG, LocalAvgTypeComputer.INSTANCE, true);
addFunction(SQL_STDDEV_SAMP, NullableDoubleTypeComputer.INSTANCE, true);
addPrivateFunction(GLOBAL_SQL_STDDEV_SAMP, NullableDoubleTypeComputer.INSTANCE, true);
@@ -2035,9 +2040,9 @@
addFunction(SCALAR_SQL_COUNT_DISTINCT, AInt64TypeComputer.INSTANCE, true);
addFunction(SUM_DISTINCT, NumericSumAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SUM_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SUM_DISTINCT, scalarNumericSumTypeComputer, true);
addFunction(SQL_SUM_DISTINCT, NumericSumAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SQL_SUM_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SQL_SUM_DISTINCT, scalarNumericSumTypeComputer, true);
addFunction(AVG_DISTINCT, NullableDoubleTypeComputer.INSTANCE, true);
addFunction(SCALAR_AVG_DISTINCT, NullableDoubleTypeComputer.INSTANCE, true);
@@ -2045,14 +2050,14 @@
addFunction(SCALAR_SQL_AVG_DISTINCT, NullableDoubleTypeComputer.INSTANCE, true);
addFunction(MAX_DISTINCT, MinMaxAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_MAX_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_MAX_DISTINCT, scalarMinMaxTypeComputer, true);
addFunction(SQL_MAX_DISTINCT, MinMaxAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SQL_MAX_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SQL_MAX_DISTINCT, scalarMinMaxTypeComputer, true);
addFunction(MIN_DISTINCT, MinMaxAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_MIN_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_MIN_DISTINCT, scalarMinMaxTypeComputer, true);
addFunction(SQL_MIN_DISTINCT, MinMaxAggTypeComputer.INSTANCE, true);
- addFunction(SCALAR_SQL_MIN_DISTINCT, ScalarVersionOfAggregateResultType.INSTANCE, true);
+ addFunction(SCALAR_SQL_MIN_DISTINCT, scalarMinMaxTypeComputer, true);
addFunction(STDDEV_SAMP_DISTINCT, NullableDoubleTypeComputer.INSTANCE, true);
addFunction(SCALAR_STDDEV_SAMP_DISTINCT, NullableDoubleTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AggregateResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AggregateResultTypeComputer.java
new file mode 100644
index 0000000..8e663a7
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AggregateResultTypeComputer.java
@@ -0,0 +1,39 @@
+/*
+ * 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.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+
+public abstract class AggregateResultTypeComputer extends AbstractResultTypeComputer {
+ @Override
+ protected void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
+ throws AlgebricksException {
+ super.checkArgType(funcId, argIndex, type, sourceLoc);
+ }
+
+ @Override
+ protected abstract IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes)
+ throws AlgebricksException;
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
index c34b5ed..fc1eee5 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
@@ -19,7 +19,6 @@
package org.apache.asterix.om.typecomputer.impl;
import org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator;
-import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.BuiltinType;
@@ -27,7 +26,7 @@
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-public class MinMaxAggTypeComputer extends AbstractResultTypeComputer {
+public class MinMaxAggTypeComputer extends AggregateResultTypeComputer {
public static final MinMaxAggTypeComputer INSTANCE = new MinMaxAggTypeComputer();
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericSumAggTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericSumAggTypeComputer.java
index 1c67e56..a4b5e34 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericSumAggTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericSumAggTypeComputer.java
@@ -18,42 +18,20 @@
*/
package org.apache.asterix.om.typecomputer.impl;
-import org.apache.asterix.om.exceptions.UnsupportedTypeException;
-import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.api.exceptions.SourceLocation;
-public class NumericSumAggTypeComputer extends AbstractResultTypeComputer {
+public class NumericSumAggTypeComputer extends AggregateResultTypeComputer {
public static final NumericSumAggTypeComputer INSTANCE = new NumericSumAggTypeComputer();
private NumericSumAggTypeComputer() {
}
@Override
- protected void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
- throws AlgebricksException {
- ATypeTag tag = type.getTypeTag();
- switch (tag) {
- case DOUBLE:
- case FLOAT:
- case BIGINT:
- case INTEGER:
- case SMALLINT:
- case TINYINT:
- case ANY:
- break;
- default:
- throw new UnsupportedTypeException(sourceLoc, funcId, tag);
- }
- }
-
- @Override
protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
ATypeTag tag = strippedInputTypes[0].getTypeTag();
switch (tag) {
@@ -61,15 +39,12 @@
case SMALLINT:
case INTEGER:
case BIGINT:
- IAType int64Type = BuiltinType.AINT64;
- return AUnionType.createNullableType(int64Type, "AggResult");
+ return AUnionType.createNullableType(BuiltinType.AINT64);
case FLOAT:
case DOUBLE:
- IAType doubleType = BuiltinType.ADOUBLE;
- return AUnionType.createNullableType(doubleType, "AggResult");
+ return AUnionType.createNullableType(BuiltinType.ADOUBLE);
case ANY:
- IAType anyType = strippedInputTypes[0];
- return AUnionType.createNullableType(anyType, "AggResult");
+ return BuiltinType.ANY;
default:
// All other possible cases.
return BuiltinType.ANULL;
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
index 5b90974..fda0285 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
@@ -18,9 +18,7 @@
*/
package org.apache.asterix.om.typecomputer.impl;
-import org.apache.asterix.om.exceptions.TypeMismatchException;
import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.AbstractCollectionType;
import org.apache.asterix.om.types.BuiltinType;
@@ -32,32 +30,48 @@
public class ScalarVersionOfAggregateResultType extends AbstractResultTypeComputer {
- public static final ScalarVersionOfAggregateResultType INSTANCE = new ScalarVersionOfAggregateResultType();
+ private final AggregateResultTypeComputer aggResultTypeComputer;
- private ScalarVersionOfAggregateResultType() {
+ public ScalarVersionOfAggregateResultType(AggregateResultTypeComputer aggResultTypeComputer) {
+ this.aggResultTypeComputer = aggResultTypeComputer;
}
@Override
- public void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
+ protected void checkArgType(FunctionIdentifier funcId, int argIndex, IAType argType, SourceLocation sourceLoc)
throws AlgebricksException {
- ATypeTag tag = type.getTypeTag();
- if (tag != ATypeTag.ANY && tag != ATypeTag.ARRAY && tag != ATypeTag.MULTISET) {
- throw new TypeMismatchException(sourceLoc, funcId, argIndex, tag, ATypeTag.ARRAY, ATypeTag.MULTISET);
+ if (argIndex == 0) {
+ switch (argType.getTypeTag()) {
+ case ARRAY:
+ case MULTISET:
+ AbstractCollectionType act = (AbstractCollectionType) argType;
+ aggResultTypeComputer.checkArgType(funcId, argIndex, act.getItemType(), sourceLoc);
+ break;
+ }
}
}
@Override
protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
- ATypeTag tag = strippedInputTypes[0].getTypeTag();
- if (tag == ATypeTag.ANY) {
- return BuiltinType.ANY;
+ IAType argType = strippedInputTypes[0];
+ switch (argType.getTypeTag()) {
+ case ARRAY:
+ case MULTISET:
+ AbstractCollectionType act = (AbstractCollectionType) argType;
+ IAType[] strippedInputTypes2 = strippedInputTypes.clone();
+ strippedInputTypes2[0] = act.getItemType();
+ IAType resultType = aggResultTypeComputer.getResultType(expr, strippedInputTypes2);
+ switch (resultType.getTypeTag()) {
+ case NULL:
+ case MISSING:
+ case ANY:
+ return resultType;
+ case UNION:
+ return AUnionType.createUnknownableType(((AUnionType) resultType).getActualType());
+ default:
+ return AUnionType.createUnknownableType(resultType);
+ }
+ default:
+ return BuiltinType.ANY;
}
- if (tag != ATypeTag.ARRAY && tag != ATypeTag.MULTISET) {
- // this condition being true would've thrown an exception above, no?
- return strippedInputTypes[0];
- }
- AbstractCollectionType act = (AbstractCollectionType) strippedInputTypes[0];
- IAType t = act.getItemType();
- return AUnionType.createUnknownableType(t);
}
}
diff --git a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/management/LogReplicationManager.java b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/management/LogReplicationManager.java
index be372df..6a23ae6 100644
--- a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/management/LogReplicationManager.java
+++ b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/management/LogReplicationManager.java
@@ -211,7 +211,7 @@
}
}
- private synchronized void handleFailure(ISocketChannel replicaSocket, IOException e) {
+ private synchronized void handleFailure(ISocketChannel replicaSocket, Exception e) {
if (failedSockets.contains(replicaSocket)) {
return;
}
@@ -249,7 +249,7 @@
}
} catch (AsynchronousCloseException e) {
LOGGER.debug(() -> "Stopped listening on socket:" + dest, e);
- } catch (IOException e) {
+ } catch (Exception e) {
handleFailure(replicaSocket, e);
}
}
diff --git a/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/functions/ScalarAggregateTypeComputerTest.java b/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/functions/ScalarAggregateTypeComputerTest.java
new file mode 100644
index 0000000..cbde36c
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/functions/ScalarAggregateTypeComputerTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.runtime.functions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.asterix.dataflow.data.common.ExpressionTypeComputer;
+import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.base.ADate;
+import org.apache.asterix.om.base.ADateTime;
+import org.apache.asterix.om.base.ADayTimeDuration;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.ADuration;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.AInterval;
+import org.apache.asterix.om.base.AOrderedList;
+import org.apache.asterix.om.base.ARecord;
+import org.apache.asterix.om.base.AString;
+import org.apache.asterix.om.base.ATime;
+import org.apache.asterix.om.base.AUnorderedList;
+import org.apache.asterix.om.base.AYearMonthDuration;
+import org.apache.asterix.om.base.IAObject;
+import org.apache.asterix.om.constants.AsterixConstantValue;
+import org.apache.asterix.om.exceptions.UnsupportedTypeException;
+import org.apache.asterix.om.functions.BuiltinFunctionInfo;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Test alignment of type computers between aggregate functions and their scalar versions
+ */
+@RunWith(Parameterized.class)
+public class ScalarAggregateTypeComputerTest {
+
+ private static final IAObject[] ITEMS = {
+ //
+ ABoolean.TRUE,
+ //
+ new AInt8((byte) 0),
+ //
+ new AInt16((short) 0),
+ //
+ new AInt32(0),
+ //
+ new AInt64(0),
+ //
+ new AFloat(0),
+ //
+ new ADouble(0),
+ //
+ new AString(""),
+ //
+ new ADate(0),
+ //
+ new ADateTime(0),
+ //
+ new ATime(0),
+ //
+ new ADuration(0, 0),
+ //
+ new AYearMonthDuration(0),
+ //
+ new ADayTimeDuration(0),
+ //
+ new AInterval(0, 0, ATypeTag.DATETIME.serialize()),
+ //
+ new AOrderedList(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE, Collections.singletonList(new AString(""))),
+ //
+ new AUnorderedList(AUnorderedListType.FULLY_OPEN_UNORDEREDLIST_TYPE,
+ Collections.singletonList(new AString(""))),
+ //
+ new ARecord(
+ new ARecordType("record-type", new String[] { "a" }, new IAType[] { BuiltinType.ASTRING }, false),
+ new IAObject[] { new AString("") }) };
+
+ // Test parameters
+ @Parameterized.Parameter
+ public String testName;
+
+ @Parameterized.Parameter(1)
+ public FunctionIdentifier scalarfid;
+
+ @Parameterized.Parameter(2)
+ public FunctionIdentifier aggfid;
+
+ @Parameterized.Parameter(3)
+ public IAObject item;
+
+ @Parameterized.Parameters(name = "ScalarAggregateTypeComputerTest {index}: {0}({3})")
+ public static Collection<Object[]> tests() {
+ List<Object[]> tests = new ArrayList<>();
+
+ FunctionCollection fcoll = FunctionCollection.createDefaultFunctionCollection();
+ for (IFunctionDescriptorFactory fdf : fcoll.getFunctionDescriptorFactories()) {
+ FunctionIdentifier fid = fdf.createFunctionDescriptor().getIdentifier();
+ FunctionIdentifier aggfid = BuiltinFunctions.getAggregateFunction(fid);
+ if (aggfid == null) {
+ continue;
+ }
+ for (IAObject item : ITEMS) {
+ tests.add(new Object[] { fid.getName(), fid, aggfid, item });
+ }
+
+ }
+ return tests;
+ }
+
+ @Test
+ public void test() throws Exception {
+
+ AOrderedListType listType = new AOrderedListType(item.getType(), null);
+ AOrderedList list = new AOrderedList(listType, Collections.singletonList(item));
+ ConstantExpression scalarArgExpr = new ConstantExpression(new AsterixConstantValue(list));
+ BuiltinFunctionInfo scalarfi = BuiltinFunctions.getBuiltinFunctionInfo(scalarfid);
+ ScalarFunctionCallExpression scalarCallExpr =
+ new ScalarFunctionCallExpression(scalarfi, new MutableObject<>(scalarArgExpr));
+ IAType scalarResultType = computeType(scalarCallExpr);
+
+ ConstantExpression aggArgExpr = new ConstantExpression(new AsterixConstantValue(item));
+ BuiltinFunctionInfo aggfi = BuiltinFunctions.getBuiltinFunctionInfo(aggfid);
+ AggregateFunctionCallExpression aggCallExpr = new AggregateFunctionCallExpression(aggfi, false,
+ Collections.singletonList(new MutableObject<>(aggArgExpr)));
+ IAType aggResultType = computeType(aggCallExpr);
+
+ if (!compareResultTypes(scalarResultType, aggResultType)) {
+ Assert.fail(String.format("%s(%s) returns %s != %s(%s) returns %s", scalarfid.getName(), item.getType(),
+ formatResultType(scalarResultType), aggfid.getName(), item.getType(),
+ formatResultType(aggResultType)));
+ }
+ }
+
+ private boolean compareResultTypes(IAType t1, IAType t2) {
+ // null means ERROR
+ if (t1 == null) {
+ // OK if both types are ERROR
+ return t2 == null;
+ } else if (t2 == null) {
+ return false;
+ }
+ boolean t1Union = false, t2Union = false;
+ if (t1.getTypeTag() == ATypeTag.UNION) {
+ t1Union = true;
+ t1 = ((AUnionType) t1).getActualType();
+ }
+ if (t2.getTypeTag() == ATypeTag.UNION) {
+ t2Union = true;
+ t2 = ((AUnionType) t2).getActualType();
+ }
+ return (t1Union == t2Union) && t1.deepEqual(t2);
+ }
+
+ private String formatResultType(IAType t) {
+ return t == null ? "ERROR" : t.toString();
+ }
+
+ private IAType computeType(AbstractFunctionCallExpression callExpr) throws AlgebricksException {
+ try {
+ BuiltinFunctionInfo fi = Objects.requireNonNull((BuiltinFunctionInfo) callExpr.getFunctionInfo());
+ return fi.getResultTypeComputer().computeType(callExpr, EMPTY_TYPE_ENV, null);
+ } catch (UnsupportedTypeException e) {
+ return null;
+ }
+ }
+
+ private static final IVariableTypeEnvironment EMPTY_TYPE_ENV = new IVariableTypeEnvironment() {
+
+ @Override
+ public boolean substituteProducedVariable(LogicalVariable v1, LogicalVariable v2) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void setVarType(LogicalVariable var, Object type) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Object getVarType(LogicalVariable var, List<LogicalVariable> nonNullVariables,
+ List<List<LogicalVariable>> correlatedNullableVariableLists) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Object getVarType(LogicalVariable var) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Object getType(ILogicalExpression expr) throws AlgebricksException {
+ return ExpressionTypeComputer.INSTANCE.getType(expr, null, this);
+ }
+ };
+}
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=60
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=60
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.5.adm b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.4.json
similarity index 100%
rename from asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.5.adm
rename to asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.4.json
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.adm b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.json
similarity index 100%
rename from asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.adm
rename to asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.json
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=60
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=30
+//prettifyjsonresult=true
nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
@@ -17,5 +17,6 @@
* under the License.
*/
//polltimeoutsecs=60
+//prettifyjsonresult=true
/admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 5cc17af..f89f0ac 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -200,6 +200,8 @@
<exclude>**/*.iml</exclude>
<exclude>**/*.json</exclude>
<exclude>**/*.adm</exclude>
+ <exclude>**/*.regexadm</exclude>
+ <exclude>**/*.regexjson</exclude>
<exclude>**/*.template</exclude>
<exclude>asterix-installer/**</exclude> <!-- in case -DskipInstaller -->
</excludes>
diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
index b66d31d..5c1b292 100644
--- a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
@@ -28,27 +28,18 @@
import java.util.stream.LongStream;
import java.util.stream.Stream;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class JSONUtil {
- private static final Logger LOGGER = LogManager.getLogger();
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
- private static final String INDENT = "\t";
-
private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
- private static final ObjectWriter PRETTY_SORTED_WRITER;
private JSONUtil() {
}
@@ -56,11 +47,10 @@
static {
SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
SORTED_MAPPER.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
- PRETTY_SORTED_WRITER = SORTED_MAPPER.writerWithDefaultPrettyPrinter();
}
public static String convertNode(final JsonNode node) throws JsonProcessingException {
- return PRETTY_SORTED_WRITER.writeValueAsString(SORTED_MAPPER.treeToValue(node, Object.class));
+ return SORTED_MAPPER.writeValueAsString(SORTED_MAPPER.treeToValue(node, Object.class));
}
public static String convertNodeOrThrow(final JsonNode node) {
@@ -72,87 +62,7 @@
}
public static void writeNode(final Writer writer, final JsonNode node) throws IOException {
- PRETTY_SORTED_WRITER.writeValue(writer, SORTED_MAPPER.treeToValue(node, Object.class));
- }
-
- public static String indent(String str, int initialIndent) {
- ObjectMapper om = new ObjectMapper();
- try {
- return appendObj(new StringBuilder(), om.readTree(str), initialIndent).toString();
- } catch (IOException e) {
- LOGGER.trace(String.valueOf(e));
- LOGGER.trace("Could not indent JSON string, returning the input string: " + str);
- return str;
- }
- }
-
- private static StringBuilder appendOrd(StringBuilder sb, JsonNode o, int indent) {
- if (o.isObject()) {
- return appendObj(sb, o, indent);
- } else if (o.isArray()) {
- return appendAry(sb, o, indent);
- } else if (o.isTextual()) {
- return quoteAndEscape(sb, o.asText());
- } else if (o.isNull() || o.isIntegralNumber() || o.isBoolean()) {
- return sb.append(String.valueOf(o));
- }
- throw new UnsupportedOperationException(o.getClass().getSimpleName());
- }
-
- private static StringBuilder appendObj(final StringBuilder sb, final JsonNode outer, final int indent) {
- sb.append("{\n");
- boolean first = true;
- for (JsonNode inner : outer) {
- final String key = inner.asText();
- if (first) {
- first = false;
- } else {
- sb.append(",\n");
- }
- indent(sb, indent + 1);
- quote(sb, key);
- sb.append(": ");
- appendVal(sb, outer.get(key), indent);
- }
- sb.append("\n");
- return indent(sb, indent).append("}");
- }
-
- private static StringBuilder appendVal(final StringBuilder sb, final JsonNode value, final int indent) {
- if (value.isArray()) {
- appendAry(sb, value, indent + 1);
- } else if (value.isObject()) {
- appendObj(sb, value, indent + 1);
- } else {
- appendOrd(sb, value, indent + 1);
- }
- return sb;
- }
-
- private static StringBuilder appendAry(final StringBuilder sb, JsonNode jarr, int indent) {
- sb.append("[\n");
- for (int i = 0; i < jarr.size(); ++i) {
- if (i > 0) {
- sb.append(",\n");
- }
- indent(sb, indent + 1);
- appendVal(sb, jarr.get(i), indent);
- }
- sb.append("\n");
- return indent(sb, indent).append("]");
- }
-
- private static StringBuilder quote(StringBuilder sb, String str) {
- return sb.append('"').append(str).append('"');
- }
-
- private static StringBuilder indent(StringBuilder sb, int i) {
- int indent = i;
- while (indent > 0) {
- sb.append(INDENT);
- --indent;
- }
- return sb;
+ SORTED_MAPPER.writeValue(writer, SORTED_MAPPER.treeToValue(node, Object.class));
}
public static String quoteAndEscape(String str) {