org.apache.calcite.plan.RelTrait - java examples

Here are the examples of the java api org.apache.calcite.plan.RelTrait taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

25 Examples 7

19 View Complete Implementation : VolcanoRuleMatch.java
Copyright Apache License 2.0
Author : apache
/**
 * Returns a guess as to which subset (that is equivalence clreplaced 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;
}

19 View Complete Implementation : ConverterRule.java
Copyright Apache License 2.0
Author : apache
/**
 * Abstract base clreplaced for a rule which converts from one calling convention to
 * another without changing semantics.
 */
public abstract clreplaced ConverterRule extends RelOptRule {

    // ~ Instance fields --------------------------------------------------------
    private final RelTrait inTrait;

    private final RelTrait outTrait;

    // ~ Constructors -----------------------------------------------------------
    /**
     * Creates a <code>ConverterRule</code>.
     *
     * @param clazz       Type of relational expression to consider converting
     * @param in          Trait of relational expression to consider converting
     * @param out         Trait which is converted to
     * @param descriptionPrefix Description prefix of rule
     */
    public ConverterRule(Clreplaced<? extends RelNode> clazz, RelTrait in, RelTrait out, String descriptionPrefix) {
        this(clazz, (Predicate<RelNode>) r -> true, in, out, RelFactories.LOGICAL_BUILDER, descriptionPrefix);
    }

    @SuppressWarnings("Guava")
    // to be removed before 2.0
    @Deprecated
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, com.google.common.base.Predicate<? super R> predicate, RelTrait in, RelTrait out, String descriptionPrefix) {
        this(clazz, predicate, in, out, RelFactories.LOGICAL_BUILDER, descriptionPrefix);
    }

    /**
     * Creates a <code>ConverterRule</code> with a predicate.
     *
     * @param clazz       Type of relational expression to consider converting
     * @param predicate   Predicate on the relational expression
     * @param in          Trait of relational expression to consider converting
     * @param out         Trait which is converted to
     * @param relBuilderFactory Builder for relational expressions
     * @param descriptionPrefix Description prefix of rule
     */
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, Predicate<? super R> predicate, RelTrait in, RelTrait out, RelBuilderFactory relBuilderFactory, String descriptionPrefix) {
        super(convertOperand(clazz, predicate, in), relBuilderFactory, createDescription(descriptionPrefix, in, out));
        this.inTrait = Objects.requireNonNull(in);
        this.outTrait = Objects.requireNonNull(out);
        // Source and target traits must have same type
        replacedert in.getTraitDef() == out.getTraitDef();
    }

    @SuppressWarnings("Guava")
    // to be removed before 2.0
    @Deprecated
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, com.google.common.base.Predicate<? super R> predicate, RelTrait in, RelTrait out, RelBuilderFactory relBuilderFactory, String description) {
        this(clazz, (Predicate<? super R>) predicate::apply, in, out, relBuilderFactory, description);
    }

    // ~ Methods ----------------------------------------------------------------
    public Convention getOutConvention() {
        return (Convention) outTrait;
    }

    public RelTrait getOutTrait() {
        return outTrait;
    }

    public RelTrait getInTrait() {
        return inTrait;
    }

    public RelTraitDef getTraitDef() {
        return inTrait.getTraitDef();
    }

    private static String createDescription(String descriptionPrefix, RelTrait in, RelTrait out) {
        return String.format(Locale.ROOT, "%s(in:%s,out:%s)", Objects.toString(descriptionPrefix, "ConverterRule"), in, out);
    }

    /**
     * Converts a relational expression to the target trait(s) of this rule.
     *
     * <p>Returns null if conversion is not possible.
     */
    public abstract RelNode convert(RelNode rel);

    /**
     * Returns true if this rule can convert <em>any</em> relational expression
     * of the input convention.
     *
     * <p>The union-to-java converter, for example, is not guaranteed, because
     * it only works on unions.</p>
     *
     * @return {@code true} if this rule can convert <em>any</em> relational
     *   expression
     */
    public boolean isGuaranteed() {
        return false;
    }

    public void onMatch(RelOptRuleCall call) {
        RelNode rel = call.rel(0);
        if (rel.getTraitSet().contains(inTrait)) {
            final RelNode converted = convert(rel);
            if (converted != null) {
                call.transformTo(converted);
            }
        }
    }
    // ~ Inner Clreplacedes ----------------------------------------------------------
}

