asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ti...@apache.org
Subject [1/4] asterixdb git commit: ASTERIXDB-1581: fix subquery decorrelation.
Date Wed, 07 Sep 2016 04:39:22 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master ae2fbc682 -> c89d668f6


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
index 2c4dacf..54acf2f 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
@@ -19,7 +19,7 @@
 package org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors;
 
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -47,12 +47,11 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOpe
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
@@ -64,6 +63,7 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.TokenizeOper
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext;
@@ -83,39 +83,43 @@ public class LogicalOperatorDeepCopyWithNewVariablesVisitor
 
     // Key: Variable in the original plan. Value: New variable replacing the
     // original one in the copied plan.
-    private final Map<LogicalVariable, LogicalVariable> inputVarToOutputVarMapping;
+    private final LinkedHashMap<LogicalVariable, LogicalVariable> inputVarToOutputVarMapping;
 
     // Key: New variable in the new plan. Value: The old variable in the
     // original plan.
-    private final Map<LogicalVariable, LogicalVariable> outputVarToInputVarMapping;
+    private final LinkedHashMap<LogicalVariable, LogicalVariable> outputVarToInputVarMapping;
 
     /**
-     * @param IOptimizationContext
-     *            , the optimization context
+     * @param varContext
+     *            , the variable context.
+     * @param typeContext
+     *            the type context.
      */
     public LogicalOperatorDeepCopyWithNewVariablesVisitor(IVariableContext varContext, ITypingContext
typeContext) {
         this.varContext = varContext;
         this.typeContext = typeContext;
-        this.inputVarToOutputVarMapping = new HashMap<>();
-        this.outputVarToInputVarMapping = new HashMap<>();
+        this.inputVarToOutputVarMapping = new LinkedHashMap<>();
+        this.outputVarToInputVarMapping = new LinkedHashMap<>();
         this.exprDeepCopyVisitor = new LogicalExpressionDeepCopyWithNewVariablesVisitor(varContext,
                 outputVarToInputVarMapping, inputVarToOutputVarMapping);
     }
 
     /**
-     * @param IOptimizationContext
-     *            the optimization context
+     * @param varContext
+     *            , the variable context.
+     * @param typeContext
+     *            the type context.
      * @param inVarMapping
      *            Variable mapping keyed by variables in the original plan.
      *            Those variables are replaced by their corresponding value in
      *            the map in the copied plan.
      */
     public LogicalOperatorDeepCopyWithNewVariablesVisitor(IVariableContext varContext, ITypingContext
typeContext,
-            Map<LogicalVariable, LogicalVariable> inVarMapping) {
+            LinkedHashMap<LogicalVariable, LogicalVariable> inVarMapping) {
         this.varContext = varContext;
         this.typeContext = typeContext;
         this.inputVarToOutputVarMapping = inVarMapping;
-        this.outputVarToInputVarMapping = new HashMap<>();
+        this.outputVarToInputVarMapping = new LinkedHashMap<>();
         exprDeepCopyVisitor = new LogicalExpressionDeepCopyWithNewVariablesVisitor(varContext,
inVarMapping,
                 inputVarToOutputVarMapping);
     }
@@ -560,11 +564,11 @@ public class LogicalOperatorDeepCopyWithNewVariablesVisitor
         return opCopy;
     }
 
