Пример #1
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);
  }
Пример #2
0
 /**
  * Applies a mapping to a field collation.
  *
  * <p>If the field is not mapped, returns null.
  *
  * @param mapping Mapping
  * @param fieldCollation Field collation
  * @return collation with mapping applied
  */
 public static RelFieldCollation apply(
     Mappings.TargetMapping mapping, RelFieldCollation fieldCollation) {
   final int target = mapping.getTargetOpt(fieldCollation.getFieldIndex());
   if (target < 0) {
     return null;
   }
   return fieldCollation.copy(target);
 }
Пример #3
0
 /**
  * Checks that a collection of collations is valid.
  *
  * @param rowType Row type of the relational expression
  * @param collationList List of collations
  * @param fail Whether to fail if invalid
  * @return Whether valid
  */
 public static boolean isValid(
     RelDataType rowType, List<RelCollation> collationList, boolean fail) {
   final int fieldCount = rowType.getFieldCount();
   for (RelCollation collation : collationList) {
     for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
       final int index = fieldCollation.getFieldIndex();
       if (index < 0 || index >= fieldCount) {
         assert !fail;
         return false;
       }
     }
   }
   return true;
 }
Пример #4
0
 /**
  * Returns a string representation of this collation, suitably terse given that it will appear in
  * plan traces. Examples: "[]", "[2]", "[0 DESC, 1]", "[0 DESC, 1 ASC NULLS LAST]".
  */
 public String toString() {
   Iterator<RelFieldCollation> it = fieldCollations.iterator();
   if (!it.hasNext()) {
     return "[]";
   }
   StringBuilder sb = new StringBuilder();
   sb.append('[');
   for (; ; ) {
     RelFieldCollation e = it.next();
     sb.append(e.getFieldIndex());
     if (e.direction != RelFieldCollation.Direction.ASCENDING
         || e.nullDirection != RelFieldCollation.NullDirection.UNSPECIFIED) {
       sb.append(' ').append(e.shortString());
     }
     if (!it.hasNext()) {
       return sb.append(']').toString();
     }
     sb.append(',').append(' ');
   }
 }