use of org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method visitLeftOuterJoinOperator.
@Override
public Void visitLeftOuterJoinOperator(LeftOuterJoinOperator op, IOptimizationContext ctx) throws AlgebricksException {
Map<LogicalVariable, EquivalenceClass> equivalenceClasses = new HashMap<LogicalVariable, EquivalenceClass>();
List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
ctx.putEquivalenceClassMap(op, equivalenceClasses);
ctx.putFDList(op, functionalDependencies);
ILogicalOperator opLeft = op.getInputs().get(0).getValue();
ILogicalOperator opRight = op.getInputs().get(1).getValue();
functionalDependencies.addAll(getOrComputeFDs(opLeft, ctx));
functionalDependencies.addAll(getOrComputeFDs(opRight, ctx));
equivalenceClasses.putAll(getOrComputeEqClasses(opLeft, ctx));
equivalenceClasses.putAll(getOrComputeEqClasses(opRight, ctx));
Collection<LogicalVariable> leftSideVars;
if (opLeft.getSchema() == null) {
leftSideVars = new LinkedList<LogicalVariable>();
VariableUtilities.getLiveVariables(opLeft, leftSideVars);
// actually, not all produced vars. are visible (due to projection)
// so using cached schema is better and faster
} else {
leftSideVars = opLeft.getSchema();
}
ILogicalExpression expr = op.getCondition().getValue();
expr.getConstraintsForOuterJoin(functionalDependencies, leftSideVars);
return null;
}
use of org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method visitDistinctOperator.
@Override
public Void visitDistinctOperator(DistinctOperator op, IOptimizationContext ctx) throws AlgebricksException {
ILogicalOperator op0 = op.getInputs().get(0).getValue();
List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
ctx.putFDList(op, functionalDependencies);
for (FunctionalDependency inherited : getOrComputeFDs(op0, ctx)) {
boolean isCoveredByDistinctByVars = true;
for (LogicalVariable v : inherited.getHead()) {
if (!op.isDistinctByVar(v)) {
isCoveredByDistinctByVars = false;
}
}
if (isCoveredByDistinctByVars) {
List<LogicalVariable> newTail = new ArrayList<LogicalVariable>();
for (LogicalVariable v2 : inherited.getTail()) {
if (op.isDistinctByVar(v2)) {
newTail.add(v2);
}
}
if (!newTail.isEmpty()) {
List<LogicalVariable> newHead = new ArrayList<LogicalVariable>(inherited.getHead());
FunctionalDependency newFd = new FunctionalDependency(newHead, newTail);
functionalDependencies.add(newFd);
}
}
}
Set<LogicalVariable> gbySet = new HashSet<LogicalVariable>();
List<Mutable<ILogicalExpression>> expressions = op.getExpressions();
for (Mutable<ILogicalExpression> pRef : expressions) {
ILogicalExpression p = pRef.getValue();
if (p.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
VariableReferenceExpression v = (VariableReferenceExpression) p;
gbySet.add(v.getVariableReference());
}
}
LocalGroupingProperty lgp = new LocalGroupingProperty(gbySet);
Map<LogicalVariable, EquivalenceClass> equivalenceClasses = getOrComputeEqClasses(op0, ctx);
ctx.putEquivalenceClassMap(op, equivalenceClasses);
ILocalStructuralProperty normalizedLgp = lgp.normalize(equivalenceClasses, functionalDependencies);
Set<LogicalVariable> normSet = new ListSet<>();
normalizedLgp.getColumns(normSet);
List<Mutable<ILogicalExpression>> newDistinctByList = new ArrayList<Mutable<ILogicalExpression>>();
for (Mutable<ILogicalExpression> p2Ref : expressions) {
ILogicalExpression p2 = p2Ref.getValue();
if (p2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
VariableReferenceExpression var2 = (VariableReferenceExpression) p2;
LogicalVariable v2 = var2.getVariableReference();
if (normSet.contains(v2)) {
newDistinctByList.add(p2Ref);
}
} else {
newDistinctByList.add(p2Ref);
}
}
expressions.clear();
expressions.addAll(newDistinctByList);
return null;
}
use of org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method visitAssignOperator.
@Override
public Void visitAssignOperator(AssignOperator op, IOptimizationContext ctx) throws AlgebricksException {
ILogicalOperator inp1 = op.getInputs().get(0).getValue();
Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
ctx.putEquivalenceClassMap(op, eqClasses);
// Propagates equivalence classes that from expressions.
// Note that an equivalence class can also contain expression members.
propagateEquivalenceFromExpressionsToVariables(eqClasses, op.getExpressions(), op.getVariables());
// Generates FDs.
List<LogicalVariable> used = new ArrayList<LogicalVariable>();
VariableUtilities.getUsedVariables(op, used);
List<FunctionalDependency> fds1 = getOrComputeFDs(inp1, ctx);
List<FunctionalDependency> eFds = new ArrayList<FunctionalDependency>(fds1.size());
for (FunctionalDependency fd : fds1) {
if (fd.getTail().containsAll(used)) {
List<LogicalVariable> hd = new ArrayList<LogicalVariable>(fd.getHead());
List<LogicalVariable> tl = new ArrayList<LogicalVariable>(fd.getTail());
tl.addAll(op.getVariables());
FunctionalDependency fd2 = new FunctionalDependency(hd, tl);
eFds.add(fd2);
} else {
eFds.add(fd);
}
}
ctx.putFDList(op, eFds);
return null;
}
use of org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method propagateEquivalenceFromExpressionsToVariables.
/**
* Propagate equivalences that carried in expressions to the variables that
* they are assigned to.
*
* @param eqClasses
* an equivalent class map
* @param assignExprs
* expressions on the right-hand-side of assignments
* @param assignVars
* variables on the left-hand-side of assignments
*/
private void propagateEquivalenceFromExpressionsToVariables(Map<LogicalVariable, EquivalenceClass> eqClasses, List<Mutable<ILogicalExpression>> assignExprs, List<LogicalVariable> assignVars) {
for (int assignVarIndex = 0; assignVarIndex < assignVars.size(); ++assignVarIndex) {
LogicalVariable var = assignVars.get(assignVarIndex);
ILogicalExpression expr = assignExprs.get(assignVarIndex).getValue();
Map<LogicalVariable, EquivalenceClass> newVarEqcMap = new HashMap<LogicalVariable, EquivalenceClass>();
for (Entry<LogicalVariable, EquivalenceClass> entry : eqClasses.entrySet()) {
EquivalenceClass eqc = entry.getValue();
// class.
if (eqc.contains(expr)) {
eqc.addMember(var);
// Add var as a map key for the
newVarEqcMap.put(var, eqc);
// equivalence class.
}
}
eqClasses.putAll(newVarEqcMap);
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method propagateFDsAndEquivClassesForUsedVars.
/***
* Propagated equivalent classes from the child to the current operator,
* based on the used variables of the current operator.
*
* @param op
* , the current operator
* @param ctx
* , the optimization context which keeps track of all equivalent
* classes.
* @param usedVariables
* , used variables.
* @throws AlgebricksException
*/
private void propagateFDsAndEquivClassesForUsedVars(ILogicalOperator op, IOptimizationContext ctx, List<LogicalVariable> usedVariables) throws AlgebricksException {
ILogicalOperator op2 = op.getInputs().get(0).getValue();
Map<LogicalVariable, EquivalenceClass> eqClasses = getOrCreateEqClasses(op, ctx);
List<FunctionalDependency> fds = new ArrayList<FunctionalDependency>();
ctx.putFDList(op, fds);
Map<LogicalVariable, EquivalenceClass> chldClasses = getOrComputeEqClasses(op2, ctx);
// Propagate equivalent classes that contain the used variables.
for (LogicalVariable v : usedVariables) {
EquivalenceClass ec = eqClasses.get(v);
if (ec == null) {
EquivalenceClass oc = chldClasses.get(v);
if (oc == null) {
continue;
}
List<LogicalVariable> m = new LinkedList<LogicalVariable>();
for (LogicalVariable v2 : oc.getMembers()) {
if (usedVariables.contains(v2)) {
m.add(v2);
}
}
EquivalenceClass nc;
if (oc.representativeIsConst()) {
nc = new EquivalenceClass(m, oc.getConstRepresentative());
} else if (m.contains(oc.getVariableRepresentative())) {
nc = new EquivalenceClass(m, oc.getVariableRepresentative());
} else {
nc = new EquivalenceClass(m, v);
}
for (LogicalVariable v3 : m) {
eqClasses.put(v3, nc);
}
}
}
// Propagates equivalent classes that contain expressions that use the
// used variables.
// Note that for the case variable $v is not in the used variables but
// it is
// equivalent to field-access($t, i) and $t is a used variable, the
// equivalent
// class should still be propagated (kept).
Set<LogicalVariable> usedVarSet = new HashSet<LogicalVariable>(usedVariables);
for (Entry<LogicalVariable, EquivalenceClass> entry : chldClasses.entrySet()) {
EquivalenceClass ec = entry.getValue();
for (ILogicalExpression expr : ec.getExpressionMembers()) {
Set<LogicalVariable> exprUsedVars = new HashSet<LogicalVariable>();
expr.getUsedVariables(exprUsedVars);
exprUsedVars.retainAll(usedVarSet);
// Check if the expression member uses a used variable.
if (!exprUsedVars.isEmpty()) {
for (LogicalVariable v : ec.getMembers()) {
eqClasses.put(v, ec);
// variable should be a used variable.
if (usedVarSet.contains(v)) {
ec.setVariableRepresentative(v);
}
}
}
}
}
List<FunctionalDependency> chldFds = getOrComputeFDs(op2, ctx);
for (FunctionalDependency fd : chldFds) {
if (!usedVariables.containsAll(fd.getHead())) {
continue;
}
List<LogicalVariable> tl = new LinkedList<LogicalVariable>();
for (LogicalVariable v : fd.getTail()) {
if (usedVariables.contains(v)) {
tl.add(v);
}
}
if (!tl.isEmpty()) {
FunctionalDependency newFd = new FunctionalDependency(fd.getHead(), tl);
fds.add(newFd);
}
}
}
Aggregations