ASTERIXDB-1226: support SQL++ core group-by semantics.
-Fixed introduce group-by combiner rule;
-Fixed deep copy (without new variables) visitor.
Change-Id: I9602681a698925bde4eca33d85df66d06b9a33dd
Reviewed-on: https://asterix-gerrit.ics.uci.edu/751
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
index 71c7ed0..b35f692 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
@@ -124,18 +124,6 @@
sb.append(ref.getValue());
}
sb.append("]");
- if (opaqueParameters != null) {
- sb.append(", OpaqueArgs:[");
- first = true;
- for (Object param : opaqueParameters) {
- if (first) {
- first = false;
- } else {
- sb.append(", ");
- }
- sb.append(param);
- }
- }
return sb.toString();
}
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
index 2410ca0..61a2353 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
@@ -88,6 +88,14 @@
return schema;
}
+ public void setSchema(List<LogicalVariable> schema) {
+ if (schema == null) {
+ return;
+ }
+ this.schema = new ArrayList<>();
+ this.schema.addAll(schema);
+ }
+
public void setPhysicalOperator(IPhysicalOperator physicalOp) {
this.physicalOperator = physicalOp;
}
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
index a3a446a..2b66e8f 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
@@ -19,9 +19,9 @@
package org.apache.hyracks.algebricks.core.algebra.operators.logical;
import java.util.ArrayList;
+import java.util.List;
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.LogicalOperatorTag;
@@ -64,7 +64,10 @@
schema = new ArrayList<LogicalVariable>();
ILogicalOperator topOp = dataSourceReference.getValue();
for (Mutable<ILogicalOperator> i : topOp.getInputs()) {
- schema.addAll(i.getValue().getSchema());
+ List<LogicalVariable> inputSchema = i.getValue().getSchema();
+ if (inputSchema != null) {
+ schema.addAll(inputSchema);
+ }
}
}
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
index 36111ff..cb89a73 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
@@ -99,6 +99,8 @@
throws AlgebricksException {
AggregateFunctionCallExpression exprCopy = new AggregateFunctionCallExpression(expr.getFunctionInfo(),
expr.isTwoStep(), deepCopyExpressionReferenceList(expr.getArguments()));
+ exprCopy.setStepOneAggregate(expr.getStepOneAggregate());
+ exprCopy.setStepTwoAggregate(expr.getStepTwoAggregate());
deepCopyAnnotations(expr, exprCopy);
deepCopyOpaqueParameters(expr, exprCopy);
return exprCopy;
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
index 213b2b1..b1d8610 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
@@ -335,8 +335,8 @@
throws AlgebricksException {
InnerJoinOperator opCopy = new InnerJoinOperator(
exprDeepCopyVisitor.deepCopyExpressionReference(op.getCondition()),
- deepCopyOperatorReference(op.getInputs().get(0), null),
- deepCopyOperatorReference(op.getInputs().get(1), null));
+ deepCopyOperatorReference(op.getInputs().get(0), arg),
+ deepCopyOperatorReference(op.getInputs().get(1), arg));
copyAnnotations(op, opCopy);
opCopy.setExecutionMode(op.getExecutionMode());
return opCopy;
@@ -347,8 +347,8 @@
throws AlgebricksException {
LeftOuterJoinOperator opCopy = new LeftOuterJoinOperator(
exprDeepCopyVisitor.deepCopyExpressionReference(op.getCondition()),
- deepCopyOperatorReference(op.getInputs().get(0), null),
- deepCopyOperatorReference(op.getInputs().get(1), null));
+ deepCopyOperatorReference(op.getInputs().get(0), arg),
+ deepCopyOperatorReference(op.getInputs().get(1), arg));
copyAnnotations(op, opCopy);
opCopy.setExecutionMode(op.getExecutionMode());
return opCopy;
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
index 931640e..ec024f3 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
@@ -102,16 +102,19 @@
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decoList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
ArrayList<ILogicalPlan> newSubplans = new ArrayList<ILogicalPlan>();
- for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getGroupByList())
+ for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getGroupByList()) {
groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(pair.first,
deepCopyExpressionRef(pair.second)));
- for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getDecorList())
+ }
+ for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getDecorList()) {
decoList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(pair.first,
deepCopyExpressionRef(pair.second)));
- for (ILogicalPlan plan : op.getNestedPlans()) {
- newSubplans.add(OperatorManipulationUtil.deepCopy(plan));
}
- return new GroupByOperator(groupByList, decoList, newSubplans);
+ GroupByOperator gbyOp = new GroupByOperator(groupByList, decoList, newSubplans);
+ for (ILogicalPlan plan : op.getNestedPlans()) {
+ newSubplans.add(OperatorManipulationUtil.deepCopy(plan, gbyOp));
+ }
+ return gbyOp;
}
@Override
@@ -190,19 +193,21 @@
@Override
public ILogicalOperator visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {
ArrayList<ILogicalPlan> newSubplans = new ArrayList<ILogicalPlan>();
+ SubplanOperator subplanOp = new SubplanOperator(newSubplans);
for (ILogicalPlan plan : op.getNestedPlans()) {
- newSubplans.add(OperatorManipulationUtil.deepCopy(plan));
+ newSubplans.add(OperatorManipulationUtil.deepCopy(plan, subplanOp));
}
- return new SubplanOperator(newSubplans);
+ return subplanOp;
}
@Override
public ILogicalOperator visitUnionOperator(UnionAllOperator op, Void arg) throws AlgebricksException {
List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> newVarMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>();
List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = op.getVariableMappings();
- for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple : varMap)
+ for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple : varMap) {
newVarMap.add(new Triple<LogicalVariable, LogicalVariable, LogicalVariable>(triple.first, triple.second,
triple.third));
+ }
return new UnionAllOperator(newVarMap);
}
@@ -343,34 +348,41 @@
private void deepCopyExpressionRefs(List<Mutable<ILogicalExpression>> newExprs,
List<Mutable<ILogicalExpression>> oldExprs) {
- for (Mutable<ILogicalExpression> oldExpr : oldExprs)
+ for (Mutable<ILogicalExpression> oldExpr : oldExprs) {
newExprs.add(new MutableObject<ILogicalExpression>(
((AbstractLogicalExpression) oldExpr.getValue()).cloneExpression()));
+ }
}
- private Mutable<ILogicalExpression> deepCopyExpressionRef(Mutable<ILogicalExpression> oldExpr) {
- return new MutableObject<ILogicalExpression>(
- ((AbstractLogicalExpression) oldExpr.getValue()).cloneExpression());
+ private Mutable<ILogicalExpression> deepCopyExpressionRef(Mutable<ILogicalExpression> oldExprRef) {
+ ILogicalExpression oldExpr = oldExprRef.getValue();
+ if (oldExpr == null) {
+ return new MutableObject<ILogicalExpression>(null);
+ }
+ return new MutableObject<ILogicalExpression>(oldExpr.cloneExpression());
}
private List<LogicalVariable> deepCopyVars(List<LogicalVariable> newVars, List<LogicalVariable> oldVars) {
- for (LogicalVariable oldVar : oldVars)
+ for (LogicalVariable oldVar : oldVars) {
newVars.add(oldVar);
+ }
return newVars;
}
private List<Object> deepCopyObjects(List<Object> newObjs, List<Object> oldObjs) {
- for (Object oldObj : oldObjs)
+ for (Object oldObj : oldObjs) {
newObjs.add(oldObj);
+ }
return newObjs;
}
private List<Pair<IOrder, Mutable<ILogicalExpression>>> deepCopyOrderAndExpression(
List<Pair<IOrder, Mutable<ILogicalExpression>>> ordersAndExprs) {
List<Pair<IOrder, Mutable<ILogicalExpression>>> newOrdersAndExprs = new ArrayList<Pair<IOrder, Mutable<ILogicalExpression>>>();
- for (Pair<IOrder, Mutable<ILogicalExpression>> pair : ordersAndExprs)
+ for (Pair<IOrder, Mutable<ILogicalExpression>> pair : ordersAndExprs) {
newOrdersAndExprs
.add(new Pair<IOrder, Mutable<ILogicalExpression>>(pair.first, deepCopyExpressionRef(pair.second)));
+ }
return newOrdersAndExprs;
}
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
index ad44b65..5c83364 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
@@ -35,12 +35,14 @@
IPartitioningProperty pp = op2.getDeliveredPhysicalProperties().getPartitioningProperty();
List<ILocalStructuralProperty> downPropsLocal = op2.getDeliveredPhysicalProperties().getLocalProperties();
List<ILocalStructuralProperty> propsLocal = new ArrayList<ILocalStructuralProperty>();
- for (ILocalStructuralProperty lsp : downPropsLocal) {
- LinkedList<LogicalVariable> cols = new LinkedList<LogicalVariable>();
- lsp.getColumns(cols);
- ILocalStructuralProperty propagatedProp = lsp.retainVariables(usedVariables);
- if (propagatedProp != null) {
- propsLocal.add(propagatedProp);
+ if (downPropsLocal != null) {
+ for (ILocalStructuralProperty lsp : downPropsLocal) {
+ LinkedList<LogicalVariable> cols = new LinkedList<LogicalVariable>();
+ lsp.getColumns(cols);
+ ILocalStructuralProperty propagatedProp = lsp.retainVariables(usedVariables);
+ if (propagatedProp != null) {
+ propsLocal.add(propagatedProp);
+ }
}
}
deliveredProperties = new StructuralPropertiesVector(pp, propsLocal);
diff --git a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index 4089268..97aa853 100644
--- a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -178,10 +178,12 @@
}
}
- public static ILogicalPlan deepCopy(ILogicalPlan plan) throws AlgebricksException {
+ public static ILogicalPlan deepCopy(ILogicalPlan plan, ILogicalOperator dataSource) throws AlgebricksException {
List<Mutable<ILogicalOperator>> roots = plan.getRoots();
List<Mutable<ILogicalOperator>> newRoots = clonePipeline(roots);
- return new ALogicalPlanImpl(newRoots);
+ ILogicalPlan newPlan = new ALogicalPlanImpl(newRoots);
+ setDataSource(newPlan, dataSource);
+ return newPlan;
}
public static ILogicalPlan deepCopy(ILogicalPlan plan, IOptimizationContext ctx) throws AlgebricksException {
@@ -191,6 +193,23 @@
return new ALogicalPlanImpl(newRoots);
}
+ private static void setDataSource(ILogicalPlan plan, ILogicalOperator dataSource) {
+ for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
+ setDataSource(rootRef, dataSource);
+ }
+ }
+
+ private static void setDataSource(Mutable<ILogicalOperator> opRef, ILogicalOperator dataSource) {
+ ILogicalOperator op = opRef.getValue();
+ if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
+ NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
+ nts.setDataSourceReference(new MutableObject<ILogicalOperator>(dataSource));
+ }
+ for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+ setDataSource(childRef, dataSource);
+ }
+ }
+
private static List<Mutable<ILogicalOperator>> clonePipeline(List<Mutable<ILogicalOperator>> roots)
throws AlgebricksException {
List<Mutable<ILogicalOperator>> newRoots = new ArrayList<Mutable<ILogicalOperator>>();
@@ -225,15 +244,15 @@
public static ILogicalOperator deepCopy(ILogicalOperator op) throws AlgebricksException {
OperatorDeepCopyVisitor visitor = new OperatorDeepCopyVisitor();
- return op.accept(visitor, null);
+ AbstractLogicalOperator copiedOperator = (AbstractLogicalOperator) op.accept(visitor, null);
+ copiedOperator.setExecutionMode(op.getExecutionMode());
+ copiedOperator.getAnnotations().putAll(op.getAnnotations());
+ copiedOperator.setSchema(op.getSchema());
+ AbstractLogicalOperator sourceOp = (AbstractLogicalOperator) op;
+ copiedOperator.setPhysicalOperator(sourceOp.getPhysicalOperator());
+ return copiedOperator;
}
- public static ILogicalOperator deepCopyWithExcutionMode(ILogicalOperator op) throws AlgebricksException {
- OperatorDeepCopyVisitor visitor = new OperatorDeepCopyVisitor();
- AbstractLogicalOperator newOp = (AbstractLogicalOperator) op.accept(visitor, null);
- newOp.setExecutionMode(op.getExecutionMode());
- return newOp;
- }
/**
* Compute type environment of a newly generated operator {@code op} and its input.
*
@@ -259,6 +278,21 @@
context.computeAndSetTypeEnvironmentForOperator(op);
}
+ /**
+ * Computes the type environment for a logical query plan.
+ *
+ * @param plan,
+ * the logical plan to consider.
+ * @param context
+ * the typing context.
+ * @throws AlgebricksException
+ */
+ public static void computeTypeEnvironment(ILogicalPlan plan, ITypingContext context) throws AlgebricksException {
+ for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
+ computeTypeEnvironmentBottomUp(rootRef.getValue(), context);
+ }
+ }
+
/***
* Is the operator <code>>op</code> an ancestor of any operators with tags in the set <code>tags</code>?
*
diff --git a/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java b/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
index 2d2619e..4d2fc30 100644
--- a/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
+++ b/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
@@ -48,6 +48,7 @@
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.IsomorphismUtilities;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
+import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
public abstract class AbstractIntroduceGroupByCombinerRule extends AbstractIntroduceCombinerRule {
@@ -135,10 +136,23 @@
annotations.putAll(gbyOp.getAnnotations());
List<LogicalVariable> gbyVars = gbyOp.getGbyVarList();
+
+ // Backup nested plans since tryToPushSubplan(...) may mutate them.
+ List<ILogicalPlan> copiedNestedPlans = new ArrayList<>();
+ for (ILogicalPlan nestedPlan : gbyOp.getNestedPlans()) {
+ ILogicalPlan copiedNestedPlan = OperatorManipulationUtil.deepCopy(nestedPlan, gbyOp);
+ OperatorManipulationUtil.computeTypeEnvironment(copiedNestedPlan, context);
+ copiedNestedPlans.add(copiedNestedPlan);
+ }
+
for (ILogicalPlan p : gbyOp.getNestedPlans()) {
+ // NOTE: tryToPushSubplan(...) can mutate the nested subplan p.
Pair<Boolean, ILogicalPlan> bip = tryToPushSubplan(p, gbyOp, newGbyOp, bi, gbyVars, context);
if (!bip.first) {
// For now, if we cannot push everything, give up.
+ // Resets the group-by operator with backup nested plans.
+ gbyOp.getNestedPlans().clear();
+ gbyOp.getNestedPlans().addAll(copiedNestedPlans);
return null;
}
ILogicalPlan pushedSubplan = bip.second;