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;
     }