merge asterix_opentype r340:364
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype_mergeback_staging@365 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
index 35a5966..4859b09 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
@@ -43,6 +43,15 @@
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+/**
+ * dynamically cast a constant from its type produced by the originated
+ * expression to its required type, in a recursive way
+ * it enables:
+ * 1. bag-based fields in a record
+ * 2. bidirectional cast of a open field and a matched closed field
+ * 3. put in null fields when necessary
+ * since we have open records, so dynamic cast is needed
+ */
public class IntroduceDynamicTypeCastRule implements IAlgebraicRewriteRule {
@Override
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 154cbe3..b91abe7 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
@@ -16,6 +16,7 @@
package edu.uci.ics.asterix.optimizer.rules;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.mutable.Mutable;
@@ -52,6 +53,16 @@
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+/**
+ * statically cast a constant from its type produced by the originated
+ * expression to its required type, in a recursive way it enables: 1. bag-based
+ * fields in a record 2. bidirectional cast of a open field and a matched closed
+ * field 3. put in null fields when necessary It should be fired before the
+ * constant folding rule
+ *
+ * This rule is not responsible for type casting between primitive types Tests
+ * open-closed/open-closed-15 and after are not to test this rule
+ */
public class IntroduceStaticTypeCastRule implements IAlgebraicRewriteRule {
@Override
@@ -83,7 +94,7 @@
* get required record type
*/
InsertDeleteOperator insertDeleteOperator = (InsertDeleteOperator) op2;
- AssignOperator oldAssignOperator = (AssignOperator) op3;
+ AssignOperator topAssignOperator = (AssignOperator) op3;
AqlDataSource dataSource = (AqlDataSource) insertDeleteOperator.getDataSource();
IAType[] schemaTypes = (IAType[]) dataSource.getSchemaTypes();
ARecordType requiredRecordType = (ARecordType) schemaTypes[schemaTypes.length - 1];
@@ -92,15 +103,19 @@
* get input record type to the insert operator
*/
List<LogicalVariable> usedVariables = new ArrayList<LogicalVariable>();
- VariableUtilities.getUsedVariables(oldAssignOperator, usedVariables);
+ VariableUtilities.getUsedVariables(topAssignOperator, usedVariables);
+
+ // the used variable should contain the record that will be inserted
+ // but it will not fail in many cases even if the used variable set is
+ // empty
if (usedVariables.size() == 0)
return false;
LogicalVariable oldRecordVariable = usedVariables.get(0);
LogicalVariable inputRecordVar = usedVariables.get(0);
- IVariableTypeEnvironment env = oldAssignOperator.computeOutputTypeEnvironment(context);
+ IVariableTypeEnvironment env = topAssignOperator.computeOutputTypeEnvironment(context);
ARecordType inputRecordType = (ARecordType) env.getVarType(inputRecordVar);
- AbstractLogicalOperator currentOperator = oldAssignOperator;
+ AbstractLogicalOperator currentOperator = topAssignOperator;
List<LogicalVariable> producedVariables = new ArrayList<LogicalVariable>();
/**
@@ -119,13 +134,15 @@
*/
if (position >= 0) {
AssignOperator originalAssign = (AssignOperator) currentOperator;
- List<Mutable<ILogicalExpression>> expressionPointers = originalAssign.getExpressions();
- ILogicalExpression expr = expressionPointers.get(position).getValue();
+ List<Mutable<ILogicalExpression>> expressionRefs = originalAssign.getExpressions();
+ ILogicalExpression expr = expressionRefs.get(position).getValue();
if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expr;
+ // that expression has been rewritten, and it will not
+ // fail but just return false
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
return false;
- IVariableTypeEnvironment assignEnv = oldAssignOperator.computeOutputTypeEnvironment(context);
+ IVariableTypeEnvironment assignEnv = topAssignOperator.computeOutputTypeEnvironment(context);
rewriteFuncExpr(funcExpr, requiredRecordType, inputRecordType, assignEnv);
}
context.computeAndSetTypeEnvironmentForOperator(originalAssign);
@@ -143,22 +160,38 @@
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) {
+ } else if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR) {
rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
} else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
}
}
+ /**
+ * only called when funcExpr is record constructor
+ * @param funcExpr record constructor function expression
+ * @param requiredListType required record type
+ * @param inputRecordType
+ * @param env type environment
+ * @throws AlgebricksException
+ */
private void rewriteRecordFuncExpr(ScalarFunctionCallExpression funcExpr, ARecordType requiredRecordType,
ARecordType inputRecordType, IVariableTypeEnvironment env) throws AlgebricksException {
+ // if already rewritten, the required type is not null
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
return;
TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
}
+ /**
+ * only called when funcExpr is list constructor
+ * @param funcExpr list constructor function expression
+ * @param requiredListType required list type
+ * @param inputListType
+ * @param env type environment
+ * @throws AlgebricksException
+ */
private void rewriteListFuncExpr(ScalarFunctionCallExpression funcExpr, AbstractCollectionType requiredListType,
AbstractCollectionType inputListType, IVariableTypeEnvironment env) throws AlgebricksException {
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
@@ -196,13 +229,10 @@
int[] fieldPermutation = new int[reqFieldTypes.length];
boolean[] nullFields = new boolean[reqFieldTypes.length];
boolean[] openFields = new boolean[inputFieldTypes.length];
-
- for (int i = 0; i < nullFields.length; i++)
- nullFields[i] = false;
- for (int i = 0; i < openFields.length; i++)
- openFields[i] = true;
- for (int i = 0; i < fieldPermutation.length; i++)
- fieldPermutation[i] = -1;
+
+ Arrays.fill(nullFields, false);
+ Arrays.fill(openFields, true);
+ Arrays.fill(fieldPermutation, -1);
// forward match: match from actual to required
boolean matched = false;
@@ -211,8 +241,9 @@
IAType fieldType = inputFieldTypes[i];
if (2 * i + 1 > func.getArguments().size())
- break;
+ throw new AlgebricksException("expression index out of bound");
+ // 2*i+1 is the index of field value expression
ILogicalExpression arg = func.getArguments().get(2 * i + 1).getValue();
matched = false;
for (int j = 0; j < reqFieldNames.length; j++) {
@@ -262,11 +293,9 @@
}
}
}
- if (matched)
- continue;
// the input has extra fields
- if (!reqType.isOpen())
- throw new IllegalStateException("static type mismatch: including extra closed fields");
+ if (!matched && !reqType.isOpen())
+ throw new AlgebricksException("static type mismatch: including an extra closed field " + fieldName);
}
// backward match: match from required to actual
@@ -277,47 +306,52 @@
for (int j = 0; j < inputFieldNames.length; j++) {
String fieldName = inputFieldNames[j];
IAType fieldType = inputFieldTypes[j];
- if (fieldName.equals(reqFieldName)) {
- if (!openFields[j]) {
+ if (!fieldName.equals(reqFieldName))
+ continue;
+ // should check open field here
+ // because number of entries in fieldPermuations is the
+ // number of required schema fields
+ // here we want to check if an input field is matched
+ // the entry index of fieldPermuatons is req field index
+ if (!openFields[j]) {
+ matched = true;
+ break;
+ }
+
+ // match the optional field
+ if (reqFieldType.getTypeTag() == ATypeTag.UNION
+ && NonTaggedFormatUtil.isOptionalField((AUnionType) reqFieldType)) {
+ IAType itemType = ((AUnionType) reqFieldType).getUnionList().get(
+ NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+ if (fieldType.equals(BuiltinType.ANULL) || fieldType.equals(itemType)) {
matched = true;
break;
}
-
- // match the optional field
- if (reqFieldType.getTypeTag() == ATypeTag.UNION
- && NonTaggedFormatUtil.isOptionalField((AUnionType) reqFieldType)) {
- IAType itemType = ((AUnionType) reqFieldType).getUnionList().get(
- NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
- if (fieldType.equals(BuiltinType.ANULL) || fieldType.equals(itemType)) {
- matched = true;
- break;
- }
- }
}
}
if (matched)
continue;
- IAType t = reqFieldTypes[i];
- if (t.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t)) {
+ if (reqFieldType.getTypeTag() == ATypeTag.UNION
+ && NonTaggedFormatUtil.isOptionalField((AUnionType) reqFieldType)) {
// add a null field
nullFields[i] = true;
} else {
// no matched field in the input for a required closed field
- throw new IllegalStateException("static type mismatch: miss a required closed field");
+ throw new AlgebricksException("static type mismatch: miss a required closed field " + reqFieldName);
}
}
List<Mutable<ILogicalExpression>> arguments = func.getArguments();
- List<Mutable<ILogicalExpression>> argumentsClone = new ArrayList<Mutable<ILogicalExpression>>();
- argumentsClone.addAll(arguments);
+ List<Mutable<ILogicalExpression>> originalArguments = new ArrayList<Mutable<ILogicalExpression>>();
+ originalArguments.addAll(arguments);
arguments.clear();
// re-order the closed part and fill in null fields
for (int i = 0; i < fieldPermutation.length; i++) {
int pos = fieldPermutation[i];
if (pos >= 0) {
- arguments.add(argumentsClone.get(2 * pos));
- arguments.add(argumentsClone.get(2 * pos + 1));
+ arguments.add(originalArguments.get(2 * pos));
+ arguments.add(originalArguments.get(2 * pos + 1));
}
if (nullFields[i]) {
// add a null field
@@ -331,10 +365,14 @@
// add the open part
for (int i = 0; i < openFields.length; i++) {
if (openFields[i]) {
- arguments.add(argumentsClone.get(2 * i));
- Mutable<ILogicalExpression> fExprRef = argumentsClone.get(2 * i + 1);
+ arguments.add(originalArguments.get(2 * i));
+ Mutable<ILogicalExpression> fExprRef = originalArguments.get(2 * i + 1);
ILogicalExpression argExpr = fExprRef.getValue();
+ // we need to handle open fields recursively by their default
+ // types
+ // for list, their item type is any
+ // for record, their
if (argExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
IAType reqFieldType = inputFieldTypes[i];
if (inputFieldTypes[i].getTypeTag() == ATypeTag.RECORD) {
diff --git a/asterix-app/src/test/resources/runtimets/ignore.txt b/asterix-app/src/test/resources/runtimets/ignore.txt
index 962d26b..70bc44d 100644
--- a/asterix-app/src/test/resources/runtimets/ignore.txt
+++ b/asterix-app/src/test/resources/runtimets/ignore.txt
@@ -23,3 +23,7 @@
open-closed/open-closed-20
open-closed/open-closed-21
open-closed/open-closed-22
+open-closed/open-closed-28
+open-closed/open-closed-30
+open-closed/heterog-list02
+open-closed/heterog-list03
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list02.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list02.aql
new file mode 100644
index 0000000..47dd921
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list02.aql
@@ -0,0 +1,35 @@
+/*
+ * Test case Name : heterog-list02.aql
+ * Description : To test insertion of an array of arrays into internal dataset.
+ * : Heterogenous list construction.
+ * Success : Yes
+ * Date : 28th May 2012
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type BatterType as {
+id:int32,
+descrpt:string
+}
+
+create type TestType as {
+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"}],[{"id":349,"descrpt":"Soft"},{"id":449,"descrpt":"Vanilla"}]] }
+);
+
+for $l in dataset('T1')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list03.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list03.aql
new file mode 100644
index 0000000..94a87c0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list03.aql
@@ -0,0 +1,36 @@
+/*
+ * Test case Name : heterog-list03.aql
+ * Description : To test insertion of an array of arrays into internal dataset.
+ * : batters field is optional in this scenario.
+ * : Heterogenous list construction.
+ * Success : Yes
+ * Date : 28th May 2012
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type BatterType as {
+id:int32,
+descrpt:string
+}
+
+create type TestType as {
+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"}],[{"id":349,"descrpt":"Soft"},{"id":449,"descrpt":"Vanilla"}]] }
+);
+
+for $l in dataset('T1')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-24.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-24.aql
new file mode 100644
index 0000000..7012a5a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-24.aql
@@ -0,0 +1,26 @@
+/*
+ * Testcase Name : open-closed-24.aql
+ * Description : Test use of additional data(open) field in create type statement
+ * Success : Yes
+ * Date : 29th May 2012
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use dataverse test;
+
+create type testType as open {
+id : int32,
+name : string,
+opt_tag : {{ string }}
+}
+
+create dataset testds(testType) partitioned by key id;
+
+insert into dataset testds({"id": 32,"name": "UCI","opt_tag":{{"optional text","put any text here","and more"}}});
+
+write output to nc1:"rttest/open-closed_open-closed-24.adm";
+for $l in dataset('testds')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-25.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-25.aql
new file mode 100644
index 0000000..b29b63a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-25.aql
@@ -0,0 +1,26 @@
+/*
+ * Testcase Name : open-closed-25.aql
+ * Description : Test use of additional data(open) optional field in create type statement
+ * Success : Yes
+ * Date : 29th May 2012
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use dataverse test;
+
+create type testType as open {
+id : int32,
+name : string,
+opt_tag : {{ string }}?
+}
+
+create dataset testds(testType) partitioned by key id;
+
+insert into dataset testds({"id": 32,"name": "UCI","opt_tag":{{"optional text","put any text here","and more"}}});
+
+write output to nc1:"rttest/open-closed_open-closed-25.adm";
+for $l in dataset('testds')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-26.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-26.aql
new file mode 100644
index 0000000..f19e4a7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-26.aql
@@ -0,0 +1,27 @@
+/*
+ * Testcase Name : open-closed-26.aql
+ * Description : Test use of additional data(open) optional field in create type statement
+ * : No additional data is inserted (as it is declared as optional) from the insert statement.
+ * Success : Yes
+ * Date : 29th May 2012
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use dataverse test;
+
+create type testType as open {
+id : int32,
+name : string,
+opt_tag : {{ string }}?
+}
+
+create dataset testds(testType) partitioned by key id;
+
+insert into dataset testds({"id": 32,"name": "UCI"});
+
+write output to nc1:"rttest/open-closed_open-closed-26.adm";
+for $l in dataset('testds')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-28.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-28.aql
new file mode 100644
index 0000000..8fdab75
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-28.aql
@@ -0,0 +1,51 @@
+/*
+ * Testcase Name : open-closed-28.aql
+ * Description : Query for undeclared data from an open type internal dataset
+ * : use the every keyword in the where clause
+ * Status : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+ id: string,
+ name: string
+}
+
+create type testtype02 as open {
+id : string,
+name : string
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "001", "name": "Person One", "hobbies": {{"scuba", "music"}}}
+);
+
+insert into dataset testds02 (
+{ "id": "002", "name": "Person Two", "hobbies": {{"fishing", "dance"}}}
+);
+
+
+insert into dataset testds02 (
+{ "id": "003", "name": "Person Three", "hobbies": {{"hiking", "surfing"}}}
+);
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+// select all hobbies where hiking is one of the hobbies
+
+write output to nc1:"rttest/open-closed_open-closed-28.adm";
+for $d in dataset('testds01')
+where every $h in $d.hobbies satisfies $h='hiking'
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-29.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-29.aql
new file mode 100644
index 0000000..9560430
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-29.aql
@@ -0,0 +1,50 @@
+/*
+ * Testcase Name : open-closed-29.aql
+ * Description : Query for undeclared data from an open type internal dataset
+ * : use the some keyword in the where clause
+ * Status : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+ id: string,
+ name: string
+}
+
+create type testtype02 as open {
+id : string,
+name : string
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "001", "name": "Person One", "hobbies": {{"scuba", "music"}}}
+);
+
+insert into dataset testds02 (
+{ "id": "002", "name": "Person Two", "hobbies": {{"fishing", "dance"}}}
+);
+
+
+insert into dataset testds02 (
+{ "id": "003", "name": "Person Three", "hobbies": {{"hiking", "surfing"}}}
+);
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+// select all hobbies where hiking is one of the hobbies
+write output to nc1:"rttest/open-closed_open-closed-29.adm";
+for $d in dataset('testds01')
+where some $h in $d.hobbies satisfies $h='hiking'
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-30.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-30.aql
new file mode 100644
index 0000000..42aa2e6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-30.aql
@@ -0,0 +1,49 @@
+/*
+ * Test case Name : open-closed-30.aql
+ * Description : Query undeclared data using every in the WHERE clause
+ * : where every $h in $d.hobbies satisfies $h='hiking'
+ * Success : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+ id: string
+}
+
+create type testtype02 as open {
+id : string,
+name : string
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "011", "name": "John Doe", "hobbies": {{"scuba", "music"}}}
+);
+
+insert into dataset testds02 (
+{ "id": "102", "name": "Roger Sanders", "hobbies": {{"fishing", "dance"}}}
+);
+
+
+insert into dataset testds02 (
+{ "id": "203", "name": "Phil Smith", "hobbies": {{"hiking", "surfing"}}}
+);
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+write output to nc1:"rttest/open-closed_open-closed-30.adm";
+for $d in dataset('testds01')
+where every $h in $d.hobbies satisfies $h='hiking'
+order by $d.id
+return $d.hobbies
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-31.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-31.aql
new file mode 100644
index 0000000..03b1754
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-31.aql
@@ -0,0 +1,48 @@
+/*
+ * Test case Name : open-closed-31.aql
+ * Description :
+ * Success : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+ id: string
+}
+
+create type testtype02 as open {
+id : string,
+name : string
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "011", "name": "John Doe", "hobbies": {{"scuba", "music"}}}
+);
+
+insert into dataset testds02 (
+{ "id": "102", "name": "Roger Sanders", "hobbies": {{"fishing", "dance"}}}
+);
+
+
+insert into dataset testds02 (
+{ "id": "203", "name": "Phil Smith", "hobbies": {{"hiking", "surfing"}}}
+);
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+write output to nc1:"rttest/open-closed_open-closed-31.adm";
+for $d in dataset('testds01')
+where some $h in $d.hobbies satisfies $h='hiking'
+order by $d.id
+return $d.hobbies
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-32.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-32.aql
new file mode 100644
index 0000000..f101e47
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-32.aql
@@ -0,0 +1,54 @@
+/*
+ * Test case Name : open-closed-32.aql
+ * Description : INSERT into target (closed type) internal dataset by doing SELECT on (closed type) source internal dataset
+ * : then query the target internal dataset for data enclosed within {{ }} braces, in this case interests field.
+ * Success : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+id: string
+}
+
+create type testtype02 as closed {
+id : string,
+name : string,
+sex : string,
+dept : string,
+salary : int32,
+interests : {{string}}
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "011", "name": "John Doe", "sex":"Male", "dept":"HR", "salary":80000,"interests":{{"hiking","scuba","painting","biking"}}});
+
+insert into dataset testds02 (
+{ "id": "921", "name": "John Smith", "sex":"Male", "dept":"Sales", "salary":65000,"interests":{{"gardening","biking","reading","hiking","fishing"}}});
+
+insert into dataset testds02 (
+{ "id": "959", "name": "Susan Malaika", "sex":"Female", "dept":"XML Dev", "salary":200000,"interests":{{"XML","Web Services","Cloud","X-Forms","art","travelling"}}});
+
+insert into dataset testds02 (
+{ "id": "371", "name": "Tom Sawyer", "sex":"Male", "dept":"Well Being", "salary":90000,"interests":{{"tennis","scuba","running","biking"}}});
+
+// insert into open type target dataset by doing a select on the closed type (source) internal dataset
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+write output to nc1:"rttest/open-closed_open-closed-32.adm";
+for $d in dataset('testds01')
+where some $h in $d.interests satisfies $h='biking'
+order by $d.id
+return $d.interests
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-33.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-33.aql
new file mode 100644
index 0000000..b75e6c6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-33.aql
@@ -0,0 +1,55 @@
+/*
+ * Test case Name : open-closed-33.aql
+ * Description : INSERT into target (closed type) internal dataset by doing SELECT on (closed type) source internal dataset
+ * : then query the target internal dataset for data enclosed within {{ }} braces, in this case interests field.
+ * : Here the interests field is optional.
+ * Success : Yes
+ * Date : 31st May 2012
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+create type testtype01 as open {
+id: string
+}
+
+create type testtype02 as closed {
+id : string,
+name : string,
+sex : string,
+dept : string,
+salary : int32,
+interests : {{string}}?
+}
+
+create dataset testds01(testtype01) partitioned by key id;
+
+create dataset testds02(testtype02) partitioned by key id;
+
+insert into dataset testds02 (
+{ "id": "011", "name": "John Doe", "sex":"Male", "dept":"HR", "salary":80000,"interests":{{"hiking","scuba","painting","biking"}}});
+
+insert into dataset testds02 (
+{ "id": "921", "name": "John Smith", "sex":"Male", "dept":"Sales", "salary":65000,"interests":{{"gardening","biking","reading","hiking","fishing"}}});
+
+insert into dataset testds02 (
+{ "id": "959", "name": "Susan Malaika", "sex":"Female", "dept":"XML Dev", "salary":200000,"interests":{{"XML","Web Services","Cloud","X-Forms","art","travelling"}}});
+
+insert into dataset testds02 (
+{ "id": "371", "name": "Tom Sawyer", "sex":"Male", "dept":"Well Being", "salary":90000,"interests":{{"tennis","scuba","running","biking"}}});
+
+// insert into open type target dataset by doing a select on the closed type (source) internal dataset
+
+insert into dataset testds01(
+for $d in dataset("testds02")
+return $d
+);
+
+write output to nc1:"rttest/open-closed_open-closed-33.adm";
+for $d in dataset('testds01')
+where some $h in $d.interests satisfies $h='biking'
+order by $d.id
+return $d.interests
+
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
index f6d3242..ee958f2 100644
--- 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
@@ -1 +1 @@
-{ "id": 1234, "description": "donut", "name": "Cake", "batters": [ [ { "id": 0, "descrpt": "" }, { "id": 0, "descrpt": "" } ] ] }
+{ "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-24.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-24.adm
new file mode 100644
index 0000000..fbcf8ee
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-24.adm
@@ -0,0 +1 @@
+{ "id": 32, "name": "UCI", "opt_tag": {{ "optional text", "put any text here", "and more" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-25.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-25.adm
new file mode 100644
index 0000000..fbcf8ee
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-25.adm
@@ -0,0 +1 @@
+{ "id": 32, "name": "UCI", "opt_tag": {{ "optional text", "put any text here", "and more" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-26.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-26.adm
new file mode 100644
index 0000000..755a799
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-26.adm
@@ -0,0 +1 @@
+{ "id": 32, "name": "UCI", "opt_tag": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-29.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-29.adm
new file mode 100644
index 0000000..2c3d0ea
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-29.adm
@@ -0,0 +1 @@
+{ "id": "003", "name": "Person Three", "hobbies": {{ "hiking", "surfing" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-31.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-31.adm
new file mode 100644
index 0000000..d5816e2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-31.adm
@@ -0,0 +1 @@
+{{ "hiking", "surfing" }}
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-32.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-32.adm
new file mode 100644
index 0000000..2103e83
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-32.adm
@@ -0,0 +1,3 @@
+{{ "hiking", "scuba", "painting", "biking" }}
+{{ "tennis", "scuba", "running", "biking" }}
+{{ "gardening", "biking", "reading", "hiking", "fishing" }}
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-33.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-33.adm
new file mode 100644
index 0000000..2103e83
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-33.adm
@@ -0,0 +1,3 @@
+{{ "hiking", "scuba", "painting", "biking" }}
+{{ "tennis", "scuba", "running", "biking" }}
+{{ "gardening", "biking", "reading", "hiking", "fishing" }}
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 db06e38..2c7ff10 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
@@ -37,8 +37,8 @@
public static IAType getRequiredType(AbstractFunctionCallExpression expr) {
Object[] type = expr.getOpaqueParameters();
if (type != null) {
- IAType recordType = (IAType) type[0];
- return recordType;
+ IAType returnType = (IAType) type[0];
+ return returnType;
} else
return null;
}
@@ -46,8 +46,8 @@
public static IAType getInputType(AbstractFunctionCallExpression expr) {
Object[] type = expr.getOpaqueParameters();
if (type != null) {
- IAType recordType = (IAType) type[1];
- return recordType;
+ IAType returnType = (IAType) type[1];
+ return returnType;
} else
return null;
}