Example #1
0
  /**
   * Applies a mapping to a collation list.
   *
   * @param mapping Mapping
   * @param collationList Collation list
   * @return collation list with mapping applied to each field
   */
  public static List<RelCollation> apply(
      Mappings.TargetMapping mapping, List<RelCollation> collationList) {
    final List<RelCollation> newCollationList = new ArrayList<RelCollation>();
    for (RelCollation collation : collationList) {
      final List<RelFieldCollation> newFieldCollationList = new ArrayList<RelFieldCollation>();
      for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
        final RelFieldCollation newFieldCollation = apply(mapping, fieldCollation);
        if (newFieldCollation == null) {
          // This field is not mapped. Stop here. The leading edge
          // of the collation is still valid (although it's useless
          // if it's empty).
          break;
        }
        newFieldCollationList.add(newFieldCollation);
      }
      // Truncation to collations to their leading edge creates empty
      // and duplicate collations. Ignore these.
      if (!newFieldCollationList.isEmpty()) {
        final RelCollationImpl newCollation = new RelCollationImpl(newFieldCollationList);
        if (!newCollationList.contains(newCollation)) {
          newCollationList.add(newCollation);
        }
      }
    }

    // REVIEW: There might be redundant collations in the list. For example,
    // in {(x), (x, y)}, (x) is redundant because it is a leading edge of
    // another collation in the list. Could remove redundant collations.

    return newCollationList;
  }
Example #2
0
  /** Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link SortRel}. */
  public TrimResult trimFields(SortRel sort, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = sort.getRowType();
    final int fieldCount = rowType.getFieldCount();
    final RelCollation collation = sort.getCollation();
    final RelNode input = sort.getChild();

    // We use the fields used by the consumer, plus any fields used as sort
    // keys.
    BitSet inputFieldsUsed = (BitSet) fieldsUsed.clone();
    for (RelFieldCollation field : collation.getFieldCollations()) {
      inputFieldsUsed.set(field.getFieldIndex());
    }

    // Create input with trimmed columns.
    final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
    TrimResult trimResult = trimChild(sort, input, inputFieldsUsed, inputExtraFields);
    RelNode newInput = trimResult.left;
    final Mapping inputMapping = trimResult.right;

    // If the input is unchanged, and we need to project all columns,
    // there's nothing we can do.
    if (newInput == input && inputMapping.isIdentity() && fieldsUsed.cardinality() == fieldCount) {
      return new TrimResult(sort, Mappings.createIdentity(fieldCount));
    }

    final SortRel newSort =
        sort.copy(sort.getTraitSet(), newInput, RexUtil.apply(inputMapping, collation));
    assert newSort.getClass() == sort.getClass();

    // The result has the same mapping as the input gave us. Sometimes we
    // return fields that the consumer didn't ask for, because the filter
    // needs them for its condition.
    return new TrimResult(newSort, inputMapping);
  }