@Override public Void visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException { for (Mutable<ILogicalOperator> c : op.getInputs()) { VariableUtilities.getLiveVariables(c.getValue(), schemaVariables); } for (ILogicalPlan p : op.getNestedPlans()) { for (Mutable<ILogicalOperator> r : p.getRoots()) { VariableUtilities.getLiveVariables(r.getValue(), schemaVariables); } } return null; }
@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).getOperator(); ILogicalOperator opRight = op.getInputs().get(1).getOperator(); 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().getExpression(); expr.getConstraintsForOuterJoin(functionalDependencies, leftSideVars); return null; }
@Override public Void visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException { List<LogicalVariable> allLiveVars = new ArrayList<LogicalVariable>(); for (Mutable<ILogicalOperator> c : op.getInputs()) { VariableUtilities.getLiveVariables(c.getValue(), allLiveVars); } VariableUtilities.getProducedVariables(op, allLiveVars); /** put distinct vars first */ schemaVariables.addAll(op.getDistinctByVarList()); /** then other live vars */ for (LogicalVariable var : allLiveVars) { if (!schemaVariables.contains(var)) { schemaVariables.add(var); } } return null; }
@Override public Void visitUnnestMapOperator(UnnestMapOperator op, Void arg) throws AlgebricksException { if (op.propagatesInput()) { standardLayout(op); } else { VariableUtilities.getProducedVariables(op, schemaVariables); } return null; }
private void fdsEqClassesForAbstractUnnestOperator( AbstractUnnestOperator op, IOptimizationContext ctx) throws AlgebricksException { ILogicalOperator inp1 = op.getInputs().get(0).getOperator(); Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx); ctx.putEquivalenceClassMap(op, eqClasses); List<FunctionalDependency> fds = getOrComputeFDs(inp1, ctx); ctx.putFDList(op, fds); ILogicalExpression expr = op.getExpressionRef().getExpression(); if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) { AbstractFunctionCallExpression afe = (AbstractFunctionCallExpression) expr; if (afe.getKind() == FunctionKind.UNNEST && ((UnnestingFunctionCallExpression) afe).returnsUniqueValues()) { List<LogicalVariable> vars = new ArrayList<LogicalVariable>(); VariableUtilities.getLiveVariables(op, vars); ArrayList<LogicalVariable> h = new ArrayList<LogicalVariable>(); h.addAll(op.getVariables()); FunctionalDependency fd = new FunctionalDependency(h, vars); fds.add(fd); } } }
@Override public Void visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException { for (ILogicalPlan p : op.getNestedPlans()) { for (Mutable<ILogicalOperator> r : p.getRoots()) { VariableUtilities.getLiveVariables(r.getValue(), schemaVariables); } } for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getGroupByList()) { if (p.first != null) { schemaVariables.add(p.first); } } for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getDecorList()) { if (p.first != null) { schemaVariables.add(p.first); } else { ILogicalExpression e = p.second.getValue(); if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) { schemaVariables.add(((VariableReferenceExpression) e).getVariableReference()); } } } return null; }
@Override public Void visitAssignOperator(AssignOperator op, IOptimizationContext ctx) throws AlgebricksException { ILogicalOperator inp1 = op.getInputs().get(0).getOperator(); Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx); ctx.putEquivalenceClassMap(op, eqClasses); 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; }
private void standardLayout(ILogicalOperator op) throws AlgebricksException { for (Mutable<ILogicalOperator> c : op.getInputs()) { VariableUtilities.getLiveVariables(c.getValue(), schemaVariables); } VariableUtilities.getProducedVariables(op, schemaVariables); }
@Override public Void visitIntersectOperator(IntersectOperator op, Void arg) throws AlgebricksException { VariableUtilities.getProducedVariables(op, schemaVariables); return null; }
@Override public Void visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Void arg) throws AlgebricksException { VariableUtilities.getLiveVariables(op.getSourceOperator(), schemaVariables); return null; }