use of org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method visitGroupByOperator.
@Override
public Void visitGroupByOperator(GroupByOperator 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);
List<FunctionalDependency> inheritedFDs = new ArrayList<FunctionalDependency>();
for (ILogicalPlan p : op.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
ILogicalOperator op2 = r.getValue();
equivalenceClasses.putAll(getOrComputeEqClasses(op2, ctx));
inheritedFDs.addAll(getOrComputeFDs(op2, ctx));
}
}
ILogicalOperator op0 = op.getInputs().get(0).getValue();
inheritedFDs.addAll(getOrComputeFDs(op0, ctx));
Map<LogicalVariable, EquivalenceClass> inheritedEcs = getOrComputeEqClasses(op0, ctx);
for (FunctionalDependency inherited : inheritedFDs) {
boolean isCoveredByGbyOrDecorVars = true;
List<LogicalVariable> newHead = new ArrayList<LogicalVariable>(inherited.getHead().size());
for (LogicalVariable v : inherited.getHead()) {
LogicalVariable vnew = getNewGbyVar(op, v);
if (vnew == null) {
vnew = getNewDecorVar(op, v);
if (vnew == null) {
isCoveredByGbyOrDecorVars = false;
}
break;
}
newHead.add(vnew);
}
if (isCoveredByGbyOrDecorVars) {
List<LogicalVariable> newTail = new ArrayList<LogicalVariable>();
for (LogicalVariable v2 : inherited.getTail()) {
LogicalVariable v3 = getNewGbyVar(op, v2);
if (v3 != null) {
newTail.add(v3);
}
}
if (!newTail.isEmpty()) {
FunctionalDependency newFd = new FunctionalDependency(newHead, newTail);
functionalDependencies.add(newFd);
}
}
}
List<LogicalVariable> premiseGby = new LinkedList<LogicalVariable>();
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gByList = op.getGroupByList();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
premiseGby.add(p.first);
}
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = op.getDecorList();
LinkedList<LogicalVariable> conclDecor = new LinkedList<LogicalVariable>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
conclDecor.add(GroupByOperator.getDecorVariable(p));
}
if (!conclDecor.isEmpty()) {
functionalDependencies.add(new FunctionalDependency(premiseGby, conclDecor));
}
Set<LogicalVariable> gbySet = new HashSet<LogicalVariable>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
ILogicalExpression expr = p.second.getValue();
if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
VariableReferenceExpression v = (VariableReferenceExpression) expr;
gbySet.add(v.getVariableReference());
}
}
LocalGroupingProperty lgp = new LocalGroupingProperty(gbySet);
ILocalStructuralProperty normalizedLgp = lgp.normalize(inheritedEcs, inheritedFDs);
Set<LogicalVariable> normSet = new ListSet<>();
normalizedLgp.getColumns(normSet);
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> newGbyList = new ArrayList<>();
boolean changed = false;
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
ILogicalExpression expr = p.second.getValue();
if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
LogicalVariable v2 = varRef.getVariableReference();
EquivalenceClass ec2 = inheritedEcs.get(v2);
LogicalVariable v3;
if (ec2 != null && !ec2.representativeIsConst()) {
v3 = ec2.getVariableRepresentative();
} else {
v3 = v2;
}
if (normSet.contains(v3)) {
newGbyList.add(p);
} else {
changed = true;
decorList.add(p);
}
} else {
newGbyList.add(p);
}
}
if (changed) {
AlgebricksConfig.ALGEBRICKS_LOGGER.fine(">>>> Group-by list changed from " + GroupByOperator.veListToString(gByList) + " to " + GroupByOperator.veListToString(newGbyList) + ".\n");
}
gByList.clear();
gByList.addAll(newGbyList);
return null;
}
use of org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency in project asterixdb by apache.
the class AbstractFunctionCallExpression method getFDsAndEquivClassesForEqWithConstant.
private static final void getFDsAndEquivClassesForEqWithConstant(ConstantExpression c, VariableReferenceExpression v, Collection<FunctionalDependency> fds, Map<LogicalVariable, EquivalenceClass> equivClasses) {
LogicalVariable var = v.getVariableReference();
LinkedList<LogicalVariable> head = new LinkedList<LogicalVariable>();
// empty set in the head
LinkedList<LogicalVariable> tail = new LinkedList<LogicalVariable>();
tail.add(var);
FunctionalDependency fd = new FunctionalDependency(head, tail);
fds.add(fd);
EquivalenceClass ec = equivClasses.get(var);
if (ec == null) {
LinkedList<LogicalVariable> members = new LinkedList<LogicalVariable>();
members.add(var);
EquivalenceClass eclass = new EquivalenceClass(members, c);
equivClasses.put(var, eclass);
} else {
if (ec.representativeIsConst()) {
ILogicalExpression c1 = ec.getConstRepresentative();
if (!c1.equals(c)) {
// here I could also rewrite to FALSE
return;
}
}
ec.setConstRepresentative(c);
}
}
use of org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency in project asterixdb by apache.
the class AbstractFunctionCallExpression method getFDsAndEquivClassesForColumnEq.
/*
* Obs.: mgmt. of equiv. classes should use a more efficient data
* structure,if we are to implem. cost-bazed optim.
*/
private static final void getFDsAndEquivClassesForColumnEq(VariableReferenceExpression v1, VariableReferenceExpression v2, Collection<FunctionalDependency> fds, Map<LogicalVariable, EquivalenceClass> equivClasses) {
LogicalVariable var1 = v1.getVariableReference();
LogicalVariable var2 = v2.getVariableReference();
LinkedList<LogicalVariable> set1 = new LinkedList<LogicalVariable>();
set1.add(var1);
LinkedList<LogicalVariable> set2 = new LinkedList<LogicalVariable>();
set2.add(var2);
FunctionalDependency fd1 = new FunctionalDependency(set1, set2);
FunctionalDependency fd2 = new FunctionalDependency(set2, set1);
fds.add(fd1);
fds.add(fd2);
EquivalenceClass ec1 = equivClasses.get(var1);
EquivalenceClass ec2 = equivClasses.get(var2);
if (ec1 == null && ec2 == null) {
LinkedList<LogicalVariable> members = new LinkedList<LogicalVariable>();
members.add(var1);
members.add(var2);
EquivalenceClass ec = new EquivalenceClass(members, var1);
equivClasses.put(var1, ec);
equivClasses.put(var2, ec);
} else if (ec1 == null && ec2 != null) {
ec2.addMember(var1);
equivClasses.put(var1, ec2);
} else if (ec2 == null && ec1 != null) {
ec1.addMember(var2);
equivClasses.put(var2, ec1);
} else {
ec1.merge(ec2);
for (LogicalVariable w : equivClasses.keySet()) {
if (ec2.getMembers().contains(w)) {
equivClasses.put(w, ec1);
}
}
}
}
use of org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency in project asterixdb by apache.
the class DataSource method computeFDs.
@Override
public void computeFDs(List<LogicalVariable> scanVariables, List<FunctionalDependency> fdList) {
int n = scanVariables.size();
if (n > 1) {
List<LogicalVariable> head = new ArrayList<>(scanVariables.subList(0, n - 1));
List<LogicalVariable> tail = new ArrayList<>(1);
tail.addAll(scanVariables);
FunctionalDependency fd = new FunctionalDependency(head, tail);
fdList.add(fd);
}
}
Aggregations