19 View Complete Implementation : RelCollationImpl.java
Copyright Apache License 2.0
Author : apache
public boolean satisfies(RelTrait trait) {
    return this == trait || trait instanceof RelCollationImpl && Util.startsWith(fieldCollations, ((RelCollationImpl) trait).fieldCollations);
}

19 View Complete Implementation : ConverterRule.java
Copyright Apache License 2.0
Author : lealone
/**
 * Abstract base clreplaced for a rule which converts from one calling convention to
 * another without changing semantics.
 */
public abstract clreplaced ConverterRule extends RelOptRule {

    // ~ Instance fields --------------------------------------------------------
    private final RelTrait inTrait;

    private final RelTrait outTrait;

    // ~ Constructors -----------------------------------------------------------
    /**
     * Creates a <code>ConverterRule</code>.
     *
     * @param clazz       Type of relational expression to consider converting
     * @param in          Trait of relational expression to consider converting
     * @param out         Trait which is converted to
     * @param description Description of rule
     */
    public ConverterRule(Clreplaced<? extends RelNode> clazz, RelTrait in, RelTrait out, String description) {
        this(clazz, (Predicate<RelNode>) r -> true, in, out, RelFactories.LOGICAL_BUILDER, description);
    }

    @SuppressWarnings("Guava")
    // to be removed before 2.0
    @Deprecated
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, com.google.common.base.Predicate<? super R> predicate, RelTrait in, RelTrait out, String description) {
        this(clazz, predicate, in, out, RelFactories.LOGICAL_BUILDER, description);
    }

    /**
     * Creates a <code>ConverterRule</code> with a predicate.
     *
     * @param clazz       Type of relational expression to consider converting
     * @param predicate   Predicate on the relational expression
     * @param in          Trait of relational expression to consider converting
     * @param out         Trait which is converted to
     * @param relBuilderFactory Builder for relational expressions
     * @param description Description of rule
     */
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, Predicate<? super R> predicate, RelTrait in, RelTrait out, RelBuilderFactory relBuilderFactory, String description) {
        super(convertOperand(clazz, predicate, in), relBuilderFactory, description == null ? "ConverterRule<in=" + in + ",out=" + out + ">" : description);
        this.inTrait = Objects.requireNonNull(in);
        this.outTrait = Objects.requireNonNull(out);
        // Source and target traits must have same type
        replacedert in.getTraitDef() == out.getTraitDef();
    }

    @SuppressWarnings("Guava")
    // to be removed before 2.0
    @Deprecated
    public <R extends RelNode> ConverterRule(Clreplaced<R> clazz, com.google.common.base.Predicate<? super R> predicate, RelTrait in, RelTrait out, RelBuilderFactory relBuilderFactory, String description) {
        this(clazz, (Predicate<? super R>) predicate::apply, in, out, relBuilderFactory, description);
    }

    // ~ Methods ----------------------------------------------------------------
    public Convention getOutConvention() {
        return (Convention) outTrait;
    }

    public RelTrait getOutTrait() {
        return outTrait;
    }

    public RelTrait getInTrait() {
        return inTrait;
    }

    public RelTraitDef getTraitDef() {
        return inTrait.getTraitDef();
    }

    /**
     * Converts a relational expression to the target trait(s) of this rule.
     *
     * <p>Returns null if conversion is not possible.
     */
    public abstract RelNode convert(RelNode rel);

    /**
     * Returns true if this rule can convert <em>any</em> relational expression
     * of the input convention.
     *
     * <p>The union-to-java converter, for example, is not guaranteed, because
     * it only works on unions.</p>
     *
     * @return {@code true} if this rule can convert <em>any</em> relational
     *   expression
     */
    public boolean isGuaranteed() {
        return false;
    }

    public void onMatch(RelOptRuleCall call) {
        RelNode rel = call.rel(0);
        if (rel.getTraitSet().contains(inTrait)) {
            final RelNode converted = convert(rel);
            if (converted != null) {
                call.transformTo(converted);
            }
        }
    }
    // ~ Inner Clreplacedes ----------------------------------------------------------
}

