Search in sources :

Example 56 with RelCollation

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.

the class EnumerableMergeJoinRule method convert.

@Override
public RelNode convert(RelNode rel) {
    LogicalJoin join = (LogicalJoin) rel;
    final JoinInfo info = JoinInfo.of(join.getLeft(), join.getRight(), join.getCondition());
    if (join.getJoinType() != JoinRelType.INNER) {
        // (It supports non-equi join, using a post-filter; see below.)
        return null;
    }
    if (info.pairs().size() == 0) {
        // EnumerableMergeJoin CAN support cartesian join, but disable it for now.
        return null;
    }
    final List<RelNode> newInputs = Lists.newArrayList();
    final List<RelCollation> collations = Lists.newArrayList();
    int offset = 0;
    for (Ord<RelNode> ord : Ord.zip(join.getInputs())) {
        RelTraitSet traits = ord.e.getTraitSet().replace(EnumerableConvention.INSTANCE);
        if (!info.pairs().isEmpty()) {
            final List<RelFieldCollation> fieldCollations = Lists.newArrayList();
            for (int key : info.keys().get(ord.i)) {
                fieldCollations.add(new RelFieldCollation(key, RelFieldCollation.Direction.ASCENDING, RelFieldCollation.NullDirection.LAST));
            }
            final RelCollation collation = RelCollations.of(fieldCollations);
            collations.add(RelCollations.shift(collation, offset));
            traits = traits.replace(collation);
        }
        newInputs.add(convert(ord.e, traits));
        offset += ord.e.getRowType().getFieldCount();
    }
    final RelNode left = newInputs.get(0);
    final RelNode right = newInputs.get(1);
    final RelOptCluster cluster = join.getCluster();
    RelNode newRel;
    try {
        RelTraitSet traits = join.getTraitSet().replace(EnumerableConvention.INSTANCE);
        if (!collations.isEmpty()) {
            traits = traits.replace(collations);
        }
        newRel = new EnumerableMergeJoin(cluster, traits, left, right, info.getEquiCondition(left, right, cluster.getRexBuilder()), info.leftKeys, info.rightKeys, join.getVariablesSet(), join.getJoinType());
    } catch (InvalidRelException e) {
        EnumerableRules.LOGGER.debug(e.toString());
        return null;
    }
    if (!info.isEqui()) {
        newRel = new EnumerableFilter(cluster, newRel.getTraitSet(), newRel, info.getRemaining(cluster.getRexBuilder()));
    }
    return newRel;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) InvalidRelException(org.apache.calcite.rel.InvalidRelException) RelTraitSet(org.apache.calcite.plan.RelTraitSet) JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation)

Example 57 with RelCollation

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.

the class CloneSchema method createCloneTable.

public static <T> Table createCloneTable(final JavaTypeFactory typeFactory, final RelProtoDataType protoRowType, final List<RelCollation> collations, final List<ColumnMetaData.Rep> repList, final Enumerable<T> source) {
    final Type elementType;
    if (source instanceof QueryableTable) {
        elementType = ((QueryableTable) source).getElementType();
    } else if (protoRowType.apply(typeFactory).getFieldCount() == 1) {
        if (repList != null) {
            elementType = repList.get(0).clazz;
        } else {
            elementType = Object.class;
        }
    } else {
        elementType = Object[].class;
    }
    return new ArrayTable(elementType, protoRowType, Suppliers.memoize(new Supplier<ArrayTable.Content>() {

        public ArrayTable.Content get() {
            final ColumnLoader loader = new ColumnLoader<>(typeFactory, source, protoRowType, repList);
            final List<RelCollation> collation2 = collations.isEmpty() && loader.sortField >= 0 ? RelCollations.createSingleton(loader.sortField) : collations;
            return new ArrayTable.Content(loader.representationValues, loader.size(), collation2);
        }
    }));
}
Also used : QueryableTable(org.apache.calcite.schema.QueryableTable) RelProtoDataType(org.apache.calcite.rel.type.RelProtoDataType) Type(java.lang.reflect.Type) RelCollation(org.apache.calcite.rel.RelCollation) Supplier(com.google.common.base.Supplier)

Example 58 with RelCollation

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.

the class RelMdUtil method checkInputForCollationAndLimit.

/**
 * Returns whether a relational expression is already sorted and has fewer
 * rows than the sum of offset and limit.
 *
 * <p>If this is the case, it is safe to push down a
 * {@link org.apache.calcite.rel.core.Sort} with limit and optional offset.
 */
public static boolean checkInputForCollationAndLimit(RelMetadataQuery mq, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) {
    // Check if the input is already sorted
    boolean alreadySorted = collation.getFieldCollations().isEmpty();
    for (RelCollation inputCollation : mq.collations(input)) {
        if (inputCollation.satisfies(collation)) {
            alreadySorted = true;
            break;
        }
    }
    // Check if we are not reducing the number of tuples
    boolean alreadySmaller = true;
    final Double rowCount = mq.getMaxRowCount(input);
    if (rowCount != null && fetch != null) {
        final int offsetVal = offset == null ? 0 : RexLiteral.intValue(offset);
        final int limit = RexLiteral.intValue(fetch);
        if ((double) offsetVal + (double) limit < rowCount) {
            alreadySmaller = false;
        }
    }
    return alreadySorted && alreadySmaller;
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation)

