/** * Adds the operand and its descendants to the list in prefix order. * * @param operandList Flattened list of operands * @param parentOperand Parent of this operand */ private void flattenRecurse( List<RelOptRuleOperand> operandList, RelOptRuleOperand parentOperand) { if (parentOperand.getChildOperands() == null) { return; } int k = 0; for (RelOptRuleOperand operand : parentOperand.getChildOperands()) { operand.setRule(this); operand.setParent(parentOperand); operand.ordinalInParent = k++; operand.ordinalInRule = operandList.size(); operandList.add(operand); flattenRecurse(operandList, operand); } }
@Override public boolean matches(RelNode rel) { return super.matches(rel) && ((FilterRel) rel).getCondition() instanceof RexInputRef; } });
/** * Creates an operand that matches a relational expression that has no * children. * * @param clazz Class of relational expression to match (must not be null) * @return Operand */ public static RelOptRuleOperand operand( Class<? extends RelNode> clazz, RelOptRuleOperandChildren operandList) { return new RelOptRuleOperand(clazz, null, operandList); }
/** * Creates a flattened list of this operand and its descendants in prefix * order. * * @param rootOperand Root operand * @return Flattened list of operands */ private List<RelOptRuleOperand> flattenOperands( RelOptRuleOperand rootOperand) { List<RelOptRuleOperand> operandList = new ArrayList<RelOptRuleOperand>(); // Flatten the operands into a list. rootOperand.setRule(this); rootOperand.setParent(null); rootOperand.ordinalInParent = 0; rootOperand.ordinalInRule = operandList.size(); operandList.add(rootOperand); flattenRecurse(operandList, rootOperand); return ImmutableList.copyOf(operandList); }
List<RelNode> bindings, Map<RelNode, List<RelNode>> nodeChildren) { if (!operand.matches(rel)) { return false; for (RelOptRuleOperand childOperand : operand.getChildOperands()) { boolean match = false; for (HepRelVertex childRel : childRels) { return true; default: int n = operand.getChildOperands().size(); if (childRels.size() < n) { return false; : Pair.zip(childRels, operand.getChildOperands())) { boolean match = matchOperands(
assert previousOperand.getParent() == operand; final RelNode childRel = rels[previousOperandOrdinal]; RelSubset subset = volcanoPlanner.getSubset(childRel); successors = subset.getParentRels(); } else { int parentOrdinal = operand.getParent().ordinalInRule; RelNode parentRel = rels[parentOrdinal]; List<RelNode> inputs = parentRel.getInputs(); RelSubset subset = (RelSubset) inputs.get(operand.ordinalInParent); if (operand.getMatchedClass() == RelSubset.class) { successors = subset.set.subsets; } else { if (!operand.matches(rel)) { continue;
/** * Creates a new TraitMatchingRule. * * @param converterRule rule to be restricted; rule must take a single * operand expecting a single input */ public TraitMatchingRule(ConverterRule converterRule) { super( some( converterRule.getOperand().getMatchedClass(), any(RelNode.class)), "TraitMatchingRule: " + converterRule); assert (converterRule.getOperand().getChildOperands() == null); this.converter = converterRule; }
assert (previousOperand.getParent() == operand); final RelNode childRel = rels[previousOperandOrdinal]; RelSet set = volcanoPlanner.getSet(childRel); successors = set.getParentRels(); } else { int parentOrdinal = operand.getParent().ordinalInRule; RelNode parentRel = rels[parentOrdinal]; List<RelNode> inputs = parentRel.getInputs(); if (!operand.matches(rel)) { continue;
/** Recursively checks whether there are any duplicate subsets along any path * from root of the operand tree to one of the leaves. * * <p>It is OK for a match to have duplicate subsets if they are not on the * same path. For example,</p> * * <pre> * Join * / \ * X X * </pre> * * <p>is a valid match.</p> * * @throws org.eigenbase.util.Util.FoundOne on match */ private void checkDuplicateSubsets(List<RelSubset> subsets, RelOptRuleOperand operand, RelNode[] rels) { final RelSubset subset = planner.getSubset(rels[operand.ordinalInRule]); if (subsets.contains(subset)) { throw Util.FoundOne.NULL; } if (!operand.getChildOperands().isEmpty()) { Stacks.push(subsets, subset); for (RelOptRuleOperand childOperand : operand.getChildOperands()) { checkDuplicateSubsets(subsets, childOperand, rels); } Stacks.pop(subsets, subset); } }
/** * Creates a rule call. * * @param planner Planner * @param operand First operand of the rule */ VolcanoRuleCall( VolcanoPlanner planner, RelOptRuleOperand operand) { this( planner, operand, new RelNode[operand.getRule().operands.size()]); }
@Override protected void onNewClass(RelNode node) { super.onNewClass(node); // Create mappings so that instances of this class will match existing // operands. final Class<? extends RelNode> clazz = node.getClass(); for (RelOptRule rule : ruleSet) { for (RelOptRuleOperand operand : rule.getOperands()) { if (operand.getMatchedClass().isAssignableFrom(clazz)) { classOperands.put(clazz, operand); } } } }
/** * Returns whether this rule is equal to another rule. * * <p>The base implementation checks that the rules have the same class and * that the operands are equal; derived classes can override. */ protected boolean equals(RelOptRule that) { // Include operands and class in the equality criteria just in case // they have chosen a poor description. return this.description.equals(that.description) && (this.getClass() == that.getClass()) && this.operand.equals(that.operand); }
/** * Builds each operand's solve-order. Start with itself, then its parent, up * to the root, then the remaining operands in prefix order. */ private void assignSolveOrder() { for (RelOptRuleOperand operand : operands) { operand.solveOrder = new int[operands.size()]; int m = 0; for (RelOptRuleOperand o = operand; o != null; o = o.getParent()) { operand.solveOrder[m++] = o.ordinalInRule; } for (int k = 0; k < operands.size(); k++) { boolean exists = false; for (int n = 0; n < m; n++) { if (operand.solveOrder[n] == k) { exists = true; } } if (!exists) { operand.solveOrder[m++] = k; } } // Assert: operand appears once in the sort-order. assert m == operands.size(); } }
Map<RelNode, List<RelNode>> nodeChildren) if (!operand.matches(rel)) { return false; RelOptRuleOperand [] childOperands = operand.getChildOperands(); if (childOperands == null) { return true;
/** * Creates a flattened list of this operand and its descendants in prefix * order. * * @param rootOperand Root operand * * @return Flattened list of operands */ private List<RelOptRuleOperand> flattenOperands( RelOptRuleOperand rootOperand) { List<RelOptRuleOperand> operandList = new ArrayList<RelOptRuleOperand>(); // Flatten the operands into a list. rootOperand.setRule(this); rootOperand.setParent(null); rootOperand.ordinalInParent = 0; rootOperand.ordinalInRule = operandList.size(); operandList.add(rootOperand); flattenRecurse(operandList, rootOperand); return ImmutableList.copyOf(operandList); }
/** * Creates a rule call. * * @param planner Planner * @param operand First operand of the rule */ VolcanoRuleCall( VolcanoPlanner planner, RelOptRuleOperand operand) { this( planner, operand, new RelNode[operand.getRule().operands.size()]); }
: subClasses(operand.getMatchedClass())) { classOperands.put(subClass, operand);
/** * Returns whether this rule is equal to another rule. * * <p>The base implementation checks that the rules have the same class and * that the operands are equal; derived classes can override. */ protected boolean equals(RelOptRule that) { // Include operands and class in the equality criteria just in case // they have chosen a poor description. return this.description.equals(that.description) && (this.getClass() == that.getClass()) && this.operand.equals(that.operand); }
/** * Builds each operand's solve-order. Start with itself, then its parent, up * to the root, then the remaining operands in prefix order. */ private void assignSolveOrder() { for (RelOptRuleOperand operand : operands) { operand.solveOrder = new int[operands.size()]; int m = 0; for (RelOptRuleOperand o = operand; o != null; o = o.getParent()) { operand.solveOrder[m++] = o.ordinalInRule; } for (int k = 0; k < operands.size(); k++) { boolean exists = false; for (int n = 0; n < m; n++) { if (operand.solveOrder[n] == k) { exists = true; } } if (!exists) { operand.solveOrder[m++] = k; } } // Assert: operand appears once in the sort-order. assert m == operands.size(); } }
List<RelNode> bindings) if (!operand.matches(rel)) { return false; RelOptRuleOperand [] childOperands = operand.getChildOperands(); if (childOperands == null) { return true;