18 View Complete Implementation : AbstractConverter.java
Copyright Apache License 2.0
Author : apache
public RelWriter explainTerms(RelWriter pw) {
    super.explainTerms(pw);
    for (RelTrait trait : traitSet) {
        pw.item(trait.getTraitDef().getSimpleName(), trait);
    }
    return pw;
}

18 View Complete Implementation : DrillDistributionTrait.java
Copyright Apache License 2.0
Author : apache
@Override
public boolean satisfies(RelTrait trait) {
    if (trait instanceof DrillDistributionTrait) {
        DistributionType requiredDist = ((DrillDistributionTrait) trait).getType();
        if (requiredDist == DistributionType.ANY) {
            return true;
        }
        if (this.type == DistributionType.HASH_DISTRIBUTED) {
            if (requiredDist == DistributionType.HASH_DISTRIBUTED) {
                // A subset of the required distribution columns can satisfy (subsume) the requirement
                // e.g: required distribution: {a, b, c}
                // Following can satisfy the requirements: {a}, {b}, {c}, {a, b}, {b, c}, {a, c} or {a, b, c}
                // New: Use equals for subsumes check of hash distribution. If we uses subsumes,
                // a join may end up with hash-distributions using different keys. This would
                // cause incorrect query result.
                return this.equals(trait);
            } else if (requiredDist == DistributionType.RANDOM_DISTRIBUTED) {
                // hash distribution subsumes random distribution and ANY distribution
                return true;
            }
        }
        if (this.type == DistributionType.RANGE_DISTRIBUTED) {
            if (requiredDist == DistributionType.RANDOM_DISTRIBUTED) {
                // RANGE_DISTRIBUTED distribution subsumes random distribution and ANY distribution
                return true;
            }
        }
    }
    return this.equals(trait);
}

18 View Complete Implementation : SubsetTransformer.java
Copyright Apache License 2.0
Author : apache
public RelTraitSet newTraitSet(RelTrait... traits) {
    RelTraitSet set = call.getPlanner().emptyTraitSet();
    for (RelTrait t : traits) {
        set = set.plus(t);
    }
    return set;
}

18 View Complete Implementation : DruidConvention.java
Copyright Apache License 2.0
Author : apache
@Override
public boolean satisfies(RelTrait trait) {
    return trait == this;
}

18 View Complete Implementation : OLAPLimitRel.java
Copyright Apache License 2.0
Author : apache
@Override
public RelTraitSet replaceTraitSet(RelTrait trait) {
    RelTraitSet oldTraitSet = this.traitSet;
    this.traitSet = this.traitSet.replace(trait);
    return oldTraitSet;
}

18 View Complete Implementation : DistributionTrait.java
Copyright Apache License 2.0
Author : dremio
@Override
public boolean satisfies(RelTrait trait) {
    if (trait instanceof DistributionTrait) {
        DistributionType requiredDist = ((DistributionTrait) trait).getType();
        if (requiredDist == DistributionType.ANY) {
            return true;
        }
        if (this.type == DistributionType.HASH_DISTRIBUTED) {
            if (requiredDist == DistributionType.HASH_DISTRIBUTED) {
                // A subset of the required distribution columns can satisfy (subsume) the requirement
                // e.g: required distribution: {a, b, c}
                // Following can satisfy the requirements: {a}, {b}, {c}, {a, b}, {b, c}, {a, c} or {a, b, c}
                // New: Use equals for subsumes check of hash distribution. If we uses subsumes,
                // a join may end up with hash-distributions using different keys. This would
                // cause incorrect query result.
                return this.equals(trait);
            }
        }
    }
    return this.equals(trait);
}

18 View Complete Implementation : NestedLoopJoinPrule.java
Copyright Apache License 2.0
Author : dremio
/**
 * Convert to a set of new traits based on overriding the existing traits of the provided node
 *
 * TODO: evaluate if we should move this to Prule for other uses.
 *
 * See DX-17835 for further details of why this was introduced.
 *
 * @param rel The rel node to start with (and use as a basis for traits)
 * @param traits The ordered list of traits to convert to.
 * @return The converted node that incldues application of all the traits.
 */
