Cleaned up the rewrite rules for adding collection.

 - Rules now remove unused expressions that have input from other operators.
 - Collection has been simplified to run only when the argument is a constant 
(previous item makes this possible).
 - Removed old treat rule that is now outdated.
 - Updated promote to work on sub-quantifiers.
 - Collection leaves the unnest operator above the data scan (Allows descendent 
path step).
 - New rule to remove unnest iterate when operating on a single tuple.


Project: http://git-wip-us.apache.org/repos/asf/vxquery/repo
Commit: http://git-wip-us.apache.org/repos/asf/vxquery/commit/6f9c8f30
Tree: http://git-wip-us.apache.org/repos/asf/vxquery/tree/6f9c8f30
Diff: http://git-wip-us.apache.org/repos/asf/vxquery/diff/6f9c8f30

Branch: refs/heads/master
Commit: 6f9c8f309d787db6fb381f73b1dc76919c6d7e57
Parents: 01a3bf1
Author: Eldon Carman <[email protected]>
Authored: Sun May 31 12:40:35 2015 -0700
Committer: Eldon Carman <[email protected]>
Committed: Wed Jun 3 14:23:48 2015 -0700

----------------------------------------------------------------------
 .../compiler/rewriter/RewriteRuleset.java       |  12 +-
 .../rewriter/rules/AbstractCollectionRule.java  |  46 ++----
 .../rewriter/rules/IntroduceCollectionRule.java |  13 +-
 .../RemoveRedundantPromoteExpressionsRule.java  |  16 +-
 .../rewriter/rules/RemoveUnusedTreatRule.java   | 147 -------------------
 .../rules/RemoveUnusedUnnestIterateRule.java    |  21 ++-
 .../rewriter/rules/util/ExpressionToolbox.java  |  23 +++
 .../rewriter/rules/util/OperatorToolbox.java    |   5 +-
 .../xmlquery/query/XMLQueryCompiler.java        |   2 +-
 9 files changed, 75 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java
index 008083d..8bda5b6 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java
@@ -37,7 +37,6 @@ import 
org.apache.vxquery.compiler.rewriter.rules.RemoveRedundantDataExpressions
 import 
org.apache.vxquery.compiler.rewriter.rules.RemoveRedundantPromoteExpressionsRule;
 import 
org.apache.vxquery.compiler.rewriter.rules.RemoveRedundantTreatExpressionsRule;
 import 
org.apache.vxquery.compiler.rewriter.rules.RemoveUnusedSortDistinctNodesRule;
-import org.apache.vxquery.compiler.rewriter.rules.RemoveUnusedTreatRule;
 import 
org.apache.vxquery.compiler.rewriter.rules.RemoveUnusedUnnestIterateRule;
 import org.apache.vxquery.compiler.rewriter.rules.SetCollectionDataSourceRule;
 import org.apache.vxquery.compiler.rewriter.rules.SetVariableIdContextRule;
@@ -85,16 +84,17 @@ public class RewriteRuleset {
 
         // Remove unused functions.
         normalization.add(new RemoveUnusedSortDistinctNodesRule());
+        normalization.add(new RemoveRedundantTreatExpressionsRule());
+        normalization.add(new RemoveRedundantDataExpressionsRule());
+        normalization.add(new RemoveRedundantPromoteExpressionsRule());
+        normalization.add(new RemoveRedundantCastExpressionsRule());
+        normalization.add(new RemoveRedundantBooleanExpressionsRule());
         normalization.add(new RemoveRedundantVariablesRule());
         normalization.add(new RemoveUnusedAssignAndAggregateRule());
 
         // TODO Fix the group by operator before putting back in the rule set.
         //        normalization.add(new 
ConvertAssignSortDistinctNodesToOperatorsRule());
 
-        normalization.add(new RemoveUnusedTreatRule());
-        normalization.add(new RemoveRedundantVariablesRule());
-        normalization.add(new RemoveUnusedAssignAndAggregateRule());
-
         // Find unnest followed by aggregate in a subplan. 
         normalization.add(new EliminateUnnestAggregateSubplanRule());
         normalization.add(new RemoveRedundantVariablesRule());