-    public Map<LogicalVariable, LogicalVariable> getOutputToInputVariableMapping()
{
+    public LinkedHashMap<LogicalVariable, LogicalVariable> getOutputToInputVariableMapping()
{
         return outputVarToInputVarMapping;
     }
 
-    public Map<LogicalVariable, LogicalVariable> getInputToOutputVariableMapping()
{
+    public LinkedHashMap<LogicalVariable, LogicalVariable> getInputToOutputVariableMapping()
{
         return inputVarToOutputVarMapping;
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
index 8859c03..7221e81 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
@@ -20,10 +20,11 @@ package org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors;
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
+import java.util.Map.Entry;
 
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -111,7 +112,25 @@ public class VariableUtilities {
         substituteVariables(op, v1, v2, true, ctx);
     }
 
-    public static void substituteVariables(ILogicalOperator op, Map<LogicalVariable, LogicalVariable>
varMap,
+    /**
+     * Substitute variable references inside an operator according to a variable map.
+     *
+     * @param op,
+     *            the operator for variable substitution.
+     * @param varMap,
+     *            a map that maps old variables to new variables. Note that we enforce
+     *            the map to be a LinkedHashMap so as to be able to perform recursive
+     *            variable substitution within one pass. The order of variable substitution
+     *            is the entry insertion order of the LinkedHashMap. Typically, the LinkedHashMap
+     *            is populated by recursively, bottom-up traversing of the query plan.
+     *            For example, if $1->$2 and $2->$3 are orderly inserted into the map,
$1 will be
+     *            replaced by $3 in the outcome of this method call.
+     *
+     * @param ctx,
+     *            a typing context that keeps track of types of each variable.
+     * @throws AlgebricksException
+     */
+    public static void substituteVariables(ILogicalOperator op, LinkedHashMap<LogicalVariable,
LogicalVariable> varMap,
             ITypingContext ctx) throws AlgebricksException {
         for (Map.Entry<LogicalVariable, LogicalVariable> entry : varMap.entrySet())
{
             VariableUtilities.substituteVariables(op, entry.getKey(), entry.getValue(), ctx);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
index a087305..4a5ac5a 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
@@ -26,6 +26,7 @@ import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -34,6 +35,12 @@ import org.apache.hyracks.algebricks.core.algebra.metadata.IDataSourceProperties
 import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import org.apache.hyracks.algebricks.core.algebra.properties.BroadcastPartitioningProperty;
+import org.apache.hyracks.algebricks.core.algebra.properties.INodeDomain;
+import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
+import org.apache.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
+import org.apache.hyracks.algebricks.core.algebra.properties.PhysicalRequirements;
+import org.apache.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
 import org.apache.hyracks.algebricks.core.jobgen.impl.JobGenContext;
 import org.apache.hyracks.api.dataflow.IOperatorDescriptor;
 
@@ -73,6 +80,24 @@ public class DataSourceScanPOperator extends AbstractScanPOperator {
         deliveredProperties = dspp.computePropertiesVector(dssOp.getVariables());
     }
 
+    @Override
+    public PhysicalRequirements getRequiredPropertiesForChildren(ILogicalOperator op,
+            IPhysicalPropertiesVector reqdByParent, IOptimizationContext context) {
+        if (op.getInputs().isEmpty()) {
+            return emptyUnaryRequirements();
+        }
+        ILogicalOperator childOp = op.getInputs().get(0).getValue();
+        // Empty tuple source is a special case that can be partitioned in the same way as
the data scan.
+        if (childOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
+            return emptyUnaryRequirements();
+        }
+        INodeDomain domain = dataSource.getDomain();
+        return new PhysicalRequirements(
+                new StructuralPropertiesVector[] {
+                        new StructuralPropertiesVector(new BroadcastPartitioningProperty(domain),
null) },
+                IPartitioningRequirementsCoordinator.NO_COORDINATION);
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public void contributeRuntimeOperator(IHyracksJobBuilder builder, JobGenContext context,
ILogicalOperator op,

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/EmptyTupleSourcePOperator.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/EmptyTupleSourcePOperator.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/EmptyTupleSourcePOperator.java
index dcb7e15..0718d13 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/EmptyTupleSourcePOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/EmptyTupleSourcePOperator.java
@@ -26,7 +26,6 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import org.apache.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
 import org.apache.hyracks.algebricks.core.algebra.properties.PhysicalRequirements;
@@ -50,8 +49,7 @@ public class EmptyTupleSourcePOperator extends AbstractPhysicalOperator
{
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context)
{
-        deliveredProperties = new StructuralPropertiesVector(IPartitioningProperty.UNPARTITIONED,
-                new LinkedList<ILocalStructuralProperty>());
+        deliveredProperties = new StructuralPropertiesVector(IPartitioningProperty.UNPARTITIONED,
new LinkedList<>());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index 97aa853..4437822 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -86,7 +86,8 @@ public class OperatorManipulationUtil {
                 AbstractLogicalOperator currentOp = op;
                 while (currentOp.getInputs().size() == 1) {
                     AbstractLogicalOperator child = (AbstractLogicalOperator) currentOp.getInputs().get(0).getValue();
-                    if (child.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
+                    // Empty tuple source is a special case that can be partitioned in the
same way as the data scan.
+                    if (child.getOperatorTag() != LogicalOperatorTag.EMPTYTUPLESOURCE) {
                         break;
                     }
                     child.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
index 353a782..87ea627 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
@@ -263,11 +263,16 @@ public class OperatorPropertiesUtil {
         return false;
     }
 
-    public static boolean isCardinalityOne(ILogicalOperator operator) throws AlgebricksException
{
+    public static boolean isCardinalityExactOne(ILogicalOperator operator) throws AlgebricksException
{
         CardinalityInferenceVisitor visitor = new CardinalityInferenceVisitor();
         return operator.accept(visitor, null) == 1L;
     }
 
+    public static boolean isCardinalityZeroOrOne(ILogicalOperator operator) throws AlgebricksException
{
+        CardinalityInferenceVisitor visitor = new CardinalityInferenceVisitor();
+        return operator.accept(visitor, null) <= 1;
+    }
+
     /**
      * Whether an operator can be moved around in the query plan.
      *

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-examples/piglet-example/src/main/java/org/apache/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-examples/piglet-example/src/main/java/org/apache/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
b/hyracks-fullstack/algebricks/algebricks-examples/piglet-example/src/main/java/org/apache/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
index 5b60022..cb62a34 100644
--- a/hyracks-fullstack/algebricks/algebricks-examples/piglet-example/src/main/java/org/apache/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
+++ b/hyracks-fullstack/algebricks/algebricks-examples/piglet-example/src/main/java/org/apache/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
@@ -27,6 +27,7 @@ import org.apache.hyracks.algebricks.core.algebra.metadata.IDataSourceProperties
 import org.apache.hyracks.algebricks.core.algebra.properties.FileSplitDomain;
 import org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import org.apache.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import org.apache.hyracks.algebricks.core.algebra.properties.INodeDomain;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
 import org.apache.hyracks.algebricks.core.algebra.properties.RandomPartitioningProperty;
 import org.apache.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
@@ -53,6 +54,12 @@ public class PigletFileDataSource implements IDataSource<String>
{
                 return vec;
             }
         };
+
+    }
+
+    @Override
+    public INodeDomain getDomain() {
+        return new FileSplitDomain(fileSplits);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
index d07544b..93c9b77 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
@@ -68,10 +68,8 @@ import org.apache.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPre
 import org.apache.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;
 import org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import org.apache.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
-import org.apache.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import org.apache.hyracks.algebricks.core.algebra.properties.INodeDomain;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
-import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningProperty.PartitioningType;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import org.apache.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
 import org.apache.hyracks.algebricks.core.algebra.properties.LocalGroupingProperty;
@@ -83,6 +81,8 @@ import org.apache.hyracks.algebricks.core.algebra.properties.PropertiesUtil;
 import org.apache.hyracks.algebricks.core.algebra.properties.RandomPartitioningProperty;
 import org.apache.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
 import org.apache.hyracks.algebricks.core.algebra.properties.UnorderedPartitionedProperty;
+import org.apache.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
+import org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningProperty.PartitioningType;
 import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import org.apache.hyracks.algebricks.core.config.AlgebricksConfig;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
@@ -428,15 +428,18 @@ public class EnforceStructuralPropertiesRule implements IAlgebraicRewriteRule
{
             IPhysicalPropertiesVector diffPropertiesVector, IPhysicalPropertiesVector required,
             IPhysicalPropertiesVector deliveredByChild, INodeDomain domain, boolean nestedPlan,
             IOptimizationContext context) throws AlgebricksException {
-
         IPartitioningProperty pp = diffPropertiesVector.getPartitioningProperty();
         if (pp == null || pp.getPartitioningType() == PartitioningType.UNPARTITIONED) {
             addLocalEnforcers(op, childIndex, diffPropertiesVector.getLocalProperties(),
nestedPlan, context);
             IPhysicalPropertiesVector deliveredByNewChild =
                     ((AbstractLogicalOperator) op.getInputs().get(0).getValue()).getDeliveredPhysicalProperties();
-            addPartitioningEnforcers(op, childIndex, pp, required, deliveredByNewChild, domain,
context);
+            if (!nestedPlan) {
+                addPartitioningEnforcers(op, childIndex, pp, required, deliveredByNewChild,
domain, context);
+            }
         } else {
-            addPartitioningEnforcers(op, childIndex, pp, required, deliveredByChild, pp.getNodeDomain(),
context);
+            if (!nestedPlan) {
+                addPartitioningEnforcers(op, childIndex, pp, required, deliveredByChild,
pp.getNodeDomain(), context);
+            }
             AbstractLogicalOperator newChild = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
             IPhysicalPropertiesVector newDiff = newPropertiesDiff(newChild, required, true,
context);
             AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> New properties diff:
" + newDiff + "\n");

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/RemoveCartesianProductWithEmptyBranchRule.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/RemoveCartesianProductWithEmptyBranchRule.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/RemoveCartesianProductWithEmptyBranchRule.java
index bd5d646..bd3656e 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/RemoveCartesianProductWithEmptyBranchRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/RemoveCartesianProductWithEmptyBranchRule.java
@@ -30,6 +30,7 @@ import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 /**
@@ -69,6 +70,9 @@ public class RemoveCartesianProductWithEmptyBranchRule implements IAlgebraicRewr
         }
         Set<LogicalVariable> liveVariables = new HashSet<>();
         VariableUtilities.getLiveVariables(op, liveVariables);
-        return liveVariables.isEmpty();
+        // No variables will be populated and the cardinality does not change.
+        // If there is only one tuple from the branch, the output cardinality
+        // of the cartesian product will not be changed.
+        return liveVariables.isEmpty() && OperatorPropertiesUtil.isCardinalityExactOne(op);
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
index 06fb360..58a15e2 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
@@ -26,14 +26,12 @@ import java.util.Set;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
@@ -50,16 +48,14 @@ public class SimpleUnnestToProductRule implements IAlgebraicRewriteRule
{
     @Override
     public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext
context)
             throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-        if (op.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN
-                && op.getOperatorTag() != LogicalOperatorTag.UNNEST) {
+        ILogicalOperator op = opRef.getValue();
+        if (!isScanOrUnnest(op)) {
             return false;
         }
 
         Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
-
-        if (!(op2 instanceof AbstractScanOperator) && !descOrSelfIsSourceScan(op2))
{
+        ILogicalOperator op2 = opRef2.getValue();
+        if (!isScanOrUnnest(op2) && !descOrSelfIsSourceScan(op2)) {
             return false;
         }
         // Make sure that op does not use any variables produced by op2.
@@ -88,7 +84,7 @@ public class SimpleUnnestToProductRule implements IAlgebraicRewriteRule
{
                      * to check if currentOpRef holds a DataSourceScanOperator.
                      */
                     && currentOpRef.getValue().getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN
-                    && descOrSelfIsSourceScan((AbstractLogicalOperator) currentOpRef.getValue()))
{
+                    && descOrSelfIsSourceScan(currentOpRef.getValue())) {
                 if (opsAreIndependent(currentOpRef.getValue(), tupleSourceOpRef.getValue()))
{
                     /** move down the boundary if the operator is independent of the tuple
source */
                     boundaryOpRef = currentOpRef.getValue().getInputs().get(0);
@@ -120,32 +116,57 @@ public class SimpleUnnestToProductRule implements IAlgebraicRewriteRule
{
             }
         }
 
+        // If the left branch has cardinality one, we do not need to rewrite the unary pipeline
+        // into a cartesian product.
+        ILogicalOperator innerBranchOperator = opRef.getValue();
+        ILogicalOperator boundaryOperator = boundaryOpRef.getValue();
+        if (OperatorPropertiesUtil.isCardinalityZeroOrOne(boundaryOperator)
+                // Note that for an external data source, the following check returns false.
+                // Thus, it does not produce absolutely correct plan for the CASE expression
+                // that contains subqueries over external datasets in THEN/ELSE branches,
in
+                // the sense that if the condition is not satisfied, the corresponding THEN/ELSE
+                // branch should not be evaluated at all. Rewriting to a join will actually
+                // evaluates those branches.
+                // Fixing ASTERIXDB-1620 will ensure correctness for external datasets.
+                && !descOrSelfIsLeafSourceScan(innerBranchOperator, boundaryOperator))
{
+            return false;
+        }
+
         /** join the two independent branches */
-        InnerJoinOperator join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE),
-                new MutableObject<ILogicalOperator>(boundaryOpRef.getValue()),
-                new MutableObject<ILogicalOperator>(opRef.getValue()));
+        InnerJoinOperator join = new InnerJoinOperator(new MutableObject<>(ConstantExpression.TRUE),
+                new MutableObject<>(boundaryOperator), new MutableObject<>(innerBranchOperator));
         opRef.setValue(join);
         ILogicalOperator ets = new EmptyTupleSourceOperator();
         context.computeAndSetTypeEnvironmentForOperator(ets);
         boundaryOpRef.setValue(ets);
-        context.computeAndSetTypeEnvironmentForOperator(boundaryOpRef.getValue());
-        context.computeAndSetTypeEnvironmentForOperator(opRef.getValue());
+        context.computeAndSetTypeEnvironmentForOperator(boundaryOperator);
+        context.computeAndSetTypeEnvironmentForOperator(innerBranchOperator);
         context.computeAndSetTypeEnvironmentForOperator(join);
         return true;
     }
 
-    private boolean descOrSelfIsSourceScan(AbstractLogicalOperator op2) {
-        // Disregard data source scans in a subplan.
-        if (op2.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
+    private boolean descOrSelfIsSourceScan(ILogicalOperator op) {
+        if (op.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+            return true;
+        }
+        for (Mutable<ILogicalOperator> cRef : op.getInputs()) {
+            if (descOrSelfIsSourceScan(cRef.getValue())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean descOrSelfIsLeafSourceScan(ILogicalOperator op, ILogicalOperator bottomOp)
{
+        if (op == bottomOp) {
             return false;
         }
-        if (op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN
-                && op2.getOperatorTag() != LogicalOperatorTag.UNNEST) {
-            return true;
+        if (op.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+            DataSourceScanOperator dataSourceScanOperator = (DataSourceScanOperator) op;
+            return dataSourceScanOperator.getDataSource().isScanAccessPathALeaf();
         }
-        for (Mutable<ILogicalOperator> cRef : op2.getInputs()) {
-            AbstractLogicalOperator alo = (AbstractLogicalOperator) cRef.getValue();
-            if (descOrSelfIsSourceScan(alo)) {
+        for (Mutable<ILogicalOperator> cRef : op.getInputs()) {
+            if (descOrSelfIsLeafSourceScan(cRef.getValue(), bottomOp)) {
                 return true;
             }
         }
@@ -168,4 +189,9 @@ public class SimpleUnnestToProductRule implements IAlgebraicRewriteRule
{
         return true;
     }
 
+    private boolean isScanOrUnnest(ILogicalOperator op) {
+        LogicalOperatorTag opTag = op.getOperatorTag();
+        return opTag == LogicalOperatorTag.DATASOURCESCAN || opTag == LogicalOperatorTag.UNNEST;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SwitchInnerJoinBranchRule.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SwitchInnerJoinBranchRule.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SwitchInnerJoinBranchRule.java
new file mode 100644
index 0000000..277353e
--- /dev/null
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SwitchInnerJoinBranchRule.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hyracks.algebricks.rewriter.rules;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
+import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * The rule switches the left branch of a join and the right branch if
+ * we know the left branch has cardinality one and the right branch does
+ * not have cardinality one. Therefore, the build (right) branch can
+ * potentially be smaller.
+ */
+public class SwitchInnerJoinBranchRule implements IAlgebraicRewriteRule {
+
+    @Override
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext
context)
+            throws AlgebricksException {
+        ILogicalOperator op = opRef.getValue();
+        if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN) {
+            return false;
+        }
+        InnerJoinOperator joinOperator = (InnerJoinOperator) op;
+        Mutable<ILogicalOperator> leftRef = joinOperator.getInputs().get(0);
+        Mutable<ILogicalOperator> rightRef = joinOperator.getInputs().get(1);
+        ILogicalOperator left = leftRef.getValue();
+        ILogicalOperator right = rightRef.getValue();
+        boolean leftCardinalityOne = OperatorPropertiesUtil.isCardinalityZeroOrOne(left);
+        boolean rightCardinalityOne = OperatorPropertiesUtil.isCardinalityZeroOrOne(right);
+        if (!leftCardinalityOne || rightCardinalityOne) {
+            return false;
+        }
+        // The cardinality of the left branch is one and the cardinality of the right branch
is not one.
+        leftRef.setValue(right);
+        rightRef.setValue(left);
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java
index b01bb43..2cd857a 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java
@@ -161,7 +161,7 @@ public class EliminateSubplanWithInputCardinalityOneRule implements IAlgebraicRe
         List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
         VariableUtilities.getLiveVariables(operator, liveVars);
 
-        if (OperatorPropertiesUtil.isCardinalityOne(operator)) {
+        if (OperatorPropertiesUtil.isCardinalityZeroOrOne(operator)) {
             for (LogicalVariable liveVar : liveVars) {
                 if (freeVars.contains(liveVar)) {
                     varsWithCardinalityOne.add(liveVar);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/ReplaceNtsWithSubplanInputOperatorVisitor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/ReplaceNtsWithSubplanInputOperatorVisitor.java
b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/ReplaceNtsWithSubplanInputOperatorVisitor.java
index 7eb9ac8..39cac06 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/ReplaceNtsWithSubplanInputOperatorVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/ReplaceNtsWithSubplanInputOperatorVisitor.java
@@ -21,6 +21,7 @@ package org.apache.hyracks.algebricks.rewriter.rules.subplan;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -78,7 +79,7 @@ class ReplaceNtsWithSubplanInputOperatorVisitor implements IQueryOperatorVisitor
 
     // The map that maps the input variables to the subplan to their deep-copied
     // variables.
-    private final Map<LogicalVariable, LogicalVariable> varMap = new HashMap<>();
+    private final LinkedHashMap<LogicalVariable, LogicalVariable> varMap = new LinkedHashMap<>();
 
     // Whether the original copy has been used.
     private boolean isOriginalCopyUsed = false;


Mime
View raw message