private static RelNode convert(RelNode rel, RelTrait... traits) {
    for (RelTrait t : traits) {
        rel = convert(rel, rel.getTraitSet().plus(t));
    }
    return rel;
}

17 View Complete Implementation : RelSubset.java
Copyright Apache License 2.0
Author : apache
@Override
protected String computeDigest() {
    StringBuilder digest = new StringBuilder("Subset#");
    digest.append(set.id);
    for (RelTrait trait : traitSet) {
        digest.append('.').append(trait);
    }
    return digest.toString();
}

17 View Complete Implementation : ConverterRule.java
Copyright Apache License 2.0
Author : apache
private static String createDescription(String descriptionPrefix, RelTrait in, RelTrait out) {
    return String.format(Locale.ROOT, "%s(in:%s,out:%s)", Objects.toString(descriptionPrefix, "ConverterRule"), in, out);
}

17 View Complete Implementation : AbstractIndexPlanGenerator.java
Copyright Apache License 2.0
Author : apache
public RelTraitSet newTraitSet(RelTrait... traits) {
    RelTraitSet set = indexContext.getCall().getPlanner().emptyTraitSet();
    for (RelTrait t : traits) {
        if (t != null) {
            set = set.plus(t);
        }
    }
    return set;
}

17 View Complete Implementation : RelOptHelper.java
Copyright Apache License 2.0
Author : apache
public static RelOptRuleOperand any(Clreplaced<? extends RelNode> first, RelTrait trait) {
    return RelOptRule.operand(first, trait, RelOptRule.any());
}

17 View Complete Implementation : PrelUtil.java
Copyright Apache License 2.0
Author : apache
// DRILL-6089 make sure no collations are added to HashJoin
public static RelTraitSet removeCollation(RelTraitSet traitSet, RelOptRuleCall call) {
    RelTraitSet newTraitSet = call.getPlanner().emptyTraitSet();
    for (RelTrait trait : traitSet) {
        if (!trait.getTraitDef().getTraitClreplaced().equals(RelCollation.clreplaced)) {
            newTraitSet = newTraitSet.plus(trait);
        }
    }
    return newTraitSet;
}

16 View Complete Implementation : RelSet.java
Copyright Apache License 2.0
Author : apache
private void addAbstractConverters(VolcanoPlanner planner, RelOptCluster cluster, RelSubset subset, boolean subsetToOthers) {
    // Converters from newly introduced subset to all the remaining one (vice versa), only if
    // we can convert.  No point adding converters if it is not possible.
    for (RelSubset other : subsets) {
        replacedert 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);
            if (curRelTrait == null) {
                addAbstractConverter = false;
                break;
            }
            replacedert curRelTrait.getTraitDef() == traitDef;
            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);
            }
        }
    }
}

16 View Complete Implementation : RelOptHelper.java
Copyright Apache License 2.0
Author : apache
public static RelOptRuleOperand some(Clreplaced<? extends RelNode> rel, RelTrait trait, RelOptRuleOperand first, RelOptRuleOperand... rest) {
    return RelOptRule.operand(rel, trait, RelOptRule.some(first, rest));
}

16 View Complete Implementation : RelSet.java
Copyright Apache License 2.0
Author : lealone
private void addAbstractConverters(VolcanoPlanner planner, RelOptCluster cluster, RelSubset subset, boolean subsetToOthers) {
    // Converters from newly introduced subset to all the remaining one (vice versa), only if
    // we can convert.  No point adding converters if it is not possible.
    for (RelSubset other : subsets) {
        replacedert 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);
            replacedert 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);
            }
        }
    }
}

16 View Complete Implementation : RelSet.java
Copyright Apache License 2.0
Author : lealone
/**
 * Adds an expression <code>rel</code> to this set, without creating a
 * {@link org.apache.calcite.plan.volcano.RelSubset}. (Called only from
 * {@link org.apache.calcite.plan.volcano.RelSubset#add}.
 *
 * @param rel Relational expression
 */
void addInternal(RelNode rel) {
    if (!rels.contains(rel)) {
        rels.add(rel);
        for (RelTrait trait : rel.getTraitSet()) {
            replacedert trait == trait.getTraitDef().canonize(trait);
        }
        VolcanoPlanner planner = (VolcanoPlanner) rel.getCluster().getPlanner();
        if (planner.listener != null) {
            postEquivalenceEvent(planner, rel);
        }
    }
    if (this.rel == null) {
        this.rel = rel;
    } else {
        // Row types must be the same, except for field names.
        RelOptUtil.verifyTypeEquivalence(this.rel, rel, this);
    }
}

