fix issue 200(55)

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_printerfix@926 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 17944bb..b38e119 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
@@ -134,31 +134,45 @@
             if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT)
                 return false;
             assignOp = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
-            if (assignOp.getOperatorTag() != LogicalOperatorTag.ASSIGN)
+            if (assignOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
+                isTopWrite = true;
+                VariableUtilities.getProducedVariables(assignOp, producedVariables);
+                oldRecordVariable = producedVariables.get(0);
+                LogicalVariable inputVar = producedVariables.get(0);
+                IVariableTypeEnvironment env = assignOp.computeOutputTypeEnvironment(context);
+                inputRecordType = (IAType) env.getVarType(inputVar);
+            } else if (assignOp.getOperatorTag() == LogicalOperatorTag.UNNEST) {
+                IVariableTypeEnvironment env = assignOp.computeOutputTypeEnvironment(context);
+                UnnestOperator unnestOp = (UnnestOperator) assignOp;
+                ILogicalExpression unnestExpr = unnestOp.getExpressionRef().getValue();
+                UnnestingFunctionCallExpression unnestExpression = (UnnestingFunctionCallExpression) unnestExpr;
+                ILogicalExpression unnestArg = unnestExpression.getArguments().get(0).getValue();
+                if (unnestArg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                    AbstractFunctionCallExpression unnestArgExpr = (AbstractFunctionCallExpression) unnestArg;
+                    inputRecordType = (IAType) env.getType(unnestArgExpr);
+                    rewriteFuncExpr(unnestArgExpr, inputRecordType, inputRecordType, env);
+                    context.computeAndSetTypeEnvironmentForOperator(unnestOp);
+                }
+                return true;
+            } else {
                 return false;
-            isTopWrite = true;
-            VariableUtilities.getProducedVariables(assignOp, producedVariables);
-            oldRecordVariable = producedVariables.get(0);
-            LogicalVariable inputVar = producedVariables.get(0);
-            IVariableTypeEnvironment env = assignOp.computeOutputTypeEnvironment(context);
-            inputRecordType = (IAType) env.getVarType(inputVar);
-        } else if (op1.getOperatorTag() == LogicalOperatorTag.WRITE) {
-            AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
-            if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT)
+            }
+        } else if (op1.getOperatorTag() == LogicalOperatorTag.UNNEST) {
+            assignOp = (AbstractLogicalOperator) op1;
+            UnnestOperator topAssignOperator = (UnnestOperator) op1;
+            List<LogicalVariable> usedVariables = new ArrayList<LogicalVariable>();
+            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;
-            assignOp = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
-            if (assignOp.getOperatorTag() != LogicalOperatorTag.UNNEST)
-                return false;
-            IVariableTypeEnvironment env = assignOp.computeOutputTypeEnvironment(context);
-            UnnestOperator unnestOp = (UnnestOperator) assignOp;
-            ILogicalExpression unnestExpr = unnestOp.getExpressionRef().getValue();
-            UnnestingFunctionCallExpression unnestExpression = (UnnestingFunctionCallExpression) unnestExpr;
-            AbstractFunctionCallExpression unnestArgExpr = (AbstractFunctionCallExpression) unnestExpression
-                    .getArguments().get(0).getValue();
-            inputRecordType = (IAType) env.getType(unnestArgExpr);
-            rewriteFuncExpr(unnestArgExpr, inputRecordType, inputRecordType, env);
-            context.computeAndSetTypeEnvironmentForOperator(unnestOp);
-            return true;
+            oldRecordVariable = usedVariables.get(0);
+            LogicalVariable inputRecordVar = usedVariables.get(0);
+            IVariableTypeEnvironment env = topAssignOperator.computeOutputTypeEnvironment(context);
+            inputRecordType = (IAType) env.getVarType(inputRecordVar);
+            requiredRecordType = inputRecordType;
         } else {
             return false;
         }
@@ -187,6 +201,7 @@
                         // that expression has been rewritten, and it will not
                         // fail but just return false
                         if (TypeComputerUtilities.getRequiredType(funcExpr) != null) {
+                            context.computeAndSetTypeEnvironmentForOperator(assignOp);
                             return false;
                         }
                         if (isTopWrite) {
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue55.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue55.aql
new file mode 100644
index 0000000..7776ff5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue55.aql
@@ -0,0 +1,4 @@
+write output to nc1:"rttest/open-closed_query-issue55.adm";
+
+for $x in [[1,3],[4,5,2],[-1,-3,0],["a"]]
+return $x
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue55.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue55.adm
new file mode 100644
index 0000000..d384bce
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue55.adm
@@ -0,0 +1,4 @@
+[ 1, 3 ]
+[ 4, 5, 2 ]
+[ -1, -3, 0 ]
+[ "a" ]
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 8fe6856..8437471 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -2304,6 +2304,11 @@
         <output-file compare="Text">query-issue134.adm</output-file>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="open-closed">
+      <compilation-unit name="query-issue55">
+        <output-file compare="Text">query-issue55.adm</output-file>
+      </compilation-unit>
+    </test-case>
     <!--
     <test-case FilePath="open-closed">
       <compilation-unit name="open-closed-15">