merge asterix_stabilization r281:334
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@335 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
index fc0a2e8..b79be86 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
@@ -10,13 +10,16 @@
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.typecomputer.base.TypeComputerUtilities;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -84,13 +87,13 @@
AbstractLogicalOperator currentOperator = oldAssignOperator;
List<LogicalVariable> producedVariables = new ArrayList<LogicalVariable>();
- boolean changed = false;
/**
* find the assign operator for the "input record" to the insert_delete
* operator
*/
do {
+ context.addToDontApplySet(this, currentOperator);
if (currentOperator.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
producedVariables.clear();
VariableUtilities.getProducedVariables(currentOperator, producedVariables);
@@ -105,21 +108,10 @@
ILogicalExpression expr = expressionPointers.get(position).getValue();
if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expr;
- changed = TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType,
- inputRecordType);
- changed &= !requiredRecordType.equals(inputRecordType);
- if (changed) {
- staticTypeCast(funcExpr, requiredRecordType, inputRecordType);
- List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
- int openPartStart = requiredRecordType.getFieldTypes().length * 2;
- for (int j = openPartStart; j < args.size(); j++) {
- ILogicalExpression arg = args.get(j).getValue();
- if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
- AbstractFunctionCallExpression argFunc = (AbstractFunctionCallExpression) arg;
- TypeComputerUtilities.setOpenType(argFunc, true);
- }
- }
- }
+ if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+ return false;
+ IVariableTypeEnvironment assignEnv = oldAssignOperator.computeOutputTypeEnvironment(context);
+ rewriteFuncExpr(funcExpr, requiredRecordType, inputRecordType, assignEnv);
}
context.computeAndSetTypeEnvironmentForOperator(originalAssign);
}
@@ -129,10 +121,58 @@
else
break;
} while (currentOperator != null);
- return changed;
+ return true;
}
- private void staticTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType) {
+ private void rewriteFuncExpr(ScalarFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
+ IVariableTypeEnvironment env) throws AlgebricksException {
+ if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+ rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ }
+ if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+ rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ } else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
+ rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
+ }
+ }
+
+ private void rewriteRecordFuncExpr(ScalarFunctionCallExpression funcExpr, ARecordType requiredRecordType,
+ ARecordType inputRecordType, IVariableTypeEnvironment env) throws AlgebricksException {
+ if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+ return;
+ TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
+ staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
+ }
+
+ private void rewriteListFuncExpr(ScalarFunctionCallExpression funcExpr, AbstractCollectionType requiredListType,
+ AbstractCollectionType inputListType, IVariableTypeEnvironment env) throws AlgebricksException {
+ if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+ return;
+
+ TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredListType, inputListType);
+ List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
+
+ IAType itemType = requiredListType.getItemType();
+ if (itemType == null || itemType.getTypeTag().equals(ATypeTag.ANY))
+ return;
+ IAType inputItemType = inputListType.getItemType();
+ for (int j = 0; j < args.size(); j++) {
+ ILogicalExpression arg = args.get(j).getValue();
+ if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) arg;
+ IAType currentItemType = (IAType) env.getType(argFunc);
+ if (inputItemType == null || inputItemType == BuiltinType.ANY) {
+ currentItemType = (IAType) env.getType(argFunc);
+ rewriteFuncExpr(argFunc, itemType, currentItemType, env);
+ } else {
+ rewriteFuncExpr(argFunc, itemType, inputItemType, env);
+ }
+ }
+ }
+ }
+
+ private void staticRecordTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType,
+ IVariableTypeEnvironment env) throws AlgebricksException {
IAType[] reqFieldTypes = reqType.getFieldTypes();
String[] reqFieldNames = reqType.getFieldNames();
IAType[] inputFieldTypes = inputType.getFieldTypes();
@@ -154,6 +194,11 @@
for (int i = 0; i < inputFieldNames.length; i++) {
String fieldName = inputFieldNames[i];
IAType fieldType = inputFieldTypes[i];
+
+ if (2 * i + 1 > func.getArguments().size())
+ break;
+
+ ILogicalExpression arg = func.getArguments().get(2 * i + 1).getValue();
matched = false;
for (int j = 0; j < reqFieldNames.length; j++) {
String reqFieldName = reqFieldNames[j];
@@ -163,6 +208,11 @@
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
+
+ if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+ }
break;
}
@@ -171,13 +221,30 @@
&& NonTaggedFormatUtil.isOptionalField((AUnionType) reqFieldType)) {
IAType itemType = ((AUnionType) reqFieldType).getUnionList().get(
NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ reqFieldType = itemType;
if (fieldType.equals(BuiltinType.ANULL) || fieldType.equals(itemType)) {
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
+
+ // rewrite record expr
+ if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+ }
break;
}
}
+
+ // match the record field: need cast
+ if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+ fieldPermutation[j] = i;
+ openFields[i] = false;
+ matched = true;
+ break;
+ }
}
}
if (matched)
@@ -196,7 +263,7 @@
String fieldName = inputFieldNames[j];
IAType fieldType = inputFieldTypes[j];
if (fieldName.equals(reqFieldName)) {
- if (fieldType.equals(reqFieldType)) {
+ if (!openFields[j]) {
matched = true;
break;
}
@@ -250,7 +317,26 @@
for (int i = 0; i < openFields.length; i++) {
if (openFields[i]) {
arguments.add(argumentsClone.get(2 * i));
- arguments.add(argumentsClone.get(2 * i + 1));
+ Mutable<ILogicalExpression> fExprRef = argumentsClone.get(2 * i + 1);
+ ILogicalExpression argExpr = fExprRef.getValue();
+
+ if (argExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ IAType reqFieldType = inputFieldTypes[i];
+ if (inputFieldTypes[i].getTypeTag() == ATypeTag.RECORD) {
+ reqFieldType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
+ }
+ if (inputFieldTypes[i].getTypeTag() == ATypeTag.ORDEREDLIST) {
+ reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
+ }
+ if (inputFieldTypes[i].getTypeTag() == ATypeTag.UNORDEREDLIST) {
+ reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+ }
+ if (TypeComputerUtilities.getRequiredType((AbstractFunctionCallExpression) argExpr) == null) {
+ ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) argExpr;
+ rewriteFuncExpr(argFunc, reqFieldType, inputFieldTypes[i], env);
+ }
+ }
+ arguments.add(fExprRef);
}
}
}
diff --git a/asterix-app/src/test/resources/logging.properties b/asterix-app/src/test/resources/logging.properties
index deb88307..4cf5545 100644
--- a/asterix-app/src/test/resources/logging.properties
+++ b/asterix-app/src/test/resources/logging.properties
@@ -61,5 +61,5 @@
# messages:
#edu.uci.ics.asterix.level = FINE
-#edu.uci.ics.algebricks.level = FINE
-#edu.uci.ics.hyracks.level = INFO
+edu.uci.ics.algebricks.level = FINE
+edu.uci.ics.hyracks.level = INFO
diff --git a/asterix-app/src/test/resources/runtimets/ignore.txt b/asterix-app/src/test/resources/runtimets/ignore.txt
index 2b456ca..962d26b 100644
--- a/asterix-app/src/test/resources/runtimets/ignore.txt
+++ b/asterix-app/src/test/resources/runtimets/ignore.txt
@@ -14,5 +14,12 @@
fuzzyjoin/events-users-aqlplus_1.aql
fuzzyjoin
failure/q1_pricing_summary_report_failure.aql
-open-closed
dml/load-from-hdfs.aql
+open-closed/open-closed-15
+open-closed/open-closed-16
+open-closed/open-closed-17
+open-closed/open-closed-18
+open-closed/open-closed-19
+open-closed/open-closed-20
+open-closed/open-closed-21
+open-closed/open-closed-22
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
new file mode 100644
index 0000000..6c8264f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
@@ -0,0 +1,62 @@
+/*
+ * Test case Name : opentype-o2c-recursive.aql
+ * Description : verify the static casting of nest record constants
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+ street: string,
+ city: string
+}
+create type Dept as open{
+ name: string,
+ id: int32
+}
+
+create type testtype as closed {
+ name: string,
+ id: string,
+ address: AddressType?,
+ department: {{Dept}}?
+}
+
+create type testtype2 as open {
+ name: string,
+ id: string
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+create dataset testds2(testtype2) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299, "review":5}, {"name":"EE", "id":399} }} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH", "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "address": {"street": "1019 DBH", "city": "irvine", "property": {"zip": 92697, "review": "positive" } } }
+);
+
+insert into dataset testds2 (
+ for $d in dataset("testds")
+ return $d
+);
+
+write output to nc1:"rttest/dml_opentype-c2o-recursive.adm";
+
+for $d in dataset("testds2")
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
index e29ccdc..a63e2df 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
@@ -12,7 +12,7 @@
create type testtype as closed {
id: string,
name: string,
- hobby: string?
+ hobby: {{string}}?
}
/*
@@ -28,19 +28,19 @@
create dataset testds2(testtype2) partitioned by key id;
insert into dataset testds (
-{ "hobby": "music", "id": "001", "name": "Person Three"}
+{ "hobby": {{"music", "coding"}}, "id": "001", "name": "Person Three"}
);
insert into dataset testds (
-{ "name": "Person One", "id": "002", "hobby": "sports"}
+{ "name": "Person One", "id": "002", "hobby": {{"sports"}} }
);
insert into dataset testds (
-{ "id": "003", "hobby": "movie", "name": "Person Two"}
+{ "id": "003", "hobby": {{"movie", "sports"}}, "name": "Person Two"}
);
insert into dataset testds (
-{ "id": "004", "name": "Person Four", "hobby": "swimming"}
+{ "id": "004", "name": "Person Four", "hobby": {{"swimming"}} }
);
insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
new file mode 100644
index 0000000..2070e20
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
@@ -0,0 +1,63 @@
+/*
+ * Test case Name : opentype-o2c-recursive.aql
+ * Description : verify the static casting of nest record constants
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+ street: string,
+ city: string
+}
+
+create type Dept as closed{
+ name: string,
+ id: int32
+}
+
+create type testtype as open {
+ name: string,
+ id: string
+}
+
+create type testtype2 as closed {
+ name: string,
+ id: string,
+ address: AddressType?,
+ department: {{Dept}}?
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+create dataset testds2(testtype2) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299}, {"name":"EE", "id":399} }} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH", "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "address": {"street": "1019 DBH", "city": "irvine", "property": {"zip": 92697, "review": "positive" } } }
+);
+
+insert into dataset testds2 (
+ for $d in dataset("testds")
+ return $d
+);
+
+write output to nc1:"rttest/dml_opentype-o2c-recursive.adm";
+
+for $d in dataset("testds2")
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
index a6ed9cc..015aa7b 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
@@ -16,7 +16,7 @@
}
create type testtype2 as closed {
- hobby: string?,
+ hobby: {{string}}?,
id: string,
name: string
}
@@ -26,19 +26,19 @@
create dataset testds2(testtype2) partitioned by key id;
insert into dataset testds (
-{ "id": "001", "hobby": "music", "name": "Person Three"}
+{ "id": "001", "hobby": {{"music"}}, "name": "Person Three"}
);
insert into dataset testds (
-{ "id": "002", "name": "Person Three", "hobby": "football"}
+{ "id": "002", "name": "Person Three", "hobby": {{"football"}}}
);
insert into dataset testds (
-{ "id": "003", "name": "Person Three", "hobby": "movie"}
+{ "id": "003", "name": "Person Three", "hobby": {{"movie", "coding", "debugging"}}}
);
insert into dataset testds (
-{ "name": "Person Three", "hobby": "swimming", "id": "004"}
+{ "name": "Person Three", "hobby": {{"swimming", "music"}}, "id": "004"}
);
insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql
new file mode 100644
index 0000000..c0b5e06
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql
@@ -0,0 +1,45 @@
+/*
+ * Test case Name : nestrecord.aql
+ * Description : verify the static casting of nest record constants
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+ street: string,
+ city: string
+}
+
+create type testtype as open {
+ name: string,
+ id: string,
+ address: AddressType?
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH", "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "home": {"street": "2019 DBH", "city": {"name": "Irvine", "zip": 92697} } }
+);
+
+write output to nc1:"rttest/nestrecords_nestrecord.adm";
+
+for $d in dataset("testds")
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql
new file mode 100644
index 0000000..27935e0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql
@@ -0,0 +1,39 @@
+/*
+ * Test case Name : heterog-list01.aql
+ * Description : To test insertion of an array of objects into internal dataset.
+ * : Heterogenous list construction.
+ * Success : Yes
+ * Date : 14th April 2012
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type BatterType as {
+id:int32,
+descrpt:string
+}
+
+create type TestType as closed {
+id:int32,
+description:string,
+name:string,
+batters:[[BatterType]]
+}
+
+create dataset T1(TestType) partitioned by key id;
+
+insert into dataset T1({
+"id":1234,
+"description":"donut",
+"name":"Cake",
+"batters":[[ {"id":345,"descrpt":"Regular"},{"id":445,"descrpt":"Chocolate"} ]] }
+);
+
+write output to nc1:"rttest/open-closed_heterog-list-ordered01.adm";
+
+for $d in dataset("T1")
+order by $d.id
+return $d
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
index d1edc3d..7ba1641 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
@@ -19,7 +19,7 @@
id:int32,
description:string,
name:string,
-batters:[BatterType]
+batters:{{BatterType}}
}
create dataset T1(TestType) partitioned by key id;
@@ -28,11 +28,12 @@
"id":1234,
"description":"donut",
"name":"Cake",
-"batters":[{"id":345,"descprt":"Regular"},{"id":445,"descprt":"Chocolate"}] }
+"batters":{{ {"id":345,"descrpt":"Regular"},{"id":445,"descrpt":"Chocolate"} }} }
);
-write output to nc1:"rttest/open-closed_heteror-list01.adm";
+write output to nc1:"rttest/open-closed_heterog-list01.adm";
for $d in dataset("T1")
+order by $d.id
return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
index 6373569..0d26b5d 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
@@ -23,4 +23,6 @@
);
write output to nc1:"rttest/open-closed_open-closed-01.adm";
-for $l in dataset("testds") return $l
+for $l in dataset("testds")
+order by $l.id
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql
deleted file mode 100644
index e15577b..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Test case Name : open-closed-02.aql
- * Description : This test is intended to test insertion of additional data into a dataset of closed type
- * Expected Result : This test should fail because closed type internal datasets can not ingest additional data.
- *
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-// name field here is optional.
-create type testType as closed {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-write output to nc1:"rttest/open-closed_open-closed-02.adm";
-for $l in dataset("testds") return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql
deleted file mode 100644
index f028c89..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-03.aql
- * Description : This test is intended to test insertion of additional data into a closed type
- * Expected Result : Failure - This should NOT be allowed!
- * Issue number : Issue 66
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123, "name": "John Doe", "hobbies": {{ "scuba", "music" }} }
-);
-
-for $l in dataset("testds") return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql
deleted file mode 100644
index 82912bd..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Test case Name : open-closed-04.aql
- * Description : This test is intended to test type in the Metdata for the dataset.
- * : Verify if the type is open.
- * Expected Result : Success - This should be allowed!
- * Issue number : Issue 73
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type TestType as open {
-id : int32,
-name : string
-}
-
-create dataset testds(TestType) partitioned by key id;
-
-/*
- * Connect to the Metadata dataverse and run the following commands.
- */
-
-use dataverse Metadata;
-
-for $l in dataset('Datatype')
-let $x := $l.Derived
-where $l.DatatypeName="TestType"
-return $x.Record
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql
deleted file mode 100644
index 2bd18fe..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Test case Name : open-closed-05.aql
- * Description : Create internal dataset and verify if the type is marked as closed in metadata.
- * Expected Result : Success
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-/*
- * Connect to the Metadata dataverse and run the following commands.
- * Verify if the type is closed by querying Metadata.
- */
-
-use dataverse Metadata;
-
-for $l in dataset('Datatype')
-let $x := $l.Derived
-where $l.DatatypeName="TestType"
-return $x.Record
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql
deleted file mode 100644
index f6605a6..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Test case Name : open-closed-06.aql
- * Description : To test non nullable field types in closed type datasets.
- * Success : Yes this test should Fail!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-// Missing name field this insert stmt should fail.
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql
deleted file mode 100644
index 155f8bb..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Test case Name : open-closed-07.aql
- * Description : To test non nullable field types in datasets of type open.
- * Success : Yes this test should Fail!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql
deleted file mode 100644
index 24423e8..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Test case Name : open-closed-08.aql
- * Description : To test nullable and non nullable field types in datasets of type closed.
- * Success : Yes this test should succeed!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql
deleted file mode 100644
index 63288d7..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-09.aql
- * Description : To test nullable and non nullable field types in datasets of type open.
- * : Missing value for nullable field and missing value for non-nullable field in insert statement.
- * Success : This test should Fail!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({ });
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql
deleted file mode 100644
index cad1f12..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-10.aql
- * Description : To test nullable and non nullable field types in datasets of type open.
- * : Missing value for nullable field in insert statement.
- * Success : This test should succeed!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id :" 32 });
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql
deleted file mode 100644
index 50d52d2..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-11.aql
- * Description : To test nullable and non nullable field types in datasets of type open.
- * : No missing value for nullable field in insert statement.
- * Success : This test should succeed!
- * Date : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id :" 32,"name :" "UCI"});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
index 2459fcc..ae21794 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
@@ -43,6 +43,8 @@
return $d
);
+write output to nc1:"rttest/open-closed_open-closed-12.adm";
for $d in dataset("testds01")
+order by $d.id
return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql
deleted file mode 100644
index 379e282..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Testcase Name : open-closed-13.aql
- * Description : Attempt to insert additional data into a dataset which is defined as closed type.
- * Success : This test should fail! No additional data allowed in datasets of closed type.
- * Date : March 27 2012
- */
-
-
-create dataverse testdv2;
-use dataverse testdv2;
-
-create type testtype as closed {
- id: string,
- name: string
-}
-
-create dataset testds(testtype) partitioned by key id;
-
-insert into dataset testds (
-{ "id": "001", "name": "Person Three", "hobbies": {{"scuba", "music"}}}
-);
-
-for $d in dataset("testds")
-return $d
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
index 03e6e33..6c517ca 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
@@ -48,6 +48,8 @@
return $d
);
+write output to nc1:"rttest/open-closed_open-closed-14.adm";
for $d in dataset("testds01")
+order by $d.id
return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
index 80cfa30..2ac2567 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
@@ -46,6 +46,7 @@
}
);
+write output to nc1:"rttest/open-closed_open-closed-15.adm";
for $l in dataset('tdtst')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
index c463cb0..5e1a591 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
@@ -46,6 +46,7 @@
}
);
+write output to nc1:"rttest/open-closed_open-closed-16.adm";
for $l in dataset('tdtst')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
index f1fe349..a590cf1 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
@@ -43,5 +43,6 @@
}
);
+write output to nc1:"rttest/open-closed_open-closed-17.adm";
for $l in dataset('tdtst')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql
deleted file mode 100644
index 0da1474..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Test case name : open-closed-18.aql
- * Description : Test insertion of additional data into an open type internal dataset.
- * Success : Yes
- * Date : 29 April 2012
- */
-
-drop dataverse test if exists;
-create dataverse test;
-use dataverse test;
-
-create type TestType as open {
-id:int32
-}
-
-create dataset testds(TestType) partitioned by key id;
-
-insert into dataset testds( for $i in range(1,10) return { "id":$i,"name":"John Doe" });
-
-for $l in dataset('testds')
-return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
index 3ff2d71..b406663 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
@@ -47,5 +47,6 @@
insert into dataset dtst01({for $l in dataset('employee') return $l});
+write output to nc1:"rttest/open-closed_open-closed-19.adm";
for $l in dataset('dtst01')
retunr $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
index d7ad173..29b4366 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
@@ -41,5 +41,6 @@
insert into dataset dtst01(for $l in dataset('employee') return $l);
+write output to nc1:"rttest/open-closed_open-closed-20.adm";
for $l in dataset('dtst01')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
index 71ce585..c52344e 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
@@ -38,5 +38,6 @@
insert into dataset dtst01(for $l in dataset('employee') return $l);
+write output to nc1:"rttest/open-closed_open-closed-21.adm";
for $l in dataset('dtst01')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
index 6e05f61..cd9ac44 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
@@ -39,5 +39,6 @@
// missing dept field
insert into dataset employee({"id":205,"name":"Mike Tyson","age":44,"sex":"M","dob":date("1970-12-22")});
+write output to nc1:"rttest/open-closed_open-closed-22.adm";
for $l in dataset('employee')
return $l
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
new file mode 100644
index 0000000..60a389c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299, "review": 5 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
index 5e7a349..6086a08 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
@@ -1,5 +1,5 @@
-{ "id": "001", "name": "Person Three", "hobby": "music" }
-{ "id": "002", "name": "Person One", "hobby": "sports" }
-{ "id": "003", "name": "Person Two", "hobby": "movie" }
-{ "id": "004", "name": "Person Four", "hobby": "swimming" }
+{ "id": "001", "name": "Person Three", "hobby": {{ "music", "coding" }} }
+{ "id": "002", "name": "Person One", "hobby": {{ "sports" }} }
+{ "id": "003", "name": "Person Two", "hobby": {{ "movie", "sports" }} }
+{ "id": "004", "name": "Person Four", "hobby": {{ "swimming" }} }
{ "id": "005", "name": "Person Five", "hobby": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
new file mode 100644
index 0000000..c67c3cb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
index d9c778b..92809fd 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
@@ -1,5 +1,5 @@
-{ "hobby": "music", "id": "001", "name": "Person Three" }
-{ "hobby": "football", "id": "002", "name": "Person Three" }
-{ "hobby": "movie", "id": "003", "name": "Person Three" }
-{ "hobby": "swimming", "id": "004", "name": "Person Three" }
+{ "hobby": {{ "music" }}, "id": "001", "name": "Person Three" }
+{ "hobby": {{ "football" }}, "id": "002", "name": "Person Three" }
+{ "hobby": {{ "movie", "coding", "debugging" }}, "id": "003", "name": "Person Three" }
+{ "hobby": {{ "swimming", "music" }}, "id": "004", "name": "Person Three" }
{ "hobby": null, "id": "005", "name": "Person Five" }
diff --git a/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm b/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm
new file mode 100644
index 0000000..2b255b0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 } }
+{ "name": "Person Two", "id": "002", "address": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" } }
+{ "name": "Person Four", "id": "004", "address": null, "home": { "street": "2019 DBH", "city": { "name": "Irvine", "zip": 92697 } } }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm
new file mode 100644
index 0000000..f6d3242
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm
@@ -0,0 +1 @@
+{ "id": 1234, "description": "donut", "name": "Cake", "batters": [ [ { "id": 0, "descrpt": "" }, { "id": 0, "descrpt": "" } ] ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm
new file mode 100644
index 0000000..30c55c2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm
@@ -0,0 +1 @@
+{ "id": 1234, "description": "donut", "name": "Cake", "batters": {{ { "id": 345, "descrpt": "Regular" }, { "id": 445, "descrpt": "Chocolate" } }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm
new file mode 100644
index 0000000..c5aac6d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm
@@ -0,0 +1 @@
+{ "id": 123, "name": "John Doe", "hobbies": {{ "scuba", "music" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm
new file mode 100644
index 0000000..7570226
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm
@@ -0,0 +1,3 @@
+{ "id": "001", "name": "Person One", "hobbies": {{ "scuba", "music" }} }
+{ "id": "002", "name": "Person Two", "hobbies": {{ "fishing", "dance" }} }
+{ "id": "003", "name": "Person Three", "hobbies": {{ "hiking", "surfing" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm
new file mode 100644
index 0000000..70b6b95
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm
@@ -0,0 +1,5 @@
+{ "id": "001", "name": null }
+{ "id": "002", "name": "John Doe" }
+{ "id": "003", "name": null }
+{ "id": "004", "name": null }
+{ "id": "005", "name": null }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index 5494669..7e3dbdb 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -33,9 +33,9 @@
private ARecordType recordType;
private int numberOfSchemaFields = 0;
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private ISerializerDeserializer serializers[];
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private ISerializerDeserializer deserializers[];
private ARecordSerializerDeserializer() {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
index e8786ec..c9ce037 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
@@ -1,28 +1,12 @@
package edu.uci.ics.asterix.om.typecomputer.base;
-import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
public class TypeComputerUtilities {
- public static void setOpenType(AbstractFunctionCallExpression expr, boolean openType) {
- Boolean openField = true;
- Object[] opaqueParameters = new Object[1];
- opaqueParameters[0] = openField;
- expr.setOpaqueParameters(opaqueParameters);
- }
-
- public static boolean isOpenType(AbstractFunctionCallExpression expr) {
- boolean openType = false;
- Object[] opaqueParameters = expr.getOpaqueParameters();
- if (opaqueParameters != null) {
- openType = (Boolean) opaqueParameters[0];
- }
- return openType;
- }
-
- public static boolean setRequiredAndInputTypes(AbstractFunctionCallExpression expr, ARecordType requiredRecordType,
- ARecordType inputRecordType) {
+ public static boolean setRequiredAndInputTypes(AbstractFunctionCallExpression expr, IAType requiredRecordType,
+ IAType inputRecordType) {
boolean changed = false;
Object opaqueParameter = expr.getOpaqueParameters();
if (opaqueParameter == null) {
@@ -35,22 +19,21 @@
return changed;
}
- public static ARecordType getRequiredType(AbstractFunctionCallExpression expr) {
+ public static IAType getRequiredType(AbstractFunctionCallExpression expr) {
Object[] type = expr.getOpaqueParameters();
if (type != null) {
- ARecordType recordType = (ARecordType) type[0];
+ IAType recordType = (IAType) type[0];
return recordType;
} else
return null;
}
- public static ARecordType getInputType(AbstractFunctionCallExpression expr) {
+ public static IAType getInputType(AbstractFunctionCallExpression expr) {
Object[] type = expr.getOpaqueParameters();
if (type != null) {
- ARecordType recordType = (ARecordType) type[1];
+ IAType recordType = (IAType) type[1];
return recordType;
} else
return null;
}
-
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
index 6a17a46..c482dfa 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
@@ -31,10 +31,10 @@
/**
* if type has been top-down propagated, use the enforced type
*/
- ARecordType type = TypeComputerUtilities.getRequiredType(f);
+ ARecordType type = (ARecordType) TypeComputerUtilities.getRequiredType(f);
if (type != null)
return type;
-
+
int n = f.getArguments().size() / 2;
String[] fieldNames = new String[n];
IAType[] fieldTypes = new IAType[n];
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
index 8b27a82..790ca3f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
@@ -33,7 +33,7 @@
/**
* if type has been top-down propagated, use the enforced type
*/
- ARecordType type = TypeComputerUtilities.getRequiredType(f);
+ ARecordType type = (ARecordType) TypeComputerUtilities.getRequiredType(f);
if (type != null)
return type;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
index 47f239b..84ac969 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
@@ -24,26 +24,28 @@
public AOrderedListType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
- boolean openType = TypeComputerUtilities.isOpenType(f);
- int n = f.getArguments().size();
- if (n == 0 || openType) {
- return new AOrderedListType(BuiltinType.ANY, null);
- } else {
- ArrayList<IAType> types = new ArrayList<IAType>();
- for (int k = 0; k < f.getArguments().size(); k++) {
- IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
- if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
- type = ((AUnionType) type).getUnionList()
- .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
- if (types.indexOf(type) < 0) {
- types.add(type);
- }
- }
- if (types.size() == 1) {
- return new AOrderedListType(types.get(0), null);
- } else {
- throw new AlgebricksException("You can not construct a heterogenous list.");
+
+ /**
+ * if type has been top-down propagated, use the enforced type
+ */
+ AOrderedListType reqType = (AOrderedListType) TypeComputerUtilities.getRequiredType(f);
+ if (reqType != null)
+ return reqType;
+
+ ArrayList<IAType> types = new ArrayList<IAType>();
+ for (int k = 0; k < f.getArguments().size(); k++) {
+ IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
+ if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
+ type = ((AUnionType) type).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ if (types.indexOf(type) < 0) {
+ types.add(type);
}
}
+ if (types.size() == 1) {
+ return new AOrderedListType(types.get(0), null);
+ } else {
+ return new AOrderedListType(BuiltinType.ANY, null);
+ }
+
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
index 0e03e6d..a4fd12a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
@@ -24,26 +24,28 @@
public AUnorderedListType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
- boolean openType = TypeComputerUtilities.isOpenType(f);
- int n = f.getArguments().size();
- if (n == 0 || openType) {
- return new AUnorderedListType(BuiltinType.ANY, null);
- } else {
- ArrayList<IAType> types = new ArrayList<IAType>();
- for (int k = 0; k < f.getArguments().size(); k++) {
- IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
- if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
- type = ((AUnionType) type).getUnionList()
- .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
- if (types.indexOf(type) < 0) {
- types.add(type);
- }
- }
- if (types.size() == 1) {
- return new AUnorderedListType(types.get(0), null);
- } else {
- throw new AlgebricksException("You can not construct a heterogenous list.");
+
+ /**
+ * if type has been top-down propagated, use the enforced type
+ */
+ AUnorderedListType reqType = (AUnorderedListType) TypeComputerUtilities.getRequiredType(f);
+ if (reqType != null)
+ return reqType;
+
+ ArrayList<IAType> types = new ArrayList<IAType>();
+ for (int k = 0; k < f.getArguments().size(); k++) {
+ IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
+ if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
+ type = ((AUnionType) type).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ if (types.indexOf(type) < 0) {
+ types.add(type);
}
}
+ if (types.size() == 1) {
+ return new AUnorderedListType(types.get(0), null);
+ } else {
+ return new AUnorderedListType(BuiltinType.ANY, null);
+ }
+
}
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
new file mode 100644
index 0000000..83c3791
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
+
+public class AFlatValueAccessor extends AbstractBinaryAccessor {
+
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public AFlatValueAccessor createElement(IAType type) {
+ return new AFlatValueAccessor();
+ }
+ };
+
+ private AFlatValueAccessor() {
+
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof IValueReference))
+ return false;
+ IValueReference ivf = (IValueReference) o;
+ byte[] odata = ivf.getBytes();
+ int ostart = ivf.getStartIndex();
+ int olen = ivf.getLength();
+
+ byte[] data = getBytes();
+ int start = getStartIndex();
+ int len = getLength();
+ if ( len!= olen)
+ return false;
+ for (int i = 0; i < len; i++) {
+ if (data[start + i] != odata[ostart + i])
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+ return vistor.visit(this, tag);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
new file mode 100644
index 0000000..e4cf40d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors;
+
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
+
+public class AListAccessor extends AbstractBinaryAccessor {
+
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public IBinaryAccessor createElement(IAType type) {
+ return new AListAccessor((AbstractCollectionType) type);
+ }
+ };
+
+ private IAType itemType;
+ private ATypeTag itemTag;
+ private boolean typedItemList = false;
+
+ private List<IBinaryAccessor> items = new ArrayList<IBinaryAccessor>();
+ private List<IBinaryAccessor> itemTags = new ArrayList<IBinaryAccessor>();
+ private AccessorAllocator allocator = new AccessorAllocator();
+
+ private byte[] dataBuffer = new byte[32768];
+ private ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
+ private DataOutputStream dataDos = new DataOutputStream(dataBos);
+
+ private AListAccessor(AbstractCollectionType inputType) {
+ if (inputType != null && inputType.getItemType() != null) {
+ itemType = inputType.getItemType();
+ if (itemType.getTypeTag() == ATypeTag.ANY) {
+ typedItemList = false;
+ } else {
+ typedItemList = true;
+ itemTag = inputType.getItemType().getTypeTag();
+ }
+ } else {
+ this.typedItemList = false;
+ }
+ }
+
+ private void reset() {
+ allocator.reset();
+ items.clear();
+ itemTags.clear();
+ dataBos.setByteArray(dataBuffer, 0);
+ }
+
+ @Override
+ public void reset(byte[] b, int s, int len) {
+ reset();
+
+ int numberOfitems = AInt32SerializerDeserializer.getInt(b, s + 6);
+ int itemOffset;
+ if (typedItemList) {
+ switch (itemTag) {
+ case STRING:
+ case RECORD:
+ case ORDEREDLIST:
+ case UNORDEREDLIST:
+ case ANY:
+ itemOffset = s + 10 + (numberOfitems * 4);
+ break;
+ default:
+ itemOffset = s + 10;
+ }
+ } else
+ itemOffset = s + 10 + (numberOfitems * 4);
+ int itemLength = 0;
+ try {
+ if (typedItemList) {
+ for (int i = 0; i < numberOfitems; i++) {
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, false);
+ IBinaryAccessor tag = allocator.allocateFieldType();
+ IBinaryAccessor item = allocator.allocateFieldValue(itemType);
+
+ // set item type tag
+ int start = dataBos.size();
+ dataDos.writeByte(itemTag.serialize());
+ int end = dataBos.size();
+ tag.reset(dataBuffer, start, end - start);
+ itemTags.add(tag);
+
+ // set item value
+ start = dataBos.size();
+ dataDos.writeByte(itemTag.serialize());
+ dataDos.write(b, itemOffset, itemLength);
+ end = dataBos.size();
+ item.reset(dataBuffer, start, end - start);
+ itemOffset += itemLength;
+ items.add(item);
+ }
+ } else {
+ for (int i = 0; i < numberOfitems; i++) {
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
+ IBinaryAccessor tag = allocator.allocateFieldType();
+ IBinaryAccessor item = allocator.allocateFieldValue(itemType);
+
+ // set item type tag
+ int start = dataBos.size();
+ dataDos.writeByte(itemTag.serialize());
+ int end = dataBos.size();
+ tag.reset(dataBuffer, start, end - start);
+ itemTags.add(tag);
+
+ // open part field already include the type tag
+ item.reset(b, itemOffset, itemLength);
+ itemOffset += itemLength;
+ items.add(item);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+ return vistor.visit(this, tag);
+ }
+
+ public List<IBinaryAccessor> getItems() {
+ return items;
+ }
+
+ public List<IBinaryAccessor> getItemTags() {
+ return itemTags;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
similarity index 69%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
index d45b4ac..776cdc0 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
@@ -13,13 +13,14 @@
* limitations under the License.
*/
-package edu.uci.ics.asterix.runtime.util;
+package edu.uci.ics.asterix.runtime.accessors;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
import edu.uci.ics.asterix.om.types.ARecordType;
@@ -28,14 +29,27 @@
import edu.uci.ics.asterix.om.types.EnumDeserializer;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
-public class ARecordAccessor implements IValueReference {
+public class ARecordAccessor extends AbstractBinaryAccessor {
- private List<SimpleValueReference> fieldNames = new ArrayList<SimpleValueReference>();
- private List<SimpleValueReference> fieldTypeTags = new ArrayList<SimpleValueReference>();
- private List<SimpleValueReference> fieldValues = new ArrayList<SimpleValueReference>();
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public IBinaryAccessor createElement(IAType type) {
+ return new ARecordAccessor((ARecordType) type);
+ }
+ };
+
+ // access results: field names, field types, and field values
+ private List<IBinaryAccessor> fieldNames = new ArrayList<IBinaryAccessor>();
+ private List<IBinaryAccessor> fieldTypeTags = new ArrayList<IBinaryAccessor>();
+ private List<IBinaryAccessor> fieldValues = new ArrayList<IBinaryAccessor>();
+
+ // accessor allocator
+ AccessorAllocator allocator = new AccessorAllocator();
private byte[] typeBuffer = new byte[32768];
private ResettableByteArrayOutputStream typeBos = new ResettableByteArrayOutputStream();
@@ -51,13 +65,8 @@
private int numberOfSchemaFields;
private int offsetArrayOffset;
private int[] fieldOffsets;
- private int fieldCursor = -1;
private ATypeTag typeTag;
- private SimpleValueReference nullReference = new SimpleValueReference();
-
- private byte[] data;
- private int start;
- private int len;
+ private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
public ARecordAccessor(ARecordType inputType) {
this.inputRecType = inputType;
@@ -72,11 +81,17 @@
for (int i = 0; i < numberOfSchemaFields; i++) {
ATypeTag ftypeTag = fieldTypes[i].getTypeTag();
+ if (fieldTypes[i].getTypeTag() == ATypeTag.UNION
+ && NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[i]))
+ // optional field: add the embedded non-null type tag
+ ftypeTag = ((AUnionType) fieldTypes[i]).getUnionList()
+ .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
+
// add type tag Reference
int tagStart = typeBos.size();
typeDos.writeByte(ftypeTag.serialize());
int tagEnd = typeBos.size();
- SimpleValueReference typeTagReference = new SimpleValueReference();
+ IBinaryAccessor typeTagReference = AFlatValueAccessor.FACTORY.createElement(null);
typeTagReference.reset(typeBuffer, tagStart, tagEnd - tagStart);
fieldTypeTags.add(typeTagReference);
@@ -85,7 +100,7 @@
typeDos.writeByte(ATypeTag.STRING.serialize());
typeDos.writeUTF(fieldNameStrs[i]);
int nameEnd = typeBos.size();
- SimpleValueReference typeNameReference = new SimpleValueReference();
+ IBinaryAccessor typeNameReference = AFlatValueAccessor.FACTORY.createElement(null);
typeNameReference.reset(typeBuffer, nameStart, nameEnd - nameStart);
fieldNames.add(typeNameReference);
}
@@ -106,15 +121,21 @@
private void reset() {
typeBos.setByteArray(typeBuffer, closedPartTypeInfoSize);
dataBos.setByteArray(dataBuffer, 0);
- fieldCursor = -1;
+ // reset the allocator
+ allocator.reset();
+
+ // clean up the returned containers
+ for (int i = fieldNames.size() - 1; i >= numberOfSchemaFields; i--)
+ fieldNames.remove(i);
+ for (int i = fieldTypeTags.size() - 1; i >= numberOfSchemaFields; i--)
+ fieldTypeTags.remove(i);
+ fieldValues.clear();
}
public void reset(byte[] b, int start, int len) {
// clear the previous states
reset();
- this.data = b;
- this.start = start;
- this.len = len;
+ super.reset(b, start, len);
boolean isExpanded = false;
int openPartOffset = 0;
@@ -153,23 +174,24 @@
offsetArrayOffset += 4;
}
for (int fieldNumber = 0; fieldNumber < numberOfSchemaFields; fieldNumber++) {
- next();
if (hasNullableFields) {
byte b1 = b[nullBitMapOffset + fieldNumber / 8];
int p = 1 << (7 - (fieldNumber % 8));
if ((b1 & p) == 0) {
// set null value (including type tag inside)
- nextFieldValue().reset(nullReference);
+ fieldValues.add(nullReference);
continue;
}
}
IAType[] fieldTypes = inputRecType.getFieldTypes();
int fieldValueLength = 0;
+ IAType fieldType = fieldTypes[fieldNumber];
if (fieldTypes[fieldNumber].getTypeTag() == ATypeTag.UNION) {
if (NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[fieldNumber])) {
- typeTag = ((AUnionType) fieldTypes[fieldNumber]).getUnionList()
- .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
+ fieldType = ((AUnionType) fieldTypes[fieldNumber]).getUnionList().get(
+ NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ typeTag = fieldType.getTypeTag();
fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffsets[fieldNumber],
typeTag, false);
}
@@ -183,14 +205,15 @@
dataDos.writeByte(typeTag.serialize());
dataDos.write(b, fieldOffsets[fieldNumber], fieldValueLength);
int fend = dataBos.size();
- nextFieldValue().reset(dataBuffer, fstart, fend - fstart);
+ IBinaryAccessor fieldValue = allocator.allocateFieldValue(fieldType);
+ fieldValue.reset(dataBuffer, fstart, fend - fstart);
+ fieldValues.add(fieldValue);
}
}
if (isExpanded) {
int numberOfOpenFields = AInt32SerializerDeserializer.getInt(b, openPartOffset);
int fieldOffset = openPartOffset + 4 + (8 * numberOfOpenFields);
for (int i = 0; i < numberOfOpenFields; i++) {
- next();
// set the field name (including a type tag, which is
// astring)
int fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, ATypeTag.STRING,
@@ -199,16 +222,24 @@
dataDos.writeByte(ATypeTag.STRING.serialize());
dataDos.write(b, fieldOffset, fieldValueLength);
int fnend = dataBos.size();
- nextFieldName().reset(dataBuffer, fnstart, fnend - fnstart);
+ IBinaryAccessor fieldName = allocator.allocateFieldName();
+ fieldName.reset(dataBuffer, fnstart, fnend - fnstart);
+ fieldNames.add(fieldName);
fieldOffset += fieldValueLength;
// set the field type tag
- nextFieldType().reset(b, fieldOffset, 1);
+ IBinaryAccessor fieldTypeTag = allocator.allocateFieldType();
+ fieldTypeTag.reset(b, fieldOffset, 1);
+ fieldTypeTags.add(fieldTypeTag);
typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[fieldOffset]);
// set the field value (already including type tag)
fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, typeTag, true) + 1;
- nextFieldValue().reset(b, fieldOffset, fieldValueLength);
+
+ // allocate
+ IBinaryAccessor fieldValueAccessor = allocator.allocateFieldValue(typeTag);
+ fieldValueAccessor.reset(b, fieldOffset, fieldValueLength);
+ fieldValues.add(fieldValueAccessor);
fieldOffset += fieldValueLength;
}
}
@@ -217,68 +248,21 @@
}
}
- private void next() {
- fieldCursor++;
- }
-
- private SimpleValueReference nextFieldName() {
- if (fieldCursor < fieldNames.size()) {
- return fieldNames.get(fieldCursor);
- } else {
- SimpleValueReference fieldNameReference = new SimpleValueReference();
- fieldNames.add(fieldNameReference);
- return fieldNameReference;
- }
- }
-
- private SimpleValueReference nextFieldType() {
- if (fieldCursor < fieldTypeTags.size()) {
- return fieldTypeTags.get(fieldCursor);
- } else {
- SimpleValueReference fieldTypeReference = new SimpleValueReference();
- fieldTypeTags.add(fieldTypeReference);
- return fieldTypeReference;
- }
- }
-
- private SimpleValueReference nextFieldValue() {
- if (fieldCursor < fieldValues.size()) {
- return fieldValues.get(fieldCursor);
- } else {
- SimpleValueReference fieldValueReference = new SimpleValueReference();
- fieldValues.add(fieldValueReference);
- return fieldValueReference;
- }
- }
-
- public int getCursor() {
- return fieldCursor;
- }
-
- public List<SimpleValueReference> getFieldNames() {
+ public List<IBinaryAccessor> getFieldNames() {
return fieldNames;
}
- public List<SimpleValueReference> getFieldTypeTags() {
+ public List<IBinaryAccessor> getFieldTypeTags() {
return fieldTypeTags;
}
- public List<SimpleValueReference> getFieldValues() {
+ public List<IBinaryAccessor> getFieldValues() {
return fieldValues;
}
@Override
- public byte[] getBytes() {
- return data;
+ public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+ return vistor.visit(this, tag);
}
- @Override
- public int getStartIndex() {
- return start;
- }
-
- @Override
- public int getLength() {
- return len;
- }
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
new file mode 100644
index 0000000..3e027b8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors;
+
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+
+public abstract class AbstractBinaryAccessor implements IBinaryAccessor {
+
+ private byte[] data;
+ private int start;
+ private int len;
+
+ @Override
+ public byte[] getBytes() {
+ return data;
+ }
+
+ @Override
+ public int getLength() {
+ return len;
+ }
+
+ @Override
+ public int getStartIndex() {
+ return start;
+ }
+
+ @Override
+ public void reset(byte[] b, int start, int len) {
+ this.data = b;
+ this.start = start;
+ this.len = len;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
new file mode 100644
index 0000000..a44885b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.container.IElementAllocator;
+import edu.uci.ics.asterix.runtime.util.container.ListElementAllocator;
+
+public class AccessorAllocator {
+
+ private IElementAllocator<IBinaryAccessor, IAType> flatArtifactAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ AFlatValueAccessor.FACTORY);
+ private IElementAllocator<IBinaryAccessor, IAType> nestedRecValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ ARecordAccessor.FACTORY);
+ private IElementAllocator<IBinaryAccessor, IAType> nestedListValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ AListAccessor.FACTORY);
+
+ public IBinaryAccessor allocateFieldName() {
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateFieldType() {
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateFieldValue(IAType type) {
+ if(type == null)
+ return flatArtifactAllocator.allocate(null);
+ else if (type.getTypeTag().equals(ATypeTag.RECORD))
+ return nestedRecValueAllocator.allocate(type);
+ else if (type.getTypeTag().equals(ATypeTag.UNORDEREDLIST) || type.getTypeTag().equals(ATypeTag.ORDEREDLIST))
+ return nestedListValueAllocator.allocate(type);
+ else
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateFieldValue(ATypeTag typeTag) {
+ if(typeTag == null)
+ return flatArtifactAllocator.allocate(null);
+ else if (typeTag.equals(ATypeTag.RECORD))
+ return nestedRecValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ else if (typeTag.equals(ATypeTag.UNORDEREDLIST))
+ return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+ else if(typeTag.equals(ATypeTag.ORDEREDLIST))
+ return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+ else
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateNestedListValue(IAType type) {
+ return nestedListValueAllocator.allocate(type);
+ }
+
+ public void reset() {
+ flatArtifactAllocator.reset();
+ nestedRecValueAllocator.reset();
+ nestedListValueAllocator.reset();
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
new file mode 100644
index 0000000..9da464f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors.base;
+
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+
+public class DefaultOpenFieldType {
+
+ // nested open field rec type
+ public static ARecordType NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {},
+ new IAType[] {}, true);
+
+ // nested open list type
+ public static AOrderedListType NESTED_OPEN_AORDERED_LIST_TYPE = new AOrderedListType(BuiltinType.ANY,
+ "nested-ordered-list");
+
+ // nested open list type
+ public static AUnorderedListType NESTED_OPEN_AUNORDERED_LIST_TYPE = new AUnorderedListType(BuiltinType.ANY,
+ "nested-unordered-list");
+
+ public static IAType getDefaultOpenFieldType(ATypeTag tag){
+ if(tag.equals(ATypeTag.RECORD))
+ return NESTED_OPEN_RECORD_TYPE;
+ if(tag.equals(ATypeTag.ORDEREDLIST))
+ return NESTED_OPEN_AORDERED_LIST_TYPE;
+ if(tag.equals(ATypeTag.UNORDEREDLIST))
+ return NESTED_OPEN_AUNORDERED_LIST_TYPE;
+ else
+ return null;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java
new file mode 100644
index 0000000..37d8b80
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors.base;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
+
+public interface IBinaryAccessor extends IValueReference {
+
+ public void reset(byte[] b, int start, int len);
+
+ public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
new file mode 100644
index 0000000..54b0960
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors.cast;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+
+public class ACastVisitor implements IBinaryAccessorVisitor<Void, Triple<IBinaryAccessor, IAType, Boolean>> {
+
+ private Map<IBinaryAccessor, ARecordCaster> raccessorToCaster = new HashMap<IBinaryAccessor, ARecordCaster>();
+ private Map<IBinaryAccessor, AListCaster> laccessorToCaster = new HashMap<IBinaryAccessor, AListCaster>();
+
+ @Override
+ public Void visit(AListAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) throws AsterixException {
+ AListCaster caster = laccessorToCaster.get(accessor);
+ if (caster == null) {
+ caster = new AListCaster();
+ laccessorToCaster.put(accessor, caster);
+ }
+ try {
+ caster.castList(accessor, arg.first, (AbstractCollectionType) arg.second, this);
+ } catch (Exception e) {
+ throw new AsterixException(e);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visit(ARecordAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) throws AsterixException {
+ ARecordCaster caster = raccessorToCaster.get(accessor);
+ if (caster == null) {
+ caster = new ARecordCaster();
+ raccessorToCaster.put(accessor, caster);
+ }
+ try {
+ caster.castRecord(accessor, arg.first, (ARecordType) arg.second, this);
+ } catch (Exception e) {
+ throw new AsterixException(e);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visit(AFlatValueAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) {
+ // set the pointer for result
+ arg.first.reset(accessor.getBytes(), accessor.getStartIndex(), accessor.getLength());
+ return null;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java
new file mode 100644
index 0000000..aba06b5
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors.cast;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.builders.UnorderedListBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+
+class AListCaster {
+
+ private IAType reqItemType;
+ private IBinaryAccessor itemTempReference = AFlatValueAccessor.FACTORY.createElement(null);
+ private Triple<IBinaryAccessor, IAType, Boolean> itemVisitorArg = new Triple<IBinaryAccessor, IAType, Boolean>(
+ itemTempReference, null, null);
+
+ private UnorderedListBuilder unOrderedListBuilder = new UnorderedListBuilder();
+ private OrderedListBuilder orderedListBuilder = new OrderedListBuilder();
+
+ private byte[] dataBuffer = new byte[32768];
+ private ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
+ private DataOutput dataDos = new DataOutputStream(dataBos);
+
+ public AListCaster() {
+
+ }
+
+ public void castList(AListAccessor listAccessor, IBinaryAccessor resultAccessor, AbstractCollectionType reqType,
+ ACastVisitor visitor) throws IOException, AsterixException {
+ if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+ unOrderedListBuilder.reset((AUnorderedListType) reqType);
+ }
+ if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+ orderedListBuilder.reset((AOrderedListType) reqType);
+ }
+ dataBos.setByteArray(dataBuffer, 0);
+
+ List<IBinaryAccessor> itemTags = listAccessor.getItemTags();
+ List<IBinaryAccessor> items = listAccessor.getItems();
+
+ int start = dataBos.size();
+ for (int i = 0; i < items.size(); i++) {
+ IBinaryAccessor itemTypeTag = itemTags.get(i);
+ IBinaryAccessor item = items.get(i);
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getBytes()[itemTypeTag
+ .getStartIndex()]);
+ if (reqItemType == null || reqItemType.getTypeTag().equals(ATypeTag.ANY)) {
+ itemVisitorArg.second = DefaultOpenFieldType.getDefaultOpenFieldType(typeTag);
+ item.accept(visitor, itemVisitorArg);
+ } else {
+ if (typeTag != reqItemType.getTypeTag())
+ throw new AsterixException("mismatched item type");
+ itemVisitorArg.second = reqItemType;
+ item.accept(visitor, itemVisitorArg);
+ }
+ if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+ orderedListBuilder.addItem(itemVisitorArg.first);
+ }
+ if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+ unOrderedListBuilder.addItem(itemVisitorArg.first);
+ }
+ }
+ if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+ orderedListBuilder.write(dataDos, true);
+ }
+ if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+ unOrderedListBuilder.write(dataDos, true);
+ }
+ int end = dataBos.size();
+ resultAccessor.reset(dataBuffer, start, end - start);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
similarity index 70%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
index 505e769..a4efa58 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-package edu.uci.ics.asterix.runtime.util;
+package edu.uci.ics.asterix.runtime.accessors.cast;
import java.io.DataOutput;
import java.io.DataOutputStream;
@@ -22,19 +22,27 @@
import java.util.List;
import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
-public class ARecordCaster {
+class ARecordCaster {
// describe closed fields in the required type
private int[] fieldPermutation;
@@ -44,9 +52,9 @@
private boolean[] openFields;
private int[] fieldNamesSortedIndex;
- private List<SimpleValueReference> reqFieldNames = new ArrayList<SimpleValueReference>();
+ private List<IBinaryAccessor> reqFieldNames = new ArrayList<IBinaryAccessor>();
private int[] reqFieldNamesSortedIndex;
- private List<SimpleValueReference> reqFieldTypeTags = new ArrayList<SimpleValueReference>();
+ private List<IBinaryAccessor> reqFieldTypeTags = new ArrayList<IBinaryAccessor>();
private ARecordType cachedReqType = null;
private byte[] buffer = new byte[32768];
@@ -54,13 +62,21 @@
private DataOutputStream dos = new DataOutputStream(bos);
private RecordBuilder recBuilder = new RecordBuilder();
- private SimpleValueReference nullReference = new SimpleValueReference();
- private SimpleValueReference nullTypeTag = new SimpleValueReference();
+ private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
+ private IBinaryAccessor nullTypeTag = AFlatValueAccessor.FACTORY.createElement(null);
private int numInputFields = 0;
private IBinaryComparator fieldNameComparator = PointableBinaryComparatorFactory.of(UTF8StringPointable.FACTORY)
.createBinaryComparator();
+ private byte[] outputBuffer = new byte[32768];
+ private ResettableByteArrayOutputStream outputBos = new ResettableByteArrayOutputStream();
+ private DataOutputStream outputDos = new DataOutputStream(outputBos);
+
+ private IBinaryAccessor fieldTempReference = AFlatValueAccessor.FACTORY.createElement(null);
+ private Triple<IBinaryAccessor, IAType, Boolean> nestedVisitorArg = new Triple<IBinaryAccessor, IAType, Boolean>(
+ fieldTempReference, null, null);
+
public ARecordCaster() {
try {
bos.setByteArray(buffer, 0);
@@ -78,11 +94,12 @@
}
}
- public void castRecord(ARecordAccessor recordAccessor, ARecordType reqType, DataOutput output) throws IOException {
- List<SimpleValueReference> fieldNames = recordAccessor.getFieldNames();
- List<SimpleValueReference> fieldTypeTags = recordAccessor.getFieldTypeTags();
- List<SimpleValueReference> fieldValues = recordAccessor.getFieldValues();
- numInputFields = recordAccessor.getCursor() + 1;
+ public void castRecord(ARecordAccessor recordAccessor, IBinaryAccessor resultAccessor, ARecordType reqType,
+ ACastVisitor visitor) throws IOException, AsterixException {
+ List<IBinaryAccessor> fieldNames = recordAccessor.getFieldNames();
+ List<IBinaryAccessor> fieldTypeTags = recordAccessor.getFieldTypeTags();
+ List<IBinaryAccessor> fieldValues = recordAccessor.getFieldValues();
+ numInputFields = fieldNames.size();
if (openFields == null || numInputFields > openFields.length) {
openFields = new boolean[numInputFields];
@@ -95,7 +112,8 @@
// clear the previous states
reset();
matchClosedPart(fieldNames, fieldTypeTags, fieldValues);
- writeOutput(fieldNames, fieldTypeTags, fieldValues, output);
+ writeOutput(fieldNames, fieldTypeTags, fieldValues, outputDos, visitor);
+ resultAccessor.reset(outputBuffer, 0, outputBos.size());
}
private void reset() {
@@ -105,6 +123,7 @@
fieldPermutation[i] = -1;
for (int i = 0; i < numInputFields; i++)
fieldNamesSortedIndex[i] = i;
+ outputBos.setByteArray(outputBuffer, 0);
}
private void loadRequiredType(ARecordType reqType) throws IOException {
@@ -136,7 +155,7 @@
int tagStart = bos.size();
dos.writeByte(ftypeTag.serialize());
int tagEnd = bos.size();
- SimpleValueReference typeTagPointable = new SimpleValueReference();
+ IBinaryAccessor typeTagPointable = AFlatValueAccessor.FACTORY.createElement(null);
typeTagPointable.reset(buffer, tagStart, tagEnd - tagStart);
reqFieldTypeTags.add(typeTagPointable);
@@ -145,7 +164,7 @@
dos.write(ATypeTag.STRING.serialize());
dos.writeUTF(fname);
int nameEnd = bos.size();
- SimpleValueReference typeNamePointable = new SimpleValueReference();
+ IBinaryAccessor typeNamePointable = AFlatValueAccessor.FACTORY.createElement(null);
typeNamePointable.reset(buffer, nameStart, nameEnd - nameStart);
reqFieldNames.add(typeNamePointable);
}
@@ -157,8 +176,8 @@
quickSort(reqFieldNamesSortedIndex, reqFieldNames, 0, reqFieldNamesSortedIndex.length - 1);
}
- private void matchClosedPart(List<SimpleValueReference> fieldNames, List<SimpleValueReference> fieldTypeTags,
- List<SimpleValueReference> fieldValues) {
+ private void matchClosedPart(List<IBinaryAccessor> fieldNames, List<IBinaryAccessor> fieldTypeTags,
+ List<IBinaryAccessor> fieldValues) {
// sort-merge based match
quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1);
int fnStart = 0;
@@ -168,8 +187,8 @@
int reqFnPos = reqFieldNamesSortedIndex[reqFnStart];
int c = compare(fieldNames.get(fnPos), reqFieldNames.get(reqFnPos));
if (c == 0) {
- SimpleValueReference fieldTypeTag = fieldTypeTags.get(fnPos);
- SimpleValueReference reqFieldTypeTag = reqFieldTypeTags.get(reqFnPos);
+ IBinaryAccessor fieldTypeTag = fieldTypeTags.get(fnPos);
+ IBinaryAccessor reqFieldTypeTag = reqFieldTypeTags.get(reqFnPos);
if (fieldTypeTag.equals(reqFieldTypeTag) || (
// match the null type of optional field
optionalFields[reqFnPos] && fieldTypeTag.equals(nullTypeTag))) {
@@ -203,8 +222,9 @@
}
}
- private void writeOutput(List<SimpleValueReference> fieldNames, List<SimpleValueReference> fieldTypeTags,
- List<SimpleValueReference> fieldValues, DataOutput output) throws IOException {
+ private void writeOutput(List<IBinaryAccessor> fieldNames, List<IBinaryAccessor> fieldTypeTags,
+ List<IBinaryAccessor> fieldValues, DataOutput output, ACastVisitor visitor) throws IOException,
+ AsterixException {
// reset the states of the record builder
recBuilder.reset(cachedReqType);
recBuilder.init();
@@ -212,27 +232,43 @@
// write the closed part
for (int i = 0; i < fieldPermutation.length; i++) {
int pos = fieldPermutation[i];
- SimpleValueReference field;
+ IBinaryAccessor field;
if (pos >= 0) {
field = fieldValues.get(pos);
} else {
field = nullReference;
}
- recBuilder.addField(i, field);
+ IAType fType = cachedReqType.getFieldTypes()[i];
+ nestedVisitorArg.second = fType;
+
+ // recursively casting, the result of casting can always be thought
+ // as flat
+ if (optionalFields[i]) {
+ nestedVisitorArg.second = ((AUnionType) fType).getUnionList().get(
+ NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ }
+ field.accept(visitor, nestedVisitorArg);
+ recBuilder.addField(i, nestedVisitorArg.first);
}
// write the open part
for (int i = 0; i < numInputFields; i++) {
if (openFields[i]) {
- SimpleValueReference name = fieldNames.get(i);
- SimpleValueReference field = fieldValues.get(i);
- recBuilder.addField(name, field);
+ IBinaryAccessor name = fieldNames.get(i);
+ IBinaryAccessor field = fieldValues.get(i);
+ IBinaryAccessor fieldTypeTag = fieldTypeTags.get(i);
+
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(fieldTypeTag.getBytes()[fieldTypeTag.getStartIndex()]);
+ nestedVisitorArg.second = DefaultOpenFieldType.getDefaultOpenFieldType(typeTag);
+ field.accept(visitor, nestedVisitorArg);
+ recBuilder.addField(name, nestedVisitorArg.first);
}
}
recBuilder.write(output, true);
}
- private void quickSort(int[] index, List<SimpleValueReference> names, int start, int end) {
+ private void quickSort(int[] index, List<IBinaryAccessor> names, int start, int end) {
if (end <= start)
return;
int i = partition(index, names, start, end);
@@ -240,7 +276,7 @@
quickSort(index, names, i + 1, end);
}
- private int partition(int[] index, List<SimpleValueReference> names, int left, int right) {
+ private int partition(int[] index, List<IBinaryAccessor> names, int left, int right) {
int i = left - 1;
int j = right;
while (true) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java
new file mode 100644
index 0000000..e35421a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.accessors.visitor;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+
+public interface IBinaryAccessorVisitor<R, T> {
+
+ public R visit(AListAccessor accessor, T arg) throws AsterixException;
+
+ public R visit(ARecordAccessor accessor, T arg) throws AsterixException;
+
+ public R visit(AFlatValueAccessor accessor, T arg) throws AsterixException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
index 705efab..c82bb9b 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
@@ -1,16 +1,18 @@
package edu.uci.ics.asterix.runtime.evaluators.functions;
import java.io.DataOutput;
-import java.io.IOException;
import edu.uci.ics.asterix.common.functions.FunctionConstants;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.cast.ACastVisitor;
import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import edu.uci.ics.asterix.runtime.util.ARecordAccessor;
-import edu.uci.ics.asterix.runtime.util.ARecordCaster;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.runtime.base.IEvaluator;
import edu.uci.ics.hyracks.algebricks.runtime.base.IEvaluatorFactory;
@@ -57,7 +59,10 @@
return new IEvaluator() {
final ARecordAccessor recAccessor = new ARecordAccessor(inputType);
- final ARecordCaster caster = new ARecordCaster();
+ final ARecordAccessor resultAccessor = new ARecordAccessor(reqType);
+ final ACastVisitor castVisitor = new ACastVisitor();
+ final Triple<IBinaryAccessor, IAType, Boolean> arg = new Triple<IBinaryAccessor, IAType, Boolean>(
+ resultAccessor, reqType, Boolean.FALSE);
@Override
public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
@@ -66,8 +71,10 @@
recEvaluator.evaluate(tuple);
recAccessor.reset(recordBuffer.getBytes(), recordBuffer.getStartIndex(),
recordBuffer.getLength());
- caster.castRecord(recAccessor, reqType, out);
- } catch (IOException ioe) {
+ recAccessor.accept(castVisitor, arg);
+ out.write(resultAccessor.getBytes(), resultAccessor.getStartIndex(),
+ resultAccessor.getLength());
+ } catch (Exception ioe) {
throw new AlgebricksException(ioe);
}
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java
deleted file mode 100644
index e49218a..0000000
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2009-2010 by The Regents of the University of California
- * Licensed 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 from
- *
- * 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 edu.uci.ics.asterix.runtime.util;
-
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
-
-public class SimpleValueReference implements IValueReference {
-
- private byte[] data;
- private int start;
- private int len;
-
- public void reset(byte[] data, int start, int len) {
- this.data = data;
- this.start = start;
- this.len = len;
- }
-
- public void reset(IValueReference ivf) {
- this.data = ivf.getBytes();
- this.start = ivf.getStartIndex();
- this.len = ivf.getLength();
- }
-
- @Override
- public byte[] getBytes() {
- return data;
- }
-
- @Override
- public int getStartIndex() {
- return start;
- }
-
- @Override
- public int getLength() {
- return len;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof IValueReference))
- return false;
- IValueReference ivf = (IValueReference) o;
- byte[] odata = ivf.getBytes();
- int ostart = ivf.getStartIndex();
- int olen = ivf.getLength();
-
- if (len != olen)
- return false;
- for (int i = 0; i < len; i++) {
- if (data[start + i] != odata[ostart + i])
- return false;
- }
- return true;
- }
-}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
new file mode 100644
index 0000000..8d17cb7
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.util.container;
+
+public interface IElementAllocator<E, T> {
+
+ public E allocate(T arg);
+
+ public void reset();
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
new file mode 100644
index 0000000..4698c25
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.util.container;
+
+public interface IElementFactory<E, T> {
+
+ public E createElement(T arg);
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
new file mode 100644
index 0000000..447b740
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.util.container;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListElementAllocator<E, T> implements IElementAllocator<E, T> {
+
+ private IElementFactory<E, T> factory;
+ private List<E> pool = new ArrayList<E>();
+ private int cursor = -1;
+
+ public ListElementAllocator(IElementFactory<E, T> factory) {
+ this.factory = factory;
+ }
+
+ public E allocate(T arg) {
+ cursor++;
+ if (cursor < pool.size()) {
+ return pool.get(cursor);
+ } else {
+ E element = factory.createElement(arg);
+ pool.add(element);
+ return element;
+ }
+ }
+
+ public void reset() {
+ cursor = -1;
+ }
+}