14 View Complete Implementation : HepPlanner.java
Copyright Apache License 2.0
Author : apache
private HepRelVertex applyRule(RelOptRule rule, HepRelVertex vertex, boolean forceConversions) {
    if (!belongsToDag(vertex)) {
        return null;
    }
    RelTrait parentTrait = null;
    List<RelNode> parents = null;
    if (rule instanceof ConverterRule) {
        // Guaranteed converter rules require special casing to make sure
        // they only fire where actually needed, otherwise they tend to
        // fire to infinity and beyond.
        ConverterRule converterRule = (ConverterRule) rule;
        if (converterRule.isGuaranteed() || !forceConversions) {
            if (!doesConverterApply(converterRule, vertex)) {
                return null;
            }
            parentTrait = converterRule.getOutTrait();
        }
    } else if (rule instanceof CommonRelSubExprRule) {
        // Only fire CommonRelSubExprRules if the vertex is a common
        // subexpression.
        List<HepRelVertex> parentVertices = getVertexParents(vertex);
        if (parentVertices.size() < 2) {
            return null;
        }
        parents = new ArrayList<>();
        for (HepRelVertex pVertex : parentVertices) {
            parents.add(pVertex.getCurrentRel());
        }
    }
    final List<RelNode> bindings = new ArrayList<>();
    final Map<RelNode, List<RelNode>> nodeChildren = new HashMap<>();
    boolean match = matchOperands(rule.getOperand(), vertex.getCurrentRel(), bindings, nodeChildren);
    if (!match) {
        return null;
    }
    HepRuleCall call = new HepRuleCall(this, rule.getOperand(), bindings.toArray(new RelNode[0]), nodeChildren, parents);
    // Allow the rule to apply its own side-conditions.
    if (!rule.matches(call)) {
        return null;
    }
    fireRule(call);
    if (!call.getResults().isEmpty()) {
        return applyTransformationResults(vertex, call, parentTrait);
    }
    return null;
}

13 View Complete Implementation : HepPlanner.java
Copyright Apache License 2.0
Author : apache
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);
}

12 View Complete Implementation : HepPlanner.java
Copyright Apache License 2.0
Author : apache
private HepRelVertex applyTransformationResults(HepRelVertex vertex, HepRuleCall call, RelTrait parentTrait) {
    // TODO jvs 5-Apr-2006:  Take the one that gives the best
    // global cost rather than the best local cost.  That requires
    // "tentative" graph edits.
    replacedert !call.getResults().isEmpty();
    RelNode bestRel = null;
    if (call.getResults().size() == 1) {
        // No costing required; skip it to minimize the chance of hitting
        // rels without cost information.
        bestRel = call.getResults().get(0);
    } else {
        RelOptCost bestCost = null;
        final RelMetadataQuery mq = call.getMetadataQuery();
        for (RelNode rel : call.getResults()) {
            RelOptCost thisCost = getCost(rel, mq);
            if (LOGGER.isTraceEnabled()) {
                // Keep in the isTraceEnabled for the getRowCount method call
                LOGGER.trace("considering {} with replacedulative cost={} and rowcount={}", rel, thisCost, mq.getRowCount(rel));
            }
            if ((bestRel == null) || thisCost.isLt(bestCost)) {
                bestRel = rel;
                bestCost = thisCost;
            }
        }
    }
    ++nTransformations;
    notifyTransformation(call, bestRel, true);
    // Before we add the result, make a copy of the list of vertex's
    // parents.  We'll need this later during contraction so that
    // we only update the existing parents, not the new parents
    // (otherwise loops can result).  Also take care of filtering
    // out parents by traits in case we're dealing with a converter rule.
    final List<HepRelVertex> allParents = Graphs.predecessorListOf(graph, vertex);
    final List<HepRelVertex> parents = new ArrayList<>();
    for (HepRelVertex parent : allParents) {
        if (parentTrait != null) {
            RelNode parentRel = parent.getCurrentRel();
            if (parentRel instanceof Converter) {
                // We don't support automatically chaining conversions.
                // Treating a converter as a candidate parent here
                // can cause the "iParentMatch" check below to
                // throw away a new converter needed in
                // the multi-parent DAG case.
                continue;
            }
            if (!parentRel.getTraitSet().contains(parentTrait)) {
                // This parent does not want the converted result.
                continue;
            }
        }
        parents.add(parent);
    }
    HepRelVertex newVertex = addRelToGraph(bestRel);
    // There's a chance that newVertex is the same as one
    // of the parents due to common subexpression recognition
    // (e.g. the LogicalProject added by JoinCommuteRule).  In that
    // case, treat the transformation as a nop to avoid
    // creating a loop.
    int iParentMatch = parents.indexOf(newVertex);
    if (iParentMatch != -1) {
        newVertex = parents.get(iParentMatch);
    } else {
        contractVertices(newVertex, vertex, parents);
    }
    if (getListener() != null) {
        // replacedume listener doesn't want to see garbage.
        collectGarbage();
    }
    notifyTransformation(call, bestRel, false);
    dumpGraph();
    return newVertex;
}

