Search in sources :

Example 6 with RelOptRuleOperand

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;
}
Also used : RelOptRuleOperand(org.apache.calcite.plan.RelOptRuleOperand) ConverterRule(org.apache.calcite.rel.convert.ConverterRule) RelTrait(org.apache.calcite.plan.RelTrait) RelTraitDef(org.apache.calcite.plan.RelTraitDef)

Example 7 with RelOptRuleOperand

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 (&gt; 0 and &le; 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);
        }
    }
}
Also used : RelOptRuleOperand(org.apache.calcite.plan.RelOptRuleOperand) RelNode(org.apache.calcite.rel.RelNode)

Aggregations

RelOptRuleOperand (org.apache.calcite.plan.RelOptRuleOperand)7 RelTrait (org.apache.calcite.plan.RelTrait)2 RelTraitDef (org.apache.calcite.plan.RelTraitDef)2 RelNode (org.apache.calcite.rel.RelNode)2 ConverterRule (org.apache.calcite.rel.convert.ConverterRule)2 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 RelOptRule (org.apache.calcite.plan.RelOptRule)1