Merge branch 'gerrit/ionic' into 'master'
Change-Id: Idaae7d6906e39513691a35bd243286638660e72d
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java
index f78aa59..98c54e6 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java
@@ -61,6 +61,7 @@
addFunctionAndArgChecker(BuiltinFunctions.IF_NULL, null);
addFunctionAndArgChecker(BuiltinFunctions.IF_MISSING_OR_NULL, null);
addFunctionAndArgChecker(BuiltinFunctions.IF_SYSTEM_NULL, null);
+ addFunctionAndArgChecker(BuiltinFunctions.IF_ERROR, null);
}
// allows the rule to check other functions in addition to the ones specified here
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
index 6813e84..7c9b548 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
@@ -34,7 +34,6 @@
import org.apache.asterix.metadata.entities.Datatype;
import org.apache.asterix.metadata.entities.Index;
import org.apache.asterix.om.types.ARecordType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.api.exceptions.SourceLocation;
/**
@@ -528,7 +527,7 @@
return condition;
}
- public Query getQuery() throws AlgebricksException {
+ public Query getQuery() {
return query;
}
@@ -605,9 +604,9 @@
private final List<OrderbyClause.NullOrderModifier> orderByNullModifierList;
private final List<Expression> keyExpressions;
private final boolean autogenerated;
-
private final ARecordType itemType;
private final ARecordType parquetSchema;
+ private final Map<String, String> formatConfigs;
public CompiledCopyToStatement(CopyToStatement copyToStatement) {
this.query = copyToStatement.getQuery();
@@ -625,6 +624,7 @@
this.autogenerated = copyToStatement.isAutogenerated();
this.itemType = eddDecl.getItemType();
this.parquetSchema = eddDecl.getParquetSchema();
+ this.formatConfigs = copyToStatement.getFormatConfigs();
}
@Override
@@ -696,6 +696,10 @@
return autogenerated;
}
+ public Map<String, String> getFormatConfigs() {
+ return formatConfigs;
+ }
+
public boolean isFileStoreSink() {
return keyExpressions.isEmpty() && !autogenerated;
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index 6d37447..ed62ba3 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -467,7 +467,7 @@
// Write adapter configuration
WriteDataSink writeDataSink = new WriteDataSink(copyTo.getAdapter(), copyTo.getProperties(),
- copyTo.getItemType(), copyTo.getParquetSchema(), expr.getSourceLocation());
+ copyTo.getItemType(), copyTo.getParquetSchema(), copyTo.getFormatConfigs(), expr.getSourceLocation());
// writeOperator
WriteOperator writeOperator = new WriteOperator(sourceExprRef, new MutableObject<>(fullPathExpr),
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index 3d806a8..31fe950 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -586,6 +586,7 @@
outerUnnestMissingValue)
: new UnnestOperator(rightVar, new MutableObject<>(pUnnestExpr.first));
}
+ unnestOp.getAnnotations().put(ARRAY_ACCESS, rightExpr.getKind() == Kind.FIELD_ACCESSOR_EXPRESSION);
ExternalSubpathAnnotation hint = ((AbstractExpression) rightExpr).findHint(ExternalSubpathAnnotation.class);
if (hint != null) {
unnestOp.getAnnotations().put(SUBPATH, hint.getSubPath());
diff --git a/asterixdb/asterix-app/pom.xml b/asterixdb/asterix-app/pom.xml
index 7cd2cb8..81f570a 100644
--- a/asterixdb/asterix-app/pom.xml
+++ b/asterixdb/asterix-app/pom.xml
@@ -185,7 +185,7 @@
<configuration>
<includeClassifiers>testlib</includeClassifiers>
<outputDirectory>target/data/externallib</outputDirectory>
- <overwrite>true</overwrite>
+ <overWriteIfNewer>true</overWriteIfNewer>
<stripVersion>true</stripVersion>
</configuration>
</execution>
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.5.query.sqlpp
new file mode 100644
index 0000000..96c263b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.5.query.sqlpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties:( c_w_id ,c_d_id, c_id)
+-- and requirement properties: (o_c_id, o_w_id, o_d_id)
+-- with the following join condition
+-- the expected final required properties of orders will be: (o_w_id, o_d_id, o_c_id)
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+
+
+CREATE TYPE cust_type AS {c_w_id : integer,c_d_id : integer, c_id : integer};
+CREATE DATASET customer(cust_type) PRIMARY KEY c_w_id, c_d_id, c_id;
+
+CREATE TYPE orders_type AS {o_w_id : integer, o_d_id : integer, o_id : integer};
+CREATE DATASET orders(orders_type) PRIMARY KEY o_w_id, o_d_id, o_id;
+
+
+
+
+
+SELECT c.c_id, o.*
+FROM customer c LEFT OUTER JOIN orders o ON (
+ c.c_w_id = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.7.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.7.query.sqlpp
new file mode 100644
index 0000000..bb0a1be
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.7.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+
+use test;
+
+
+
+SELECT c.c_id, o.*
+FROM customer c LEFT OUTER JOIN orders o ON (
+ c.c_w_id /*+ hash-bcast */ = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.9.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.9.query.sqlpp
new file mode 100644
index 0000000..c0ed3de
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange/hash_join_exchange.9.query.sqlpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties: (o_w_id, o_d_id, o_id)
+-- and requirement properties: (o_w_id, o_d_id, o_id)
+-- with the following join condition
+-- the expected final required properties of orders will be: (o_w_id, o_d_id, o_id)
+
+
+use test;
+
+
+
+SELECT o.o_d_id, o.o_w_id, o.o_id, o.c_id, o.o_carrier_id, o.o_ol_cnt, c.*
+FROM orders o LEFT OUTER JOIN customer c ON (
+ c.c_w_id = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8);
+
+
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.sqlpp
new file mode 100644
index 0000000..9f01f47
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.sqlpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties: (a_1, a_0, a_2)
+-- with join condition a_0=b_0, a_1=b_1, a_2=b_2 and equivalence mapping a_0=a_1
+-- the expected final required properties of B will be: (b_0, b_1, b_2) which should be okay.
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+CREATE TYPE A_TYPE AS {a_0 : integer, a_1 : integer, a_2 : integer};
+CREATE DATASET A(A_TYPE) PRIMARY KEY a_0, a_1, a_2;
+
+CREATE TYPE B_TYPE AS {b_0 : integer, b_1 : integer, b_2 : integer};
+CREATE DATASET B(B_TYPE) PRIMARY KEY b_0, b_1, b_2;
+
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2)
+WHERE A.a_0=A.a_2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.sqlpp
new file mode 100644
index 0000000..9e2fbe3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.sqlpp
@@ -0,0 +1,36 @@
+/*
+* 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.
+*/
+
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first partition properties:( a_0, a_1, a_2)
+-- and requirement properties: (b_0, b_1, b_2)
+-- with the join condition A.a_0 = B.b_0 AND B.b_1 = A.a_1 AND A.a_2 = B.b_2 AND A.a_3 = B.b_3
+-- No extra hash exchanges are required as its already partitioned on (a_0, a_1, a_2, a_3) & (b_0, b_1, b_2, b_3)
+-- As partition on (a_0, a_1, a_2) implies partition on (a_0, a_1, a_2, a_3)
+
+
+use test;
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+ FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2
+ AND A.a_3 = B.b_3);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.sqlpp
new file mode 100644
index 0000000..ace3520
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.sqlpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties: (a_1, a_0, a_2)
+-- with join condition a_0=b_0, a_1=b_1, a_2=b_2
+-- the expected final required properties of B will be: (b_0, b_1, b_2) which should be okay.
+
+
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+
+
+CREATE TYPE A_TYPE AS {a_0 : integer, a_1 : integer, a_2 : integer};
+CREATE DATASET A(A_TYPE) PRIMARY KEY a_0, a_1, a_2;
+
+CREATE TYPE B_TYPE AS {b_0 : integer, b_1 : integer, b_2 : integer};
+CREATE DATASET B(B_TYPE) PRIMARY KEY b_0, b_1, b_2;
+
+
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.sqlpp
new file mode 100644
index 0000000..1a364fc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties:( a_3 ,a_0, a_1)
+-- and requirement properties: (b_3, b_0, b_1)
+-- with the following join condition
+-- the expected final required properties of orders will be: (b_3, b_0, b_1)
+
+use test;
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_3 = B.b_3);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.sqlpp
new file mode 100644
index 0000000..1aff08c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties:( a_0, a_1)
+-- and requirement properties: (b_0, b_1)
+-- with the following join condition
+-- the expected final required properties of orders will be: (b_0, b_1)
+use test;
+
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan
new file mode 100644
index 0000000..c9c3348
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan
@@ -0,0 +1,40 @@
+distribute result [$$43]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$43] <- [object-concat-strict({"c_id": $$46}, to-object-var-str($$o))] project: [$$43]
+ -- ASSIGN |PARTITIONED|
+ project ([$$46, $$o])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48)))
+ -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ project ([$$46, $$44, $$45])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$47, $$48, $$51] |PARTITIONED|
+ select (gt($$o.getField("o_carrier_id"), 8))
+ -- STREAM_SELECT |PARTITIONED|
+ assign [$$51] <- [$$o.getField("o_c_id")]
+ -- ASSIGN |PARTITIONED|
+ project ([$$47, $$48, $$o])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$47, $$48, $$49, $$o] <- test.orders
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan
new file mode 100644
index 0000000..02a3b43
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan
@@ -0,0 +1,40 @@
+distribute result [$$43]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$43] <- [object-concat-strict({"c_id": $$46}, to-object-var-str($$o))] project: [$$43]
+ -- ASSIGN |PARTITIONED|
+ project ([$$46, $$o])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48)))
+ -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ project ([$$46, $$44, $$45])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- BROADCAST_EXCHANGE |PARTITIONED|
+ select (gt($$o.getField("o_carrier_id"), 8))
+ -- STREAM_SELECT |PARTITIONED|
+ assign [$$51] <- [$$o.getField("o_c_id")]
+ -- ASSIGN |PARTITIONED|
+ project ([$$47, $$48, $$o])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$47, $$48, $$49, $$o] <- test.orders
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan
new file mode 100644
index 0000000..4a69a97
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan
@@ -0,0 +1,54 @@
+distribute result [$$48]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$48] <- [object-concat-strict({"o_d_id": $$50, "o_w_id": $$49, "o_id": $$51, "c_id": $$65, "o_carrier_id": $$61, "o_ol_cnt": $$67}, to-object-var-str($$c))] project: [$$48]
+ -- ASSIGN |PARTITIONED|
+ project ([$$50, $$49, $$51, $$65, $$61, $$67, $$c])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$49, $$73), eq($$50, $$74), eq($$51, $$75)))
+ -- HYBRID_HASH_JOIN [$$49, $$50, $$51][$$73, $$74, $$75] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$67, $$61, $$65] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_carrier_id"), $$o.getField("c_id")] project: [$$50, $$49, $$51, $$65, $$61, $$67]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$49, $$50, $$51, $$o] <- test.orders
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$75] |PARTITIONED|
+ project ([$$c, $$73, $$74, $$75])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ join (and(eq($$54, $$68), eq($$52, $$73), eq($$53, $$74)))
+ -- HYBRID_HASH_JOIN [$$68, $$73, $$74][$$54, $$52, $$53] |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$68] |PARTITIONED|
+ select (gt($$69.getField("o_carrier_id"), 8)) project: [$$73, $$74, $$75, $$68]
+ -- STREAM_SELECT |PARTITIONED|
+ assign [$$68] <- [$$69.getField("o_c_id")]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$73, $$74, $$75, $$69] <- test.orders
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$52, $$53, $$54, $$c] <- test.customer
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan
new file mode 100644
index 0000000..20fa187
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan
@@ -0,0 +1,38 @@
+distribute result [$$46]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$46] <- [{"a_0": $$49, "a_1": $$50, "a_2": $$51, "a_3": $$62, "b_3": $$63}] project: [$$46]
+ -- ASSIGN |PARTITIONED|
+ project ([$$49, $$50, $$51, $$62, $$63])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$51, $$54), eq($$49, $$52), eq($$53, $$50)))
+ -- HYBRID_HASH_JOIN [$$51, $$49, $$50][$$54, $$52, $$53] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ select (eq($$49, $$51))
+ -- STREAM_SELECT |PARTITIONED|
+ assign [$$62] <- [$$A.getField("a_3")] project: [$$49, $$50, $$51, $$62]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$49, $$50, $$51, $$A] <- test.A
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$63] <- [$$B.getField("b_3")] project: [$$63, $$54, $$52, $$53]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$52, $$53, $$54, $$B] <- test.B
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan
new file mode 100644
index 0000000..f4d6562
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan
@@ -0,0 +1,36 @@
+distribute result [$$46]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$46] <- [{"a_0": $$47, "a_1": $$48, "a_2": $$49, "a_3": $$55, "b_3": $$56}] project: [$$46]
+ -- ASSIGN |PARTITIONED|
+ project ([$$47, $$48, $$49, $$55, $$56])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$49, $$52), eq($$55, $$56), eq($$47, $$50), eq($$51, $$48)))
+ -- HYBRID_HASH_JOIN [$$49, $$55, $$47, $$48][$$52, $$56, $$50, $$51] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$55] <- [$$A.getField("a_3")] project: [$$47, $$48, $$49, $$55]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$47, $$48, $$49, $$A] <- test.A
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$56] <- [$$B.getField("b_3")] project: [$$56, $$52, $$50, $$51]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$50, $$51, $$52, $$B] <- test.B
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan
new file mode 100644
index 0000000..3bf9f1a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan
@@ -0,0 +1,36 @@
+distribute result [$$43]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$43] <- [{"a_0": $$44, "a_1": $$45, "a_2": $$46, "a_3": $$59, "b_3": $$60}] project: [$$43]
+ -- ASSIGN |PARTITIONED|
+ project ([$$44, $$45, $$46, $$59, $$60])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$46, $$49), eq($$44, $$47), eq($$48, $$45)))
+ -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$49, $$47, $$48] |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$59] <- [$$A.getField("a_3")] project: [$$44, $$45, $$46, $$59]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$44, $$45, $$46, $$A] <- test.A
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$60] <- [$$B.getField("b_3")] project: [$$60, $$49, $$47, $$48]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$47, $$48, $$49, $$B] <- test.B
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan
new file mode 100644
index 0000000..2751a74
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan
@@ -0,0 +1,38 @@
+distribute result [$$43]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$43] <- [{"a_0": $$44, "a_1": $$45, "a_2": $$46, "a_3": $$50, "b_3": $$51}] project: [$$43]
+ -- ASSIGN |PARTITIONED|
+ project ([$$44, $$45, $$46, $$50, $$51])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$50, $$51), eq($$44, $$47), eq($$48, $$45)))
+ -- HYBRID_HASH_JOIN [$$50, $$44, $$45][$$51, $$47, $$48] |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$50, $$44, $$45] |PARTITIONED|
+ assign [$$50] <- [$$A.getField("a_3")] project: [$$44, $$45, $$46, $$50]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$44, $$45, $$46, $$A] <- test.A
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$51, $$47, $$48] |PARTITIONED|
+ assign [$$51] <- [$$B.getField("b_3")] project: [$$51, $$47, $$48]
+ -- ASSIGN |PARTITIONED|
+ project ([$$47, $$48, $$B])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$47, $$48, $$49, $$B] <- test.B
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan
new file mode 100644
index 0000000..483fdc2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan
@@ -0,0 +1,38 @@
+distribute result [$$40]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$40] <- [{"a_0": $$41, "a_1": $$42, "a_2": $$43, "a_3": $$54, "b_3": $$55}] project: [$$40]
+ -- ASSIGN |PARTITIONED|
+ project ([$$41, $$42, $$43, $$54, $$55])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$41, $$44), eq($$45, $$42)))
+ -- HYBRID_HASH_JOIN [$$41, $$42][$$44, $$45] |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$41, $$42] |PARTITIONED|
+ assign [$$54] <- [$$A.getField("a_3")] project: [$$41, $$42, $$43, $$54]
+ -- ASSIGN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$41, $$42, $$43, $$A] <- test.A
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange
+ -- HASH_PARTITION_EXCHANGE [$$44, $$45] |PARTITIONED|
+ assign [$$55] <- [$$B.getField("b_3")] project: [$$55, $$44, $$45]
+ -- ASSIGN |PARTITIONED|
+ project ([$$44, $$45, $$B])
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ data-scan []<-[$$44, $$45, $$46, $$B] <- test.B
+ -- DATASOURCE_SCAN |PARTITIONED|
+ exchange
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ empty-tuple-source
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.000.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.000.ddl.sqlpp
new file mode 100644
index 0000000..c04056a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.000.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.030.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.030.update.sqlpp
new file mode 100644
index 0000000..4372e59
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.030.update.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398"), "joinDate": date("2025-04-25"), "joinTime": time("14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-not-formatted")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime, joinDate: date, joinTime: time} )
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.031.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.031.update.sqlpp
new file mode 100644
index 0000000..8adfd8c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.031.update.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-formatted")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime} )
+DATETIME "DD-MM-YYYYTss:mm:hh"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.032.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.032.update.sqlpp
new file mode 100644
index 0000000..38b0eef
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.032.update.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398"), "joinDate": date("2025-04-25")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-date-formatted")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime, joinDate: date} )
+DATE "DD-MM-YYYY" DATETIME "DD-MM-YYYY"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.033.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.033.update.sqlpp
new file mode 100644
index 0000000..5628b8e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.033.update.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398"), "joinTime": time("14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-time-formatted")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime, joinTime: time} )
+DATETIME "hh:mm:ss.nnna"
+TIME "hh:mm:ss.nnna"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.034.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.034.update.sqlpp
new file mode 100644
index 0000000..d5044cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.034.update.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-formatted-2")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime} )
+DATETIME "DD/MM/YYYY ss:mm:hh a"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.035.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.035.update.sqlpp
new file mode 100644
index 0000000..a80fd43
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.035.update.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-formatted-with-comma")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime} )
+DATETIME "DD/MMM/YYYY, ss:mm:hh a"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.036.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.036.update.sqlpp
new file mode 100644
index 0000000..26fb57c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.036.update.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+COPY (
+ select value x FROM [
+ {"id":1, "name":"", "amount":123.2, "accountNumber":345.34, "joinDatetime": datetime("2025-04-25T14:53:54.398"), "joinDate": date("2025-04-25"), "joinTime": time("14:53:54.398")}
+ ] as x
+) toWrite
+TO %adapter%
+PATH (%pathprefix% "copy-to-result", "csv", "simple-csv", "datetime-date-time-formatted-with-comma")
+TYPE ( {id: bigint, name: string?, amount: float, accountNumber: double, joinDatetime: datetime, joinDate: date, joinTime: time} )
+DATETIME "DD/MMM/YYYY, ss:mm:hh a"
+TIME "ss:mm:hh a"
+DATE "DD/MMM/YYYY"
+WITH {
+ %template_colons%,
+ %additionalProperties%
+ "format":"csv",
+ "header":"true"
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.040.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.040.ddl.sqlpp
new file mode 100644
index 0000000..e8dc8bd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.040.ddl.sqlpp
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+drop dataset datetimeNotFormattedDataset if exists;
+drop dataset datetimeFormattedDataset if exists;
+drop dataset datetimeDateFormattedDataset if exists;
+drop dataset datatimeTimeFormattedDataset if exists;
+drop dataset datetimeFormattedDataset2 if exists;
+drop dataset datetimeFormattedWithCommaDataset if exists;
+drop dataset datetimeDateTimeFormattedWithCommaDataset if exists;
+
+drop type datetimeNotFormattedType if exists;
+drop type datetimeFormattedType if exists;
+drop type datetimeDateFormattedType if exists;
+drop type datatimeTimeFormattedType if exists;
+drop type datetimeFormattedType2 if exists;
+drop type datetimeFormattedWithCommaType if exists;
+drop type datetimeDateTimeFormattedWithCommaType if exists;
+
+CREATE TYPE datetimeNotFormattedType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string, joinDate: string, joinTime: string };
+CREATE TYPE datetimeFormattedType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string };
+CREATE TYPE datetimeDateFormattedType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string, joinDate: string };
+CREATE TYPE datatimeTimeFormattedType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string, joinTime: string };
+CREATE TYPE datetimeFormattedType2 AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string };
+CREATE TYPE datetimeFormattedWithCommaType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string };
+CREATE TYPE datetimeDateTimeFormattedWithCommaType AS { id: bigint, name: string?, amount: float, accountNumber: double, joinDateTime: string, joinDate: string, joinTime: string };
+
+CREATE EXTERNAL DATASET datetimeNotFormattedDataset(datetimeNotFormattedType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-not-formatted"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datetimeFormattedDataset(datetimeFormattedType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-formatted"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datetimeDateFormattedDataset(datetimeDateFormattedType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-date-formatted"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datatimeTimeFormattedDataset(datatimeTimeFormattedType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-time-formatted"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datetimeFormattedDataset2(datetimeFormattedType2) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-formatted-2"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datetimeFormattedWithCommaDataset(datetimeFormattedWithCommaType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-formatted-with-comma"),
+ ("format" = "csv")
+);
+
+CREATE EXTERNAL DATASET datetimeDateTimeFormattedWithCommaDataset(datetimeDateTimeFormattedWithCommaType) USING %adapter%
+(
+ %template%,
+ %additional_Properties%,
+ ("header"="true"),
+ ("definition"="%path_prefix%copy-to-result/csv/simple-csv/datetime-date-time-formatted-with-comma"),
+ ("format" = "csv")
+);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.130.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.130.query.sqlpp
new file mode 100644
index 0000000..4ccbb8d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.130.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, datetime(joinDateTime) as joinDateTimeCasted, get_type(datetime(joinDateTime)) as joinDateTimeCastedType,
+joinDate as joinDate, get_type(joinDate) as joinDateType, date(joinDate) as joinDateCasted, get_type(date(joinDate)) as joinDateCastedType,
+joinTime as joinTime, get_type(joinTime) as joinTimeType, time(joinTime) as joinTimeCasted, get_type(time(joinTime)) as joinTimeCastedType
+FROM datetimeNotFormattedDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.131.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.131.query.sqlpp
new file mode 100644
index 0000000..ddd60e6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.131.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, parse_datetime(joinDateTime, "DD-MM-YYYYTss:mm:hh") as joinDateTimeCasted, get_type(parse_datetime(joinDateTime, "DD-MM-YYYYTss:mm:hh")) as joinDateTimeCastedType
+FROM datetimeFormattedDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.132.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.132.query.sqlpp
new file mode 100644
index 0000000..ac6158e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.132.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, parse_datetime(joinDateTime, "DD-MM-YYYY") as joinDateTimeCasted, get_type(parse_datetime(joinDateTime, "DD-MM-YYYY")) as joinDateTimeCastedType,
+joinDate as joinDate, get_type(joinDate) as joinDateType, parse_Date(joinDate, "DD-MM-YYYY") as joinDateCasted, get_type(parse_Date(joinDate, "DD-MM-YYYY")) as joinDateCastedType
+FROM datetimeDateFormattedDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.133.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.133.query.sqlpp
new file mode 100644
index 0000000..870e830
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.133.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinTime as joinTime, get_type(joinTime) as joinTimeType, parse_time(joinTime, "hh:mm:ss.nnna") as joinTimeCasted, get_type(parse_time(joinTime, "hh:mm:ss.nnna")) as joinTimeCastedType
+FROM datatimeTimeFormattedDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.134.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.134.query.sqlpp
new file mode 100644
index 0000000..332222d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.134.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, parse_datetime(joinDateTime, "DD/MM/YYYY ss:mm:hh a") as joinDateTimeCasted, get_type(parse_datetime(joinDateTime, "DD/MM/YYYY ss:mm:hh a")) as joinDateTimeCastedType
+FROM datetimeFormattedDataset2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.135.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.135.query.sqlpp
new file mode 100644
index 0000000..ffe5b55
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.135.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, parse_datetime(joinDateTime, "DD/MMM/YYYY, ss:mm:hh a") as joinDateTimeCasted, get_type(parse_datetime(joinDateTime, "DD/MMM/YYYY, ss:mm:hh a")) as joinDateTimeCastedType
+FROM datetimeFormattedWithCommaDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.136.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.136.query.sqlpp
new file mode 100644
index 0000000..aa3afad
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.136.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT
+joinDateTime as joinDateTime, get_type(joinDateTime) as joinDateTimeType, parse_datetime(joinDateTime, "DD/MMM/YYYY, ss:mm:hh a") as joinDateTimeCasted, get_type(parse_datetime(joinDateTime, "DD/MMM/YYYY, ss:mm:hh a")) as joinDateTimeCastedType,
+joinDate as joinDate, get_type(joinDate) as joinDateType, parse_Date(joinDate, "DD/MMM/YYYY") as joinDateCasted, get_type(parse_Date(joinDate, "DD/MMM/YYYY")) as joinDateCastedType,
+joinTime as joinTime, get_type(joinTime) as joinTimeType, parse_time(joinTime, "ss:mm:hh a") as joinTimeCasted, get_type(parse_time(joinTime, "ss:mm:hh a")) as joinTimeCastedType
+FROM datetimeDateTimeFormattedWithCommaDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.999.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.999.ddl.sqlpp
new file mode 100644
index 0000000..220c7be
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/copy-to/csv/datetime/test.999.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.01.ddl.sqlpp
new file mode 100644
index 0000000..1a3bfb4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.01.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+USE test;
+
+CREATE TYPE t1 IF NOT EXISTS AS {id: int, f: string?};
+CREATE DATASET ds1(t1) IF NOT EXISTS PRIMARY KEY id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.02.update.sqlpp
new file mode 100644
index 0000000..dbf6daf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.02.update.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+UPSERT INTO ds1 ([
+{"id": 1, "f": "asterix", "f2": "asterix"},
+{"id": 2, "f": "𩸽", "f2": "𩸽"},
+{"id": 3, "f": "a𩸽b", "f2": "a𩸽b"},
+{"id": 4, "f": null, "f2": null},
+{"id": 5},
+{"id": 6, "f2": 1}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.03.query.sqlpp
new file mode 100644
index 0000000..e00b33e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.03.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT sha1_hex(f) a, sha1_hex(f2) b, sha1_base64(f) c, sha1_base64(f2) d
+FROM ds1
+ORDER BY ds1.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.04.query.sqlpp
new file mode 100644
index 0000000..3f00c24
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.04.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT sha1_hex("asterix") a, sha1_hex("𩸽") b, sha1_hex("a𩸽b") c, sha1_hex(null) d,
+ sha1_base64("asterix") e, sha1_base64("𩸽") f, sha1_base64("a𩸽b") g, sha1_base64(null) h,
+ sha1_hex(missing) i, sha1_base64(missing) j, sha1_hex(1) k, sha1_base64(1) l;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.99.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.99.ddl.sqlpp
new file mode 100644
index 0000000..36b2bab
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/crypto/sha1/sha1.99.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.1.ddl.sqlpp
new file mode 100644
index 0000000..2b817b2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.1.ddl.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.
+ */
+
+
+CREATE TYPE cust_type AS {c_w_id : integer,c_d_id : integer, c_id : integer};
+CREATE DATASET customer(cust_type) PRIMARY KEY c_w_id, c_d_id, c_id;
+
+CREATE TYPE orders_type AS {o_w_id : integer, o_d_id : integer, o_id : integer};
+CREATE DATASET orders(orders_type) PRIMARY KEY o_w_id, o_d_id, o_id;
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.2.update.sqlpp
new file mode 100644
index 0000000..b7042c8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.2.update.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+
+INSERT INTO customer ({"c_id":2,"c_d_id":1,"c_w_id":1,"c_discount":0.3413,"c_credit":"GC","c_first":"jqmoaqly","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":4228533.790000002,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"ingngcunkfzoku","c_street_2":"sihqvjfhhphyd","c_city":"jtflodpnsmtn","c_state":"ps","c_zip":"640711111","c_phone":"8709221552477813","c_since":"2016-04-28 05:24:17","key":"1.1.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":2,"c_w_id":1,"c_discount":0.4472,"c_credit":"GC","c_first":"yupforh","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":2637344.5900000003,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"kfmblhsbdf","c_street_2":"ldmnvpzyzqpjgdldcxd","c_city":"jakerbxcuwmnfvqntd","c_state":"ft","c_zip":"377611111","c_phone":"2594721341099812","c_since":"2019-07-23 11:35:08","key":"1.2.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":3,"c_w_id":1,"c_discount":0.4549,"c_credit":"GC","c_first":"cdchdqts","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":2275392.5500000003,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"emwtajlhjyzigbxtll","c_street_2":"bsxxckrjkxvnx","c_city":"vuthjjchaubyurhxu","c_state":"ae","c_zip":"207611111","c_phone":"2223483665383895","c_since":"2015-01-10 09:13:11","key":"1.3.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":4,"c_w_id":1,"c_discount":0.2902,"c_credit":"BC","c_first":"dbxdynrsxq","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":-10.0,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"cdnrcokhecssszdxy","c_street_2":"owkrknkjxxeh","c_city":"dizrkudapnhlur","c_state":"ne","c_zip":"214211111","c_phone":"9527105621833116","c_since":"2019-09-30 04:41:34","key":"1.4.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":5,"c_w_id":1,"c_discount":0.1233,"c_credit":"GC","c_first":"xvaijyn","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":8318309.3500000015,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"tbjodrhupcwdyhiul","c_street_2":"fvbhntiihftymwkabbr","c_city":"cjlfuvcqvkg","c_state":"ng","c_zip":"417111111","c_phone":"5673180500149103","c_since":"2014-10-20 20:06:32","key":"1.5.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":6,"c_w_id":1,"c_discount":0.4838,"c_credit":"GC","c_first":"ikjojneh","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":6788632.1400000015,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"djtnknodfrkny","c_street_2":"iwarlwscxj","c_city":"eaixkpruvqiuhbqnpasf","c_state":"nl","c_zip":"461611111","c_phone":"7068147293579806","c_since":"2018-08-29 23:19:39","key":"1.6.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":7,"c_w_id":1,"c_discount":0.3469,"c_credit":"GC","c_first":"mqvlqra","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":-10.0,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"rcnecgnkrtpgkzrjap","c_street_2":"voabsdpbfuxusyiqs","c_city":"udtfebydicf","c_state":"am","c_zip":"528111111","c_phone":"3972476735934659","c_since":"2020-02-17 05:48:03","key":"1.7.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":8,"c_w_id":1,"c_discount":0.319,"c_credit":"GC","c_first":"hcmxoxvr","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":3253865.68,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"jrkgfusmekbbjygma","c_street_2":"ljkmhxyzyctxyrtlo","c_city":"uxceeygbpgjh","c_state":"he","c_zip":"111611111","c_phone":"3276574132758646","c_since":"2019-08-03 09:05:23","key":"1.8.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":9,"c_w_id":1,"c_discount":0.1118,"c_credit":"BC","c_first":"horovuvbi","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":-10.0,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"ikznzllcvcejsvsf","c_street_2":"lmaferykvzvnlck","c_city":"xzqhxyxkfwgd","c_state":"eu","c_zip":"130211111","c_phone":"3913647178718934","c_since":"2018-07-13 11:47:36","key":"1.9.2"});
+INSERT INTO customer ({"c_id":2,"c_d_id":10,"c_w_id":1,"c_discount":0.4349,"c_credit":"GC","c_first":"ghoevrth","c_middle":"OE","c_last":"BARBAROUGHT","c_credit_lim":50000.0,"c_balance":-10.0,"c_ytd_payment":10.0,"c_payment_cnt":1,"c_delivery_cnt":0,"c_street_1":"qvyasidzgzxzkf","c_street_2":"yyqlehcjsyoaf","c_city":"svnmulhzkp","c_state":"ni","c_zip":"302111111","c_phone":"0212917484161389","c_since":"2017-04-29 18:46:22","key":"1.10.2"});
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.3.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.3.update.sqlpp
new file mode 100644
index 0000000..5a27699
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.3.update.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+
+INSERT INTO orders ({"o_id":881,"o_c_id":2,"o_d_id":1,"o_w_id":1,"o_carrier_id":6,"o_ol_cnt":11});
+INSERT INTO orders ({"o_id":525,"o_c_id":2,"o_d_id":2,"o_w_id":1,"o_carrier_id":1,"o_ol_cnt":15});
+INSERT INTO orders ({"o_id":466,"o_c_id":2,"o_d_id":3,"o_w_id":1,"o_carrier_id":10,"o_ol_cnt":14});
+INSERT INTO orders ({"o_id":2449,"o_c_id":2,"o_d_id":4,"o_w_id":1,"o_carrier_id":0,"o_ol_cnt":15});
+INSERT INTO orders ({"o_id":1652,"o_c_id":2,"o_d_id":5,"o_w_id":1,"o_carrier_id":10,"o_ol_cnt":7});
+INSERT INTO orders ({"o_id":1350,"o_c_id":2,"o_d_id":6,"o_w_id":1,"o_carrier_id":8,"o_ol_cnt":9});
+INSERT INTO orders ({"o_id":2822,"o_c_id":2,"o_d_id":7,"o_w_id":1,"o_carrier_id":0,"o_ol_cnt":12});
+INSERT INTO orders ({"o_id":677,"o_c_id":2,"o_d_id":8,"o_w_id":1,"o_carrier_id":6,"o_ol_cnt":6});
+INSERT INTO orders ({"o_id":2851,"o_c_id":2,"o_d_id":9,"o_w_id":1,"o_carrier_id":0,"o_ol_cnt":12});
+INSERT INTO orders ({"o_id":2841,"o_c_id":2,"o_d_id":10,"o_w_id":1,"o_carrier_id":0,"o_ol_cnt":9});
+
+
+
+
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.4.query.sqlpp
new file mode 100644
index 0000000..a878aa5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.4.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+
+
+
+SELECT c.c_id, o.*
+FROM customer c LEFT OUTER JOIN orders o ON (
+ c.c_w_id = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8)
+ORDER BY o.o_d_id, o.o_id;
+
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.6.query.sqlpp
new file mode 100644
index 0000000..f9572a1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.6.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+SELECT c.c_id, o.*
+FROM customer c LEFT OUTER JOIN orders o ON (
+ c.c_w_id /*+ hash-bcast */ = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8)
+ORDER BY o.o_d_id, o.o_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.8.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.8.query.sqlpp
new file mode 100644
index 0000000..c77148b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange/hash_join_exchange.8.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+
+
+SELECT o.o_d_id, o.o_w_id, o.o_id, o.c_id, o.o_carrier_id, o.o_ol_cnt, c.*
+FROM orders o LEFT OUTER JOIN customer c ON (
+ c.c_w_id = o.o_w_id
+ AND c.c_d_id = o.o_d_id
+ AND c.c_id = o.o_c_id
+ AND o.o_carrier_id > 8)
+ORDER BY o.o_d_id, o.o_w_id, o.o_id, o.c_id, o.o_carrier_id, o.o_ol_cnt;
+
+
+
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.1.ddl.sqlpp
new file mode 100644
index 0000000..c12c22d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.1.ddl.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+CREATE TYPE A_TYPE AS {a_0 : integer, a_1 : integer, a_2 : integer};
+CREATE DATASET A(A_TYPE) PRIMARY KEY a_0, a_1, a_2;
+
+CREATE TYPE B_TYPE AS {b_0 : integer, b_1 : integer, b_2 : integer};
+CREATE DATASET B(B_TYPE) PRIMARY KEY b_0, b_1, b_2;
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.10.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.10.query.sqlpp
new file mode 100644
index 0000000..07bf929
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.10.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties: (a_1, a_0, a_2)
+-- with join condition a_0=b_0, a_1=b_1, a_2=b_2 and equivalence mapping a_0=a_1
+-- the expected final required properties of B will be: (b_0, b_1, b_2) which should be okay.
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2)
+WHERE A.a_0=A.a_2
+ORDER BY A.a_0, A.a_1, A.a_2, A.a_3, B.b_3;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.12.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.12.query.sqlpp
new file mode 100644
index 0000000..42a62ef
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.12.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.
+*/
+
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2
+ AND A.a_3 = B.b_3)
+ORDER BY A.a_0, A.a_1, A.a_2, A.a_3, B.b_3;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.2.update.sqlpp
new file mode 100644
index 0000000..c8f69c8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.2.update.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+
+INSERT INTO A(
+ SELECT VALUE {"a_0": i, "a_1": i, "a_2": i, "a_3": i}
+ FROM range(1, 100) i
+);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.3.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.3.update.sqlpp
new file mode 100644
index 0000000..074d554
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.3.update.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+
+
+INSERT INTO B(
+ SELECT VALUE {"b_0": i, "b_1": i, "b_2": i, "b_3": i}
+ FROM range(51, 150) i
+);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.4.query.sqlpp
new file mode 100644
index 0000000..c50b573
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.4.query.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+-- This Test is intended to test the IPartitioningRequirementsCoordinator for outer join
+-- in the case where the first delivered properties: (a_1, a_0, a_2)
+-- with join condition a_0=b_0, a_1=b_1, a_2=b_2
+-- the expected final required properties of B will be: (b_0, b_1, b_2) which should be okay.
+
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_2 = B.b_2)
+ORDER BY A.a_0, A.a_1, A.a_2, A.a_3, B.b_3;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.6.query.sqlpp
new file mode 100644
index 0000000..b7d7196
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.6.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1
+ AND A.a_3 = B.b_3)
+ORDER BY A.a_0, A.a_1, A.a_2, A.a_3, B.b_3;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.8.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.8.query.sqlpp
new file mode 100644
index 0000000..605e70f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/join/hash_join_exchange_1/hash_join_exchange_1.8.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+SELECT A.a_0, A.a_1, A.a_2, A.a_3, B.b_3
+FROM A LEFT OUTER JOIN B ON (
+ A.a_0 = B.b_0
+ AND B.b_1 = A.a_1)
+ORDER BY A.a_0, A.a_1, A.a_2, A.a_3, B.b_3;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/handle_error_fun/handle_error_fun.01.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/handle_error_fun/handle_error_fun.01.query.sqlpp
new file mode 100644
index 0000000..c47e3f5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/handle_error_fun/handle_error_fun.01.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+SET `import-private-functions` `true`;
+SELECT VALUE t
+FROM [
+{"id": 1, "f": "fine doc"},
+{"id": 2, "f": "problematic doc"}
+] AS t
+WHERE if_error(inject_failure("", t.id = 2), true) = true;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.01.ddl.sqlpp
new file mode 100644
index 0000000..1a3bfb4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.01.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+USE test;
+
+CREATE TYPE t1 IF NOT EXISTS AS {id: int, f: string?};
+CREATE DATASET ds1(t1) IF NOT EXISTS PRIMARY KEY id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.02.update.sqlpp
new file mode 100644
index 0000000..0eeb028
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.02.update.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+// testing base 16
+USE test;
+
+UPSERT INTO ds1 ([
+{"id": 1, "f": "1", "f2": "1"}, // 1
+{"id": 2, "f": "A", "f2": "A"}, // 10
+{"id": 3, "f": "10", "f2": "10"}, // 16
+{"id": 4, "f": null, "f2": null},
+{"id": 5},
+{"id": 6, "f": "35BC6C28BCA27FB", "f2": "35BC6C28BCA27FB"}, // 242005543865690107
+{"id": 7, "f": "35BC6C28BCA27FBECC144761D32D09986876438F", "f2": "35BC6C28BCA27FBECC144761D32D09986876438F"}, // does not fit in a 64-bit integer
+{"id": 8, "f2": 1} // should return null for non-string inputs
+]);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.03.query.sqlpp
new file mode 100644
index 0000000..c4e4b7b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.03.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT from_base(f, 16) a, from_base(f2, 16) b
+FROM ds1
+ORDER BY ds1.id;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.04.query.sqlpp
new file mode 100644
index 0000000..bbd27aa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.04.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+SELECT from_base("1", 16) a, from_base("A", 16) b, from_base("10", 16) c, from_base("35BC6C28BCA27FB", 16) d,
+ from_base("35BC6C28BCA27FBECC144761D32D09986876438F", 16) e,
+ from_base(null, 16) f, from_base(missing, 16) g,
+ from_base("A", null) h, from_base("A", missing) i,
+ from_base("A", -1) j, from_base("A", 1) k, from_base("A", 46) l, from_base(1, 16) m;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.05.query.sqlpp
new file mode 100644
index 0000000..94f5707
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.05.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+SELECT from_base("1", 10) a, from_base("10", 10) b, from_base("A", 10) c,
+ from_base("1", 2) d, from_base("10", 2) e, from_base("11", 2) f;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.99.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.99.ddl.sqlpp
new file mode 100644
index 0000000..36b2bab
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/from_base/from_base.99.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.00.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.00.ddl.sqlpp
new file mode 100644
index 0000000..897aac5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.00.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+drop dataset padding_example if exists;
+create dataset padding_example primary key (id:int);
+upsert into padding_example ([
+{"id":1, "f":"Hi", "f1": "👩"},
+{"id":2, "f": "-7262.98", "f1": "👨"},
+{"id":3, "f": "a𩸽b", "f1": "🎉"},
+{"id":4, "f": "👩👩👧👦", "f1": "✓✓✓"},
+{"id":5, "f": null, "f1" : null}
+]);
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.01.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.01.query.sqlpp
new file mode 100644
index 0000000..9b3f0bf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.01.query.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+SELECT id, f, f1,
+ lpad(f, 10, '$') AS f_padded_with_dollar_to_10_codepoints,
+ lpad(f, 2, '$') AS f_truncated_or_padded_to_2_codepoints,
+ lpad(f, 10, '👩👩👧👦') AS f_padded_with_emoji_to_10_codepoints,
+ lpad(f1, 4, '%%') AS f1_padded_to_4_codepoints
+FROM padding_example
+ORDER BY id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.02.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.02.query.sqlpp
new file mode 100644
index 0000000..a1383e6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.02.query.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+SELECT
+ lpad('asterix', 11, '$&^') AS padded_to_11_codepoints,
+ lpad('👩👩👧', 2, '$') AS truncated_to_2_codepoints,
+ lpad('👩👩👧', 10, '👩👩👧👦') AS padded_to_10_codepoints,
+ lpad(null, 4, '%%') AS padded_to_null_is_null,
+ lpad(22, 11, 'y') AS padded_non_str,
+ lpad('abcd', -2, 'y') AS negative_length;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.03.query.sqlpp
new file mode 100644
index 0000000..5adab87
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/lpad/lpad.03.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+SELECT lpad(repeat('a', 228), 240, '$') AS padded_long_input,
+ lpad(repeat('u', 310) || '你8世界🌍', 1000, repeat('彩2', 150) || 'END') AS very_long_unicode_test,
+ lpad(repeat('s', 95) || '©®™§¶你好世界🌍', 100, '$') AS very_long_truncation_with_unicode_result;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.00.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.00.ddl.sqlpp
new file mode 100644
index 0000000..897aac5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.00.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+drop dataset padding_example if exists;
+create dataset padding_example primary key (id:int);
+upsert into padding_example ([
+{"id":1, "f":"Hi", "f1": "👩"},
+{"id":2, "f": "-7262.98", "f1": "👨"},
+{"id":3, "f": "a𩸽b", "f1": "🎉"},
+{"id":4, "f": "👩👩👧👦", "f1": "✓✓✓"},
+{"id":5, "f": null, "f1" : null}
+]);
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.01.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.01.query.sqlpp
new file mode 100644
index 0000000..a95ec0b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.01.query.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+SELECT id, f, f1,
+ rpad(f, 10, '$') AS f_padded_with_dollar_to_10_codepoints,
+ rpad(f, 2, '$') AS f_truncated_or_padded_to_2_codepoints,
+ rpad(f, 10, '👩👩👧👦') AS f_padded_with_emoji_to_10_codepoints,
+ rpad(f1, 4, '%%') AS f1_padded_to_4_codepoints
+FROM padding_example
+ORDER BY id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.02.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.02.query.sqlpp
new file mode 100644
index 0000000..c0d1316
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.02.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+SELECT
+ rpad('asterix', 11, '$&^') AS padded_to_11_codepoints,
+ rpad('👩👩👧', 2, '$') AS truncated_to_2_codepoints,
+ rpad('👩👩👧', 10, '👩👩👧👦') AS padded_to_10_codepoints,
+ rpad(null, 4, '%%') AS padded_to_null_is_null,
+ rpad(22, 11, 'y') AS padded_non_str;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.03.query.sqlpp
new file mode 100644
index 0000000..701d36b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/pad/rpad/rpad.03.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+SELECT rpad(repeat('a', 228), 240, '$') AS padded_long_input,
+ rpad(repeat('u', 310) || '你8世界🌍', 1000, repeat('彩2', 150) || 'END') AS very_long_unicode_test,
+ rpad(repeat('s', 95) || '©®™§¶你好世界🌍', 100, '$') AS very_long_truncation_with_unicode_result;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.130.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.130.adm
new file mode 100644
index 0000000..b6a231a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.130.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "2025-04-25T14:53:54.398", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T14:53:54.398"), "joinDateTimeCastedType": "datetime", "joinDate": "2025-04-25", "joinDateType": "string", "joinDateCasted": date("2025-04-25"), "joinDateCastedType": "date", "joinTime": "14:53:54.398", "joinTimeType": "string", "joinTimeCasted": time("14:53:54.398"), "joinTimeCastedType": "time" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.131.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.131.adm
new file mode 100644
index 0000000..74c33cc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.131.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "25-04-2025T54:53:14", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T14:53:54.000"), "joinDateTimeCastedType": "datetime" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.132.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.132.adm
new file mode 100644
index 0000000..1f221d1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.132.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "25-04-2025", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T00:00:00.000"), "joinDateTimeCastedType": "datetime", "joinDate": "25-04-2025", "joinDateType": "string", "joinDateCasted": date("2025-04-25"), "joinDateCastedType": "date" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.133.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.133.adm
new file mode 100644
index 0000000..2e3cb97
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.133.adm
@@ -0,0 +1 @@
+{ "joinTime": "02:53:54.398PM", "joinTimeType": "string", "joinTimeCasted": time("14:53:54.398"), "joinTimeCastedType": "time" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.134.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.134.adm
new file mode 100644
index 0000000..59d3024
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.134.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "25/04/2025 54:53:02 PM", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T14:53:54.000"), "joinDateTimeCastedType": "datetime" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.135.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.135.adm
new file mode 100644
index 0000000..84e241a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.135.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "25/APR/2025, 54:53:02 PM", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T14:53:54.000"), "joinDateTimeCastedType": "datetime" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.136.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.136.adm
new file mode 100644
index 0000000..3d29643
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/copy-to/csv/datetime/result.136.adm
@@ -0,0 +1 @@
+{ "joinDateTime": "25/APR/2025, 54:53:02 PM", "joinDateTimeType": "string", "joinDateTimeCasted": datetime("2025-04-25T14:53:54.000"), "joinDateTimeCastedType": "datetime", "joinDate": "25/APR/2025", "joinDateType": "string", "joinDateCasted": date("2025-04-25"), "joinDateCastedType": "date", "joinTime": "54:53:02 PM", "joinTimeType": "string", "joinTimeCasted": time("14:53:54.000"), "joinTimeCastedType": "time" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.03.adm
new file mode 100644
index 0000000..9063191
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.03.adm
@@ -0,0 +1,6 @@
+{ "a": "35BC6C28BCA27FBECC144761D32D09986876438F", "b": "35BC6C28BCA27FBECC144761D32D09986876438F", "c": "NbxsKLyif77MFEdh0y0JmGh2Q48=", "d": "NbxsKLyif77MFEdh0y0JmGh2Q48=" }
+{ "a": "93315873BA703F909C19493045450FE0FDF84AD7", "b": "93315873BA703F909C19493045450FE0FDF84AD7", "c": "kzFYc7pwP5CcGUkwRUUP4P34Stc=", "d": "kzFYc7pwP5CcGUkwRUUP4P34Stc=" }
+{ "a": "AA20F3C74E59734035C2B11EF4C90F3E8521DC9E", "b": "AA20F3C74E59734035C2B11EF4C90F3E8521DC9E", "c": "qiDzx05Zc0A1wrEe9MkPPoUh3J4=", "d": "qiDzx05Zc0A1wrEe9MkPPoUh3J4=" }
+{ "a": null, "b": null, "c": null, "d": null }
+{ }
+{ "b": null, "d": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.04.adm
new file mode 100644
index 0000000..5f77732
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/crypto/sha1/sha1.04.adm
@@ -0,0 +1 @@
+{ "a": "35BC6C28BCA27FBECC144761D32D09986876438F", "b": "93315873BA703F909C19493045450FE0FDF84AD7", "c": "AA20F3C74E59734035C2B11EF4C90F3E8521DC9E", "d": null, "e": "NbxsKLyif77MFEdh0y0JmGh2Q48=", "f": "kzFYc7pwP5CcGUkwRUUP4P34Stc=", "g": "qiDzx05Zc0A1wrEe9MkPPoUh3J4=", "h": null, "k": null, "l": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.4.adm
new file mode 100644
index 0000000..097f737
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.4.adm
@@ -0,0 +1,10 @@
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "o_w_id": 1, "o_d_id": 3, "o_id": 466, "o_c_id": 2, "o_carrier_id": 10, "o_ol_cnt": 14, "c_id": 2 }
+{ "o_w_id": 1, "o_d_id": 5, "o_id": 1652, "o_c_id": 2, "o_carrier_id": 10, "o_ol_cnt": 7, "c_id": 2 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.6.adm
new file mode 100644
index 0000000..097f737
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.6.adm
@@ -0,0 +1,10 @@
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "c_id": 2 }
+{ "o_w_id": 1, "o_d_id": 3, "o_id": 466, "o_c_id": 2, "o_carrier_id": 10, "o_ol_cnt": 14, "c_id": 2 }
+{ "o_w_id": 1, "o_d_id": 5, "o_id": 1652, "o_c_id": 2, "o_carrier_id": 10, "o_ol_cnt": 7, "c_id": 2 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.8.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.8.adm
new file mode 100644
index 0000000..113d305
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange/hash_join_exchange.8.adm
@@ -0,0 +1,10 @@
+{ "o_d_id": 1, "o_w_id": 1, "o_id": 881, "o_carrier_id": 6, "o_ol_cnt": 11 }
+{ "o_d_id": 2, "o_w_id": 1, "o_id": 525, "o_carrier_id": 1, "o_ol_cnt": 15 }
+{ "c_w_id": 1, "c_d_id": 3, "c_id": 2, "c_discount": 0.4549, "c_credit": "GC", "c_first": "cdchdqts", "c_middle": "OE", "c_last": "BARBAROUGHT", "c_credit_lim": 50000.0, "c_balance": 2275392.5500000003, "c_ytd_payment": 10.0, "c_payment_cnt": 1, "c_delivery_cnt": 0, "c_street_1": "emwtajlhjyzigbxtll", "c_street_2": "bsxxckrjkxvnx", "c_city": "vuthjjchaubyurhxu", "c_state": "ae", "c_zip": "207611111", "c_phone": "2223483665383895", "c_since": "2015-01-10 09:13:11", "key": "1.3.2", "o_d_id": 3, "o_w_id": 1, "o_id": 466, "o_carrier_id": 10, "o_ol_cnt": 14 }
+{ "o_d_id": 4, "o_w_id": 1, "o_id": 2449, "o_carrier_id": 0, "o_ol_cnt": 15 }
+{ "c_w_id": 1, "c_d_id": 5, "c_id": 2, "c_discount": 0.1233, "c_credit": "GC", "c_first": "xvaijyn", "c_middle": "OE", "c_last": "BARBAROUGHT", "c_credit_lim": 50000.0, "c_balance": 8318309.3500000015, "c_ytd_payment": 10.0, "c_payment_cnt": 1, "c_delivery_cnt": 0, "c_street_1": "tbjodrhupcwdyhiul", "c_street_2": "fvbhntiihftymwkabbr", "c_city": "cjlfuvcqvkg", "c_state": "ng", "c_zip": "417111111", "c_phone": "5673180500149103", "c_since": "2014-10-20 20:06:32", "key": "1.5.2", "o_d_id": 5, "o_w_id": 1, "o_id": 1652, "o_carrier_id": 10, "o_ol_cnt": 7 }
+{ "o_d_id": 6, "o_w_id": 1, "o_id": 1350, "o_carrier_id": 8, "o_ol_cnt": 9 }
+{ "o_d_id": 7, "o_w_id": 1, "o_id": 2822, "o_carrier_id": 0, "o_ol_cnt": 12 }
+{ "o_d_id": 8, "o_w_id": 1, "o_id": 677, "o_carrier_id": 6, "o_ol_cnt": 6 }
+{ "o_d_id": 9, "o_w_id": 1, "o_id": 2851, "o_carrier_id": 0, "o_ol_cnt": 12 }
+{ "o_d_id": 10, "o_w_id": 1, "o_id": 2841, "o_carrier_id": 0, "o_ol_cnt": 9 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.10.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.10.adm
new file mode 100644
index 0000000..497b339
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.10.adm
@@ -0,0 +1,100 @@
+{ "a_0": 1, "a_1": 1, "a_2": 1, "a_3": 1 }
+{ "a_0": 2, "a_1": 2, "a_2": 2, "a_3": 2 }
+{ "a_0": 3, "a_1": 3, "a_2": 3, "a_3": 3 }
+{ "a_0": 4, "a_1": 4, "a_2": 4, "a_3": 4 }
+{ "a_0": 5, "a_1": 5, "a_2": 5, "a_3": 5 }
+{ "a_0": 6, "a_1": 6, "a_2": 6, "a_3": 6 }
+{ "a_0": 7, "a_1": 7, "a_2": 7, "a_3": 7 }
+{ "a_0": 8, "a_1": 8, "a_2": 8, "a_3": 8 }
+{ "a_0": 9, "a_1": 9, "a_2": 9, "a_3": 9 }
+{ "a_0": 10, "a_1": 10, "a_2": 10, "a_3": 10 }
+{ "a_0": 11, "a_1": 11, "a_2": 11, "a_3": 11 }
+{ "a_0": 12, "a_1": 12, "a_2": 12, "a_3": 12 }
+{ "a_0": 13, "a_1": 13, "a_2": 13, "a_3": 13 }
+{ "a_0": 14, "a_1": 14, "a_2": 14, "a_3": 14 }
+{ "a_0": 15, "a_1": 15, "a_2": 15, "a_3": 15 }
+{ "a_0": 16, "a_1": 16, "a_2": 16, "a_3": 16 }
+{ "a_0": 17, "a_1": 17, "a_2": 17, "a_3": 17 }
+{ "a_0": 18, "a_1": 18, "a_2": 18, "a_3": 18 }
+{ "a_0": 19, "a_1": 19, "a_2": 19, "a_3": 19 }
+{ "a_0": 20, "a_1": 20, "a_2": 20, "a_3": 20 }
+{ "a_0": 21, "a_1": 21, "a_2": 21, "a_3": 21 }
+{ "a_0": 22, "a_1": 22, "a_2": 22, "a_3": 22 }
+{ "a_0": 23, "a_1": 23, "a_2": 23, "a_3": 23 }
+{ "a_0": 24, "a_1": 24, "a_2": 24, "a_3": 24 }
+{ "a_0": 25, "a_1": 25, "a_2": 25, "a_3": 25 }
+{ "a_0": 26, "a_1": 26, "a_2": 26, "a_3": 26 }
+{ "a_0": 27, "a_1": 27, "a_2": 27, "a_3": 27 }
+{ "a_0": 28, "a_1": 28, "a_2": 28, "a_3": 28 }
+{ "a_0": 29, "a_1": 29, "a_2": 29, "a_3": 29 }
+{ "a_0": 30, "a_1": 30, "a_2": 30, "a_3": 30 }
+{ "a_0": 31, "a_1": 31, "a_2": 31, "a_3": 31 }
+{ "a_0": 32, "a_1": 32, "a_2": 32, "a_3": 32 }
+{ "a_0": 33, "a_1": 33, "a_2": 33, "a_3": 33 }
+{ "a_0": 34, "a_1": 34, "a_2": 34, "a_3": 34 }
+{ "a_0": 35, "a_1": 35, "a_2": 35, "a_3": 35 }
+{ "a_0": 36, "a_1": 36, "a_2": 36, "a_3": 36 }
+{ "a_0": 37, "a_1": 37, "a_2": 37, "a_3": 37 }
+{ "a_0": 38, "a_1": 38, "a_2": 38, "a_3": 38 }
+{ "a_0": 39, "a_1": 39, "a_2": 39, "a_3": 39 }
+{ "a_0": 40, "a_1": 40, "a_2": 40, "a_3": 40 }
+{ "a_0": 41, "a_1": 41, "a_2": 41, "a_3": 41 }
+{ "a_0": 42, "a_1": 42, "a_2": 42, "a_3": 42 }
+{ "a_0": 43, "a_1": 43, "a_2": 43, "a_3": 43 }
+{ "a_0": 44, "a_1": 44, "a_2": 44, "a_3": 44 }
+{ "a_0": 45, "a_1": 45, "a_2": 45, "a_3": 45 }
+{ "a_0": 46, "a_1": 46, "a_2": 46, "a_3": 46 }
+{ "a_0": 47, "a_1": 47, "a_2": 47, "a_3": 47 }
+{ "a_0": 48, "a_1": 48, "a_2": 48, "a_3": 48 }
+{ "a_0": 49, "a_1": 49, "a_2": 49, "a_3": 49 }
+{ "a_0": 50, "a_1": 50, "a_2": 50, "a_3": 50 }
+{ "a_0": 51, "a_1": 51, "a_2": 51, "a_3": 51, "b_3": 51 }
+{ "a_0": 52, "a_1": 52, "a_2": 52, "a_3": 52, "b_3": 52 }
+{ "a_0": 53, "a_1": 53, "a_2": 53, "a_3": 53, "b_3": 53 }
+{ "a_0": 54, "a_1": 54, "a_2": 54, "a_3": 54, "b_3": 54 }
+{ "a_0": 55, "a_1": 55, "a_2": 55, "a_3": 55, "b_3": 55 }
+{ "a_0": 56, "a_1": 56, "a_2": 56, "a_3": 56, "b_3": 56 }
+{ "a_0": 57, "a_1": 57, "a_2": 57, "a_3": 57, "b_3": 57 }
+{ "a_0": 58, "a_1": 58, "a_2": 58, "a_3": 58, "b_3": 58 }
+{ "a_0": 59, "a_1": 59, "a_2": 59, "a_3": 59, "b_3": 59 }
+{ "a_0": 60, "a_1": 60, "a_2": 60, "a_3": 60, "b_3": 60 }
+{ "a_0": 61, "a_1": 61, "a_2": 61, "a_3": 61, "b_3": 61 }
+{ "a_0": 62, "a_1": 62, "a_2": 62, "a_3": 62, "b_3": 62 }
+{ "a_0": 63, "a_1": 63, "a_2": 63, "a_3": 63, "b_3": 63 }
+{ "a_0": 64, "a_1": 64, "a_2": 64, "a_3": 64, "b_3": 64 }
+{ "a_0": 65, "a_1": 65, "a_2": 65, "a_3": 65, "b_3": 65 }
+{ "a_0": 66, "a_1": 66, "a_2": 66, "a_3": 66, "b_3": 66 }
+{ "a_0": 67, "a_1": 67, "a_2": 67, "a_3": 67, "b_3": 67 }
+{ "a_0": 68, "a_1": 68, "a_2": 68, "a_3": 68, "b_3": 68 }
+{ "a_0": 69, "a_1": 69, "a_2": 69, "a_3": 69, "b_3": 69 }
+{ "a_0": 70, "a_1": 70, "a_2": 70, "a_3": 70, "b_3": 70 }
+{ "a_0": 71, "a_1": 71, "a_2": 71, "a_3": 71, "b_3": 71 }
+{ "a_0": 72, "a_1": 72, "a_2": 72, "a_3": 72, "b_3": 72 }
+{ "a_0": 73, "a_1": 73, "a_2": 73, "a_3": 73, "b_3": 73 }
+{ "a_0": 74, "a_1": 74, "a_2": 74, "a_3": 74, "b_3": 74 }
+{ "a_0": 75, "a_1": 75, "a_2": 75, "a_3": 75, "b_3": 75 }
+{ "a_0": 76, "a_1": 76, "a_2": 76, "a_3": 76, "b_3": 76 }
+{ "a_0": 77, "a_1": 77, "a_2": 77, "a_3": 77, "b_3": 77 }
+{ "a_0": 78, "a_1": 78, "a_2": 78, "a_3": 78, "b_3": 78 }
+{ "a_0": 79, "a_1": 79, "a_2": 79, "a_3": 79, "b_3": 79 }
+{ "a_0": 80, "a_1": 80, "a_2": 80, "a_3": 80, "b_3": 80 }
+{ "a_0": 81, "a_1": 81, "a_2": 81, "a_3": 81, "b_3": 81 }
+{ "a_0": 82, "a_1": 82, "a_2": 82, "a_3": 82, "b_3": 82 }
+{ "a_0": 83, "a_1": 83, "a_2": 83, "a_3": 83, "b_3": 83 }
+{ "a_0": 84, "a_1": 84, "a_2": 84, "a_3": 84, "b_3": 84 }
+{ "a_0": 85, "a_1": 85, "a_2": 85, "a_3": 85, "b_3": 85 }
+{ "a_0": 86, "a_1": 86, "a_2": 86, "a_3": 86, "b_3": 86 }
+{ "a_0": 87, "a_1": 87, "a_2": 87, "a_3": 87, "b_3": 87 }
+{ "a_0": 88, "a_1": 88, "a_2": 88, "a_3": 88, "b_3": 88 }
+{ "a_0": 89, "a_1": 89, "a_2": 89, "a_3": 89, "b_3": 89 }
+{ "a_0": 90, "a_1": 90, "a_2": 90, "a_3": 90, "b_3": 90 }
+{ "a_0": 91, "a_1": 91, "a_2": 91, "a_3": 91, "b_3": 91 }
+{ "a_0": 92, "a_1": 92, "a_2": 92, "a_3": 92, "b_3": 92 }
+{ "a_0": 93, "a_1": 93, "a_2": 93, "a_3": 93, "b_3": 93 }
+{ "a_0": 94, "a_1": 94, "a_2": 94, "a_3": 94, "b_3": 94 }
+{ "a_0": 95, "a_1": 95, "a_2": 95, "a_3": 95, "b_3": 95 }
+{ "a_0": 96, "a_1": 96, "a_2": 96, "a_3": 96, "b_3": 96 }
+{ "a_0": 97, "a_1": 97, "a_2": 97, "a_3": 97, "b_3": 97 }
+{ "a_0": 98, "a_1": 98, "a_2": 98, "a_3": 98, "b_3": 98 }
+{ "a_0": 99, "a_1": 99, "a_2": 99, "a_3": 99, "b_3": 99 }
+{ "a_0": 100, "a_1": 100, "a_2": 100, "a_3": 100, "b_3": 100 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.12.adm
new file mode 100644
index 0000000..497b339
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.12.adm
@@ -0,0 +1,100 @@
+{ "a_0": 1, "a_1": 1, "a_2": 1, "a_3": 1 }
+{ "a_0": 2, "a_1": 2, "a_2": 2, "a_3": 2 }
+{ "a_0": 3, "a_1": 3, "a_2": 3, "a_3": 3 }
+{ "a_0": 4, "a_1": 4, "a_2": 4, "a_3": 4 }
+{ "a_0": 5, "a_1": 5, "a_2": 5, "a_3": 5 }
+{ "a_0": 6, "a_1": 6, "a_2": 6, "a_3": 6 }
+{ "a_0": 7, "a_1": 7, "a_2": 7, "a_3": 7 }
+{ "a_0": 8, "a_1": 8, "a_2": 8, "a_3": 8 }
+{ "a_0": 9, "a_1": 9, "a_2": 9, "a_3": 9 }
+{ "a_0": 10, "a_1": 10, "a_2": 10, "a_3": 10 }
+{ "a_0": 11, "a_1": 11, "a_2": 11, "a_3": 11 }
+{ "a_0": 12, "a_1": 12, "a_2": 12, "a_3": 12 }
+{ "a_0": 13, "a_1": 13, "a_2": 13, "a_3": 13 }
+{ "a_0": 14, "a_1": 14, "a_2": 14, "a_3": 14 }
+{ "a_0": 15, "a_1": 15, "a_2": 15, "a_3": 15 }
+{ "a_0": 16, "a_1": 16, "a_2": 16, "a_3": 16 }
+{ "a_0": 17, "a_1": 17, "a_2": 17, "a_3": 17 }
+{ "a_0": 18, "a_1": 18, "a_2": 18, "a_3": 18 }
+{ "a_0": 19, "a_1": 19, "a_2": 19, "a_3": 19 }
+{ "a_0": 20, "a_1": 20, "a_2": 20, "a_3": 20 }
+{ "a_0": 21, "a_1": 21, "a_2": 21, "a_3": 21 }
+{ "a_0": 22, "a_1": 22, "a_2": 22, "a_3": 22 }
+{ "a_0": 23, "a_1": 23, "a_2": 23, "a_3": 23 }
+{ "a_0": 24, "a_1": 24, "a_2": 24, "a_3": 24 }
+{ "a_0": 25, "a_1": 25, "a_2": 25, "a_3": 25 }
+{ "a_0": 26, "a_1": 26, "a_2": 26, "a_3": 26 }
+{ "a_0": 27, "a_1": 27, "a_2": 27, "a_3": 27 }
+{ "a_0": 28, "a_1": 28, "a_2": 28, "a_3": 28 }
+{ "a_0": 29, "a_1": 29, "a_2": 29, "a_3": 29 }
+{ "a_0": 30, "a_1": 30, "a_2": 30, "a_3": 30 }
+{ "a_0": 31, "a_1": 31, "a_2": 31, "a_3": 31 }
+{ "a_0": 32, "a_1": 32, "a_2": 32, "a_3": 32 }
+{ "a_0": 33, "a_1": 33, "a_2": 33, "a_3": 33 }
+{ "a_0": 34, "a_1": 34, "a_2": 34, "a_3": 34 }
+{ "a_0": 35, "a_1": 35, "a_2": 35, "a_3": 35 }
+{ "a_0": 36, "a_1": 36, "a_2": 36, "a_3": 36 }
+{ "a_0": 37, "a_1": 37, "a_2": 37, "a_3": 37 }
+{ "a_0": 38, "a_1": 38, "a_2": 38, "a_3": 38 }
+{ "a_0": 39, "a_1": 39, "a_2": 39, "a_3": 39 }
+{ "a_0": 40, "a_1": 40, "a_2": 40, "a_3": 40 }
+{ "a_0": 41, "a_1": 41, "a_2": 41, "a_3": 41 }
+{ "a_0": 42, "a_1": 42, "a_2": 42, "a_3": 42 }
+{ "a_0": 43, "a_1": 43, "a_2": 43, "a_3": 43 }
+{ "a_0": 44, "a_1": 44, "a_2": 44, "a_3": 44 }
+{ "a_0": 45, "a_1": 45, "a_2": 45, "a_3": 45 }
+{ "a_0": 46, "a_1": 46, "a_2": 46, "a_3": 46 }
+{ "a_0": 47, "a_1": 47, "a_2": 47, "a_3": 47 }
+{ "a_0": 48, "a_1": 48, "a_2": 48, "a_3": 48 }
+{ "a_0": 49, "a_1": 49, "a_2": 49, "a_3": 49 }
+{ "a_0": 50, "a_1": 50, "a_2": 50, "a_3": 50 }
+{ "a_0": 51, "a_1": 51, "a_2": 51, "a_3": 51, "b_3": 51 }
+{ "a_0": 52, "a_1": 52, "a_2": 52, "a_3": 52, "b_3": 52 }
+{ "a_0": 53, "a_1": 53, "a_2": 53, "a_3": 53, "b_3": 53 }
+{ "a_0": 54, "a_1": 54, "a_2": 54, "a_3": 54, "b_3": 54 }
+{ "a_0": 55, "a_1": 55, "a_2": 55, "a_3": 55, "b_3": 55 }
+{ "a_0": 56, "a_1": 56, "a_2": 56, "a_3": 56, "b_3": 56 }
+{ "a_0": 57, "a_1": 57, "a_2": 57, "a_3": 57, "b_3": 57 }
+{ "a_0": 58, "a_1": 58, "a_2": 58, "a_3": 58, "b_3": 58 }
+{ "a_0": 59, "a_1": 59, "a_2": 59, "a_3": 59, "b_3": 59 }
+{ "a_0": 60, "a_1": 60, "a_2": 60, "a_3": 60, "b_3": 60 }
+{ "a_0": 61, "a_1": 61, "a_2": 61, "a_3": 61, "b_3": 61 }
+{ "a_0": 62, "a_1": 62, "a_2": 62, "a_3": 62, "b_3": 62 }
+{ "a_0": 63, "a_1": 63, "a_2": 63, "a_3": 63, "b_3": 63 }
+{ "a_0": 64, "a_1": 64, "a_2": 64, "a_3": 64, "b_3": 64 }
+{ "a_0": 65, "a_1": 65, "a_2": 65, "a_3": 65, "b_3": 65 }
+{ "a_0": 66, "a_1": 66, "a_2": 66, "a_3": 66, "b_3": 66 }
+{ "a_0": 67, "a_1": 67, "a_2": 67, "a_3": 67, "b_3": 67 }
+{ "a_0": 68, "a_1": 68, "a_2": 68, "a_3": 68, "b_3": 68 }
+{ "a_0": 69, "a_1": 69, "a_2": 69, "a_3": 69, "b_3": 69 }
+{ "a_0": 70, "a_1": 70, "a_2": 70, "a_3": 70, "b_3": 70 }
+{ "a_0": 71, "a_1": 71, "a_2": 71, "a_3": 71, "b_3": 71 }
+{ "a_0": 72, "a_1": 72, "a_2": 72, "a_3": 72, "b_3": 72 }
+{ "a_0": 73, "a_1": 73, "a_2": 73, "a_3": 73, "b_3": 73 }
+{ "a_0": 74, "a_1": 74, "a_2": 74, "a_3": 74, "b_3": 74 }
+{ "a_0": 75, "a_1": 75, "a_2": 75, "a_3": 75, "b_3": 75 }
+{ "a_0": 76, "a_1": 76, "a_2": 76, "a_3": 76, "b_3": 76 }
+{ "a_0": 77, "a_1": 77, "a_2": 77, "a_3": 77, "b_3": 77 }
+{ "a_0": 78, "a_1": 78, "a_2": 78, "a_3": 78, "b_3": 78 }
+{ "a_0": 79, "a_1": 79, "a_2": 79, "a_3": 79, "b_3": 79 }
+{ "a_0": 80, "a_1": 80, "a_2": 80, "a_3": 80, "b_3": 80 }
+{ "a_0": 81, "a_1": 81, "a_2": 81, "a_3": 81, "b_3": 81 }
+{ "a_0": 82, "a_1": 82, "a_2": 82, "a_3": 82, "b_3": 82 }
+{ "a_0": 83, "a_1": 83, "a_2": 83, "a_3": 83, "b_3": 83 }
+{ "a_0": 84, "a_1": 84, "a_2": 84, "a_3": 84, "b_3": 84 }
+{ "a_0": 85, "a_1": 85, "a_2": 85, "a_3": 85, "b_3": 85 }
+{ "a_0": 86, "a_1": 86, "a_2": 86, "a_3": 86, "b_3": 86 }
+{ "a_0": 87, "a_1": 87, "a_2": 87, "a_3": 87, "b_3": 87 }
+{ "a_0": 88, "a_1": 88, "a_2": 88, "a_3": 88, "b_3": 88 }
+{ "a_0": 89, "a_1": 89, "a_2": 89, "a_3": 89, "b_3": 89 }
+{ "a_0": 90, "a_1": 90, "a_2": 90, "a_3": 90, "b_3": 90 }
+{ "a_0": 91, "a_1": 91, "a_2": 91, "a_3": 91, "b_3": 91 }
+{ "a_0": 92, "a_1": 92, "a_2": 92, "a_3": 92, "b_3": 92 }
+{ "a_0": 93, "a_1": 93, "a_2": 93, "a_3": 93, "b_3": 93 }
+{ "a_0": 94, "a_1": 94, "a_2": 94, "a_3": 94, "b_3": 94 }
+{ "a_0": 95, "a_1": 95, "a_2": 95, "a_3": 95, "b_3": 95 }
+{ "a_0": 96, "a_1": 96, "a_2": 96, "a_3": 96, "b_3": 96 }
+{ "a_0": 97, "a_1": 97, "a_2": 97, "a_3": 97, "b_3": 97 }
+{ "a_0": 98, "a_1": 98, "a_2": 98, "a_3": 98, "b_3": 98 }
+{ "a_0": 99, "a_1": 99, "a_2": 99, "a_3": 99, "b_3": 99 }
+{ "a_0": 100, "a_1": 100, "a_2": 100, "a_3": 100, "b_3": 100 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.4.adm
new file mode 100644
index 0000000..497b339
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.4.adm
@@ -0,0 +1,100 @@
+{ "a_0": 1, "a_1": 1, "a_2": 1, "a_3": 1 }
+{ "a_0": 2, "a_1": 2, "a_2": 2, "a_3": 2 }
+{ "a_0": 3, "a_1": 3, "a_2": 3, "a_3": 3 }
+{ "a_0": 4, "a_1": 4, "a_2": 4, "a_3": 4 }
+{ "a_0": 5, "a_1": 5, "a_2": 5, "a_3": 5 }
+{ "a_0": 6, "a_1": 6, "a_2": 6, "a_3": 6 }
+{ "a_0": 7, "a_1": 7, "a_2": 7, "a_3": 7 }
+{ "a_0": 8, "a_1": 8, "a_2": 8, "a_3": 8 }
+{ "a_0": 9, "a_1": 9, "a_2": 9, "a_3": 9 }
+{ "a_0": 10, "a_1": 10, "a_2": 10, "a_3": 10 }
+{ "a_0": 11, "a_1": 11, "a_2": 11, "a_3": 11 }
+{ "a_0": 12, "a_1": 12, "a_2": 12, "a_3": 12 }
+{ "a_0": 13, "a_1": 13, "a_2": 13, "a_3": 13 }
+{ "a_0": 14, "a_1": 14, "a_2": 14, "a_3": 14 }
+{ "a_0": 15, "a_1": 15, "a_2": 15, "a_3": 15 }
+{ "a_0": 16, "a_1": 16, "a_2": 16, "a_3": 16 }
+{ "a_0": 17, "a_1": 17, "a_2": 17, "a_3": 17 }
+{ "a_0": 18, "a_1": 18, "a_2": 18, "a_3": 18 }
+{ "a_0": 19, "a_1": 19, "a_2": 19, "a_3": 19 }
+{ "a_0": 20, "a_1": 20, "a_2": 20, "a_3": 20 }
+{ "a_0": 21, "a_1": 21, "a_2": 21, "a_3": 21 }
+{ "a_0": 22, "a_1": 22, "a_2": 22, "a_3": 22 }
+{ "a_0": 23, "a_1": 23, "a_2": 23, "a_3": 23 }
+{ "a_0": 24, "a_1": 24, "a_2": 24, "a_3": 24 }
+{ "a_0": 25, "a_1": 25, "a_2": 25, "a_3": 25 }
+{ "a_0": 26, "a_1": 26, "a_2": 26, "a_3": 26 }
+{ "a_0": 27, "a_1": 27, "a_2": 27, "a_3": 27 }
+{ "a_0": 28, "a_1": 28, "a_2": 28, "a_3": 28 }
+{ "a_0": 29, "a_1": 29, "a_2": 29, "a_3": 29 }
+{ "a_0": 30, "a_1": 30, "a_2": 30, "a_3": 30 }
+{ "a_0": 31, "a_1": 31, "a_2": 31, "a_3": 31 }
+{ "a_0": 32, "a_1": 32, "a_2": 32, "a_3": 32 }
+{ "a_0": 33, "a_1": 33, "a_2": 33, "a_3": 33 }
+{ "a_0": 34, "a_1": 34, "a_2": 34, "a_3": 34 }
+{ "a_0": 35, "a_1": 35, "a_2": 35, "a_3": 35 }
+{ "a_0": 36, "a_1": 36, "a_2": 36, "a_3": 36 }
+{ "a_0": 37, "a_1": 37, "a_2": 37, "a_3": 37 }
+{ "a_0": 38, "a_1": 38, "a_2": 38, "a_3": 38 }
+{ "a_0": 39, "a_1": 39, "a_2": 39, "a_3": 39 }
+{ "a_0": 40, "a_1": 40, "a_2": 40, "a_3": 40 }
+{ "a_0": 41, "a_1": 41, "a_2": 41, "a_3": 41 }
+{ "a_0": 42, "a_1": 42, "a_2": 42, "a_3": 42 }
+{ "a_0": 43, "a_1": 43, "a_2": 43, "a_3": 43 }
+{ "a_0": 44, "a_1": 44, "a_2": 44, "a_3": 44 }
+{ "a_0": 45, "a_1": 45, "a_2": 45, "a_3": 45 }
+{ "a_0": 46, "a_1": 46, "a_2": 46, "a_3": 46 }
+{ "a_0": 47, "a_1": 47, "a_2": 47, "a_3": 47 }
+{ "a_0": 48, "a_1": 48, "a_2": 48, "a_3": 48 }
+{ "a_0": 49, "a_1": 49, "a_2": 49, "a_3": 49 }
+{ "a_0": 50, "a_1": 50, "a_2": 50, "a_3": 50 }
+{ "a_0": 51, "a_1": 51, "a_2": 51, "a_3": 51, "b_3": 51 }
+{ "a_0": 52, "a_1": 52, "a_2": 52, "a_3": 52, "b_3": 52 }
+{ "a_0": 53, "a_1": 53, "a_2": 53, "a_3": 53, "b_3": 53 }
+{ "a_0": 54, "a_1": 54, "a_2": 54, "a_3": 54, "b_3": 54 }
+{ "a_0": 55, "a_1": 55, "a_2": 55, "a_3": 55, "b_3": 55 }
+{ "a_0": 56, "a_1": 56, "a_2": 56, "a_3": 56, "b_3": 56 }
+{ "a_0": 57, "a_1": 57, "a_2": 57, "a_3": 57, "b_3": 57 }
+{ "a_0": 58, "a_1": 58, "a_2": 58, "a_3": 58, "b_3": 58 }
+{ "a_0": 59, "a_1": 59, "a_2": 59, "a_3": 59, "b_3": 59 }
+{ "a_0": 60, "a_1": 60, "a_2": 60, "a_3": 60, "b_3": 60 }
+{ "a_0": 61, "a_1": 61, "a_2": 61, "a_3": 61, "b_3": 61 }
+{ "a_0": 62, "a_1": 62, "a_2": 62, "a_3": 62, "b_3": 62 }
+{ "a_0": 63, "a_1": 63, "a_2": 63, "a_3": 63, "b_3": 63 }
+{ "a_0": 64, "a_1": 64, "a_2": 64, "a_3": 64, "b_3": 64 }
+{ "a_0": 65, "a_1": 65, "a_2": 65, "a_3": 65, "b_3": 65 }
+{ "a_0": 66, "a_1": 66, "a_2": 66, "a_3": 66, "b_3": 66 }
+{ "a_0": 67, "a_1": 67, "a_2": 67, "a_3": 67, "b_3": 67 }
+{ "a_0": 68, "a_1": 68, "a_2": 68, "a_3": 68, "b_3": 68 }
+{ "a_0": 69, "a_1": 69, "a_2": 69, "a_3": 69, "b_3": 69 }
+{ "a_0": 70, "a_1": 70, "a_2": 70, "a_3": 70, "b_3": 70 }
+{ "a_0": 71, "a_1": 71, "a_2": 71, "a_3": 71, "b_3": 71 }
+{ "a_0": 72, "a_1": 72, "a_2": 72, "a_3": 72, "b_3": 72 }
+{ "a_0": 73, "a_1": 73, "a_2": 73, "a_3": 73, "b_3": 73 }
+{ "a_0": 74, "a_1": 74, "a_2": 74, "a_3": 74, "b_3": 74 }
+{ "a_0": 75, "a_1": 75, "a_2": 75, "a_3": 75, "b_3": 75 }
+{ "a_0": 76, "a_1": 76, "a_2": 76, "a_3": 76, "b_3": 76 }
+{ "a_0": 77, "a_1": 77, "a_2": 77, "a_3": 77, "b_3": 77 }
+{ "a_0": 78, "a_1": 78, "a_2": 78, "a_3": 78, "b_3": 78 }
+{ "a_0": 79, "a_1": 79, "a_2": 79, "a_3": 79, "b_3": 79 }
+{ "a_0": 80, "a_1": 80, "a_2": 80, "a_3": 80, "b_3": 80 }
+{ "a_0": 81, "a_1": 81, "a_2": 81, "a_3": 81, "b_3": 81 }
+{ "a_0": 82, "a_1": 82, "a_2": 82, "a_3": 82, "b_3": 82 }
+{ "a_0": 83, "a_1": 83, "a_2": 83, "a_3": 83, "b_3": 83 }
+{ "a_0": 84, "a_1": 84, "a_2": 84, "a_3": 84, "b_3": 84 }
+{ "a_0": 85, "a_1": 85, "a_2": 85, "a_3": 85, "b_3": 85 }
+{ "a_0": 86, "a_1": 86, "a_2": 86, "a_3": 86, "b_3": 86 }
+{ "a_0": 87, "a_1": 87, "a_2": 87, "a_3": 87, "b_3": 87 }
+{ "a_0": 88, "a_1": 88, "a_2": 88, "a_3": 88, "b_3": 88 }
+{ "a_0": 89, "a_1": 89, "a_2": 89, "a_3": 89, "b_3": 89 }
+{ "a_0": 90, "a_1": 90, "a_2": 90, "a_3": 90, "b_3": 90 }
+{ "a_0": 91, "a_1": 91, "a_2": 91, "a_3": 91, "b_3": 91 }
+{ "a_0": 92, "a_1": 92, "a_2": 92, "a_3": 92, "b_3": 92 }
+{ "a_0": 93, "a_1": 93, "a_2": 93, "a_3": 93, "b_3": 93 }
+{ "a_0": 94, "a_1": 94, "a_2": 94, "a_3": 94, "b_3": 94 }
+{ "a_0": 95, "a_1": 95, "a_2": 95, "a_3": 95, "b_3": 95 }
+{ "a_0": 96, "a_1": 96, "a_2": 96, "a_3": 96, "b_3": 96 }
+{ "a_0": 97, "a_1": 97, "a_2": 97, "a_3": 97, "b_3": 97 }
+{ "a_0": 98, "a_1": 98, "a_2": 98, "a_3": 98, "b_3": 98 }
+{ "a_0": 99, "a_1": 99, "a_2": 99, "a_3": 99, "b_3": 99 }
+{ "a_0": 100, "a_1": 100, "a_2": 100, "a_3": 100, "b_3": 100 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.6.adm
new file mode 100644
index 0000000..497b339
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.6.adm
@@ -0,0 +1,100 @@
+{ "a_0": 1, "a_1": 1, "a_2": 1, "a_3": 1 }
+{ "a_0": 2, "a_1": 2, "a_2": 2, "a_3": 2 }
+{ "a_0": 3, "a_1": 3, "a_2": 3, "a_3": 3 }
+{ "a_0": 4, "a_1": 4, "a_2": 4, "a_3": 4 }
+{ "a_0": 5, "a_1": 5, "a_2": 5, "a_3": 5 }
+{ "a_0": 6, "a_1": 6, "a_2": 6, "a_3": 6 }
+{ "a_0": 7, "a_1": 7, "a_2": 7, "a_3": 7 }
+{ "a_0": 8, "a_1": 8, "a_2": 8, "a_3": 8 }
+{ "a_0": 9, "a_1": 9, "a_2": 9, "a_3": 9 }
+{ "a_0": 10, "a_1": 10, "a_2": 10, "a_3": 10 }
+{ "a_0": 11, "a_1": 11, "a_2": 11, "a_3": 11 }
+{ "a_0": 12, "a_1": 12, "a_2": 12, "a_3": 12 }
+{ "a_0": 13, "a_1": 13, "a_2": 13, "a_3": 13 }
+{ "a_0": 14, "a_1": 14, "a_2": 14, "a_3": 14 }
+{ "a_0": 15, "a_1": 15, "a_2": 15, "a_3": 15 }
+{ "a_0": 16, "a_1": 16, "a_2": 16, "a_3": 16 }
+{ "a_0": 17, "a_1": 17, "a_2": 17, "a_3": 17 }
+{ "a_0": 18, "a_1": 18, "a_2": 18, "a_3": 18 }
+{ "a_0": 19, "a_1": 19, "a_2": 19, "a_3": 19 }
+{ "a_0": 20, "a_1": 20, "a_2": 20, "a_3": 20 }
+{ "a_0": 21, "a_1": 21, "a_2": 21, "a_3": 21 }
+{ "a_0": 22, "a_1": 22, "a_2": 22, "a_3": 22 }
+{ "a_0": 23, "a_1": 23, "a_2": 23, "a_3": 23 }
+{ "a_0": 24, "a_1": 24, "a_2": 24, "a_3": 24 }
+{ "a_0": 25, "a_1": 25, "a_2": 25, "a_3": 25 }
+{ "a_0": 26, "a_1": 26, "a_2": 26, "a_3": 26 }
+{ "a_0": 27, "a_1": 27, "a_2": 27, "a_3": 27 }
+{ "a_0": 28, "a_1": 28, "a_2": 28, "a_3": 28 }
+{ "a_0": 29, "a_1": 29, "a_2": 29, "a_3": 29 }
+{ "a_0": 30, "a_1": 30, "a_2": 30, "a_3": 30 }
+{ "a_0": 31, "a_1": 31, "a_2": 31, "a_3": 31 }
+{ "a_0": 32, "a_1": 32, "a_2": 32, "a_3": 32 }
+{ "a_0": 33, "a_1": 33, "a_2": 33, "a_3": 33 }
+{ "a_0": 34, "a_1": 34, "a_2": 34, "a_3": 34 }
+{ "a_0": 35, "a_1": 35, "a_2": 35, "a_3": 35 }
+{ "a_0": 36, "a_1": 36, "a_2": 36, "a_3": 36 }
+{ "a_0": 37, "a_1": 37, "a_2": 37, "a_3": 37 }
+{ "a_0": 38, "a_1": 38, "a_2": 38, "a_3": 38 }
+{ "a_0": 39, "a_1": 39, "a_2": 39, "a_3": 39 }
+{ "a_0": 40, "a_1": 40, "a_2": 40, "a_3": 40 }
+{ "a_0": 41, "a_1": 41, "a_2": 41, "a_3": 41 }
+{ "a_0": 42, "a_1": 42, "a_2": 42, "a_3": 42 }
+{ "a_0": 43, "a_1": 43, "a_2": 43, "a_3": 43 }
+{ "a_0": 44, "a_1": 44, "a_2": 44, "a_3": 44 }
+{ "a_0": 45, "a_1": 45, "a_2": 45, "a_3": 45 }
+{ "a_0": 46, "a_1": 46, "a_2": 46, "a_3": 46 }
+{ "a_0": 47, "a_1": 47, "a_2": 47, "a_3": 47 }
+{ "a_0": 48, "a_1": 48, "a_2": 48, "a_3": 48 }
+{ "a_0": 49, "a_1": 49, "a_2": 49, "a_3": 49 }
+{ "a_0": 50, "a_1": 50, "a_2": 50, "a_3": 50 }
+{ "a_0": 51, "a_1": 51, "a_2": 51, "a_3": 51, "b_3": 51 }
+{ "a_0": 52, "a_1": 52, "a_2": 52, "a_3": 52, "b_3": 52 }
+{ "a_0": 53, "a_1": 53, "a_2": 53, "a_3": 53, "b_3": 53 }
+{ "a_0": 54, "a_1": 54, "a_2": 54, "a_3": 54, "b_3": 54 }
+{ "a_0": 55, "a_1": 55, "a_2": 55, "a_3": 55, "b_3": 55 }
+{ "a_0": 56, "a_1": 56, "a_2": 56, "a_3": 56, "b_3": 56 }
+{ "a_0": 57, "a_1": 57, "a_2": 57, "a_3": 57, "b_3": 57 }
+{ "a_0": 58, "a_1": 58, "a_2": 58, "a_3": 58, "b_3": 58 }
+{ "a_0": 59, "a_1": 59, "a_2": 59, "a_3": 59, "b_3": 59 }
+{ "a_0": 60, "a_1": 60, "a_2": 60, "a_3": 60, "b_3": 60 }
+{ "a_0": 61, "a_1": 61, "a_2": 61, "a_3": 61, "b_3": 61 }
+{ "a_0": 62, "a_1": 62, "a_2": 62, "a_3": 62, "b_3": 62 }
+{ "a_0": 63, "a_1": 63, "a_2": 63, "a_3": 63, "b_3": 63 }
+{ "a_0": 64, "a_1": 64, "a_2": 64, "a_3": 64, "b_3": 64 }
+{ "a_0": 65, "a_1": 65, "a_2": 65, "a_3": 65, "b_3": 65 }
+{ "a_0": 66, "a_1": 66, "a_2": 66, "a_3": 66, "b_3": 66 }
+{ "a_0": 67, "a_1": 67, "a_2": 67, "a_3": 67, "b_3": 67 }
+{ "a_0": 68, "a_1": 68, "a_2": 68, "a_3": 68, "b_3": 68 }
+{ "a_0": 69, "a_1": 69, "a_2": 69, "a_3": 69, "b_3": 69 }
+{ "a_0": 70, "a_1": 70, "a_2": 70, "a_3": 70, "b_3": 70 }
+{ "a_0": 71, "a_1": 71, "a_2": 71, "a_3": 71, "b_3": 71 }
+{ "a_0": 72, "a_1": 72, "a_2": 72, "a_3": 72, "b_3": 72 }
+{ "a_0": 73, "a_1": 73, "a_2": 73, "a_3": 73, "b_3": 73 }
+{ "a_0": 74, "a_1": 74, "a_2": 74, "a_3": 74, "b_3": 74 }
+{ "a_0": 75, "a_1": 75, "a_2": 75, "a_3": 75, "b_3": 75 }
+{ "a_0": 76, "a_1": 76, "a_2": 76, "a_3": 76, "b_3": 76 }
+{ "a_0": 77, "a_1": 77, "a_2": 77, "a_3": 77, "b_3": 77 }
+{ "a_0": 78, "a_1": 78, "a_2": 78, "a_3": 78, "b_3": 78 }
+{ "a_0": 79, "a_1": 79, "a_2": 79, "a_3": 79, "b_3": 79 }
+{ "a_0": 80, "a_1": 80, "a_2": 80, "a_3": 80, "b_3": 80 }
+{ "a_0": 81, "a_1": 81, "a_2": 81, "a_3": 81, "b_3": 81 }
+{ "a_0": 82, "a_1": 82, "a_2": 82, "a_3": 82, "b_3": 82 }
+{ "a_0": 83, "a_1": 83, "a_2": 83, "a_3": 83, "b_3": 83 }
+{ "a_0": 84, "a_1": 84, "a_2": 84, "a_3": 84, "b_3": 84 }
+{ "a_0": 85, "a_1": 85, "a_2": 85, "a_3": 85, "b_3": 85 }
+{ "a_0": 86, "a_1": 86, "a_2": 86, "a_3": 86, "b_3": 86 }
+{ "a_0": 87, "a_1": 87, "a_2": 87, "a_3": 87, "b_3": 87 }
+{ "a_0": 88, "a_1": 88, "a_2": 88, "a_3": 88, "b_3": 88 }
+{ "a_0": 89, "a_1": 89, "a_2": 89, "a_3": 89, "b_3": 89 }
+{ "a_0": 90, "a_1": 90, "a_2": 90, "a_3": 90, "b_3": 90 }
+{ "a_0": 91, "a_1": 91, "a_2": 91, "a_3": 91, "b_3": 91 }
+{ "a_0": 92, "a_1": 92, "a_2": 92, "a_3": 92, "b_3": 92 }
+{ "a_0": 93, "a_1": 93, "a_2": 93, "a_3": 93, "b_3": 93 }
+{ "a_0": 94, "a_1": 94, "a_2": 94, "a_3": 94, "b_3": 94 }
+{ "a_0": 95, "a_1": 95, "a_2": 95, "a_3": 95, "b_3": 95 }
+{ "a_0": 96, "a_1": 96, "a_2": 96, "a_3": 96, "b_3": 96 }
+{ "a_0": 97, "a_1": 97, "a_2": 97, "a_3": 97, "b_3": 97 }
+{ "a_0": 98, "a_1": 98, "a_2": 98, "a_3": 98, "b_3": 98 }
+{ "a_0": 99, "a_1": 99, "a_2": 99, "a_3": 99, "b_3": 99 }
+{ "a_0": 100, "a_1": 100, "a_2": 100, "a_3": 100, "b_3": 100 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.8.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.8.adm
new file mode 100644
index 0000000..497b339
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/join/hash_join_exchange_1/hash_join_exchange_1.8.adm
@@ -0,0 +1,100 @@
+{ "a_0": 1, "a_1": 1, "a_2": 1, "a_3": 1 }
+{ "a_0": 2, "a_1": 2, "a_2": 2, "a_3": 2 }
+{ "a_0": 3, "a_1": 3, "a_2": 3, "a_3": 3 }
+{ "a_0": 4, "a_1": 4, "a_2": 4, "a_3": 4 }
+{ "a_0": 5, "a_1": 5, "a_2": 5, "a_3": 5 }
+{ "a_0": 6, "a_1": 6, "a_2": 6, "a_3": 6 }
+{ "a_0": 7, "a_1": 7, "a_2": 7, "a_3": 7 }
+{ "a_0": 8, "a_1": 8, "a_2": 8, "a_3": 8 }
+{ "a_0": 9, "a_1": 9, "a_2": 9, "a_3": 9 }
+{ "a_0": 10, "a_1": 10, "a_2": 10, "a_3": 10 }
+{ "a_0": 11, "a_1": 11, "a_2": 11, "a_3": 11 }
+{ "a_0": 12, "a_1": 12, "a_2": 12, "a_3": 12 }
+{ "a_0": 13, "a_1": 13, "a_2": 13, "a_3": 13 }
+{ "a_0": 14, "a_1": 14, "a_2": 14, "a_3": 14 }
+{ "a_0": 15, "a_1": 15, "a_2": 15, "a_3": 15 }
+{ "a_0": 16, "a_1": 16, "a_2": 16, "a_3": 16 }
+{ "a_0": 17, "a_1": 17, "a_2": 17, "a_3": 17 }
+{ "a_0": 18, "a_1": 18, "a_2": 18, "a_3": 18 }
+{ "a_0": 19, "a_1": 19, "a_2": 19, "a_3": 19 }
+{ "a_0": 20, "a_1": 20, "a_2": 20, "a_3": 20 }
+{ "a_0": 21, "a_1": 21, "a_2": 21, "a_3": 21 }
+{ "a_0": 22, "a_1": 22, "a_2": 22, "a_3": 22 }
+{ "a_0": 23, "a_1": 23, "a_2": 23, "a_3": 23 }
+{ "a_0": 24, "a_1": 24, "a_2": 24, "a_3": 24 }
+{ "a_0": 25, "a_1": 25, "a_2": 25, "a_3": 25 }
+{ "a_0": 26, "a_1": 26, "a_2": 26, "a_3": 26 }
+{ "a_0": 27, "a_1": 27, "a_2": 27, "a_3": 27 }
+{ "a_0": 28, "a_1": 28, "a_2": 28, "a_3": 28 }
+{ "a_0": 29, "a_1": 29, "a_2": 29, "a_3": 29 }
+{ "a_0": 30, "a_1": 30, "a_2": 30, "a_3": 30 }
+{ "a_0": 31, "a_1": 31, "a_2": 31, "a_3": 31 }
+{ "a_0": 32, "a_1": 32, "a_2": 32, "a_3": 32 }
+{ "a_0": 33, "a_1": 33, "a_2": 33, "a_3": 33 }
+{ "a_0": 34, "a_1": 34, "a_2": 34, "a_3": 34 }
+{ "a_0": 35, "a_1": 35, "a_2": 35, "a_3": 35 }
+{ "a_0": 36, "a_1": 36, "a_2": 36, "a_3": 36 }
+{ "a_0": 37, "a_1": 37, "a_2": 37, "a_3": 37 }
+{ "a_0": 38, "a_1": 38, "a_2": 38, "a_3": 38 }
+{ "a_0": 39, "a_1": 39, "a_2": 39, "a_3": 39 }
+{ "a_0": 40, "a_1": 40, "a_2": 40, "a_3": 40 }
+{ "a_0": 41, "a_1": 41, "a_2": 41, "a_3": 41 }
+{ "a_0": 42, "a_1": 42, "a_2": 42, "a_3": 42 }
+{ "a_0": 43, "a_1": 43, "a_2": 43, "a_3": 43 }
+{ "a_0": 44, "a_1": 44, "a_2": 44, "a_3": 44 }
+{ "a_0": 45, "a_1": 45, "a_2": 45, "a_3": 45 }
+{ "a_0": 46, "a_1": 46, "a_2": 46, "a_3": 46 }
+{ "a_0": 47, "a_1": 47, "a_2": 47, "a_3": 47 }
+{ "a_0": 48, "a_1": 48, "a_2": 48, "a_3": 48 }
+{ "a_0": 49, "a_1": 49, "a_2": 49, "a_3": 49 }
+{ "a_0": 50, "a_1": 50, "a_2": 50, "a_3": 50 }
+{ "a_0": 51, "a_1": 51, "a_2": 51, "a_3": 51, "b_3": 51 }
+{ "a_0": 52, "a_1": 52, "a_2": 52, "a_3": 52, "b_3": 52 }
+{ "a_0": 53, "a_1": 53, "a_2": 53, "a_3": 53, "b_3": 53 }
+{ "a_0": 54, "a_1": 54, "a_2": 54, "a_3": 54, "b_3": 54 }
+{ "a_0": 55, "a_1": 55, "a_2": 55, "a_3": 55, "b_3": 55 }
+{ "a_0": 56, "a_1": 56, "a_2": 56, "a_3": 56, "b_3": 56 }
+{ "a_0": 57, "a_1": 57, "a_2": 57, "a_3": 57, "b_3": 57 }
+{ "a_0": 58, "a_1": 58, "a_2": 58, "a_3": 58, "b_3": 58 }
+{ "a_0": 59, "a_1": 59, "a_2": 59, "a_3": 59, "b_3": 59 }
+{ "a_0": 60, "a_1": 60, "a_2": 60, "a_3": 60, "b_3": 60 }
+{ "a_0": 61, "a_1": 61, "a_2": 61, "a_3": 61, "b_3": 61 }
+{ "a_0": 62, "a_1": 62, "a_2": 62, "a_3": 62, "b_3": 62 }
+{ "a_0": 63, "a_1": 63, "a_2": 63, "a_3": 63, "b_3": 63 }
+{ "a_0": 64, "a_1": 64, "a_2": 64, "a_3": 64, "b_3": 64 }
+{ "a_0": 65, "a_1": 65, "a_2": 65, "a_3": 65, "b_3": 65 }
+{ "a_0": 66, "a_1": 66, "a_2": 66, "a_3": 66, "b_3": 66 }
+{ "a_0": 67, "a_1": 67, "a_2": 67, "a_3": 67, "b_3": 67 }
+{ "a_0": 68, "a_1": 68, "a_2": 68, "a_3": 68, "b_3": 68 }
+{ "a_0": 69, "a_1": 69, "a_2": 69, "a_3": 69, "b_3": 69 }
+{ "a_0": 70, "a_1": 70, "a_2": 70, "a_3": 70, "b_3": 70 }
+{ "a_0": 71, "a_1": 71, "a_2": 71, "a_3": 71, "b_3": 71 }
+{ "a_0": 72, "a_1": 72, "a_2": 72, "a_3": 72, "b_3": 72 }
+{ "a_0": 73, "a_1": 73, "a_2": 73, "a_3": 73, "b_3": 73 }
+{ "a_0": 74, "a_1": 74, "a_2": 74, "a_3": 74, "b_3": 74 }
+{ "a_0": 75, "a_1": 75, "a_2": 75, "a_3": 75, "b_3": 75 }
+{ "a_0": 76, "a_1": 76, "a_2": 76, "a_3": 76, "b_3": 76 }
+{ "a_0": 77, "a_1": 77, "a_2": 77, "a_3": 77, "b_3": 77 }
+{ "a_0": 78, "a_1": 78, "a_2": 78, "a_3": 78, "b_3": 78 }
+{ "a_0": 79, "a_1": 79, "a_2": 79, "a_3": 79, "b_3": 79 }
+{ "a_0": 80, "a_1": 80, "a_2": 80, "a_3": 80, "b_3": 80 }
+{ "a_0": 81, "a_1": 81, "a_2": 81, "a_3": 81, "b_3": 81 }
+{ "a_0": 82, "a_1": 82, "a_2": 82, "a_3": 82, "b_3": 82 }
+{ "a_0": 83, "a_1": 83, "a_2": 83, "a_3": 83, "b_3": 83 }
+{ "a_0": 84, "a_1": 84, "a_2": 84, "a_3": 84, "b_3": 84 }
+{ "a_0": 85, "a_1": 85, "a_2": 85, "a_3": 85, "b_3": 85 }
+{ "a_0": 86, "a_1": 86, "a_2": 86, "a_3": 86, "b_3": 86 }
+{ "a_0": 87, "a_1": 87, "a_2": 87, "a_3": 87, "b_3": 87 }
+{ "a_0": 88, "a_1": 88, "a_2": 88, "a_3": 88, "b_3": 88 }
+{ "a_0": 89, "a_1": 89, "a_2": 89, "a_3": 89, "b_3": 89 }
+{ "a_0": 90, "a_1": 90, "a_2": 90, "a_3": 90, "b_3": 90 }
+{ "a_0": 91, "a_1": 91, "a_2": 91, "a_3": 91, "b_3": 91 }
+{ "a_0": 92, "a_1": 92, "a_2": 92, "a_3": 92, "b_3": 92 }
+{ "a_0": 93, "a_1": 93, "a_2": 93, "a_3": 93, "b_3": 93 }
+{ "a_0": 94, "a_1": 94, "a_2": 94, "a_3": 94, "b_3": 94 }
+{ "a_0": 95, "a_1": 95, "a_2": 95, "a_3": 95, "b_3": 95 }
+{ "a_0": 96, "a_1": 96, "a_2": 96, "a_3": 96, "b_3": 96 }
+{ "a_0": 97, "a_1": 97, "a_2": 97, "a_3": 97, "b_3": 97 }
+{ "a_0": 98, "a_1": 98, "a_2": 98, "a_3": 98, "b_3": 98 }
+{ "a_0": 99, "a_1": 99, "a_2": 99, "a_3": 99, "b_3": 99 }
+{ "a_0": 100, "a_1": 100, "a_2": 100, "a_3": 100, "b_3": 100 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/handle_error_fun/handle_error_fun.01.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/handle_error_fun/handle_error_fun.01.adm
new file mode 100644
index 0000000..b9a7cb5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/handle_error_fun/handle_error_fun.01.adm
@@ -0,0 +1 @@
+{ "id": 2, "f": "problematic doc" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.03.adm
new file mode 100644
index 0000000..9b33be8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.03.adm
@@ -0,0 +1,8 @@
+{ "a": 1, "b": 1 }
+{ "a": 10, "b": 10 }
+{ "a": 16, "b": 16 }
+{ "a": null, "b": null }
+{ }
+{ "a": 242005543865690107, "b": 242005543865690107 }
+{ "a": null, "b": null }
+{ "b": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.04.adm
new file mode 100644
index 0000000..8272596
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.04.adm
@@ -0,0 +1 @@
+{ "a": 1, "b": 10, "c": 16, "d": 242005543865690107, "e": null, "f": null, "h": null, "j": null, "k": null, "l": null, "m": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.05.adm
new file mode 100644
index 0000000..375bff5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/from_base/from_base.05.adm
@@ -0,0 +1 @@
+{ "a": 1, "b": 10, "c": null, "d": 1, "e": 2, "f": 3 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.01.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.01.adm
new file mode 100644
index 0000000..006e70c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.01.adm
@@ -0,0 +1,5 @@
+{ "id": 1, "f_padded_with_dollar_to_10_codepoints": "$$$$$$$$Hi", "f_truncated_or_padded_to_2_codepoints": "Hi", "f_padded_with_emoji_to_10_codepoints": "👩👩👧👦👩Hi", "f1_padded_to_4_codepoints": "%%%👩", "f": "Hi", "f1": "👩" }
+{ "id": 2, "f_padded_with_dollar_to_10_codepoints": "$$-7262.98", "f_truncated_or_padded_to_2_codepoints": "-7", "f_padded_with_emoji_to_10_codepoints": "👩-7262.98", "f1_padded_to_4_codepoints": "%%👨", "f": "-7262.98", "f1": "👨" }
+{ "id": 3, "f_padded_with_dollar_to_10_codepoints": "$$$$$$$a𩸽b", "f_truncated_or_padded_to_2_codepoints": "a𩸽", "f_padded_with_emoji_to_10_codepoints": "👩👩👧👦a𩸽b", "f1_padded_to_4_codepoints": "%%%🎉", "f": "a𩸽b", "f1": "🎉" }
+{ "id": 4, "f_padded_with_dollar_to_10_codepoints": "$$$👩👩👧👦", "f_truncated_or_padded_to_2_codepoints": "👩", "f_padded_with_emoji_to_10_codepoints": "👩👩👩👩👧👦", "f1_padded_to_4_codepoints": "%✓✓✓", "f": "👩👩👧👦", "f1": "✓✓✓" }
+{ "id": 5, "f_padded_with_dollar_to_10_codepoints": null, "f_truncated_or_padded_to_2_codepoints": null, "f_padded_with_emoji_to_10_codepoints": null, "f1_padded_to_4_codepoints": null, "f": null, "f1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.02.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.02.adm
new file mode 100644
index 0000000..3f6d3e4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.02.adm
@@ -0,0 +1 @@
+{ "padded_to_11_codepoints": "$&^$asterix", "truncated_to_2_codepoints": "👩", "padded_to_10_codepoints": "👩👩👩👩👧", "padded_to_null_is_null": null, "padded_non_str": null, "negative_length": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.03.adm
new file mode 100644
index 0000000..6ef482b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/lpad/lpad.03.adm
@@ -0,0 +1 @@
+{ "padded_long_input": "$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "very_long_unicode_test": "彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2END彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2END彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu你8世界🌍", "very_long_truncation_with_unicode_result": "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss©®™§¶" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.01.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.01.adm
new file mode 100644
index 0000000..d534124
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.01.adm
@@ -0,0 +1,5 @@
+{ "id": 1, "f_padded_with_dollar_to_10_codepoints": "Hi$$$$$$$$", "f_truncated_or_padded_to_2_codepoints": "Hi", "f_padded_with_emoji_to_10_codepoints": "Hi👩👩👧👦👩", "f1_padded_to_4_codepoints": "👩%%%", "f": "Hi", "f1": "👩" }
+{ "id": 2, "f_padded_with_dollar_to_10_codepoints": "-7262.98$$", "f_truncated_or_padded_to_2_codepoints": "-7", "f_padded_with_emoji_to_10_codepoints": "-7262.98👩", "f1_padded_to_4_codepoints": "👨%%", "f": "-7262.98", "f1": "👨" }
+{ "id": 3, "f_padded_with_dollar_to_10_codepoints": "a𩸽b$$$$$$$", "f_truncated_or_padded_to_2_codepoints": "a𩸽", "f_padded_with_emoji_to_10_codepoints": "a𩸽b👩👩👧👦", "f1_padded_to_4_codepoints": "🎉%%%", "f": "a𩸽b", "f1": "🎉" }
+{ "id": 4, "f_padded_with_dollar_to_10_codepoints": "👩👩👧👦$$$", "f_truncated_or_padded_to_2_codepoints": "👩", "f_padded_with_emoji_to_10_codepoints": "👩👩👧👦👩👩", "f1_padded_to_4_codepoints": "✓✓✓%", "f": "👩👩👧👦", "f1": "✓✓✓" }
+{ "id": 5, "f_padded_with_dollar_to_10_codepoints": null, "f_truncated_or_padded_to_2_codepoints": null, "f_padded_with_emoji_to_10_codepoints": null, "f1_padded_to_4_codepoints": null, "f": null, "f1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.02.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.02.adm
new file mode 100644
index 0000000..ba875f6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.02.adm
@@ -0,0 +1 @@
+{ "padded_to_11_codepoints": "asterix$&^$", "truncated_to_2_codepoints": "👩", "padded_to_10_codepoints": "👩👩👧👩👩", "padded_to_null_is_null": null, "padded_non_str": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.03.adm
new file mode 100644
index 0000000..8f86a8a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/pad/rpad/rpad.03.adm
@@ -0,0 +1 @@
+{ "padded_long_input": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$", "very_long_unicode_test": "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu你8世界🌍彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2END彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2END彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩2彩", "very_long_truncation_with_unicode_result": "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss©®™§¶" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
index a26853b..fadf9df 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
@@ -4019,6 +4019,13 @@
</compilation-unit>
</test-case>
</test-group>
+ <test-group name="crypto">
+ <test-case FilePath="crypto">
+ <compilation-unit name="sha1">
+ <output-dir compare="Text">sha1</output-dir>
+ </compilation-unit>
+ </test-case>
+ </test-group>
<test-group name="custord">
<!--
<test-case FilePath="custord">
@@ -6884,6 +6891,16 @@
</compilation-unit>
</test-case>
<test-case FilePath="join">
+ <compilation-unit name="hash_join_exchange">
+ <output-dir compare="Text">hash_join_exchange</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="join">
+ <compilation-unit name="hash_join_exchange_1">
+ <output-dir compare="Text">hash_join_exchange_1</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="join">
<compilation-unit name="ASTERIXDB-3502">
<output-dir compare="Text">ASTERIXDB-3502</output-dir>
</compilation-unit>
@@ -7530,6 +7547,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="misc">
+ <compilation-unit name="handle_error_fun">
+ <output-dir compare="Text">handle_error_fun</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
<compilation-unit name="query-ASTERIXDB-3299">
<output-dir compare="Text">query-ASTERIXDB-3299</output-dir>
</compilation-unit>
@@ -9642,6 +9664,11 @@
<output-dir compare="Text">unary-minus_double_02</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="numeric">
+ <compilation-unit name="from_base">
+ <output-dir compare="Text">from_base</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="open-closed">
<!--
@@ -11684,6 +11711,16 @@
<expected-warn>Function 'position1' failed to evaluate because: Decoding error - got a low surrogate without a leading high surrogate</expected-warn>
</compilation-unit>
</test-case>
+ <test-case FilePath="string">
+ <compilation-unit name="pad/lpad">
+ <output-dir compare="Text">pad/lpad</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="string">
+ <compilation-unit name="pad/rpad">
+ <output-dir compare="Text">pad/rpad</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="subquery">
<test-case FilePath="subquery">
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
index e232bc6..810393f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
@@ -384,6 +384,16 @@
<expected-error>'||' is not a valid escape. The length of a escape should be 1</expected-error>
</compilation-unit>
</test-case>
+ <test-case FilePath="copy-to/csv">
+ <compilation-unit name="datetime">
+ <placeholder name="adapter" value="S3" />
+ <placeholder name="pathprefix" value="" />
+ <placeholder name="path_prefix" value="" />
+ <placeholder name="additionalProperties" value='"container":"playground",' />
+ <placeholder name="additional_Properties" value='("container"="playground")' />
+ <output-dir compare="Text">datetime</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="aws-s3-external-dataset">
<test-case FilePath="external-dataset">
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
index d332944..0baebc7 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
@@ -23,11 +23,13 @@
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Set;
+import java.util.function.Predicate;
import org.apache.asterix.cloud.IWriteBufferProvider;
import org.apache.asterix.cloud.clients.profiler.IRequestProfilerLimiter;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.io.FileReference;
+import org.apache.hyracks.cloud.io.request.ICloudRetryPredicate;
import org.apache.hyracks.control.nc.io.IOManager;
import com.fasterxml.jackson.databind.JsonNode;
@@ -168,4 +170,10 @@
* Performs any necessary closing and cleaning up
*/
void close() throws HyracksDataException;
+
+ Predicate<Exception> getObjectNotFoundExceptionPredicate();
+
+ default ICloudRetryPredicate getRetryUnlessNotFound() {
+ return ex -> Predicate.not(getObjectNotFoundExceptionPredicate()).test(ex);
+ }
}
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/NoopCloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/NoopCloudClient.java
index fb83aa9..8f37191 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/NoopCloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/NoopCloudClient.java
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.function.Predicate;
import org.apache.asterix.cloud.IWriteBufferProvider;
import org.apache.asterix.cloud.clients.profiler.IRequestProfilerLimiter;
@@ -117,6 +118,11 @@
}
@Override
+ public Predicate<Exception> getObjectNotFoundExceptionPredicate() {
+ return e -> true;
+ }
+
+ @Override
public JsonNode listAsJson(ObjectMapper objectMapper, String bucket) {
return OBJECT_MAPPER.createArrayNode();
}
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/UnstableCloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/UnstableCloudClient.java
index 178984a..d81419b 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/UnstableCloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/UnstableCloudClient.java
@@ -26,6 +26,7 @@
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Predicate;
import org.apache.asterix.cloud.CloudResettableInputStream;
import org.apache.asterix.cloud.IWriteBufferProvider;
@@ -143,6 +144,11 @@
cloudClient.close();
}
+ @Override
+ public Predicate<Exception> getObjectNotFoundExceptionPredicate() {
+ return cloudClient.getObjectNotFoundExceptionPredicate();
+ }
+
private static void fail() throws HyracksDataException {
double prob = RANDOM.nextInt(100) / 100.0d;
if (prob < ERROR_RATE.get()) {
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
index fc35792..8a28f53 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
@@ -34,6 +34,7 @@
import java.util.List;
import java.util.Set;
import java.util.function.Function;
+import java.util.function.Predicate;
import org.apache.asterix.cloud.CloudResettableInputStream;
import org.apache.asterix.cloud.IWriteBufferProvider;
@@ -328,6 +329,11 @@
s3Client.close();
}
+ @Override
+ public Predicate<Exception> getObjectNotFoundExceptionPredicate() {
+ return ex -> ex instanceof NoSuchKeyException;
+ }
+
/**
* FOR TESTING ONLY
*/
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
index 7922fc4..e2bbb5b 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
@@ -34,6 +34,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -391,6 +392,11 @@
// Hence this implementation is a no op.
}
+ @Override
+ public Predicate<Exception> getObjectNotFoundExceptionPredicate() {
+ return ex -> (ex instanceof BlobStorageException bse) && bse.getErrorCode().equals(BlobErrorCode.BLOB_NOT_FOUND);
+ }
+
private static BlobServiceClient buildClient(AzBlobStorageClientConfig config) {
BlobServiceClientBuilder blobServiceClientBuilder = new BlobServiceClientBuilder();
blobServiceClientBuilder.endpoint(getEndpoint(config));
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/google/gcs/GCSCloudClient.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/google/gcs/GCSCloudClient.java
index 62c1835..bd0a044 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/google/gcs/GCSCloudClient.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/google/gcs/GCSCloudClient.java
@@ -32,6 +32,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.function.Predicate;
import org.apache.asterix.cloud.IWriteBufferProvider;
import org.apache.asterix.cloud.clients.CloudFile;
@@ -301,6 +302,11 @@
}
}
+ @Override
+ public Predicate<Exception> getObjectNotFoundExceptionPredicate() {
+ return ex -> (ex instanceof BaseServiceException bse)&& bse.getCode() == 404;
+ }
+
private static Storage buildClient(GCSClientConfig config) throws HyracksDataException {
StorageOptions.Builder builder = StorageOptions.newBuilder().setCredentials(config.createCredentialsProvider());
builder.setStorageRetryStrategy(DEFAULT_NO_RETRY_ON_THREAD_INTERRUPT_STRATEGY);
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/parquet/ParquetSchemaInferPoolWriter.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/parquet/ParquetSchemaInferPoolWriter.java
index 255009e..ca87ced 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/parquet/ParquetSchemaInferPoolWriter.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/parquet/ParquetSchemaInferPoolWriter.java
@@ -29,9 +29,13 @@
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.data.std.api.IValueReference;
import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import org.apache.hyracks.util.LogRedactionUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
// Maintains a pool of Parquet writers holding a file, each with its own schema , and writes values to the appropriate writer based on schema.
public class ParquetSchemaInferPoolWriter {
+ private static final Logger LOGGER = LogManager.getLogger();
private final ParquetExternalWriterFactory writerFactory;
private List<ParquetSchemaTree.SchemaNode> schemaNodes;
private List<IExternalWriter> writerList;
@@ -65,6 +69,10 @@
}
if (schemaNodes.size() == maxSchemas) {
+ LOGGER.info("Schema limit exceeded, max schemas allowed: {}", maxSchemas);
+ schemaNodes.forEach(schemaNode -> {
+ LOGGER.info("Inferred schema: {}", LogRedactionUtil.userData(schemaNode.toString()));
+ });
throw new HyracksDataException(ErrorCode.SCHEMA_LIMIT_EXCEEDED, maxSchemas);
}
schemaNodes.add(schemaLazyVisitor.inferSchema(value));
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriter.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriter.java
index d02b34e..f93ae92 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriter.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriter.java
@@ -19,6 +19,7 @@
package org.apache.asterix.cloud.writer;
import static org.apache.hyracks.api.util.ExceptionUtils.getMessageOrToString;
+import static org.apache.hyracks.cloud.util.CloudRetryableRequestUtil.runWithNoRetryOnInterruption;
import org.apache.asterix.cloud.CloudOutputStream;
import org.apache.asterix.cloud.IWriteBufferProvider;
@@ -33,6 +34,7 @@
import org.apache.hyracks.api.exceptions.IWarningCollector;
import org.apache.hyracks.api.exceptions.SourceLocation;
import org.apache.hyracks.api.exceptions.Warning;
+import org.apache.hyracks.cloud.io.request.ICloudRequest;
import org.apache.hyracks.data.std.api.IValueReference;
import com.google.common.base.Utf8;
@@ -60,7 +62,7 @@
@Override
public final void open() throws HyracksDataException {
- printer.open();
+ runWithRetryIfSdkException(printer::open);
}
@Override
@@ -69,7 +71,8 @@
return;
}
- if (partitionedPath && !cloudClient.isEmptyPrefix(bucket, directory)) {
+ boolean emptyPrefix = runWithNoRetryOnInterruption(() -> cloudClient.isEmptyPrefix(bucket, directory));
+ if (partitionedPath && !emptyPrefix) {
throw new RuntimeDataException(ErrorCode.DIRECTORY_IS_NOT_EMPTY, pathSourceLocation, directory);
}
}
@@ -91,7 +94,7 @@
@Override
public final void write(IValueReference value) throws HyracksDataException {
try {
- printer.print(value);
+ runWithRetryIfSdkException(() -> printer.print(value));
} catch (HyracksDataException e) {
throw e;
} catch (Exception e) {
@@ -106,9 +109,9 @@
public final void abort() throws HyracksDataException {
try {
if (cloudWriter != null) {
- cloudWriter.abort();
+ runWithRetryIfSdkException(cloudWriter::abort);
}
- printer.close();
+ runWithRetryIfSdkException(printer::close);
} catch (HyracksDataException e) {
throw e;
} catch (Exception e) {
@@ -122,7 +125,7 @@
@Override
public final void close() throws HyracksDataException {
try {
- printer.close();
+ runWithRetryIfSdkException(printer::close);
} catch (HyracksDataException e) {
throw e;
} catch (Exception e) {
@@ -139,6 +142,10 @@
abstract boolean isSdkException(Exception e);
+ private void runWithRetryIfSdkException(ICloudRequest request) throws HyracksDataException {
+ runWithNoRetryOnInterruption(request, this::isSdkException);
+ }
+
private boolean checkAndWarnExceedingMaxLength(String fullPath) {
boolean exceeding = isExceedingMaxLength(fullPath, getPathMaxLengthInBytes());
if (exceeding && warningCollector.shouldWarn()) {
diff --git a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriterFactory.java b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriterFactory.java
index 977f90a..c52e2b6 100644
--- a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriterFactory.java
+++ b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/writer/AbstractCloudExternalFileWriterFactory.java
@@ -20,6 +20,7 @@
import static org.apache.asterix.cloud.writer.AbstractCloudExternalFileWriter.isExceedingMaxLength;
import static org.apache.hyracks.api.util.ExceptionUtils.getMessageOrToString;
+import static org.apache.hyracks.cloud.util.CloudRetryableRequestUtil.runWithNoRetryOnInterruption;
import java.io.IOException;
import java.util.Collections;
@@ -40,6 +41,7 @@
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.hyracks.cloud.io.request.ICloudReturnableRequest;
import org.apache.hyracks.data.std.primitive.LongPointable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -122,7 +124,7 @@
staticPath, getPathMaxLengthInBytes(), getAdapterName());
}
- if (!testClient.isEmptyPrefix(bucket, staticPath)) {
+ if (!runWithNoRetryOnInterruption(() -> testClient.isEmptyPrefix(bucket, staticPath))) {
// Ensure that the static path is empty
throw new CompilationException(ErrorCode.DIRECTORY_IS_NOT_EMPTY, pathSourceLocation, staticPath);
}
@@ -138,10 +140,16 @@
Random random = new Random();
String pathPrefix = "testFile";
String path = pathPrefix + random.nextInt();
- while (testClient.exists(bucket, path)) {
+
+ String existsFinalPath = path;
+ ICloudReturnableRequest<Boolean> existsRequest = () -> testClient.exists(bucket, existsFinalPath);
+ while (runWithNoRetryOnInterruption(existsRequest, testClient.getRetryUnlessNotFound())) {
path = pathPrefix + random.nextInt();
+ String existsFinalPathUpdated = path;
+ existsRequest = () -> testClient.exists(bucket, existsFinalPathUpdated);
}
+ final String finalPath = path;
long writeValue = random.nextLong();
byte[] data = new byte[Long.BYTES];
LongPointable.setLong(data, 0, writeValue);
@@ -149,28 +157,29 @@
ICloudWriter writer = testClient.createWriter(bucket, path, bufferProvider);
boolean aborted = false;
try {
- writer.write(data, 0, data.length);
+ runWithNoRetryOnInterruption(() -> writer.write(data, 0, data.length));
} catch (HyracksDataException e) {
- writer.abort();
+ runWithNoRetryOnInterruption(writer::abort);
aborted = true;
throw e;
} finally {
if (writer != null && !aborted) {
- writer.finish();
+ runWithNoRetryOnInterruption(writer::finish);
}
}
try {
- long readValue = LongPointable.getLong(testClient.readAllBytes(bucket, path), 0);
+ byte[] bytes = runWithNoRetryOnInterruption(() -> testClient.readAllBytes(bucket, finalPath));
+ long readValue = LongPointable.getLong(bytes, 0);
if (writeValue != readValue) {
- // This should never happen unless S3 is messed up. But log for sanity check
+ // This should never happen unless cloud storage is messed up. But log for sanity check
LOGGER.warn(
"The writer can write but the written values wasn't successfully read back (wrote: {}, read:{})",
writeValue, readValue);
}
} finally {
// Delete the written file
- testClient.deleteObjects(bucket, Collections.singleton(path));
+ runWithNoRetryOnInterruption(() -> testClient.deleteObjects(bucket, Collections.singleton(finalPath)));
}
}
}
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
index 3eb1e4c..cb5323f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
@@ -326,12 +326,12 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
unpin(page, DEFAULT);
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
vbc.unpin(page, context);
}
diff --git a/asterixdb/asterix-external-data/pom.xml b/asterixdb/asterix-external-data/pom.xml
index d2f47ba..6ede278 100644
--- a/asterixdb/asterix-external-data/pom.xml
+++ b/asterixdb/asterix-external-data/pom.xml
@@ -218,7 +218,6 @@
<usedDependency>net.razorvine:serpent</usedDependency>
<usedDependency>io.netty:netty-resolver-dns</usedDependency>
<usedDependency>io.netty:netty-codec-http2</usedDependency>
- <usedDependency>io.netty:netty-transport-native-unix-common</usedDependency>
<usedDependency>io.netty:netty-handler-proxy</usedDependency>
<usedDependency>io.netty:netty-handler-proxy</usedDependency>
</usedDependencies>
@@ -557,10 +556,6 @@
</dependency>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-transport-native-unix-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
</dependency>
<!-- Manually included to avoid CVE-2023-1370 -->
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetRecordLazyVisitor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetRecordLazyVisitor.java
index 2a03bfd..cffeb2f 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetRecordLazyVisitor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetRecordLazyVisitor.java
@@ -35,13 +35,16 @@
import org.apache.hyracks.api.exceptions.ErrorCode;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.util.LogRedactionUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.apache.parquet.io.api.RecordConsumer;
import org.apache.parquet.schema.GroupType;
import org.apache.parquet.schema.MessageType;
import org.apache.parquet.schema.Type;
public class ParquetRecordLazyVisitor implements ILazyVisitablePointableVisitor<Void, Type> {
-
+ private static final Logger LOGGER = LogManager.getLogger();
private final MessageType schema;
private final RecordLazyVisitablePointable rec;
// The Record Consumer is responsible for traversing the record tree,
@@ -72,6 +75,7 @@
public Void visit(RecordLazyVisitablePointable pointable, Type type) throws HyracksDataException {
if (type.isPrimitive()) {
+ LOGGER.info("Expected primitive type: {} but got record type", LogRedactionUtil.userData(type.toString()));
throw new HyracksDataException(ErrorCode.RESULT_DOES_NOT_FOLLOW_SCHEMA, GROUP_TYPE_ERROR_FIELD,
PRIMITIVE_TYPE_ERROR_FIELD, type.getName());
}
@@ -84,6 +88,8 @@
String columnName = fieldNamesDictionary.getOrCreateFieldNameIndex(pointable.getFieldName());
if (!groupType.containsField(columnName)) {
+ LOGGER.info("Group type: {} does not contain field in record type: {}",
+ LogRedactionUtil.userData(groupType.getName()), LogRedactionUtil.userData(columnName));
throw new HyracksDataException(ErrorCode.EXTRA_FIELD_IN_RESULT_NOT_FOUND_IN_SCHEMA, columnName,
groupType.getName());
}
@@ -99,17 +105,22 @@
public Void visit(AbstractListLazyVisitablePointable pointable, Type type) throws HyracksDataException {
if (type.isPrimitive()) {
+ LOGGER.info("Expected primitive type: {} but got list type", LogRedactionUtil.userData(type.toString()));
throw new HyracksDataException(ErrorCode.RESULT_DOES_NOT_FOLLOW_SCHEMA, GROUP_TYPE_ERROR_FIELD,
PRIMITIVE_TYPE_ERROR_FIELD, type.getName());
}
GroupType groupType = type.asGroupType();
if (!groupType.containsField(LIST_FIELD)) {
+ LOGGER.info("Group type: {} does not contain field in list type: {}",
+ LogRedactionUtil.userData(groupType.getName()), LIST_FIELD);
throw new HyracksDataException(ErrorCode.EXTRA_FIELD_IN_RESULT_NOT_FOUND_IN_SCHEMA, LIST_FIELD,
groupType.getName());
}
if (groupType.getType(LIST_FIELD).isPrimitive()) {
+ LOGGER.info("Expected group type: {} but got primitive type",
+ LogRedactionUtil.userData(groupType.getType(LIST_FIELD).toString()));
throw new HyracksDataException(ErrorCode.RESULT_DOES_NOT_FOLLOW_SCHEMA, GROUP_TYPE_ERROR_FIELD,
PRIMITIVE_TYPE_ERROR_FIELD, LIST_FIELD);
}
@@ -117,6 +128,8 @@
GroupType listType = groupType.getType(LIST_FIELD).asGroupType();
if (!listType.containsField(ELEMENT_FIELD)) {
+ LOGGER.info("Group type: {} does not contain field: {}", LogRedactionUtil.userData(listType.toString()),
+ ELEMENT_FIELD);
throw new HyracksDataException(ErrorCode.EXTRA_FIELD_IN_RESULT_NOT_FOUND_IN_SCHEMA, ELEMENT_FIELD,
listType.getName());
}
@@ -147,8 +160,9 @@
@Override
public Void visit(FlatLazyVisitablePointable pointable, Type type) throws HyracksDataException {
-
if (!type.isPrimitive()) {
+ LOGGER.info("Expected non primitive type: {} but got: {}", LogRedactionUtil.userData(type.toString()),
+ pointable.getTypeTag());
throw new HyracksDataException(ErrorCode.RESULT_DOES_NOT_FOLLOW_SCHEMA, PRIMITIVE_TYPE_ERROR_FIELD,
GROUP_TYPE_ERROR_FIELD, type.getName());
}
@@ -168,6 +182,8 @@
AbstractLazyVisitablePointable child = rec.getChildVisitablePointable();
if (!schema.containsField(columnName)) {
+ LOGGER.info("Schema: {} does not contain field: {}", LogRedactionUtil.userData(schema.toString()),
+ LogRedactionUtil.userData(columnName));
throw new HyracksDataException(ErrorCode.EXTRA_FIELD_IN_RESULT_NOT_FOUND_IN_SCHEMA, columnName,
schema.getName());
}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaLazyVisitor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaLazyVisitor.java
index bd869e9..2278372 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaLazyVisitor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaLazyVisitor.java
@@ -36,11 +36,15 @@
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.util.LogRedactionUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.apache.parquet.schema.MessageType;
import org.apache.parquet.schema.Types;
// This class is used to infer the schema of a record into SchemaNode, which is an internal tree representation of the schema.
public class ParquetSchemaLazyVisitor implements ILazyVisitablePointableVisitor<Void, ParquetSchemaTree.SchemaNode> {
+ private static final Logger LOGGER = LogManager.getLogger();
private final RecordLazyVisitablePointable rec;
private final FieldNamesDictionary fieldNamesDictionary;
private final static String SCHEMA_NAME = "asterix_schema";
@@ -63,6 +67,8 @@
schemaNode.setType(new ParquetSchemaTree.RecordType());
}
if (!(schemaNode.getType() instanceof ParquetSchemaTree.RecordType)) {
+ LOGGER.info("Incompatible type found in record: {} and {}",
+ LogRedactionUtil.userData(schemaNode.toString()), pointable.getTypeTag());
throw RuntimeDataException.create(PARQUET_UNSUPPORTED_MIXED_TYPE_ARRAY);
}
ParquetSchemaTree.RecordType recordType = (ParquetSchemaTree.RecordType) schemaNode.getType();
@@ -88,11 +94,12 @@
if (schemaNode.getType() == null) {
schemaNode.setType(new ParquetSchemaTree.ListType());
}
- if (!(schemaNode.getType() instanceof ParquetSchemaTree.ListType)) {
+ if (!(schemaNode.getType() instanceof ParquetSchemaTree.ListType listType)) {
+ LOGGER.info("Incompatible type found in list: {} and {}" ,LogRedactionUtil.userData(schemaNode.toString()) ,pointable.getTypeTag());
throw RuntimeDataException.create(PARQUET_UNSUPPORTED_MIXED_TYPE_ARRAY);
}
- ParquetSchemaTree.ListType listType = (ParquetSchemaTree.ListType) schemaNode.getType();
- for (int i = 0; i < pointable.getNumberOfChildren(); i++) {
+ int numChildren = pointable.getNumberOfChildren();
+ for (int i = 0; i < numChildren; i++) {
pointable.nextChild();
AbstractLazyVisitablePointable child = pointable.getChildVisitablePointable();
if (listType.isEmpty()) {
@@ -114,11 +121,14 @@
return null;
}
if (!(schemaNode.getType() instanceof ParquetSchemaTree.FlatType)) {
+ LOGGER.info("Incompatible type found: {} and {}", LogRedactionUtil.userData(schemaNode.toString()),
+ pointable.getTypeTag());
throw RuntimeDataException.create(PARQUET_UNSUPPORTED_MIXED_TYPE_ARRAY);
}
ParquetSchemaTree.FlatType flatType = (ParquetSchemaTree.FlatType) schemaNode.getType();
if (!flatType.isCompatibleWith(pointable.getTypeTag())) {
+ LOGGER.info("Incompatible type found: {} and {}", flatType, pointable.getTypeTag());
throw RuntimeDataException.create(PARQUET_UNSUPPORTED_MIXED_TYPE_ARRAY);
}
@@ -136,6 +146,7 @@
public static MessageType generateSchema(ParquetSchemaTree.SchemaNode schemaRoot) throws HyracksDataException {
Types.MessageTypeBuilder builder = Types.buildMessage();
+ LOGGER.info("Building parquet schema: {}", LogRedactionUtil.userData(schemaRoot.toString()));
if (schemaRoot.getType() == null)
return builder.named(SCHEMA_NAME);
for (Map.Entry<String, ParquetSchemaTree.SchemaNode> entry : ((ParquetSchemaTree.RecordType) schemaRoot
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaTree.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaTree.java
index 2ca086f..dae5295 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaTree.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/writer/printer/parquet/ParquetSchemaTree.java
@@ -28,11 +28,15 @@
import org.apache.asterix.om.types.ATypeTag;
import org.apache.hyracks.api.exceptions.ErrorCode;
import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.util.LogRedactionUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.apache.parquet.schema.LogicalTypeAnnotation;
import org.apache.parquet.schema.PrimitiveType;
import org.apache.parquet.schema.Types;
public class ParquetSchemaTree {
+ private static final Logger LOGGER = LogManager.getLogger();
public static class SchemaNode {
private AbstractType type;
@@ -48,6 +52,11 @@
public AbstractType getType() {
return type;
}
+
+ @Override
+ public String toString() {
+ return type == null ? "NULL" : type.toString();
+ }
}
static class RecordType extends AbstractType {
@@ -68,6 +77,17 @@
Map<String, SchemaNode> getChildren() {
return children;
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{ ");
+ for (Map.Entry<String, SchemaNode> entry : children.entrySet()) {
+ sb.append(entry.getKey()).append(" : ").append(entry.getValue()).append(", ");
+ }
+ sb.append(" }");
+ return sb.toString();
+ }
}
abstract static class AbstractType {
@@ -82,6 +102,11 @@
isHierarchical = AsterixParquetTypeMap.HIERARCHIAL_TYPES.containsKey(typeTag);
}
+ @Override
+ public String toString() {
+ return typeTag.toString();
+ }
+
public boolean isCompatibleWith(ATypeTag typeTag) {
if (isHierarchical) {
return AsterixParquetTypeMap.HIERARCHIAL_TYPES.containsKey(typeTag);
@@ -113,6 +138,11 @@
child = null;
}
+ @Override
+ public String toString() {
+ return "[ " + child + " ]";
+ }
+
void setChild(SchemaNode child) {
this.child = child;
}
@@ -129,6 +159,8 @@
public static void buildParquetSchema(Types.Builder builder, SchemaNode schemaNode, String columnName)
throws HyracksDataException {
if (schemaNode.getType() == null) {
+ LOGGER.info(
+ "Child type not set for record value with column name: " + LogRedactionUtil.userData(columnName));
throw new HyracksDataException(ErrorCode.EMPTY_TYPE_INFERRED);
}
AbstractType typeClass = schemaNode.getType();
@@ -154,6 +186,7 @@
Types.BaseListBuilder<?, ?> childBuilder = getListChild(builder);
SchemaNode child = type.child;
if (child == null) {
+ LOGGER.info("Child type not set for list with column name: " + LogRedactionUtil.userData(columnName));
throw new HyracksDataException(ErrorCode.EMPTY_TYPE_INFERRED);
}
buildParquetSchema(childBuilder, child, columnName);
@@ -161,6 +194,8 @@
private static void buildFlat(Types.Builder builder, FlatType type, String columnName) throws HyracksDataException {
if (type.getPrimitiveTypeName() == null) {
+ LOGGER.info("Child primitive type not set for flat value with column name: "
+ + LogRedactionUtil.userData(columnName));
// Not sure if this is the right thing to do here
throw new HyracksDataException(ErrorCode.EMPTY_TYPE_INFERRED);
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CopyToStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CopyToStatement.java
index 5c89a9f..ef76d14 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CopyToStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CopyToStatement.java
@@ -54,15 +54,16 @@
private List<Expression> partitionExpressions;
private List<Expression> orderByList;
private int varCounter;
- private RecordTypeDefinition itemType;
- private TypeExpression typeExpressionItemType;
+ private final RecordTypeDefinition itemType;
+ private final TypeExpression typeExpressionItemType;
+ private final Map<String, String> formatConfigs;
public CopyToStatement(Namespace namespace, String datasetName, Query query, VariableExpr sourceVariable,
ExternalDetailsDecl externalDetailsDecl, int varCounter, List<Expression> keyExpressions,
boolean autogenerated) {
this(namespace, datasetName, query, sourceVariable, externalDetailsDecl, new ArrayList<>(), new ArrayList<>(),
new HashMap<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), varCounter, keyExpressions,
- autogenerated, null, null);
+ autogenerated, null, null, null);
}
public CopyToStatement(Namespace namespace, String datasetName, Query query, VariableExpr sourceVariable,
@@ -72,7 +73,7 @@
List<OrderbyClause.NullOrderModifier> orderByNullModifierList, int varCounter) {
this(namespace, datasetName, query, sourceVariable, externalDetailsDecl, pathExpressions, partitionExpressions,
partitionsVariables, orderbyList, orderByModifiers, orderByNullModifierList, varCounter,
- new ArrayList<>(), false, null, null);
+ new ArrayList<>(), false, null, null, null);
}
public CopyToStatement(Namespace namespace, String datasetName, Query query, VariableExpr sourceVariable,
@@ -80,10 +81,10 @@
List<Expression> partitionExpressions, Map<Integer, VariableExpr> partitionsVariables,
List<Expression> orderbyList, List<OrderbyClause.OrderModifier> orderByModifiers,
List<OrderbyClause.NullOrderModifier> orderByNullModifierList, int varCounter,
- TypeExpression typeExpressionItemType, RecordTypeDefinition itemType) {
+ TypeExpression typeExpressionItemType, RecordTypeDefinition itemType, Map<String, String> formatConfigs) {
this(namespace, datasetName, query, sourceVariable, externalDetailsDecl, pathExpressions, partitionExpressions,
partitionsVariables, orderbyList, orderByModifiers, orderByNullModifierList, varCounter,
- new ArrayList<>(), false, typeExpressionItemType, itemType);
+ new ArrayList<>(), false, typeExpressionItemType, itemType, formatConfigs);
}
private CopyToStatement(Namespace namespace, String datasetName, Query query, VariableExpr sourceVariable,
@@ -92,7 +93,7 @@
List<Expression> orderbyList, List<OrderbyClause.OrderModifier> orderByModifiers,
List<OrderbyClause.NullOrderModifier> orderByNullModifierList, int varCounter,
List<Expression> keyExpressions, boolean autogenerated, TypeExpression typeExpressionItemType,
- RecordTypeDefinition itemType) {
+ RecordTypeDefinition itemType, Map<String, String> formatConfigs) {
this.namespace = namespace;
this.datasetName = datasetName;
this.query = query;
@@ -109,6 +110,7 @@
this.autogenerated = autogenerated;
this.itemType = itemType;
this.typeExpressionItemType = typeExpressionItemType;
+ this.formatConfigs = formatConfigs;
if (pathExpressions.isEmpty()) {
// Ensure path expressions to have at least an empty string
@@ -218,6 +220,10 @@
return typeExpressionItemType;
}
+ public Map<String, String> getFormatConfigs() {
+ return formatConfigs;
+ }
+
@Override
public int getVarCounter() {
return varCounter;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 8afe035..34f5ba0 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -2986,6 +2986,8 @@
RecordTypeDefinition recordTypeDefinition = null;
TypeExpression typeExpr = null;
Boolean isRecordTypeDefinition = false;
+ Map<String, String> formatConfigs = null;
+ String propertyName = null, propertyValue = null;
List<Expression> partitionExprs = new ArrayList<Expression>();
Map<Integer, VariableExpr> partitionVarExprs = new HashMap<Integer, VariableExpr>();
@@ -3002,7 +3004,8 @@
recordTypeDefinition = RecordTypeDef();
isRecordTypeDefinition = true;
}
- <RIGHTPAREN>) ?
+ <RIGHTPAREN>
+ )?
(<AS>
{
if (isRecordTypeDefinition == false) {
@@ -3012,6 +3015,14 @@
}
}
)?
+ (LOOKAHEAD(2) <IDENTIFIER> { propertyName = token.image.toLowerCase(); } propertyValue = StringLiteral()
+ {
+ if (formatConfigs == null) {
+ formatConfigs = new HashMap<String, String>();
+ }
+ formatConfigs.put(propertyName, propertyValue);
+ }
+ )*
<WITH> withRecord = RecordConstructor()
{
ExternalDetailsDecl edd = new ExternalDetailsDecl();
@@ -3026,7 +3037,7 @@
usedAlias = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(datasetName));
}
- CopyToStatement stmt = new CopyToStatement(namespace, datasetName, query, usedAlias, edd, pathExprs, partitionExprs, partitionVarExprs, orderbyList, orderbyModifierList, orderbyNullModifierList, getVarCounter(), typeExpr, recordTypeDefinition);
+ CopyToStatement stmt = new CopyToStatement(namespace, datasetName, query, usedAlias, edd, pathExprs, partitionExprs, partitionVarExprs, orderbyList, orderbyModifierList, orderbyNullModifierList, getVarCounter(), typeExpr, recordTypeDefinition, formatConfigs);
return addSourceLocation(stmt, startToken);
}
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/IExternalWriteDataSink.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/IExternalWriteDataSink.java
index 1168ba1..157f0f8 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/IExternalWriteDataSink.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/IExternalWriteDataSink.java
@@ -19,6 +19,8 @@
package org.apache.asterix.metadata.declared;
+import java.util.Map;
+
import org.apache.asterix.om.types.ARecordType;
import org.apache.hyracks.algebricks.core.algebra.metadata.IWriteDataSink;
import org.apache.hyracks.api.exceptions.SourceLocation;
@@ -28,5 +30,7 @@
ARecordType getParquetSchema();
+ Map<String, String> getFormatConfigs();
+
SourceLocation getSourceLoc();
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/WriteDataSink.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/WriteDataSink.java
index 4a10f7f..4541162 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/WriteDataSink.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/WriteDataSink.java
@@ -29,15 +29,17 @@
private final String adapterName;
private final Map<String, String> configuration;
private final ARecordType itemType;
+ private final Map<String, String> formatConfigs;
private final ARecordType parquetSchema;
private final SourceLocation sourceLoc;
public WriteDataSink(String adapterName, Map<String, String> configuration, ARecordType itemType,
- ARecordType parquetSchema, SourceLocation sourceLoc) {
+ ARecordType parquetSchema, Map<String, String> formatConfigs, SourceLocation sourceLoc) {
this.adapterName = adapterName;
this.configuration = configuration;
this.itemType = itemType;
this.parquetSchema = parquetSchema;
+ this.formatConfigs = formatConfigs;
this.sourceLoc = sourceLoc;
}
@@ -46,6 +48,7 @@
this.configuration = new HashMap<>(writeDataSink.configuration);
this.itemType = writeDataSink.itemType;
this.parquetSchema = writeDataSink.parquetSchema;
+ this.formatConfigs = writeDataSink.getFormatConfigs();
this.sourceLoc = writeDataSink.sourceLoc;
}
@@ -74,6 +77,10 @@
return configuration;
}
+ public Map<String, String> getFormatConfigs() {
+ return formatConfigs;
+ }
+
@Override
public IWriteDataSink createCopy() {
return new WriteDataSink(this);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/provider/ExternalWriterProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/provider/ExternalWriterProvider.java
index 4315c97..bdfffa0 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/provider/ExternalWriterProvider.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/provider/ExternalWriterProvider.java
@@ -185,9 +185,10 @@
compressStreamFactory = createCompressionStreamFactory(appCtx, compression, configuration);
if (sink instanceof IExternalWriteDataSink externalSink) {
ARecordType itemType = externalSink.getItemType();
+ Map<String, String> formatConfigs = externalSink.getFormatConfigs();
if (itemType != null) {
printerFactory = CSVPrinterFactoryProvider
- .createInstance(itemType, externalSink.getConfiguration(), externalSink.getSourceLoc())
+ .createInstance(itemType, externalSink.getConfiguration(), formatConfigs, externalSink.getSourceLoc())
.getPrinterFactory(sourceType);
externalPrinterFactory =
new CsvExternalFilePrinterFactory(printerFactory, compressStreamFactory);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/PrintTools.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/PrintTools.java
index 372b5fd..92fb1bb 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/PrintTools.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/PrintTools.java
@@ -49,7 +49,7 @@
private static final long CHRONON_OF_DAY = TimeUnit.DAYS.toMillis(1);
public static void printDateString(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
- long chrononTime = AInt32SerializerDeserializer.getInt(b, s + 1) * CHRONON_OF_DAY;
+ long chrononTime = getDateChronon(b, s + 1);
try {
gCalInstance.getExtendStringRepUntilField(chrononTime, ps, GregorianCalendarSystem.Fields.YEAR,
@@ -59,8 +59,12 @@
}
}
+ public static long getDateChronon(byte[] b, int s) {
+ return AInt32SerializerDeserializer.getInt(b, s) * CHRONON_OF_DAY;
+ }
+
public static void printDateTimeString(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
- long chrononTime = AInt64SerializerDeserializer.getLong(b, s + 1);
+ long chrononTime = getDateTimeChronon(b, s + 1);
try {
gCalInstance.getExtendStringRepUntilField(chrononTime, ps, GregorianCalendarSystem.Fields.YEAR,
@@ -70,9 +74,13 @@
}
}
+ public static long getDateTimeChronon(byte[] b, int s) {
+ return AInt64SerializerDeserializer.getLong(b, s);
+ }
+
public static void printDayTimeDurationString(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
boolean positive = true;
- long milliseconds = AInt64SerializerDeserializer.getLong(b, s + 1);
+ long milliseconds = getDateTimeChronon(b, s + 1);
// set the negative flag. "||" is necessary in case that months field is not there (so it is 0)
if (milliseconds < 0) {
@@ -218,7 +226,7 @@
}
public static void printTimeString(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
- int time = AInt32SerializerDeserializer.getInt(b, s + 1);
+ int time = getTimeChronon(b, s + 1);
try {
gCalInstance.getExtendStringRepUntilField(time, ps, GregorianCalendarSystem.Fields.HOUR,
@@ -228,6 +236,10 @@
}
}
+ public static int getTimeChronon(byte[] b, int s) {
+ return AInt32SerializerDeserializer.getInt(b, s);
+ }
+
public static void printDoubleForJson(byte[] b, int s, PrintStream ps) {
final double d = ADoubleSerializerDeserializer.getDouble(b, s + 1);
if (Double.isFinite(d)) {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java
index dd03c97..83146ec 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java
@@ -18,8 +18,6 @@
*/
package org.apache.asterix.dataflow.data.nontagged.printers.csv;
-import java.io.PrintStream;
-
import org.apache.asterix.dataflow.data.nontagged.printers.PrintTools;
import org.apache.hyracks.algebricks.data.IPrinter;
import org.apache.hyracks.algebricks.data.IPrinterFactory;
@@ -30,11 +28,7 @@
private static final long serialVersionUID = 1L;
public static final ADatePrinterFactory INSTANCE = new ADatePrinterFactory();
- public static final IPrinter PRINTER = (byte[] b, int s, int l, PrintStream ps) -> {
- ps.print("\"");
- PrintTools.printDateString(b, s, l, ps);
- ps.print("\"");
- };
+ public static final IPrinter PRINTER = PrintTools::printDateString;
@Override
public IPrinter createPrinter(IEvaluatorContext context) {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java
index b5b6185..f28c012 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java
@@ -18,8 +18,6 @@
*/
package org.apache.asterix.dataflow.data.nontagged.printers.csv;
-import java.io.PrintStream;
-
import org.apache.asterix.dataflow.data.nontagged.printers.PrintTools;
import org.apache.hyracks.algebricks.data.IPrinter;
import org.apache.hyracks.algebricks.data.IPrinterFactory;
@@ -30,11 +28,7 @@
private static final long serialVersionUID = 1L;
public static final ADateTimePrinterFactory INSTANCE = new ADateTimePrinterFactory();
- public static final IPrinter PRINTER = (byte[] b, int s, int l, PrintStream ps) -> {
- ps.print("\"");
- PrintTools.printDateTimeString(b, s, l, ps);
- ps.print("\"");
- };
+ public static final IPrinter PRINTER = PrintTools::printDateTimeString;
@Override
public IPrinter createPrinter(IEvaluatorContext context) {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java
index 2f4d180..c3ef619 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java
@@ -26,10 +26,15 @@
import static org.apache.asterix.common.utils.CSVConstants.KEY_QUOTE;
import static org.apache.asterix.dataflow.data.nontagged.printers.csv.CSVUtils.DEFAULT_VALUES;
import static org.apache.asterix.dataflow.data.nontagged.printers.csv.CSVUtils.getCharOrDefault;
+import static org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode.DATETIME;
+import static org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode.DATE_ONLY;
+import static org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode.TIME_ONLY;
import java.io.PrintStream;
import java.util.Map;
+import org.apache.asterix.dataflow.data.nontagged.printers.PrintTools;
+import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
import org.apache.asterix.om.pointables.ARecordVisitablePointable;
import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
import org.apache.asterix.om.pointables.printer.IPrintVisitor;
@@ -42,12 +47,17 @@
import org.apache.hyracks.algebricks.data.IPrinterFactory;
import org.apache.hyracks.api.context.IEvaluatorContext;
import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
public class AObjectPrinterFactory implements IPrinterFactory {
private static final long serialVersionUID = 1L;
+ private static final String DATE_FORMAT_PROPERTY_NAME = "date";
+ private static final String TIME_FORMAT_PROPERTY_NAME = "time";
+ private static final String DATETIME_FORMAT_PROPERTY_NAME = "datetime";
private static final String DEFAULT_NULL_STRING = "";
private final ARecordType itemType;
private final Map<String, String> configuration;
+ private final Map<String, String> formatConfigs;
private final boolean emptyFieldAsNull;
private final String nullString;
private final char quote;
@@ -55,9 +65,28 @@
private final char escape;
private final char delimiter;
- private AObjectPrinterFactory(ARecordType itemType, Map<String, String> configuration) {
+ private DateTimeFormatUtils dateTimeFormatUtils;
+ private String timeFormat;
+ private String dateFormat;
+ private String datetimeFormat;
+ private byte[] timeFormatBytes;
+ private byte[] dateFormatBytes;
+ private byte[] datetimeFormatBytes;
+ private int timeFormatOffset;
+ private int dateFormatOffset;
+ private int datetimeFormatOffset;
+ private int timeFormatLength;
+ private int dateFormatLength;
+ private int datetimeFormatLength;
+ private boolean quoteTime;
+ private boolean quoteDate;
+ private boolean quoteDatetime;
+
+ private AObjectPrinterFactory(ARecordType itemType, Map<String, String> formatConfigs,
+ Map<String, String> configuration) {
this.itemType = itemType;
this.configuration = configuration;
+ this.formatConfigs = formatConfigs;
this.emptyFieldAsNull = Boolean.parseBoolean(configuration.get(KEY_EMPTY_STRING_AS_NULL));
this.nullString =
configuration.get(KEY_NULL_STR) != null ? configuration.get(KEY_NULL_STR) : DEFAULT_NULL_STRING;
@@ -65,10 +94,12 @@
this.quote = getCharOrDefault(configuration.get(KEY_QUOTE), DEFAULT_VALUES.get(KEY_QUOTE));
this.escape = getCharOrDefault(configuration.get(KEY_ESCAPE), DEFAULT_VALUES.get(KEY_ESCAPE));
this.delimiter = getCharOrDefault(configuration.get(KEY_DELIMITER), DEFAULT_VALUES.get(KEY_DELIMITER));
+ extractDateTimeFormats(formatConfigs);
}
- public static AObjectPrinterFactory createInstance(ARecordType itemType, Map<String, String> configuration) {
- return new AObjectPrinterFactory(itemType, configuration);
+ public static AObjectPrinterFactory createInstance(ARecordType itemType, Map<String, String> formatConfigs,
+ Map<String, String> configuration) {
+ return new AObjectPrinterFactory(itemType, formatConfigs, configuration);
}
public boolean printFlatValue(ATypeTag typeTag, byte[] b, int s, int l, PrintStream ps)
@@ -100,13 +131,31 @@
ADoublePrinterFactory.PRINTER.print(b, s, l, ps);
return true;
case DATE:
- ADatePrinterFactory.PRINTER.print(b, s, l, ps);
+ if (dateFormat == null) {
+ ADatePrinterFactory.PRINTER.print(b, s, l, ps);
+ } else {
+ long chronon = PrintTools.getDateChronon(b, s + 1);
+ printFormattedDatetime(dateFormatBytes, dateFormatOffset, dateFormatLength, ps, chronon, DATE_ONLY,
+ quoteDate);
+ }
return true;
case TIME:
- ATimePrinterFactory.PRINTER.print(b, s, l, ps);
+ if (timeFormat == null) {
+ ATimePrinterFactory.PRINTER.print(b, s, l, ps);
+ } else {
+ long chronon = PrintTools.getTimeChronon(b, s + 1);
+ printFormattedDatetime(timeFormatBytes, timeFormatOffset, timeFormatLength, ps, chronon, TIME_ONLY,
+ quoteTime);
+ }
return true;
case DATETIME:
- ADateTimePrinterFactory.PRINTER.print(b, s, l, ps);
+ if (datetimeFormat == null) {
+ ADateTimePrinterFactory.PRINTER.print(b, s, l, ps);
+ } else {
+ long chronon = PrintTools.getDateTimeChronon(b, s + 1);
+ printFormattedDatetime(datetimeFormatBytes, datetimeFormatOffset, datetimeFormatLength, ps, chronon,
+ DATETIME, quoteDatetime);
+ }
return true;
case DURATION:
ADurationPrinterFactory.PRINTER.print(b, s, l, ps);
@@ -161,7 +210,7 @@
final ARecordVisitablePointable recordVisitablePointable =
new ARecordVisitablePointable(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
final Pair<PrintStream, ATypeTag> streamTag = new Pair<>(null, null);
- final IPrintVisitor visitor = new APrintVisitor(context, itemType, configuration);
+ final IPrintVisitor visitor = new APrintVisitor(context, itemType, formatConfigs, configuration);
return (byte[] b, int s, int l, PrintStream ps) -> {
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[s]);
@@ -185,4 +234,50 @@
private void printString(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
CSVUtils.printString(b, s, l, ps, quote, forceQuote, escape, delimiter);
}
+
+ private void printFormattedDatetime(byte[] formatBytes, int formatOffset, int formatLength, PrintStream ps,
+ long chronon, DateTimeFormatUtils.DateTimeParseMode dateTimeParseMode, boolean shouldQuote)
+ throws HyracksDataException {
+ if (shouldQuote) {
+ ps.print("\"");
+ }
+ dateTimeFormatUtils.printDateTime(chronon, formatBytes, formatOffset, formatLength, ps, dateTimeParseMode);
+ if (shouldQuote) {
+ ps.print("\"");
+ }
+ }
+
+ private void extractDateTimeFormats(Map<String, String> formatConfigs) {
+ if (formatConfigs != null && !formatConfigs.isEmpty()) {
+ timeFormat = formatConfigs.get(TIME_FORMAT_PROPERTY_NAME);
+ dateFormat = formatConfigs.get(DATE_FORMAT_PROPERTY_NAME);
+ datetimeFormat = formatConfigs.get(DATETIME_FORMAT_PROPERTY_NAME);
+ dateTimeFormatUtils = DateTimeFormatUtils.getInstance();
+
+ UTF8StringPointable pointable;
+ if (timeFormat != null) {
+ pointable = UTF8StringPointable.generateUTF8Pointable(timeFormat);
+ timeFormatBytes = pointable.getByteArray();
+ timeFormatOffset = pointable.getStartOffset() + 1;
+ timeFormatLength = pointable.getLength() - 1;
+ quoteTime = timeFormat.indexOf(this.delimiter) != -1;
+ }
+
+ if (dateFormat != null) {
+ pointable = UTF8StringPointable.generateUTF8Pointable(dateFormat);
+ dateFormatBytes = pointable.getByteArray();
+ dateFormatOffset = pointable.getStartOffset() + 1;
+ dateFormatLength = pointable.getLength() - 1;
+ quoteDate = dateFormat.indexOf(this.delimiter) != -1;
+ }
+
+ if (datetimeFormat != null) {
+ pointable = UTF8StringPointable.generateUTF8Pointable(datetimeFormat);
+ datetimeFormatBytes = pointable.getByteArray();
+ datetimeFormatOffset = pointable.getStartOffset() + 1;
+ datetimeFormatLength = pointable.getLength() - 1;
+ quoteDatetime = datetimeFormat.indexOf(this.delimiter) != -1;
+ }
+ }
+ }
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java
index d3ec388..cef0e6e 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java
@@ -39,11 +39,14 @@
private static final long serialVersionUID = 1L;
private final ARecordType recType;
private final ARecordType itemType;
+ private final Map<String, String> formatConfigs;
private final Map<String, String> configuration;
- public ARecordPrinterFactory(ARecordType recType, ARecordType itemType, Map<String, String> configuration) {
+ public ARecordPrinterFactory(ARecordType recType, ARecordType itemType, Map<String, String> formatConfigs,
+ Map<String, String> configuration) {
this.recType = recType;
this.itemType = itemType;
+ this.formatConfigs = formatConfigs;
this.configuration = configuration;
}
@@ -54,7 +57,7 @@
final IAType inputType =
recType == null ? DefaultOpenFieldType.getDefaultOpenFieldType(ATypeTag.OBJECT) : recType;
final IVisitablePointable recAccessor = allocator.allocateRecordValue(inputType);
- final APrintVisitor printVisitor = new APrintVisitor(context, itemType, configuration);
+ final APrintVisitor printVisitor = new APrintVisitor(context, itemType, formatConfigs, configuration);
final Pair<PrintStream, ATypeTag> arg = new Pair<>(null, null);
return new IPrinter() {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java
index 2a73c56..e647ec8 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java
@@ -18,8 +18,6 @@
*/
package org.apache.asterix.dataflow.data.nontagged.printers.csv;
-import java.io.PrintStream;
-
import org.apache.asterix.dataflow.data.nontagged.printers.PrintTools;
import org.apache.hyracks.algebricks.data.IPrinter;
import org.apache.hyracks.algebricks.data.IPrinterFactory;
@@ -30,11 +28,7 @@
private static final long serialVersionUID = 1L;
public static final ATimePrinterFactory INSTANCE = new ATimePrinterFactory();
- public static final IPrinter PRINTER = (byte[] b, int s, int l, PrintStream ps) -> {
- ps.print("\"");
- PrintTools.printTimeString(b, s, l, ps);
- ps.print("\"");
- };
+ public static final IPrinter PRINTER = PrintTools::printTimeString;
@Override
public IPrinter createPrinter(IEvaluatorContext context) {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/CSVPrinterFactoryProvider.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/CSVPrinterFactoryProvider.java
index 4d28ce4..799df8d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/CSVPrinterFactoryProvider.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/CSVPrinterFactoryProvider.java
@@ -66,20 +66,22 @@
public class CSVPrinterFactoryProvider implements IPrinterFactoryProvider {
private final ARecordType itemType;
private final Map<String, String> configuration;
+ private final Map<String, String> formatConfigs;
private final SourceLocation sourceLocation;
public static final CSVPrinterFactoryProvider INSTANCE =
- new CSVPrinterFactoryProvider(null, Collections.emptyMap(), null);
+ new CSVPrinterFactoryProvider(null, Collections.emptyMap(), null, null);
public static CSVPrinterFactoryProvider createInstance(ARecordType itemType, Map<String, String> configuration,
- SourceLocation sourceLocation) {
- return new CSVPrinterFactoryProvider(itemType, configuration, sourceLocation);
+ Map<String, String> formatConfigs, SourceLocation sourceLocation) {
+ return new CSVPrinterFactoryProvider(itemType, configuration, formatConfigs, sourceLocation);
}
private CSVPrinterFactoryProvider(ARecordType itemType, Map<String, String> configuration,
- SourceLocation sourceLocation) {
+ Map<String, String> formatConfigs, SourceLocation sourceLocation) {
this.itemType = itemType;
this.configuration = configuration;
+ this.formatConfigs = formatConfigs;
this.sourceLocation = sourceLocation;
}
@@ -137,7 +139,7 @@
configuration.get(KEY_FORCE_QUOTE), configuration.get(KEY_ESCAPE),
configuration.get(KEY_DELIMITER));
case OBJECT:
- return new ARecordPrinterFactory((ARecordType) type, itemType, configuration);
+ return new ARecordPrinterFactory((ARecordType) type, itemType, formatConfigs, configuration);
case ARRAY:
throw new NotImplementedException("'OrderedList' type unsupported for CSV output");
case MULTISET:
@@ -167,7 +169,7 @@
break;
}
}
- return AObjectPrinterFactory.createInstance(itemType, configuration);
+ return AObjectPrinterFactory.createInstance(itemType, formatConfigs, configuration);
}
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
index c6cb707..24909d7 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
@@ -93,6 +93,15 @@
}
}
+ public static void warnValueOutOfRange(IEvaluatorContext ctx, SourceLocation srcLoc, FunctionIdentifier fid,
+ int inputPosition, int lowerBound, int upperBound, int actual) {
+ IWarningCollector warningCollector = ctx.getWarningCollector();
+ if (warningCollector.shouldWarn()) {
+ warningCollector.warn(Warning.of(srcLoc, ErrorCode.VALUE_OUT_OF_RANGE, fid,
+ ExceptionUtil.indexToPosition(inputPosition), lowerBound, upperBound, actual));
+ }
+ }
+
public static void warnTypeMismatch(IEvaluatorContext ctx, SourceLocation srcLoc, FunctionIdentifier fid,
byte actualType, int argIdx, ATypeTag expectedType) {
warnTypeMismatch(ctx, srcLoc, fid, actualType, argIdx, expectedType::toString);
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 2bf5adc..f631b32 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
@@ -398,6 +398,8 @@
public static final FunctionIdentifier STRING_REPEAT = FunctionConstants.newAsterix("repeat", 2);
public static final FunctionIdentifier STRING_SPLIT = FunctionConstants.newAsterix("split", 2);
public static final FunctionIdentifier STRING_PARSE_JSON = FunctionConstants.newAsterix("parse-json", 1);
+ public static final FunctionIdentifier STRING_LPAD = FunctionConstants.newAsterix("lpad", 3);
+ public static final FunctionIdentifier STRING_RPAD = FunctionConstants.newAsterix("rpad", 3);
public static final FunctionIdentifier DATASET =
FunctionConstants.newAsterix("dataset", FunctionIdentifier.VARARGS); // 1, 2 or 3
@@ -1305,6 +1307,14 @@
public static final FunctionIdentifier ACCESS_NESTED_FIELD = FunctionConstants.newAsterix("access-nested-field", 2);
+ public static final FunctionIdentifier IF_ERROR = FunctionConstants.newAsterix("if-error", 2);
+
+ // crypto
+ public static final FunctionIdentifier SHA1_HEX = FunctionConstants.newAsterix("sha1-hex", 1);
+ public static final FunctionIdentifier SHA1_BASE64 = FunctionConstants.newAsterix("sha1-base64", 1);
+
+ public static final FunctionIdentifier FROM_BASE = FunctionConstants.newAsterix("from-base", 2);
+
static {
// first, take care of Algebricks builtin functions
addFunction(IS_MISSING, BooleanOnlyTypeComputer.INSTANCE, true);
@@ -1335,7 +1345,6 @@
addFunction(NOT, ABooleanTypeComputer.INSTANCE, true);
addFunction(GET_TYPE, AStringTypeComputer.INSTANCE, true);
-
addPrivateFunction(EQ, BooleanFunctionTypeComputer.INSTANCE, true);
addPrivateFunction(LE, BooleanFunctionTypeComputer.INSTANCE, true);
addPrivateFunction(GE, BooleanFunctionTypeComputer.INSTANCE, true);
@@ -1532,6 +1541,8 @@
addFunction(STRING_REPEAT, AStringTypeComputer.INSTANCE_NULLABLE, true);
addFunction(STRING_SPLIT, UniformInputTypeComputer.STRING_STRING_LIST_INSTANCE, true);
addFunction(STRING_PARSE_JSON, AnyTypeComputer.INSTANCE, true);
+ addFunction(STRING_LPAD, AStringTypeComputer.INSTANCE_NULLABLE, true);
+ addFunction(STRING_RPAD, AStringTypeComputer.INSTANCE_NULLABLE, true);
addPrivateFunction(ORDERED_LIST_CONSTRUCTOR, OrderedListConstructorTypeComputer.INSTANCE, true);
addFunction(POINT_CONSTRUCTOR, APointTypeComputer.INSTANCE, true);
@@ -2161,6 +2172,7 @@
addPrivateFunction(COLLECTION_TO_SEQUENCE, CollectionToSequenceTypeComputer.INSTANCE, true);
addFunction(SERIALIZED_SIZE, AInt64TypeComputer.INSTANCE, true);
// used by CBO's internal sampling queries for determining projection sizes
+ addPrivateFunction(IF_ERROR, AnyTypeComputer.INSTANCE, true);
// external lookup
addPrivateFunction(EXTERNAL_LOOKUP, AnyTypeComputer.INSTANCE, false);
@@ -2177,6 +2189,11 @@
addPrivateFunction(ACCESS_FIELD, FieldAccessByNameResultType.INSTANCE, false);
addPrivateFunction(ACCESS_NESTED_FIELD, FieldAccessNestedResultType.INSTANCE, false);
+ // crypto
+ addFunction(SHA1_HEX, AStringTypeComputer.INSTANCE_NULLABLE, true);
+ addFunction(SHA1_BASE64, AStringTypeComputer.INSTANCE_NULLABLE, true);
+
+ addFunction(FROM_BASE, AInt64TypeComputer.INSTANCE_NULLABLE, true);
}
static {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/printer/csv/APrintVisitor.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/printer/csv/APrintVisitor.java
index 7eadca5..7d5a52d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/printer/csv/APrintVisitor.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/printer/csv/APrintVisitor.java
@@ -42,13 +42,16 @@
public class APrintVisitor extends AbstractPrintVisitor {
private final IEvaluatorContext context;
private final ARecordType itemType;
+ private final Map<String, String> formatConfigs;
private final Map<String, String> configuration;
private AObjectPrinterFactory objectPrinterFactory;
- public APrintVisitor(IEvaluatorContext context, ARecordType itemType, Map<String, String> configuration) {
+ public APrintVisitor(IEvaluatorContext context, ARecordType itemType, Map<String, String> formatConfigs,
+ Map<String, String> configuration) {
super();
this.context = context;
this.itemType = itemType;
+ this.formatConfigs = formatConfigs;
this.configuration = configuration;
}
@@ -69,7 +72,7 @@
protected boolean printFlatValue(ATypeTag typeTag, byte[] b, int s, int l, PrintStream ps)
throws HyracksDataException {
if (objectPrinterFactory == null) {
- objectPrinterFactory = AObjectPrinterFactory.createInstance(itemType, configuration);
+ objectPrinterFactory = AObjectPrinterFactory.createInstance(itemType, formatConfigs, configuration);
}
return objectPrinterFactory.printFlatValue(typeTag, b, s, l, ps);
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/FromBaseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/FromBaseDescriptor.java
new file mode 100644
index 0000000..fb57fb3
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/FromBaseDescriptor.java
@@ -0,0 +1,127 @@
+/*
+ * 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.evaluators.functions;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.common.ArgumentUtils;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import org.apache.hyracks.util.string.UTF8StringUtil;
+
+@MissingNullInOutFunction
+public class FromBaseDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = FromBaseDescriptor::new;
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IEvaluatorContext ctx) throws HyracksDataException {
+ return new IScalarEvaluator() {
+
+ private final ArrayBackedValueStorage storage = new ArrayBackedValueStorage();
+ private final StringBuilder strBuilder = new StringBuilder();
+ private final IScalarEvaluator evalString = args[0].createScalarEvaluator(ctx);
+ private final IScalarEvaluator evalBase = args[1].createScalarEvaluator(ctx);
+ private final IPointable argString = new VoidPointable();
+ private final IPointable argNumber = new VoidPointable();
+ private final AMutableInt32 aInt32 = new AMutableInt32(0);
+ private final AMutableInt64 aInt64 = new AMutableInt64(0);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AInt64> int64Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ evalString.evaluate(tuple, argString);
+ evalBase.evaluate(tuple, argNumber);
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, argString, argNumber)) {
+ return;
+ }
+ byte[] bytes = argNumber.getByteArray();
+ int offset = argNumber.getStartOffset();
+ if (!ArgumentUtils.setInteger(ctx, sourceLoc, getIdentifier(), 1, bytes, offset, aInt32)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+ int base = aInt32.getIntegerValue();
+ if (base < 2 || base > 36) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnValueOutOfRange(ctx, sourceLoc, getIdentifier(), 1, 2, 36, base);
+ return;
+ }
+
+ bytes = argString.getByteArray();
+ offset = argString.getStartOffset();
+ if (bytes[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), bytes[offset], 0,
+ ATypeTag.STRING);
+ return;
+ }
+ strBuilder.setLength(0);
+ UTF8StringUtil.toString(strBuilder, bytes, offset + 1);
+
+ try {
+ aInt64.setValue(Long.parseLong(strBuilder, 0, strBuilder.length(), base));
+ } catch (NumberFormatException e) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnFunctionEvalFailed(ctx, sourceLoc, getIdentifier(), e.getMessage());
+ return;
+ }
+ storage.reset();
+ int64Serde.serialize(aInt64, storage.getDataOutput());
+ result.set(storage);
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.FROM_BASE;
+ }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfErrorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfErrorDescriptor.java
new file mode 100644
index 0000000..d51d8d0
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfErrorDescriptor.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.runtime.evaluators.functions;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public final class IfErrorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = IfErrorDescriptor::new;
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
+ return new AbstractScalarEval(sourceLoc, getIdentifier()) {
+ private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+ private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+ private final VoidPointable arg = VoidPointable.FACTORY.createPointable();
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ try {
+ eval0.evaluate(tuple, arg);
+ result.set(arg);
+ } catch (Throwable th) {
+ eval1.evaluate(tuple, arg);
+ result.set(arg);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.IF_ERROR;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1Base64Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1Base64Descriptor.java
new file mode 100644
index 0000000..fb9eef6
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1Base64Descriptor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.evaluators.functions;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+@MissingNullInOutFunction
+public class Sha1Base64Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = Sha1Base64Descriptor::new;
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IEvaluatorContext ctx) throws HyracksDataException {
+ return new Sha1StringEvaluator(args, ctx, sourceLoc, getIdentifier(),
+ Sha1StringEvaluator.Encoding.BASE64);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.SHA1_BASE64;
+ }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1HexDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1HexDescriptor.java
new file mode 100644
index 0000000..bf3449e
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1HexDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.evaluators.functions;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+@MissingNullInOutFunction
+public class Sha1HexDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = Sha1HexDescriptor::new;
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IEvaluatorContext ctx) throws HyracksDataException {
+ return new Sha1StringEvaluator(args, ctx, sourceLoc, getIdentifier(), Sha1StringEvaluator.Encoding.HEX);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.SHA1_HEX;
+ }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1StringEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1StringEvaluator.java
new file mode 100755
index 0000000..3bbf125
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/Sha1StringEvaluator.java
@@ -0,0 +1,111 @@
+/*
+ * 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.evaluators.functions;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.asterix.dataflow.data.nontagged.printers.PrintTools;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import org.apache.hyracks.util.bytes.Base64Printer;
+import org.apache.hyracks.util.bytes.HexPrinter;
+import org.apache.hyracks.util.string.UTF8StringWriter;
+
+public class Sha1StringEvaluator extends AbstractScalarEval {
+
+ private final IScalarEvaluator eval;
+ private final ArrayBackedValueStorage storage;
+ private final IPointable argPtr;
+ private final UTF8StringWriter writer;
+ private final StringBuilder strBuilder;
+ private final MessageDigest md;
+ private final IEvaluatorContext ctx;
+ private final Encoding encoding;
+
+ Sha1StringEvaluator(IScalarEvaluatorFactory[] args, IEvaluatorContext ctx, SourceLocation srcLoc,
+ FunctionIdentifier funId, Encoding encoding) throws HyracksDataException {
+ super(srcLoc, funId);
+ this.ctx = ctx;
+ this.encoding = encoding;
+ storage = new ArrayBackedValueStorage(43);
+ eval = args[0].createScalarEvaluator(ctx);
+ strBuilder = new StringBuilder(40);
+ writer = new UTF8StringWriter();
+ argPtr = new VoidPointable();
+ try {
+ md = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ throw HyracksDataException.create(e);
+ }
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ eval.evaluate(tuple, argPtr);
+ if (PointableHelper.checkAndSetMissingOrNull(result, argPtr)) {
+ return;
+ }
+ byte[] bytes = argPtr.getByteArray();
+ int offset = argPtr.getStartOffset();
+ if (bytes[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, srcLoc, funID, bytes[offset], 0, ATypeTag.STRING);
+ return;
+ }
+
+ storage.reset();
+ try {
+ // convert modified UTF-8 bytes to UTF-8 bytes
+ PrintTools.writeUTF8StringRaw(bytes, offset + 1, argPtr.getLength() - 1, storage.getDataOutput());
+ md.update(storage.getByteArray(), storage.getStartOffset(), storage.getLength());
+ byte[] digestBytes = md.digest();
+ strBuilder.setLength(0);
+ // convert UTF-8 bytes to hex or base64 string
+ if (encoding == Encoding.HEX) {
+ HexPrinter.printHexString(digestBytes, 0, digestBytes.length, strBuilder);
+ } else {
+ Base64Printer.printBase64Binary(digestBytes, 0, digestBytes.length, strBuilder);
+ }
+ // serialize the encoded string as modified UTF-8
+ storage.reset();
+ storage.getDataOutput().writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ writer.writeUTF8(strBuilder, storage.getDataOutput());
+ } catch (IOException e) {
+ throw HyracksDataException.create(e);
+ }
+ result.set(storage);
+ }
+
+ enum Encoding {
+ HEX,
+ BASE64;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLpadDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLpadDescriptor.java
new file mode 100644
index 0000000..a801d9a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLpadDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.evaluators.functions;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+@MissingNullInOutFunction
+public class StringLpadDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = StringLpadDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.STRING_LPAD;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
+ return new StringPadEvaluator(ctx, args[0], args[1], args[2], StringLpadDescriptor.this.getIdentifier(),
+ sourceLoc, true) {
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPadEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPadEvaluator.java
new file mode 100644
index 0000000..d4b01e2
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPadEvaluator.java
@@ -0,0 +1,169 @@
+/*
+ * 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.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.evaluators.common.ArgumentUtils;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import org.apache.hyracks.util.string.UTF8StringUtil;
+
+public abstract class StringPadEvaluator extends AbstractScalarEval {
+
+ private final IEvaluatorContext ctx;
+ private final IScalarEvaluator inStrEval;
+ private final IScalarEvaluator lenEval;
+ private final IScalarEvaluator padStrEval;
+
+ private final UTF8StringPointable inStrUtf8Ptr = new UTF8StringPointable();
+ private final UTF8StringPointable padStrUtf8Ptr = new UTF8StringPointable();
+ private final IPointable inStrArg = new VoidPointable();
+ private final IPointable lenArg = new VoidPointable();
+ private final IPointable padStrArg = new VoidPointable();
+ private final AMutableInt32 mutableInt = new AMutableInt32(0);
+
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ private final DataOutput out = resultStorage.getDataOutput();
+ private final GrowableArray builderInternalArray = new GrowableArray();
+ private final UTF8StringBuilder builder = new UTF8StringBuilder();
+ private final boolean lpad;
+
+ public StringPadEvaluator(IEvaluatorContext ctx, IScalarEvaluatorFactory inStrEvalFact,
+ IScalarEvaluatorFactory lenEvalFact, IScalarEvaluatorFactory padStrEvalFact, FunctionIdentifier funcID,
+ SourceLocation srcLoc, boolean lpad) throws HyracksDataException {
+ super(srcLoc, funcID);
+ this.lpad = lpad;
+ this.inStrEval = inStrEvalFact.createScalarEvaluator(ctx);
+ this.lenEval = lenEvalFact.createScalarEvaluator(ctx);
+ this.padStrEval = padStrEvalFact.createScalarEvaluator(ctx);
+ this.ctx = ctx;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ inStrEval.evaluate(tuple, inStrArg);
+ lenEval.evaluate(tuple, lenArg);
+ padStrEval.evaluate(tuple, padStrArg);
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, inStrArg, lenArg, padStrArg)) {
+ return;
+ }
+
+ byte[] inStrBytes = inStrArg.getByteArray();
+ int inStrStart = inStrArg.getStartOffset();
+ if (inStrBytes[inStrStart] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, srcLoc, funID, inStrBytes[inStrStart], 0, ATypeTag.STRING);
+ return;
+ }
+
+ byte[] lenBytes = lenArg.getByteArray();
+ int lenStart = lenArg.getStartOffset();
+ if (!ArgumentUtils.setInteger(ctx, srcLoc, funID, 1, lenBytes, lenStart, mutableInt)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+ // Desired length of the string in Unicode code points
+ int targetNumCodePoints = mutableInt.getIntegerValue();
+ if (targetNumCodePoints < 0) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnNegativeValue(ctx, srcLoc, funID, 1, targetNumCodePoints);
+ return;
+ }
+
+ // TODO: usually this will be a constant. if constant, the code could be optimized
+ byte[] padStrBytes = padStrArg.getByteArray();
+ int padStrStart = padStrArg.getStartOffset();
+ if (padStrBytes[padStrStart] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, srcLoc, funID, padStrBytes[padStrStart], 2, ATypeTag.STRING);
+ return;
+ }
+
+ int inStrCodePointsNum = UTF8StringUtil.getNumCodePoint(inStrBytes, inStrStart + 1);
+ if (inStrCodePointsNum == targetNumCodePoints) {
+ result.set(inStrArg);
+ return;
+ }
+ try {
+ builderInternalArray.reset();
+ builder.reset(builderInternalArray, targetNumCodePoints);
+ // skip the type tag byte
+ inStrUtf8Ptr.set(inStrBytes, inStrStart + 1, inStrArg.getLength() - 1);
+ padStrUtf8Ptr.set(padStrBytes, padStrStart + 1, padStrArg.getLength() - 1);
+
+ process(targetNumCodePoints, inStrCodePointsNum);
+ builder.finish();
+
+ resultStorage.reset();
+ out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ out.write(builderInternalArray.getByteArray(), 0, builderInternalArray.getLength());
+ //result -> type tag, len, actual data
+ result.set(resultStorage);
+ } catch (IOException e) {
+ throw HyracksDataException.create(e);
+ }
+ }
+
+ public void process(int targetNumCodePoints, int inStrCodePointsNum) throws IOException {
+ if (targetNumCodePoints < inStrCodePointsNum) {
+ truncate(targetNumCodePoints);
+ } else {
+ int numCodePointsToPad = targetNumCodePoints - inStrCodePointsNum;
+ if (lpad) {
+ // For LPAD: first, append the required padding characters.
+ appendPaddingCodepoints(numCodePointsToPad);
+ // Then, append the codepoints of the original string.
+ appendCodePoints();
+ } else {
+ appendCodePoints();
+ appendPaddingCodepoints(numCodePointsToPad);
+ }
+ }
+ }
+
+ private void truncate(int targetNumCodePoints) throws IOException {
+ UTF8StringPointable.append(inStrUtf8Ptr, targetNumCodePoints, builder, builderInternalArray);
+ }
+
+ private void appendCodePoints() throws IOException {
+ builder.appendUtf8StringPointable(inStrUtf8Ptr);
+ }
+
+ private void appendPaddingCodepoints(int numCodePointsToPad) throws IOException {
+ UTF8StringPointable.append(padStrUtf8Ptr, numCodePointsToPad, builder, builderInternalArray);
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRpadDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRpadDescriptor.java
new file mode 100644
index 0000000..2ff28e4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRpadDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.evaluators.functions;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+@MissingNullInOutFunction
+public class StringRpadDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = StringRpadDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.STRING_RPAD;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
+ return new StringPadEvaluator(ctx, args[0], args[1], args[2], StringRpadDescriptor.this.getIdentifier(),
+ sourceLoc, false) {
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
index d682d7a..166352c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
@@ -382,12 +382,14 @@
import org.apache.asterix.runtime.evaluators.functions.CreateUUIDDescriptor;
import org.apache.asterix.runtime.evaluators.functions.DecodeDataverseNameDescriptor;
import org.apache.asterix.runtime.evaluators.functions.DeepEqualityDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.FromBaseDescriptor;
import org.apache.asterix.runtime.evaluators.functions.FullTextContainsFunctionDescriptor;
import org.apache.asterix.runtime.evaluators.functions.FullTextContainsWithoutOptionFunctionDescriptor;
import org.apache.asterix.runtime.evaluators.functions.GetIntersectionDescriptor;
import org.apache.asterix.runtime.evaluators.functions.GetItemDescriptor;
import org.apache.asterix.runtime.evaluators.functions.GetJobParameterByNameDescriptor;
import org.apache.asterix.runtime.evaluators.functions.GetTypeDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.IfErrorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfInfDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfMissingDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfMissingOrNullDescriptor;
@@ -463,6 +465,8 @@
import org.apache.asterix.runtime.evaluators.functions.RandomWithSeedDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ReferenceTileDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SerializedSizeDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.Sha1Base64Descriptor;
+import org.apache.asterix.runtime.evaluators.functions.Sha1HexDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SleepDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SpatialAreaDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SpatialCellDescriptor;
@@ -479,6 +483,7 @@
import org.apache.asterix.runtime.evaluators.functions.StringLengthDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringLikeDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringLowerCaseDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringLpadDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringPositionDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringPositionOffset1Descriptor;
import org.apache.asterix.runtime.evaluators.functions.StringRTrim2Descriptor;
@@ -499,6 +504,7 @@
import org.apache.asterix.runtime.evaluators.functions.StringReplaceDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringReplaceWithLimitDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringReverseDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRpadDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringSplitDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringStartsWithDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringToCodePointDescriptor;
@@ -1055,6 +1061,7 @@
fc.add(NumericSignDescriptor.FACTORY);
fc.add(NumericTruncDescriptor.FACTORY);
fc.add(NumericATan2Descriptor.FACTORY);
+ fc.add(FromBaseDescriptor.FACTORY);
// Comparisons.
fc.add(EqualsDescriptor.FACTORY);
@@ -1141,6 +1148,8 @@
fc.add(StringReplaceWithLimitDescriptor.FACTORY);
fc.add(StringReverseDescriptor.FACTORY);
fc.add(StringSplitDescriptor.FACTORY);
+ fc.add(StringLpadDescriptor.FACTORY);
+ fc.add(StringRpadDescriptor.FACTORY);
// Constructors
fc.add(ABooleanConstructorDescriptor.FACTORY);
@@ -1356,11 +1365,16 @@
// Record function
fc.add(RecordPairsDescriptor.FACTORY);
+ // Crypto functions
+ fc.add(Sha1HexDescriptor.FACTORY);
+ fc.add(Sha1Base64Descriptor.FACTORY);
+
// Other functions
fc.add(DecodeDataverseNameDescriptor.FACTORY);
fc.add(RandomWithSeedDescriptor.FACTORY);
fc.add(SerializedSizeDescriptor.FACTORY);
fc.add(PutAutogeneratedKeyDescriptor.FACTORY);
+ fc.add(IfErrorDescriptor.FACTORY);
ServiceLoader.load(IFunctionRegistrant.class).iterator().forEachRemaining(c -> c.register(fc));
return fc;
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 35f9219..1216f8a 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -662,9 +662,9 @@
${coverageArgLine}
${extraFailsafeArgLine}
</argLine>
- <systemProperties>
+ <systemPropertyVariables>
<log4j.configurationFile>${testLog4jConfigFile}</log4j.configurationFile>
- </systemProperties>
+ </systemPropertyVariables>
<includes>
<include>${itest.includes}</include>
</includes>
@@ -1116,6 +1116,10 @@
<artifactId>jsr311-api</artifactId>
</exclusion>
<exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ </exclusion>
+ <exclusion>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
</exclusion>
@@ -1190,10 +1194,6 @@
<artifactId>jline</artifactId>
</exclusion>
<exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- </exclusion>
- <exclusion>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
</exclusion>
@@ -1569,35 +1569,7 @@
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http2</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-epoll</artifactId>
+ <artifactId>netty-transport-classes-epoll</artifactId>
</exclusion>
</exclusions>
</dependency>
@@ -1693,70 +1665,6 @@
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler-proxy</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http2</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-epoll</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-unix-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-tcnative-boringssl-static</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-kqueue</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver-dns-native-macos</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </exclusion>
</exclusions>
</dependency>
<dependency>
@@ -1766,34 +1674,6 @@
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler-proxy</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http2</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
<exclusion>
@@ -1802,104 +1682,18 @@
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
- <artifactId>netty-tcnative-boringssl-static</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
- <artifactId>netty-resolver</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
<artifactId>netty-resolver-dns-native-macos</artifactId>
</exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-common</artifactId>
<version>${azurecommonjavasdk.version}</version>
- <exclusions>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler-proxy</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http2</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-epoll</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-unix-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-tcnative-boringssl-static</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-kqueue</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver-dns</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-resolver-dns-native-macos</artifactId>
- </exclusion>
- <exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </exclusion>
- </exclusions>
</dependency>
<!-- Azure Blob Storage end -->
<!-- Google Cloud Storage start -->
@@ -2067,12 +1861,17 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
- <version>9.4.56.v20240826</version>
+ <version>9.4.57.v20241219</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util-ajax</artifactId>
- <version>9.4.56.v20240826</version>
+ <version>9.4.57.v20241219</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-tcnative-boringssl-static</artifactId>
+ <version>2.0.71.Final</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
index 800c839..920f567 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
@@ -143,21 +143,20 @@
Set<LogicalVariable> firstDeliveredVars = unorderedFirstDelivered.getColumnSet();
UnorderedPartitionedProperty unorderedRequired =
(UnorderedPartitionedProperty) requirements;
- Set<LogicalVariable> originalRequiredVars = unorderedRequired.getColumnSet();
Set<LogicalVariable> modifiedRequiredVars = new ListSet<>();
Map<LogicalVariable, EquivalenceClass> eqmap = context.getEquivalenceClassMap(op);
Set<LogicalVariable> coveredVars = new ListSet<>();
- List<LogicalVariable> keysFirst =
- (keysRightBranch.containsAll(originalRequiredVars)) ? keysRightBranch
- : keysLeftBranch;
+ List<LogicalVariable> keysFirst = (keysRightBranch.containsAll(firstDeliveredVars))
+ ? keysRightBranch : keysLeftBranch;
List<LogicalVariable> keysSecond =
keysFirst == keysRightBranch ? keysLeftBranch : keysRightBranch;
- for (LogicalVariable r : originalRequiredVars) {
- EquivalenceClass ecSnd = eqmap.get(r);
+ for (LogicalVariable r : firstDeliveredVars) {
+ EquivalenceClass ecFirst = eqmap.get(r);
boolean found = false;
int j = 0;
for (LogicalVariable rvar : keysFirst) {
- if (rvar == r || ecSnd != null && eqmap.get(rvar) == ecSnd) {
+ if (!modifiedRequiredVars.contains(keysSecond.get(j))
+ && (rvar == r || (ecFirst != null && ecFirst == eqmap.get(rvar)))) {
found = true;
break;
}
@@ -168,16 +167,8 @@
+ " among " + keysFirst);
}
LogicalVariable v2 = keysSecond.get(j);
- EquivalenceClass ecFst = eqmap.get(v2);
- for (LogicalVariable vset1 : firstDeliveredVars) {
- if (vset1 == v2 || ecFst != null && eqmap.get(vset1) == ecFst) {
- if (!coveredVars.add(vset1)) {
- continue;
- }
- modifiedRequiredVars.add(r);
- break;
- }
- }
+ coveredVars.add(r);
+ modifiedRequiredVars.add(v2);
if (coveredVars.equals(firstDeliveredVars)) {
break;
}
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/InvokeUtil.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/InvokeUtil.java
index 9326427..2a77bab 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/InvokeUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/InvokeUtil.java
@@ -56,7 +56,12 @@
/**
* Executes the passed interruptible, retrying if the operation is interrupted. Once the interruptible
* completes, the current thread will be re-interrupted, if the original operation was interrupted.
+ *
+ * @deprecated this method does not throw an exception when the action is interrupted, or when the thread
+ * was interrupted prior to calling this method. This can lead to confusing behavior, if the caller
+ * does not check for interrupted thread state after calling this method.
*/
+ @Deprecated
public static void doUninterruptibly(InterruptibleAction interruptible) {
boolean interrupted = Thread.interrupted();
try {
@@ -219,7 +224,6 @@
public static void tryWithCleanupsAsHyracks(ThrowingAction action, ThrowingAction... cleanups)
throws HyracksDataException {
Throwable savedT = null;
- boolean suppressedInterrupted = false;
try {
action.run();
} catch (Throwable t) {
@@ -229,21 +233,16 @@
try {
cleanup.run();
} catch (Throwable t) {
- if (savedT != null) {
- savedT.addSuppressed(t);
- suppressedInterrupted |= t instanceof InterruptedException;
- } else {
- savedT = t;
- }
+ savedT = ExceptionUtils.suppress(savedT, t);
}
}
}
+ if (Thread.interrupted()) {
+ savedT = ExceptionUtils.suppress(savedT, new InterruptedException());
+ }
if (savedT == null) {
return;
}
- if (suppressedInterrupted) {
- Thread.currentThread().interrupt();
- }
throw HyracksDataException.create(savedT);
}
@@ -251,7 +250,6 @@
// catching Throwable, instanceofs, false-positive unreachable code
public static void tryWithCleanups(ThrowingAction action, ThrowingAction... cleanups) throws Exception {
Throwable savedT = null;
- boolean suppressedInterrupted = false;
try {
action.run();
} catch (Throwable t) {
@@ -261,21 +259,16 @@
try {
cleanup.run();
} catch (Throwable t) {
- if (savedT != null) {
- savedT.addSuppressed(t);
- suppressedInterrupted = suppressedInterrupted || t instanceof InterruptedException;
- } else {
- savedT = t;
- }
+ savedT = ExceptionUtils.suppress(savedT, t);
}
}
}
+ if (Thread.interrupted()) {
+ savedT = ExceptionUtils.suppress(savedT, new InterruptedException());
+ }
if (savedT == null) {
return;
}
- if (suppressedInterrupted) {
- Thread.currentThread().interrupt();
- }
if (savedT instanceof Error) {
throw (Error) savedT;
} else if (savedT instanceof Exception) {
@@ -285,6 +278,20 @@
}
}
+ /**
+ * Runs the supplied action, and any specified cleanups. Any pending interruption will be cleared prior
+ * to running the action and all cleanups. An error will be logged if the action and/or any of the cleanups
+ * are themselves interrupted. Finally, if any action or cleanup was interrupted, or if the there was an
+ * interrupt cleared as part of running any of these activities, either an InterruptedException will be returned
+ * if the action & cleanups all ran without exception, or an InterruptedException will be suppressed into the
+ * exception if the action or any of the cleanups threw an exception. In the case where InterruptedException is
+ * suppressed, the current thread will be interrupted.
+ *
+ * @param action the action to run
+ * @param cleanups the cleanups to run after the action
+ * @return Exception if the action throws an exception or the action or any of the cleanups are interrupted, or if
+ * the current thread was interrupted before running the action or any of the cleanups.
+ */
@SuppressWarnings({ "squid:S1181", "squid:S1193", "ConstantConditions", "UnreachableCode" })
// catching Throwable, instanceofs, false-positive unreachable code
public static Exception tryUninterruptibleWithCleanups(Exception root, ThrowingAction action,
@@ -297,12 +304,24 @@
return root;
}
+ /**
+ * Runs the supplied action, and any specified cleanups. Any pending interruption will be cleared prior
+ * to running the action and all cleanups. An error will be logged if the action and/or any of the cleanups
+ * are themselves interrupted. Finally, if any action or cleanup was interrupted, or if the there was an
+ * interrupt cleared as part of running any of these activities, either an InterruptedException will be thrown
+ * if the action & cleanups all ran without exception, or an InterruptedException will be suppressed into the
+ * exception if the action or any of the cleanups threw an exception. In the case where InterruptedException is
+ * suppressed, the current thread will be interrupted.
+ *
+ * @param action the action to run
+ * @param cleanups the cleanups to run after the action
+ * @throws Exception if the action throws an exception or the action or any of the cleanups are interrupted.
+ */
@SuppressWarnings({ "squid:S1181", "squid:S1193", "ConstantConditions", "UnreachableCode" })
// catching Throwable, instanceofs, false-positive unreachable code
public static void tryUninterruptibleWithCleanups(ThrowingAction action, ThrowingAction... cleanups)
throws Exception {
Throwable savedT = null;
- boolean suppressedInterrupted = false;
try {
runUninterruptible(action);
} catch (Throwable t) {
@@ -312,21 +331,16 @@
try {
runUninterruptible(cleanup);
} catch (Throwable t) {
- if (savedT != null) {
- savedT.addSuppressed(t);
- suppressedInterrupted = suppressedInterrupted || t instanceof InterruptedException;
- } else {
- savedT = t;
- }
+ savedT = ExceptionUtils.suppress(savedT, t);
}
}
}
+ if (Thread.interrupted()) {
+ savedT = ExceptionUtils.suppress(savedT, new InterruptedException());
+ }
if (savedT == null) {
return;
}
- if (suppressedInterrupted) {
- Thread.currentThread().interrupt();
- }
if (savedT instanceof Error) {
throw (Error) savedT;
} else if (savedT instanceof Exception) {
@@ -494,16 +508,12 @@
boolean interrupted = Thread.interrupted();
try {
action.run();
- if (Thread.interrupted()) {
+ if (interrupted || Thread.interrupted()) {
throw new InterruptedException();
}
} catch (InterruptedException e) {
LOGGER.error("uninterruptible action {} was interrupted!", action, e);
- interrupted = true;
- } finally {
- if (interrupted) {
- Thread.currentThread().interrupt();
- }
+ throw e;
}
}
diff --git a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/buffercache/context/DefaultCloudReadContext.java b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/buffercache/context/DefaultCloudReadContext.java
index dab23d9..fc66958 100644
--- a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/buffercache/context/DefaultCloudReadContext.java
+++ b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/buffercache/context/DefaultCloudReadContext.java
@@ -30,6 +30,7 @@
import org.apache.hyracks.storage.common.buffercache.BufferCache;
import org.apache.hyracks.storage.common.buffercache.BufferCacheHeaderHelper;
import org.apache.hyracks.storage.common.buffercache.CachedPage;
+import org.apache.hyracks.storage.common.buffercache.IBufferCache;
import org.apache.hyracks.storage.common.buffercache.ICachedPage;
import org.apache.hyracks.storage.common.buffercache.context.IBufferCacheReadContext;
import org.apache.hyracks.storage.common.disk.IPhysicalDrive;
@@ -39,7 +40,7 @@
/**
* Default context for {@link BufferCache#pin(long, IBufferCacheReadContext)}
- * and {@link BufferCache#unpin(ICachedPage, IBufferCacheReadContext)} in a cloud deployment.
+ * and {@link IBufferCache#unpin(ICachedPage, IBufferCacheReadContext)} in a cloud deployment.
* <p>
* The default behavior of this context is persisting the pages read from cloud if {@link IPhysicalDrive}
* reports that the local drive(s) are not pressured.
diff --git a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudBeforeRetryRequest.java b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudBeforeRetryRequest.java
index 4dab80d..3ace317 100644
--- a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudBeforeRetryRequest.java
+++ b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudBeforeRetryRequest.java
@@ -18,6 +18,7 @@
*/
package org.apache.hyracks.cloud.io.request;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.cloud.util.CloudRetryableRequestUtil;
/**
@@ -30,5 +31,5 @@
/**
* Run pre-retry routine before reattempting {@link ICloudRequest} or {@link ICloudReturnableRequest}
*/
- void beforeRetry();
+ void beforeRetry() throws HyracksDataException;
}
diff --git a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudRetryPredicate.java b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudRetryPredicate.java
new file mode 100644
index 0000000..bcaae11
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/io/request/ICloudRetryPredicate.java
@@ -0,0 +1,29 @@
+/*
+ * 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.hyracks.cloud.io.request;
+
+import java.util.function.Predicate;
+
+/**
+ * An interface for a condition that determines whether a cloud operation should stop or not.
+ * If met, the encountered exception is re-thrown as root cause in HyracksDataException
+ */
+@FunctionalInterface
+public interface ICloudRetryPredicate extends Predicate<Exception> {
+}
diff --git a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/util/CloudRetryableRequestUtil.java b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/util/CloudRetryableRequestUtil.java
index da9c8fb..e011900 100644
--- a/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/util/CloudRetryableRequestUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-cloud/src/main/java/org/apache/hyracks/cloud/util/CloudRetryableRequestUtil.java
@@ -26,6 +26,7 @@
import org.apache.hyracks.api.util.ExceptionUtils;
import org.apache.hyracks.cloud.io.request.ICloudBeforeRetryRequest;
import org.apache.hyracks.cloud.io.request.ICloudRequest;
+import org.apache.hyracks.cloud.io.request.ICloudRetryPredicate;
import org.apache.hyracks.cloud.io.request.ICloudReturnableRequest;
import org.apache.hyracks.util.ExponentialRetryPolicy;
import org.apache.hyracks.util.IRetryPolicy;
@@ -55,7 +56,8 @@
private static final int NUMBER_OF_RETRIES = getNumberOfRetries();
private static final long MAX_DELAY_BETWEEN_RETRIES = getMaxDelayBetweenRetries();
- private static final ICloudBeforeRetryRequest NO_OP_RETRY = () -> {
+ private static final ICloudRetryPredicate RETRY_ALWAYS_PREDICATE = e -> true;
+ private static final ICloudBeforeRetryRequest NO_OP_BEFORE_RETRY = () -> {
};
private CloudRetryableRequestUtil() {
@@ -67,7 +69,7 @@
* @param request request to run
*/
public static void run(ICloudRequest request) throws HyracksDataException {
- run(request, NO_OP_RETRY);
+ run(request, NO_OP_BEFORE_RETRY);
}
/**
@@ -89,7 +91,7 @@
* @return a value of return type
*/
public static <T> T run(ICloudReturnableRequest<T> request) throws HyracksDataException {
- return run(request, NO_OP_RETRY);
+ return run(request, NO_OP_BEFORE_RETRY);
}
/**
@@ -107,7 +109,7 @@
try {
while (true) {
try {
- return doRun(request, retry);
+ return doRun(request, retry, RETRY_ALWAYS_PREDICATE);
} catch (Throwable e) {
// First, clear the interrupted flag
interrupted |= Thread.interrupted();
@@ -135,7 +137,7 @@
* @param request request to run
*/
public static void runWithNoRetryOnInterruption(ICloudRequest request) throws HyracksDataException {
- doRun(request, NO_OP_RETRY);
+ runWithNoRetryOnInterruption(request, RETRY_ALWAYS_PREDICATE);
}
/**
@@ -151,14 +153,41 @@
doRun(request, retry);
}
- private static <T> T doRun(ICloudReturnableRequest<T> request, ICloudBeforeRetryRequest retry)
+ public static void runWithNoRetryOnInterruption(ICloudRequest request, ICloudRetryPredicate shouldRetry)
throws HyracksDataException {
+ doRun(request, NO_OP_BEFORE_RETRY, shouldRetry);
+ }
+
+ public static <T> T runWithNoRetryOnInterruption(ICloudReturnableRequest<T> request) throws HyracksDataException {
+ return runWithNoRetryOnInterruption(request, NO_OP_BEFORE_RETRY, RETRY_ALWAYS_PREDICATE);
+ }
+
+ public static <T> T runWithNoRetryOnInterruption(ICloudReturnableRequest<T> request, ICloudBeforeRetryRequest retry)
+ throws HyracksDataException {
+ return runWithNoRetryOnInterruption(request, retry, RETRY_ALWAYS_PREDICATE);
+ }
+
+ public static <T> T runWithNoRetryOnInterruption(ICloudReturnableRequest<T> request,
+ ICloudRetryPredicate shouldRetry) throws HyracksDataException {
+ return runWithNoRetryOnInterruption(request, NO_OP_BEFORE_RETRY, shouldRetry);
+ }
+
+ public static <T> T runWithNoRetryOnInterruption(ICloudReturnableRequest<T> request, ICloudBeforeRetryRequest retry,
+ ICloudRetryPredicate shouldRetry) throws HyracksDataException {
+ return doRun(request, retry, shouldRetry);
+ }
+
+ private static <T> T doRun(ICloudReturnableRequest<T> request, ICloudBeforeRetryRequest retry,
+ ICloudRetryPredicate shouldRetry) throws HyracksDataException {
int attempt = 1;
IRetryPolicy retryPolicy = null;
while (true) {
try {
return request.call();
} catch (IOException | BaseServiceException | SdkException e) {
+ if (!shouldRetry.test(e)) {
+ throw HyracksDataException.create(e);
+ }
if (retryPolicy == null) {
retryPolicy = new ExponentialRetryPolicy(NUMBER_OF_RETRIES, MAX_DELAY_BETWEEN_RETRIES);
}
@@ -182,7 +211,12 @@
}
private static void doRun(ICloudRequest request, ICloudBeforeRetryRequest retry) throws HyracksDataException {
- doRun(asReturnableRequest(request), retry);
+ doRun(request, retry, RETRY_ALWAYS_PREDICATE);
+ }
+
+ private static void doRun(ICloudRequest request, ICloudBeforeRetryRequest retry, ICloudRetryPredicate shouldRetry)
+ throws HyracksDataException {
+ doRun(asReturnableRequest(request), retry, shouldRetry);
}
private static int getNumberOfRetries() {
diff --git a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
index 530dab4..81afdf6 100644
--- a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
+++ b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
@@ -474,6 +474,25 @@
return true;
}
+ /*
+ * Appends {@code numCodePoints} code points from the given source string {@code src} to the {@code builder}.
+ * {@code src} is shorter than {@code numCodePoints}, it repeats from the beginning of {@code src} as needed
+ * until the required number of code points have been appended.
+ */
+ public static void append(UTF8StringPointable src, int numCodePoints, UTF8StringBuilder builder, GrowableArray out)
+ throws IOException {
+ int utfLen = src.getUTF8Length();
+ int byteIdx = 0;
+ while (numCodePoints > 0) {
+ if (byteIdx == utfLen) {
+ byteIdx = 0;
+ }
+ builder.appendCodePoint(src.codePointAt(src.getMetaDataLength() + byteIdx));
+ numCodePoints--;
+ byteIdx += src.codePointSize(src.getMetaDataLength() + byteIdx);
+ }
+ }
+
public void substrBefore(UTF8StringPointable match, UTF8StringBuilder builder, GrowableArray out)
throws IOException {
substrBefore(this, match, builder, out);
diff --git a/hyracks-fullstack/hyracks/hyracks-hdfs/pom.xml b/hyracks-fullstack/hyracks/hyracks-hdfs/pom.xml
index 1291564..0b22744 100644
--- a/hyracks-fullstack/hyracks/hyracks-hdfs/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-hdfs/pom.xml
@@ -160,8 +160,8 @@
<scope>test</scope>
<exclusions>
<exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
index a010fde..e956622 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
@@ -108,13 +108,14 @@
stopTupleIndex = getHighKeyIndex();
}
- private void releasePage() throws HyracksDataException {
+ private void releasePage() {
if (exclusiveLatchNodes) {
page.releaseWriteLatch(isPageDirty);
} else {
page.releaseReadLatch();
}
bufferCache.unpin(page);
+ page = null;
}
private void fetchNextLeafPage(int nextLeafPage) throws HyracksDataException {
@@ -218,7 +219,6 @@
}
tupleBuilder.reset();
tupleIndex = 0;
- page = null;
isPageDirty = false;
pred = null;
count = -1;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
index 034a714..50ecb53 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
@@ -46,7 +46,6 @@
protected final IBTreeLeafFrame frame;
protected final ITreeIndexTupleReference frameTuple;
protected final boolean exclusiveLatchNodes;
- protected boolean isPageDirty;
protected IBufferCache bufferCache = null;
protected int fileId = -1;
@@ -118,7 +117,6 @@
releasePage();
}
page = nextLeaf;
- isPageDirty = false;
frame.setPage(page);
pageId = nextLeafPage;
nextLeafPage = frame.getNextLeaf();
@@ -159,8 +157,6 @@
reconciliationTuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
releasePage();
- page = null;
- isPageDirty = false;
// reconcile
searchCb.reconcile(reconciliationTuple);
@@ -236,7 +232,6 @@
originalKeyCmp = initialState.getOriginalKeyComparator();
pageId = ((BTreeCursorInitialState) initialState).getPageId();
page = initialState.getPage();
- isPageDirty = false;
frame.setPage(page);
pred = (RangePredicate) searchPred;
@@ -267,7 +262,7 @@
stopTupleIndex = getHighKeyIndex();
}
- protected void resetBeforeOpen() throws HyracksDataException {
+ protected void resetBeforeOpen() {
releasePage();
}
@@ -278,8 +273,6 @@
}
tupleIndex = 0;
- page = null;
- isPageDirty = false;
pred = null;
}
@@ -298,13 +291,17 @@
return exclusiveLatchNodes;
}
- protected void releasePage() throws HyracksDataException {
+ /**
+ * Releases the page and unpins it from the buffer cache, clearing the reference to the page.
+ */
+ protected void releasePage() {
if (exclusiveLatchNodes) {
- page.releaseWriteLatch(isPageDirty);
+ page.releaseWriteLatch(false);
} else {
page.releaseReadLatch();
}
bufferCache.unpin(page);
+ page = null;
}
protected ICachedPage acquirePage(int pageId) throws HyracksDataException {
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTree.java
index 87b0032..fcfaa40 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTree.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTree.java
@@ -220,7 +220,7 @@
}
@Override
- protected void releasePage() throws HyracksDataException {
+ protected void releasePage() {
if (page != null) {
bufferCache.unpin(page);
page = null;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreePointSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreePointSearchCursor.java
index 8fd9a96..beadcf1 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreePointSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreePointSearchCursor.java
@@ -76,7 +76,6 @@
originalKeyCmp = initialState.getOriginalKeyComparator();
pageId = ((BTreeCursorInitialState) initialState).getPageId();
page = initialState.getPage();
- isPageDirty = false;
frame.setPage(page);
setCursorToNextKey(searchPred);
}
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreeRangeSearchCursor.java
index 3dc4df7..683bbf8 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreeRangeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/DiskBTreeRangeSearchCursor.java
@@ -66,8 +66,9 @@
}
@Override
- protected void releasePage() throws HyracksDataException {
+ protected void releasePage() {
bufferCache.unpin(page);
+ page = null;
}
@Override
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
index 14decb4..f637ac7 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
@@ -142,7 +142,10 @@
return false;
}
- protected void releasePage() throws HyracksDataException {
+ /**
+ * Releases the current page, if it is not null, clearing the reference to it.
+ */
+ protected void releasePage() {
if (page != null) {
page.releaseReadLatch();
bufferCache.unpin(page);
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/ColumnMultiBufferProvider.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/ColumnMultiBufferProvider.java
index 2a2926f..22ef4f1 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/ColumnMultiBufferProvider.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/ColumnMultiBufferProvider.java
@@ -94,8 +94,8 @@
@Override
public void releaseAll() throws HyracksDataException {
- while (!pages.isEmpty()) {
- ICachedPage page = pages.poll();
+ ICachedPage page;
+ while ((page = pages.poll()) != null) {
multiPageOp.unpin(page);
}
}
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MultitenantVirtualBufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MultitenantVirtualBufferCache.java
index f42d0d3..7f4fd38 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MultitenantVirtualBufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MultitenantVirtualBufferCache.java
@@ -79,12 +79,12 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
unpin(page, DEFAULT);
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
vbc.unpin(page, context);
}
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
index 564a9b7..66c596d 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
@@ -327,11 +327,11 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
}
@Override
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/AbstractOnDiskInvertedListCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/AbstractOnDiskInvertedListCursor.java
index c5ad6eb..460ac20 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/AbstractOnDiskInvertedListCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/AbstractOnDiskInvertedListCursor.java
@@ -220,6 +220,7 @@
currentBufferIdx++;
bufferCache.unpin(page);
+ page = null;
bufferEndPageId = i;
// Buffer full?
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/ondisk/fixedsize/FixedSizeElementInvertedListScanCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/ondisk/fixedsize/FixedSizeElementInvertedListScanCursor.java
index f237865..f570bd8 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/ondisk/fixedsize/FixedSizeElementInvertedListScanCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/ondisk/fixedsize/FixedSizeElementInvertedListScanCursor.java
@@ -127,7 +127,7 @@
}
@Override
- public void unloadPages() throws HyracksDataException {
+ public void unloadPages() {
if (pinned) {
bufferCache.unpin(page);
pinned = false;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
index a4ecb6f..a77ccdf 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
@@ -601,14 +601,14 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
unpin(page, defaultContext);
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
if (closed) {
- throw new HyracksDataException("unpin called on a closed cache");
+ throw new IllegalStateException("unpin called on a closed cache");
}
context.onUnpin(page);
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/DebugBufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/DebugBufferCache.java
index 342d003..f1298b7 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/DebugBufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/DebugBufferCache.java
@@ -93,12 +93,12 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
unpin(page, DEFAULT);
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
bufferCache.unpin(page, context);
unpinCount.addAndGet(1);
}
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/IBufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/IBufferCache.java
index d69ded1..81d6d56 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/IBufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/IBufferCache.java
@@ -105,7 +105,7 @@
*
* @param page the page
*/
- void unpin(ICachedPage page) throws HyracksDataException;
+ void unpin(ICachedPage page);
/**
* Unpin a page to indicate can be evicted
@@ -114,7 +114,7 @@
* @param page the page
* @param context read context
*/
- void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException;
+ void unpin(ICachedPage page, IBufferCacheReadContext context);
/**
* Flush the page if it is dirty
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/StorageFileAccessTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/StorageFileAccessTest.java
index bdcb206..756a29f 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/StorageFileAccessTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/StorageFileAccessTest.java
@@ -143,31 +143,27 @@
private void unpinRandomPage() {
int index = Math.abs(rnd.nextInt() % pinnedPages.size());
- try {
- PinnedLatchedPage plPage = pinnedPages.get(index);
+ PinnedLatchedPage plPage = pinnedPages.get(index);
- if (plPage.latch != null) {
- if (plPage.latch == LatchType.LATCH_S) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info(workerId + " S UNLATCHING: " + plPage.pageId);
- }
- plPage.page.releaseReadLatch();
- } else {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info(workerId + " X UNLATCHING: " + plPage.pageId);
- }
- plPage.page.releaseWriteLatch(true);
+ if (plPage.latch != null) {
+ if (plPage.latch == LatchType.LATCH_S) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info(workerId + " S UNLATCHING: " + plPage.pageId);
}
+ plPage.page.releaseReadLatch();
+ } else {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info(workerId + " X UNLATCHING: " + plPage.pageId);
+ }
+ plPage.page.releaseWriteLatch(true);
}
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info(workerId + " UNPINNING PAGE: " + plPage.pageId);
- }
-
- bufferCache.unpin(plPage.page);
- pinnedPages.remove(index);
- } catch (HyracksDataException e) {
- e.printStackTrace();
}
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info(workerId + " UNPINNING PAGE: " + plPage.pageId);
+ }
+
+ bufferCache.unpin(plPage.page);
+ pinnedPages.remove(index);
}
private void openFile() {
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestVirtualBufferCache.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestVirtualBufferCache.java
index 637e553..d4ea5a0 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestVirtualBufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestVirtualBufferCache.java
@@ -111,12 +111,12 @@
}
@Override
- public void unpin(ICachedPage page) throws HyracksDataException {
+ public void unpin(ICachedPage page) {
unpin(page, DEFAULT);
}
@Override
- public void unpin(ICachedPage page, IBufferCacheReadContext context) throws HyracksDataException {
+ public void unpin(ICachedPage page, IBufferCacheReadContext context) {
vbc.unpin(page, context);
}
diff --git a/hyracks-fullstack/pom.xml b/hyracks-fullstack/pom.xml
index 6793d24..aa1f8a2 100644
--- a/hyracks-fullstack/pom.xml
+++ b/hyracks-fullstack/pom.xml
@@ -75,7 +75,7 @@
<snappy.version>1.1.10.5</snappy.version>
<jackson.version>2.14.3</jackson.version>
<jackson-databind.version>${jackson.version}</jackson-databind.version>
- <netty.version>4.1.118.Final</netty.version>
+ <netty.version>4.1.121.Final</netty.version>
<asm.version>9.3</asm.version>
<awsjavasdk.version>2.29.27</awsjavasdk.version>
<gcsjavasdk.version>2.45.0</gcsjavasdk.version>
@@ -89,6 +89,73 @@
<dependencies>
<dependency>
<groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>${netty.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-classes-epoll</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-kqueue</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-classes-kqueue</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-resolver-dns-classes-macos</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-resolver-dns-native-macos</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-rxtx</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-sctp</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-udt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-memcache</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-mqtt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-redis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-smtp</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-socks</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-stomp</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>${netty.version}</version>
</dependency>
@@ -126,6 +193,12 @@
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>${netty.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-unix-common</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>io.netty</groupId>
@@ -149,6 +222,23 @@
</dependency>
<dependency>
<groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ <classifier>linux-x86_64</classifier>
+ <version>${netty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-kqueue</artifactId>
+ <classifier>osx-x86_64</classifier>
+ <version>${netty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-kqueue</artifactId>
+ <version>${netty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
<artifactId>netty-resolver-dns</artifactId>
<version>${netty.version}</version>
</dependency>
@@ -158,17 +248,6 @@
<version>${netty.version}</version>
</dependency>
<dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-unix-common</artifactId>
- <version>${netty.version}</version>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- <version>${netty.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
@@ -224,10 +303,6 @@
<version>${hadoop.version}</version>
<exclusions>
<exclusion>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- </exclusion>
- <exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
</exclusion>