12 View Complete Implementation : HashJoinPrel.java
Copyright Apache License 2.0
Author : apache
private static boolean validateTraits(RelTraitSet traitSet, RelNode left, RelNode right) {
    ImmutableBitSet bitSet = ImmutableBitSet.range(left.getRowType().getFieldCount(), left.getRowType().getFieldCount() + right.getRowType().getFieldCount());
    for (RelTrait trait : traitSet) {
        if (trait.getTraitDef().getTraitClreplaced().equals(RelCollation.clreplaced)) {
            RelCollation collationTrait = (RelCollation) trait;
            for (RelFieldCollation field : collationTrait.getFieldCollations()) {
                if (bitSet.indexOf(field.getFieldIndex()) > 0) {
                    return false;
                }
            }
        } else if (trait.getTraitDef().getTraitClreplaced().equals(DrillDistributionTrait.clreplaced)) {
            DrillDistributionTrait distributionTrait = (DrillDistributionTrait) trait;
            for (DrillDistributionTrait.DistributionField field : distributionTrait.getFields()) {
                if (bitSet.indexOf(field.getFieldId()) > 0) {
                    return false;
                }
            }
        }
    }
    return true;
}

6 View Complete Implementation : MapRDBPushProjectIntoScan.java
Copyright Apache License 2.0
Author : apache
protected void doPushProjectIntoGroupScan(RelOptRuleCall call, ProjectPrel project, ScanPrel scan, JsonTableGroupScan groupScan) {
    try {
        DrillRelOptUtil.ProjectPushInfo columnInfo = DrillRelOptUtil.getFieldsInformation(scan.getRowType(), project.getProjects());
        if (columnInfo == null || Utilities.isStarQuery(columnInfo.getFields()) || !groupScan.canPushdownProjects(columnInfo.getFields())) {
            return;
        }
        RelTraitSet newTraits = call.getPlanner().emptyTraitSet();
        // Clear out collation trait
        for (RelTrait trait : scan.getTraitSet()) {
            if (!(trait instanceof RelCollation)) {
                newTraits.plus(trait);
            }
        }
        final ScanPrel newScan = new ScanPrel(scan.getCluster(), newTraits.plus(Prel.DRILL_PHYSICAL), groupScan.clone(columnInfo.getFields()), columnInfo.createNewRowType(project.getInput().getCluster().getTypeFactory()), scan.getTable());
        List<RexNode> newProjects = Lists.newArrayList();
        for (RexNode n : project.getChildExps()) {
            newProjects.add(n.accept(columnInfo.getInputReWriter()));
        }
        final ProjectPrel newProj = new ProjectPrel(project.getCluster(), project.getTraitSet().plus(Prel.DRILL_PHYSICAL), newScan, newProjects, project.getRowType());
        if (ProjectRemoveRule.isTrivial(newProj) && // the old project did not involve any column renaming
        sameRowTypeProjectionsFields(project.getRowType(), newScan.getRowType())) {
            call.transformTo(newScan);
        } else {
            call.transformTo(newProj);
        }
    } catch (Exception e) {
        throw new DrillRuntimeException(e);
    }
}