/** * Creates a rule with an explicit description. * * @param operand root operand, must not be null * * @param description Description, or null to guess description */ public RelOptRule(RelOptRuleOperand operand, String description) { assert operand != null; this.operand = operand; if (description == null) { description = guessDescription(getClass().getName()); } this.description = description; this.operands = flattenOperands(operand); assignSolveOrder(); }
/** * Converts a list of relational expressions. * * @param rels Relational expressions * @param traitSet Trait set to apply to each relational expression * @return List of converted relational expressions, or null if any could * not be converted */ public static List<RelNode> convertList( List<RelNode> rels, RelTraitSet traitSet) { final List<RelNode> list = new ArrayList<RelNode>(); for (RelNode rel : rels) { list.add(convert(rel, traitSet)); } return list; }
rule.getOperand(), rel, bindings)) new MockRuleCall( this, rule.getOperand(), bindings.toArray(new RelNode[bindings.size()])); if (rule.matches(call)) { rule.onMatch(call);
boolean match = matchOperands( rule.getOperand(), vertex.getCurrentRel(), bindings, new HepRuleCall( this, rule.getOperand(), bindings.toArray(new RelNode[bindings.size()]), nodeChildren, if (!rule.matches(call)) { return null;
@Override public boolean matches(RelOptRuleCall call) { if (!super.matches(call)) { return false; } AggregateRelBase oldAggRel = (AggregateRelBase) call.rels[0]; return containsAvgStddevVarCall(oldAggRel.getAggCallList()); }
/** * Tests the rules for how we name rules. */ @Test public void testRuleGuessDescription() { assertEquals("Bar", RelOptRule.guessDescription("com.foo.Bar")); assertEquals("Baz", RelOptRule.guessDescription("com.flatten.Bar$Baz")); // yields "1" (which as an integer is an invalid try { Util.discard(RelOptRule.guessDescription("com.foo.Bar$1")); fail("expected exception"); } catch (RuntimeException e) { assertEquals( "Derived description of rule class com.foo.Bar$1 is an " + "integer, not valid. Supply a description manually.", e.getMessage()); } } }
/** Returns whether to skip a match. This happens if any of the * {@link RelNode}s have importance zero. */ private boolean skipMatch(VolcanoRuleMatch match) { for (RelNode rel : match.rels) { Double importance = planner.relImportances.get(rel); if (importance != null && importance == 0d) { return true; } } // If the same subset appears more than once along any path from root // operand to a leaf operand, we have matched a cycle. A relational // expression that consumes its own output can never be implemented, and // furthermore, if we fire rules on it we may generate lots of garbage. // For example, if // Project(A, X = X + 0) // is in the same subset as A, then we would generate // Project(A, X = X + 0 + 0) // Project(A, X = X + 0 + 0 + 0) // also in the same subset. They are valid but useless. final List<RelSubset> subsets = new ArrayList<RelSubset>(); try { checkDuplicateSubsets(subsets, match.rule.getOperand(), match.rels); } catch (Util.FoundOne e) { return true; } return false; }
public boolean equals(Object obj) { return (obj instanceof RelOptRule) && equals((RelOptRule) obj); }
/** * 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 an operand that matches a relational expression that has any * number of children. * * @param clazz Class of relational expression to match (must not be null) * @return Operand */ public static RelOptRuleOperand any( Class<? extends RelNode> clazz) { return any(clazz, null); }
List<RelNode> bindings = new ArrayList<RelNode>(); if (match( rule.getOperand(), rel, bindings)) { new MockRuleCall( this, rule.getOperand(), bindings.toArray(new RelNode[bindings.size()])); if (rule.matches(call)) { rule.onMatch(call);
boolean match = matchOperands( rule.getOperand(), vertex.getCurrentRel(), bindings, new HepRuleCall( this, rule.getOperand(), bindings.toArray(new RelNode[bindings.size()]), nodeChildren, if (!rule.matches(call)) { return null;
assert match.getRule().matches(match); match.onMatch();
/** * Tests the rules for how we name rules. */ @Test public void testRuleGuessDescription() { assertEquals("Bar", RelOptRule.guessDescription("com.foo.Bar")); assertEquals("Baz", RelOptRule.guessDescription("com.flatten.Bar$Baz")); // yields "1" (which as an integer is an invalid try { Util.discard(RelOptRule.guessDescription("com.foo.Bar$1")); fail("expected exception"); } catch (RuntimeException e) { assertEquals( "Derived description of rule class com.foo.Bar$1 is an " + "integer, not valid. Supply a description manually.", e.getMessage()); } } }
public boolean equals(Object obj) { return (obj instanceof RelOptRule) && equals((RelOptRule) obj); }
/** * 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); }
public ConverterRelOptRuleOperand( Class<? extends RelNode> clazz, RelTrait in) { super(clazz, in, any()); }