use of org.apache.calcite.plan.RelTrait in project calcite by apache.
the class RelSet method addAbstractConverters.
private void addAbstractConverters(VolcanoPlanner planner, RelOptCluster cluster, RelSubset subset, boolean subsetToOthers) {
// we can convert. No point adding converters if it is not possible.
for (RelSubset other : subsets) {
assert other.getTraitSet().size() == subset.getTraitSet().size();
if ((other == subset) || (subsetToOthers && !subset.getConvention().useAbstractConvertersForConversion(subset.getTraitSet(), other.getTraitSet())) || (!subsetToOthers && !other.getConvention().useAbstractConvertersForConversion(other.getTraitSet(), subset.getTraitSet()))) {
continue;
}
final ImmutableList<RelTrait> difference = subset.getTraitSet().difference(other.getTraitSet());
boolean addAbstractConverter = true;
int numTraitNeedConvert = 0;
for (RelTrait curOtherTrait : difference) {
RelTraitDef traitDef = curOtherTrait.getTraitDef();
RelTrait curRelTrait = subset.getTraitSet().getTrait(traitDef);
assert curRelTrait.getTraitDef() == traitDef;
if (curRelTrait == null) {
addAbstractConverter = false;
break;
}
boolean canConvert = false;
boolean needConvert = false;
if (subsetToOthers) {
// We can convert from subset to other. So, add converter with subset as child and
// traitset as the other's traitset.
canConvert = traitDef.canConvert(cluster.getPlanner(), curRelTrait, curOtherTrait, subset);
needConvert = !curRelTrait.satisfies(curOtherTrait);
} else {
// We can convert from others to subset.
canConvert = traitDef.canConvert(cluster.getPlanner(), curOtherTrait, curRelTrait, other);
needConvert = !curOtherTrait.satisfies(curRelTrait);
}
if (!canConvert) {
addAbstractConverter = false;
break;
}
if (needConvert) {
numTraitNeedConvert++;
}
}
if (addAbstractConverter && numTraitNeedConvert > 0) {
if (subsetToOthers) {
final AbstractConverter converter = new AbstractConverter(cluster, subset, null, other.getTraitSet());
planner.register(converter, other);
} else {
final AbstractConverter converter = new AbstractConverter(cluster, other, null, subset.getTraitSet());
planner.register(converter, subset);
}
}
}
}
use of org.apache.calcite.plan.RelTrait 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.RelTrait in project calcite by apache.
the class VolcanoPlanner method completeConversion.
/**
* Converts traits using well-founded induction. We don't require that
* each conversion preserves all traits that have previously been converted,
* but if it changes "locked in" traits we'll try some other conversion.
*
* @param rel Relational expression
* @param allowInfiniteCostConverters Whether to allow infinite converters
* @param toTraits Target trait set
* @param usedTraits Traits that have been locked in
* @return Converted relational expression
*/
private RelNode completeConversion(RelNode rel, boolean allowInfiniteCostConverters, RelTraitSet toTraits, Expressions.FluentList<RelTraitDef> usedTraits) {
if (true) {
return rel;
}
for (RelTrait trait : rel.getTraitSet()) {
if (toTraits.contains(trait)) {
// We're already a match on this trait type.
continue;
}
final RelTraitDef traitDef = trait.getTraitDef();
RelNode rel2 = traitDef.convert(this, rel, toTraits.getTrait(traitDef), allowInfiniteCostConverters);
// heading for a cycle.
for (RelTraitDef usedTrait : usedTraits) {
if (!rel2.getTraitSet().contains(usedTrait)) {
continue;
}
}
// recursive call, to convert one more trait
rel = completeConversion(rel2, allowInfiniteCostConverters, toTraits, usedTraits.append(traitDef));
if (rel != null) {
return rel;
}
}
assert rel.getTraitSet().equals(toTraits);
return rel;
}
use of org.apache.calcite.plan.RelTrait in project calcite by apache.
the class VolcanoRuleMatch method guessSubset.
/**
* Returns a guess as to which subset (that is equivalence class of
* relational expressions combined with a set of physical traits) the result
* of this rule will belong to.
*
* @return expected subset, or null if we cannot guess
*/
private RelSubset guessSubset() {
if (targetSubset != null) {
return targetSubset;
}
final RelTrait targetTrait = getRule().getOutTrait();
if ((targetSet != null) && (targetTrait != null)) {
final RelTraitSet targetTraitSet = rels[0].getTraitSet().replace(targetTrait);
// Find the subset in the target set which matches the expected
// set of traits. It may not exist yet.
targetSubset = targetSet.getSubset(targetTraitSet);
return targetSubset;
}
// The target subset doesn't exist yet.
return null;
}
use of org.apache.calcite.plan.RelTrait in project calcite by apache.
the class HepPlanner method doesConverterApply.
private boolean doesConverterApply(ConverterRule converterRule, HepRelVertex vertex) {
RelTrait outTrait = converterRule.getOutTrait();
List<HepRelVertex> parents = Graphs.predecessorListOf(graph, vertex);
for (HepRelVertex parent : parents) {
RelNode parentRel = parent.getCurrentRel();
if (parentRel instanceof Converter) {
// We don't support converter chains.
continue;
}
if (parentRel.getTraitSet().contains(outTrait)) {
// This parent wants the traits produced by the converter.
return true;
}
}
return (vertex == root) && (requestedRootTraits != null) && requestedRootTraits.contains(outTrait);
}
Aggregations