@@ -154,7 +154,7 @@ public class RewriteRuleset {
     /**
      * Remove expressions known to be redundant.
      */
-    public final static List<IAlgebraicRewriteRule> 
buildRedundantExpressionNormalizationRuleCollection() {
+    public final static List<IAlgebraicRewriteRule> 
buildInlineRedundantExpressionNormalizationRuleCollection() {
         List<IAlgebraicRewriteRule> normalization = new 
LinkedList<IAlgebraicRewriteRule>();
         normalization.add(new InlineNestedVariablesRule());
         normalization.add(new RemoveRedundantTreatExpressionsRule());

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/AbstractCollectionRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/AbstractCollectionRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/AbstractCollectionRule.java
index a5ef4ba..717914a 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/AbstractCollectionRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/AbstractCollectionRule.java
@@ -23,10 +23,10 @@ import java.util.Arrays;
 
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.vxquery.compiler.algebricks.VXQueryConstantValue;
+import org.apache.vxquery.compiler.rewriter.rules.util.OperatorToolbox;
 import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
 import org.apache.vxquery.datamodel.values.ValueTag;
 import org.apache.vxquery.functions.BuiltinFunctions;
-import org.apache.vxquery.functions.BuiltinOperators;
 import org.apache.vxquery.types.BuiltinTypeRegistry;
 import org.apache.vxquery.types.Quantifier;
 import org.apache.vxquery.types.SequenceType;
@@ -39,6 +39,7 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
@@ -81,45 +82,24 @@ public abstract class AbstractCollectionRule implements 
IAlgebraicRewriteRule {
             return null;
         }
 
+        ILogicalExpression logicalExpression2 = (ILogicalExpression) 
functionCall.getArguments().get(0).getValue();
+        if (logicalExpression2.getExpressionTag() != 
LogicalExpressionTag.VARIABLE) {
+            return null;
+        }
+        VariableReferenceExpression vre = (VariableReferenceExpression) 
logicalExpression2;
+        Mutable<ILogicalOperator> opRef3 = 
OperatorToolbox.findProducerOf(opRef, vre.getVariableReference());
+
         // Get the string assigned to the collection function.
-        AbstractLogicalOperator op3 = (AbstractLogicalOperator) 
assign.getInputs().get(0).getValue();
+        AbstractLogicalOperator op3 = (AbstractLogicalOperator) 
opRef3.getValue();
         if (op3.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
             AssignOperator assign2 = (AssignOperator) op3;
 
             // Check to see if the expression is a constant expression and 
type string.
-            ILogicalExpression logicalExpression2 = (ILogicalExpression) 
assign2.getExpressions().get(0).getValue();
-            if (logicalExpression2.getExpressionTag() != 
LogicalExpressionTag.CONSTANT) {
-                return null;
-            }
-            ConstantExpression constantExpression = (ConstantExpression) 
logicalExpression2;
-            constantValue = (VXQueryConstantValue) 
constantExpression.getValue();
-            if (constantValue.getType() != 
SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE)) {
-                return null;
-            }
-        } else if (op3.getOperatorTag() == 
LogicalOperatorTag.EMPTYTUPLESOURCE) {
-            ILogicalExpression logicalExpression2 = (ILogicalExpression) 
functionCall.getArguments().get(0).getValue();
-            if (logicalExpression2.getExpressionTag() != 
LogicalExpressionTag.FUNCTION_CALL) {
-                return null;
-            }
-            AbstractFunctionCallExpression functionCall2 = 
(AbstractFunctionCallExpression) logicalExpression2;
-            if 
(!functionCall2.getFunctionIdentifier().equals(BuiltinOperators.PROMOTE.getFunctionIdentifier()))
 {
-                return null;
-            }
-
-            ILogicalExpression logicalExpression3 = (ILogicalExpression) 
functionCall2.getArguments().get(0).getValue();
-            if (logicalExpression3.getExpressionTag() != 
LogicalExpressionTag.FUNCTION_CALL) {
-                return null;
-            }
-            AbstractFunctionCallExpression functionCall3 = 
(AbstractFunctionCallExpression) logicalExpression3;
-            if 
(!functionCall3.getFunctionIdentifier().equals(BuiltinFunctions.FN_DATA_1.getFunctionIdentifier()))
 {
-                return null;
-            }
-
-            ILogicalExpression logicalExpression4 = (ILogicalExpression) 
functionCall3.getArguments().get(0).getValue();
-            if (logicalExpression4.getExpressionTag() != 
LogicalExpressionTag.CONSTANT) {
+            ILogicalExpression logicalExpression3 = (ILogicalExpression) 
assign2.getExpressions().get(0).getValue();
+            if (logicalExpression3.getExpressionTag() != 
LogicalExpressionTag.CONSTANT) {
                 return null;
             }
-            ConstantExpression constantExpression = (ConstantExpression) 
logicalExpression4;
+            ConstantExpression constantExpression = (ConstantExpression) 
logicalExpression3;
             constantValue = (VXQueryConstantValue) 
constantExpression.getValue();
             if (constantValue.getType() != 
SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE)) {
                 return null;

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/IntroduceCollectionRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/IntroduceCollectionRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/IntroduceCollectionRule.java
index c599876..9daafed 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/IntroduceCollectionRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/IntroduceCollectionRule.java
@@ -42,23 +42,18 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOpera
  * 
  *   plan__parent
  *   UNNEST( $v2 : exp($v1) )
- *   ASSIGN( $v1 : collection( $source ) )
- *   plan__child
- *   
- *   Where $v1 is not used anywhere else in the plan and $source is:
- *   ASSIGN( $source : promote( data( constant ) ) )
- *    or
- *   ASSIGN( $source : promote( data( $v0 ) ) )
+ *   ASSIGN( $v1 : collection( $v0 ) )
  *   ASSIGN( $v0 : constant )
+ *   plan__child
  *   
  * After 
  * 
  *   plan__parent
  *   UNNEST( $v2 : exp($v1) )
- *   DATASCAN( collection( $source ) , $v1 )
+ *   DATASCAN( collection( $v0 ) , $v1 )
  *   plan__child
  *   
- *   Where DATASCAN operator is configured to use the collection( $source) for 
+ *   Where DATASCAN operator is configured to use the collection( $v0) for 
  *   data represented by the "constant" and $v1 represents the xml document 
  *   nodes from the collection.
  * </pre>

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveRedundantPromoteExpressionsRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveRedundantPromoteExpressionsRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveRedundantPromoteExpressionsRule.java
index 12865e0..3700abf 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveRedundantPromoteExpressionsRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveRedundantPromoteExpressionsRule.java
@@ -16,10 +16,7 @@
  */
 package org.apache.vxquery.compiler.rewriter.rules;
 
-import org.apache.vxquery.datamodel.values.ValueTag;
 import org.apache.vxquery.functions.BuiltinOperators;
-import org.apache.vxquery.runtime.functions.cast.CastToDoubleOperation;
-import org.apache.vxquery.runtime.functions.cast.CastToFloatOperation;
 import org.apache.vxquery.types.BuiltinTypeRegistry;
 import org.apache.vxquery.types.SequenceType;
 
@@ -64,9 +61,16 @@ public class RemoveRedundantPromoteExpressionsRule extends 
AbstractRemoveRedunda
                 // These types can not be promoted.
                 return true;
             }
-            if (sTypeOutput != null && sTypeOutput.equals(sTypeArg)) {
-                // Same type.
-                return true;
+            if (sTypeOutput != null) {
+                if (sTypeOutput.equals(sTypeArg)) {
+                    // Same type and quantifier.
+                    return true;
+                }
+                if (sTypeOutput.getItemType().equals(sTypeArg.getItemType())
+                        && 
sTypeArg.getQuantifier().isSubQuantifier(sTypeOutput.getQuantifier())) {
+                    // Same type and stronger quantifier.
+                    return true;
+                }
             }
         }
         return false;

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedTreatRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedTreatRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedTreatRule.java
deleted file mode 100644
index 4b14c50..0000000
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedTreatRule.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.vxquery.compiler.rewriter.rules;
-
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.vxquery.compiler.algebricks.VXQueryConstantValue;
-import org.apache.vxquery.context.RootStaticContextImpl;
-import org.apache.vxquery.context.StaticContextImpl;
-import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
-import org.apache.vxquery.functions.BuiltinOperators;
-import org.apache.vxquery.runtime.functions.type.SequenceTypeMatcher;
-import org.apache.vxquery.types.SequenceType;
-
-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;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
-import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
-import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
-import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
-
-/**
- * The rule searches for where the xquery treat function is used and
- * determines if the treat is necessary. The plan is modified if
- * any of these items is not required.
- * 
- * <pre>
- * Before
- * 
- *   plan__parent
- *   ASSIGN( $v1 : treat( $v0, \@type_expression ) )
- *   ASSIGN( $v0 : $$constant )
- *   plan__child
- *   
- *   Where $$constant is of \@type_expression.
- *   
- * After 
- * 
- *   plan__parent
- *   ASSIGN( $v1 : $v0 )
- *   ASSIGN( $v0 : $$constant )
- *   plan__child
- * </pre>
- * 
- * @author prestonc
- */
-// TODO Replace with constant folding rule.
-public class RemoveUnusedTreatRule implements IAlgebraicRewriteRule {
-    final StaticContextImpl dCtx = new 
StaticContextImpl(RootStaticContextImpl.INSTANCE);
-
-    @Override
-    public boolean rewritePre(Mutable<ILogicalOperator> opRef, 
IOptimizationContext context) throws AlgebricksException {
-        return false;
-    }
-
-    @Override
-    public boolean rewritePost(Mutable<ILogicalOperator> opRef, 
IOptimizationContext context) {
-        boolean operatorChanged = false;
-        // Check if assign is for treat.
-        AbstractLogicalOperator op = (AbstractLogicalOperator) 
opRef.getValue();
-        if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
-            return false;
-        }
-        AssignOperator assignTreat = (AssignOperator) op;
-
-        // Check to see if the expression is a function and treat.
-        ILogicalExpression logicalExpression11 = (ILogicalExpression) 
assignTreat.getExpressions().get(0).getValue();
-        if (logicalExpression11.getExpressionTag() != 
LogicalExpressionTag.FUNCTION_CALL) {
-            return false;
-        }
-        AbstractFunctionCallExpression functionTreat = 
(AbstractFunctionCallExpression) logicalExpression11;
-        if 
(!functionTreat.getFunctionIdentifier().equals(BuiltinOperators.TREAT.getFunctionIdentifier()))
 {
-            return false;
-        }
-
-        // Find the variable id used as the parameter.
-        ILogicalExpression treatArg1 = (ILogicalExpression) 
functionTreat.getArguments().get(0).getValue();
-        if (treatArg1.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
-            return false;
-        }
-        VariableReferenceExpression variableExpression = 
(VariableReferenceExpression) treatArg1;
-        int variableId = variableExpression.getVariableReference().getId();
-
-        // Get type to check against constant.
-        ILogicalExpression treatArg2 = (ILogicalExpression) 
functionTreat.getArguments().get(1).getValue();
-        if (treatArg2.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
-            return false;
-        }
-        TaggedValuePointable tvp = (TaggedValuePointable) 
TaggedValuePointable.FACTORY.createPointable();
-        getConstantAsPointable((ConstantExpression) treatArg2, tvp);
-
-        IntegerPointable pTypeCode = (IntegerPointable) 
IntegerPointable.FACTORY.createPointable();
-        tvp.getValue(pTypeCode);
-        SequenceType sType = dCtx.lookupSequenceType(pTypeCode.getInteger());
-
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) 
assignTreat.getInputs().get(0).getValue();
-        if (op2.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
-            return false;
-        }
-        AssignOperator assignConstant = (AssignOperator) op2;
-
-        if (variableId == assignConstant.getVariables().get(0).getId()) {
-            ILogicalExpression expressionConstant = (ILogicalExpression) 
assignConstant.getExpressions().get(0)
-                    .getValue();
-            if (expressionConstant.getExpressionTag() == 
LogicalExpressionTag.CONSTANT) {
-                // Check constant against type supplied.
-                TaggedValuePointable tvp2 = (TaggedValuePointable) 
TaggedValuePointable.FACTORY.createPointable();
-                getConstantAsPointable((ConstantExpression) 
expressionConstant, tvp2);
-
-                SequenceTypeMatcher stm = new SequenceTypeMatcher();
-                stm.setSequenceType(sType);
-
-                if (stm.sequenceTypeMatch(tvp2)) {
-                    assignTreat.getExpressions().get(0).setValue(treatArg1);
-                    operatorChanged = true;
-                }
-            }
-        }
-
-        return operatorChanged;
-    }
-
-    private void getConstantAsPointable(ConstantExpression typeExpression, 
TaggedValuePointable tvp) {
-        VXQueryConstantValue treatTypeConstant = (VXQueryConstantValue) 
typeExpression.getValue();
-        tvp.set(treatTypeConstant.getValue(), 0, 
treatTypeConstant.getValue().length);
-    }
-}

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedUnnestIterateRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedUnnestIterateRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedUnnestIterateRule.java
index d960735..ceab6a9 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedUnnestIterateRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/RemoveUnusedUnnestIterateRule.java
@@ -17,6 +17,8 @@
 package org.apache.vxquery.compiler.rewriter.rules;
 
 import org.apache.commons.lang3.mutable.Mutable;
+import 
org.apache.vxquery.compiler.rewriter.rules.propagationpolicies.documentorder.DocumentOrder;
+import 
org.apache.vxquery.compiler.rewriter.rules.propagationpolicies.uniquenodes.UniqueNodes;
 import org.apache.vxquery.functions.BuiltinOperators;
 
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -30,11 +32,12 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionC
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 
 /**
- * The rule searches for an unnest operator (1) immediately following an 
unnest 
+ * The rule searches for an unnest operator (1) immediately following an unnest
  * or data scan operator (2). If the variable is only used in unnest (1) then
  * unnest (1) can be removed.
  * 
@@ -51,7 +54,8 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOpera
  * After
  * 
  *   plan__parent
- *   UNNEST( $v2 : $v )
+ *   ASSIGN( $v2 : $v1 )
+ *   UNNEST( $v1 : $v )
  *   plan__child
  * </pre>
  * 
@@ -78,8 +82,8 @@ public class RemoveUnusedUnnestIterateRule extends 
AbstractUsedVariablesProcessi
         }
 
         // Check to see if the expression is a variable.
-        ILogicalExpression logicalExpressionUnnest2 = (ILogicalExpression) 
functionCallUnnest1.getArguments().get(0)
-                .getValue();
+        Mutable<ILogicalExpression> logicalExpressionUnnestRef2 = 
functionCallUnnest1.getArguments().get(0);
+        ILogicalExpression logicalExpressionUnnest2 = (ILogicalExpression) 
logicalExpressionUnnestRef2.getValue();
         if (logicalExpressionUnnest2.getExpressionTag() != 
LogicalExpressionTag.VARIABLE) {
             return false;
         }
@@ -89,11 +93,14 @@ public class RemoveUnusedUnnestIterateRule extends 
AbstractUsedVariablesProcessi
         // Check if the input is an DATASCAN or UNNEST operator..
         Mutable<ILogicalOperator> opRef2 = unnest.getInputs().get(0);
         AbstractLogicalOperator op2 = (AbstractLogicalOperator) 
opRef2.getValue();
-        if (op2.getOperatorTag() == LogicalOperatorTag.UNNEST || 
op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+        if (op2.getOperatorTag() == LogicalOperatorTag.UNNEST
+                || op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
             AbstractScanOperator aso = (AbstractScanOperator) op2;
             if (aso.getVariables().size() == 1 && 
aso.getVariables().contains(unnestInput)) {
-                aso.setVariables(unnest.getVariables());
-                opRef.setValue(aso);
+                // Add in a noop.
+                AssignOperator assign = new 
AssignOperator(unnest.getVariable(), logicalExpressionUnnestRef2);
+                assign.getInputs().addAll(unnest.getInputs());
+                opRef.setValue(assign);
                 return true;
             }
         }

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
index 34efdd8..e76fd15 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
@@ -38,6 +38,8 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpressio
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
 
@@ -226,6 +228,14 @@ public class ExpressionToolbox {
                     case UNNEST:
                         UnnestOperator unnest = (UnnestOperator) variableOp;
                         return getOutputSequenceType(variableProducer, 
unnest.getExpressionRef(), dCtx);
+                    case ASSIGN:
+                        AssignOperator assign = (AssignOperator) variableOp;
+                        for (int i = 0; i < assign.getVariables().size(); ++i) 
{
+                            if 
(variableId.equals(assign.getVariables().get(i))) {
+                                return getOutputSequenceType(variableProducer, 
assign.getExpressions().get(i), dCtx);
+                            }
+                        }
+                        return null;
                     default:
                         // TODO Consider support for other operators. i.e. 
Assign.
                         break;
@@ -234,4 +244,17 @@ public class ExpressionToolbox {
         }
         return null;
     }
+
+    public static boolean isFunctionExpression(Mutable<ILogicalExpression> 
mutableLe,
+            AbstractFunctionCallExpression afce) {
+        ILogicalExpression le = mutableLe.getValue();
+        if (le.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+            return false;
+        }
+        AbstractFunctionCallExpression fc = (AbstractFunctionCallExpression) 
le;
+        if (!fc.getFunctionIdentifier().equals(afce)) {
+            return false;
+        }
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/OperatorToolbox.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/OperatorToolbox.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/OperatorToolbox.java
index 725a082..78cd80f 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/OperatorToolbox.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/OperatorToolbox.java
@@ -30,6 +30,7 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBin
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 
 public class OperatorToolbox {
@@ -144,8 +145,10 @@ public class OperatorToolbox {
                     }
                 }
                 break;
-            case EMPTYTUPLESOURCE:
             case NESTEDTUPLESOURCE:
+                NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
+                return findProducerOf(nts.getDataSourceReference(), lv);
+            case EMPTYTUPLESOURCE:
                 return null;
             default:
                 // Skip operators and go look at input.

http://git-wip-us.apache.org/repos/asf/vxquery/blob/6f9c8f30/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/query/XMLQueryCompiler.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/query/XMLQueryCompiler.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/query/XMLQueryCompiler.java
index 3055c64..38272dd 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/query/XMLQueryCompiler.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/query/XMLQueryCompiler.java
@@ -234,7 +234,7 @@ public class XMLQueryCompiler {
         defaultLogicalRewrites.add(new Pair<AbstractRuleController, 
List<IAlgebraicRewriteRule>>(priorityCtrl,
                 RewriteRuleset.buildXQueryNormalizationRuleCollection()));
         defaultLogicalRewrites.add(new Pair<AbstractRuleController, 
List<IAlgebraicRewriteRule>>(seqCtrlFullDfs,
-                
RewriteRuleset.buildRedundantExpressionNormalizationRuleCollection()));
+                
RewriteRuleset.buildInlineRedundantExpressionNormalizationRuleCollection()));
         defaultLogicalRewrites.add(new Pair<AbstractRuleController, 
List<IAlgebraicRewriteRule>>(priorityCtrl,
                 RewriteRuleset.buildNestedDataSourceRuleCollection()));
         defaultLogicalRewrites.add(new Pair<AbstractRuleController, 
List<IAlgebraicRewriteRule>>(seqOnceCtrl,

Reply via email to