>From Ali Alsuliman <[email protected]>:
Ali Alsuliman has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20767?usp=email )
Change subject: push assign to join branch
......................................................................
push assign to join branch
Change-Id: I74452d71423610ca2a34631235f5da8325e3b625
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/LoadRecordFieldsRule.java
2 files changed, 80 insertions(+), 39 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/67/20767/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
index abc434f..e4bcbd8 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.asterix.algebra.base.OperatorAnnotation;
import org.apache.asterix.om.base.AInt32;
@@ -45,6 +47,7 @@
import
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
import
org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
import org.apache.hyracks.api.exceptions.SourceLocation;
@@ -85,20 +88,54 @@
if (fce.getFunctionIdentifier() !=
BuiltinFunctions.FIELD_ACCESS_BY_NAME) {
return changed;
}
- changed |= extractFirstArg(fce, op, context);
- IVariableTypeEnvironment env =
context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
- IAType t = (IAType) env.getType(fce.getArguments().get(0).getValue());
- changed |= rewriteFieldAccess(exprRef, fce,
TypeComputeUtils.getActualType(t));
+ int k = extractFirstArg(fce, op, context);
+ changed |= k >= 0;
+ if (k < 0) {
+ if (op.getInputs().size() > 1) {
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ changed |= rewriteFieldAccessUsing(op, exprRef, context, fce);
+ return changed;
+ }
+ k = 0;
+ }
+ changed |= rewriteFieldAccessUsing(op.getInputs().get(k).getValue(),
exprRef, context, fce);
return changed;
}
- // Extracts the first argument of a field-access expression into an
separate assign operator.
- private boolean extractFirstArg(AbstractFunctionCallExpression fce,
ILogicalOperator op,
+ // Extracts the first argument of a field-access expression into a
separate assign operator.
+ private static int extractFirstArg(AbstractFunctionCallExpression fce,
ILogicalOperator op,
IOptimizationContext context) throws AlgebricksException {
ILogicalExpression firstArg = fce.getArguments().get(0).getValue();
if (firstArg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL)
{
- return false;
+ return -1;
}
+ if (op.getInputs().size() > 1) {
+ return extractToBranch(fce, op, context, firstArg);
+ }
+ extractToAssignOp(fce, op.getInputs().get(0), context, firstArg);
+ return 0;
+ }
+
+ private static int extractToBranch(AbstractFunctionCallExpression fce,
ILogicalOperator op,
+ IOptimizationContext ctx, ILogicalExpression firstArg) throws
AlgebricksException {
+ Set<LogicalVariable> usedByExpr = new HashSet<>();
+ Set<LogicalVariable> inputLiveVars = new HashSet<>();
+ fce.getUsedVariables(usedByExpr);
+ int i = 0;
+ for (Mutable<ILogicalOperator> input : op.getInputs()) {
+ inputLiveVars.clear();
+ VariableUtilities.getLiveVariables(input.getValue(),
inputLiveVars);
+ if (inputLiveVars.containsAll(usedByExpr)) {
+ extractToAssignOp(fce, input, ctx, firstArg);
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+
+ private static void extractToAssignOp(AbstractFunctionCallExpression fce,
Mutable<ILogicalOperator> op,
+ IOptimizationContext context, ILogicalExpression firstArg) throws
AlgebricksException {
SourceLocation sourceLoc = firstArg.getSourceLocation();
LogicalVariable var1 = context.newVar();
AssignOperator assignOp = new AssignOperator(new
ArrayList<>(Collections.singletonList(var1)),
@@ -107,14 +144,20 @@
VariableReferenceExpression var1Ref = new
VariableReferenceExpression(var1);
var1Ref.setSourceLocation(sourceLoc);
fce.getArguments().get(0).setValue(var1Ref);
- assignOp.getInputs().add(new
MutableObject<>(op.getInputs().get(0).getValue()));
- op.getInputs().get(0).setValue(assignOp);
+ assignOp.getInputs().add(new MutableObject<>(op.getValue()));
+ op.setValue(assignOp);
context.computeAndSetTypeEnvironmentForOperator(assignOp);
- return true;
+ }
+
+ private static boolean rewriteFieldAccessUsing(ILogicalOperator op,
Mutable<ILogicalExpression> exprRef,
+ IOptimizationContext ctx, AbstractFunctionCallExpression fce)
throws AlgebricksException {
+ IVariableTypeEnvironment env = ctx.getOutputTypeEnvironment(op);
+ IAType t = (IAType) env.getType(fce.getArguments().get(0).getValue());
+ return rewriteFieldAccess(exprRef, fce,
TypeComputeUtils.getActualType(t));
}
// Rewrites field-access-by-name into field-access-by-index if possible.
- private boolean rewriteFieldAccess(Mutable<ILogicalExpression> exprRef,
AbstractFunctionCallExpression fce,
+ private static boolean rewriteFieldAccess(Mutable<ILogicalExpression>
exprRef, AbstractFunctionCallExpression fce,
IAType t) {
if (t.getTypeTag() != ATypeTag.OBJECT) {
return false;
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/LoadRecordFieldsRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/LoadRecordFieldsRule.java
index 42cce52..b361ee1 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/LoadRecordFieldsRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/LoadRecordFieldsRule.java
@@ -21,12 +21,10 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import org.apache.asterix.algebra.base.OperatorAnnotation;
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.common.exceptions.ErrorCode;
import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.om.base.AInt32;
import org.apache.asterix.om.base.AString;
@@ -96,8 +94,7 @@
context.addToDontApplySet(this, op1);
}
if (res && op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
- // checking if we can annotate a Selection as using just one field
- // access
+ // checking if we can annotate a Selection as using just one field
access
SelectOperator sigma = (SelectOperator) op1;
List<LogicalVariable> vars = new ArrayList<>();
VariableUtilities.getUsedVariables(sigma, vars);
@@ -107,8 +104,7 @@
ILogicalExpression expr1 = getFirstExpr(assign1);
if (FunctionUtil.isFieldAccessFunction(expr1)) {
AbstractFunctionCallExpression f =
(AbstractFunctionCallExpression) expr1;
- // f should be a call to a field/data access kind of
- // function
+ // f should be a call to a field/data access kind of
function
sigma.getAnnotations().put(OperatorAnnotation.FIELD_ACCESS,
f.getArguments().get(0));
}
}
@@ -144,7 +140,9 @@
LogicalVariable v = context.newVar();
AssignOperator a2 = new AssignOperator(v, new
MutableObject<>(f));
a2.setSourceLocation(expr.getSourceLocation());
- pushFieldAssign(a2, topOp, context);
+ if (!pushFieldAssign(a2, topOp, context)) {
+ return false;
+ }
context.computeAndSetTypeEnvironmentForOperator(a2);
ILogicalExpression arg =
f.getArguments().get(0).getValue();
if (arg.getExpressionTag() ==
LogicalExpressionTag.VARIABLE) {
@@ -183,59 +181,59 @@
}
}
- private static void pushFieldAssign(AssignOperator a2,
AbstractLogicalOperator topOp, IOptimizationContext context)
- throws AlgebricksException {
+ private static boolean pushFieldAssign(AssignOperator a2,
AbstractLogicalOperator topOp,
+ IOptimizationContext context) throws AlgebricksException {
if (topOp.getInputs().size() == 1 && !topOp.hasNestedPlans()) {
Mutable<ILogicalOperator> topChild = topOp.getInputs().get(0);
- // plugAccessAboveOp(a2, topChild, context);
List<Mutable<ILogicalOperator>> a2InptList = a2.getInputs();
- a2InptList.clear();
a2InptList.add(topChild);
// and link it as child in the op. tree
topOp.getInputs().set(0, new MutableObject<>(a2));
findAndEliminateRedundantFieldAccess(a2, context);
+ return true;
} else { // e.g., a join
- LinkedList<LogicalVariable> usedInAccess = new
LinkedList<LogicalVariable>();
+ Set<LogicalVariable> usedInAccess = new HashSet<>();
VariableUtilities.getUsedVariables(a2, usedInAccess);
- LinkedList<LogicalVariable> produced2 = new
LinkedList<LogicalVariable>();
+ Set<LogicalVariable> produced2 = new HashSet<>();
VariableUtilities.getProducedVariables(topOp, produced2);
if (OperatorPropertiesUtil.disjoint(produced2, usedInAccess)) {
+ Set<LogicalVariable> inputLiveVars = new HashSet<>();
for (Mutable<ILogicalOperator> inp : topOp.getInputs()) {
- HashSet<LogicalVariable> v2 = new
HashSet<LogicalVariable>();
- VariableUtilities.getLiveVariables(inp.getValue(), v2);
- if (!OperatorPropertiesUtil.disjoint(usedInAccess, v2)) {
- pushAccessAboveOpRef(a2, inp, context);
- return;
+ inputLiveVars.clear();
+ VariableUtilities.getLiveVariables(inp.getValue(),
inputLiveVars);
+ // push the assign to the correct branch that contains all
the used vars
+ if (inputLiveVars.containsAll(usedInAccess)) {
+ pushAccessThroughOp(a2, inp, context);
+ return true;
}
}
if (topOp.hasNestedPlans()) {
AbstractOperatorWithNestedPlans nestedOp =
(AbstractOperatorWithNestedPlans) topOp;
for (ILogicalPlan plan : nestedOp.getNestedPlans()) {
for (Mutable<ILogicalOperator> root : plan.getRoots())
{
- HashSet<LogicalVariable> v2 = new
HashSet<LogicalVariable>();
-
VariableUtilities.getLiveVariables(root.getValue(), v2);
- if (!OperatorPropertiesUtil.disjoint(usedInAccess,
v2)) {
- pushAccessAboveOpRef(a2, root, context);
- return;
+ inputLiveVars.clear();
+
VariableUtilities.getLiveVariables(root.getValue(), inputLiveVars);
+ if (inputLiveVars.containsAll(usedInAccess)) {
+ pushAccessThroughOp(a2, root, context);
+ return true;
}
}
}
}
- throw new CompilationException(ErrorCode.COMPILATION_ERROR,
a2.getSourceLocation(),
- "Field access " + getFirstExpr(a2) + " does not
correspond to any input");
}
}
+ return false;
}
/**
- * Pushes one field-access assignment above toPushThroughChildRef
+ * Pushes one field-access assignment through toPushThroughChildRef
*
* @param toPush
* @param toPushThroughChildRef
*/
- private static void pushAccessAboveOpRef(AssignOperator toPush,
Mutable<ILogicalOperator> toPushThroughChildRef,
+ private static void pushAccessThroughOp(AssignOperator toPush,
Mutable<ILogicalOperator> toPushThroughChildRef,
IOptimizationContext context) throws AlgebricksException {
List<Mutable<ILogicalOperator>> tpInpList = toPush.getInputs();
tpInpList.clear();
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20767?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: neo
Gerrit-Change-Id: I74452d71423610ca2a34631235f5da8325e3b625
Gerrit-Change-Number: 20767
Gerrit-PatchSet: 1
Gerrit-Owner: Ali Alsuliman <[email protected]>