use of org.apache.calcite.plan.RelOptRuleOperand in project calcite by apache.
the class VolcanoPlanner method addRule.
public boolean addRule(RelOptRule rule) {
if (locked) {
return false;
}
if (ruleSet.contains(rule)) {
// Rule already exists.
return false;
}
final boolean added = ruleSet.add(rule);
assert added;
final String ruleName = rule.toString();
if (ruleNames.put(ruleName, rule.getClass())) {
Set<Class> x = ruleNames.get(ruleName);
if (x.size() > 1) {
throw new RuntimeException("Rule description '" + ruleName + "' is not unique; classes: " + x);
}
}
mapRuleDescription(rule);
// it.
for (RelOptRuleOperand operand : rule.getOperands()) {
for (Class<? extends RelNode> subClass : subClasses(operand.getMatchedClass())) {
classOperands.put(subClass, operand);
}
}
// with the trait.
if (rule instanceof ConverterRule) {
ConverterRule converterRule = (ConverterRule) rule;
final RelTrait ruleTrait = converterRule.getInTrait();
final RelTraitDef ruleTraitDef = ruleTrait.getTraitDef();
if (traitDefs.contains(ruleTraitDef)) {
ruleTraitDef.registerConverterRule(this, converterRule);
}
}
return true;
}
use of org.apache.calcite.plan.RelOptRuleOperand in project calcite by apache.
the class VolcanoRuleCall method matchRecurse.
/**
* Recursively matches operands above a given solve order.
*
* @param solve Solve order of operand (> 0 and ≤ the operand count)
*/
private void matchRecurse(int solve) {
assert solve > 0;
assert solve <= rule.operands.size();
final List<RelOptRuleOperand> operands = getRule().operands;
if (solve == operands.size()) {
// If the side-conditions are satisfied, we have a match.
if (getRule().matches(this)) {
onMatch();
}
} else {
final int operandOrdinal = operand0.solveOrder[solve];
final int previousOperandOrdinal = operand0.solveOrder[solve - 1];
boolean ascending = operandOrdinal < previousOperandOrdinal;
final RelOptRuleOperand previousOperand = operands.get(previousOperandOrdinal);
final RelOptRuleOperand operand = operands.get(operandOrdinal);
final RelNode previous = rels[previousOperandOrdinal];
final RelOptRuleOperand parentOperand;
final Collection<? extends RelNode> successors;
if (ascending) {
assert previousOperand.getParent() == operand;
parentOperand = operand;
final RelSubset subset = volcanoPlanner.getSubset(previous);
successors = subset.getParentRels();
} else {
parentOperand = previousOperand;
final int parentOrdinal = operand.getParent().ordinalInRule;
final RelNode parentRel = rels[parentOrdinal];
final List<RelNode> inputs = parentRel.getInputs();
if (operand.ordinalInParent < inputs.size()) {
final RelSubset subset = (RelSubset) inputs.get(operand.ordinalInParent);
if (operand.getMatchedClass() == RelSubset.class) {
successors = subset.set.subsets;
} else {
successors = subset.getRelList();
}
} else {
// The operand expects parentRel to have a certain number
// of inputs and it does not.
successors = ImmutableList.of();
}
}
for (RelNode rel : successors) {
if (!operand.matches(rel)) {
continue;
}
if (ascending) {
// We know that the previous operand was *a* child of its parent,
// but now check that it is the *correct* child.
final RelSubset input = (RelSubset) rel.getInput(previousOperand.ordinalInParent);
List<RelNode> inputRels = input.set.getRelsFromAllSubsets();
if (!inputRels.contains(previous)) {
continue;
}
}
// Assign "childRels" if the operand is UNORDERED.
switch(parentOperand.childPolicy) {
case UNORDERED:
if (ascending) {
final List<RelNode> inputs = Lists.newArrayList(rel.getInputs());
inputs.set(previousOperand.ordinalInParent, previous);
setChildRels(rel, inputs);
} else {
List<RelNode> inputs = getChildRels(previous);
if (inputs == null) {
inputs = Lists.newArrayList(previous.getInputs());
}
inputs.set(operand.ordinalInParent, rel);
setChildRels(previous, inputs);
}
}
rels[operandOrdinal] = rel;
matchRecurse(solve + 1);
}
}
}
Aggregations