Example 59 with RelCollation

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.

the class RelMdCollation method mergeJoin.

/**
 * Helper method to determine a {@link Join}'s collation assuming that it
 * uses a merge-join algorithm.
 *
 * <p>If the inputs are sorted on other keys <em>in addition to</em> the join
 * key, the result preserves those collations too.
 */
public static List<RelCollation> mergeJoin(RelMetadataQuery mq, RelNode left, RelNode right, ImmutableIntList leftKeys, ImmutableIntList rightKeys) {
    final ImmutableList.Builder<RelCollation> builder = ImmutableList.builder();
    final ImmutableList<RelCollation> leftCollations = mq.collations(left);
    assert RelCollations.contains(leftCollations, leftKeys) : "cannot merge join: left input is not sorted on left keys";
    builder.addAll(leftCollations);
    final ImmutableList<RelCollation> rightCollations = mq.collations(right);
    assert RelCollations.contains(rightCollations, rightKeys) : "cannot merge join: right input is not sorted on right keys";
    final int leftFieldCount = left.getRowType().getFieldCount();
    for (RelCollation collation : rightCollations) {
        builder.add(RelCollations.shift(collation, leftFieldCount));
    }
    return builder.build();
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation) ImmutableList(com.google.common.collect.ImmutableList)

Example 60 with RelCollation

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.

the class RelMdCollation method project.

/**
 * Helper method to determine a {@link Project}'s collation.
 */
public static List<RelCollation> project(RelMetadataQuery mq, RelNode input, List<? extends RexNode> projects) {
    final SortedSet<RelCollation> collations = new TreeSet<>();
    final List<RelCollation> inputCollations = mq.collations(input);
    if (inputCollations == null || inputCollations.isEmpty()) {
        return ImmutableList.of();
    }
    final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
    final Map<Integer, SqlMonotonicity> targetsWithMonotonicity = new HashMap<>();
    for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
        if (project.e instanceof RexInputRef) {
            targets.put(((RexInputRef) project.e).getIndex(), project.i);
        } else if (project.e instanceof RexCall) {
            final RexCall call = (RexCall) project.e;
            final RexCallBinding binding = RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
            targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
        }
    }
    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
    loop: for (RelCollation ic : inputCollations) {
        if (ic.getFieldCollations().isEmpty()) {
            continue;
        }
        fieldCollations.clear();
        for (RelFieldCollation ifc : ic.getFieldCollations()) {
            final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
            if (integers.isEmpty()) {
                // cannot do this collation
                continue loop;
            }
            fieldCollations.add(ifc.copy(integers.iterator().next()));
        }
        assert !fieldCollations.isEmpty();
        collations.add(RelCollations.of(fieldCollations));
    }
    final List<RelFieldCollation> fieldCollationsForRexCalls = new ArrayList<>();
    for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
        final SqlMonotonicity value = entry.getValue();
        switch(value) {
            case NOT_MONOTONIC:
            case CONSTANT:
                break;
            default:
                fieldCollationsForRexCalls.add(new RelFieldCollation(entry.getKey(), RelFieldCollation.Direction.of(value)));
                break;
        }
    }
    if (!fieldCollationsForRexCalls.isEmpty()) {
        collations.add(RelCollations.of(fieldCollationsForRexCalls));
    }
    return ImmutableList.copyOf(collations);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RexCall(org.apache.calcite.rex.RexCall) RexCallBinding(org.apache.calcite.rex.RexCallBinding) RelCollation(org.apache.calcite.rel.RelCollation) TreeSet(java.util.TreeSet) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelCollation (org.apache.calcite.rel.RelCollation)83 RelNode (org.apache.calcite.rel.RelNode)40 RelTraitSet (org.apache.calcite.plan.RelTraitSet)37 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)33 RexNode (org.apache.calcite.rex.RexNode)24 ArrayList (java.util.ArrayList)19 RelDataType (org.apache.calcite.rel.type.RelDataType)17 RelOptCluster (org.apache.calcite.plan.RelOptCluster)15 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)13 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)12 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)12 List (java.util.List)11 Sort (org.apache.calcite.rel.core.Sort)11 ImmutableList (com.google.common.collect.ImmutableList)8 RelDistribution (org.apache.calcite.rel.RelDistribution)8 RexInputRef (org.apache.calcite.rex.RexInputRef)8 Map (java.util.Map)7 Mappings (org.apache.calcite.util.mapping.Mappings)7 Supplier (com.google.common.base.Supplier)6 HashMap (java.util.HashMap)6