示例#1
0
 /** Creates a SortRel by parsing serialized output. */
 public SortRel(RelInput input) {
   this(
       input.getCluster(),
       input.getTraitSet().plus(input.getCollation()),
       input.getInput(),
       RelCollationTraitDef.INSTANCE.canonize(input.getCollation()),
       input.getExpression("offset"),
       input.getExpression("fetch"));
 }
示例#2
0
/** Simple implementation of {@link RelCollation}. */
public class RelCollationImpl implements RelCollation {
  // ~ Static fields/initializers ---------------------------------------------

  /** A collation indicating that a relation is not sorted. Ordering by no columns. */
  public static final RelCollation EMPTY =
      RelCollationTraitDef.INSTANCE.canonize(
          new RelCollationImpl(ImmutableList.<RelFieldCollation>of()));

  /**
   * A collation that cannot be replicated by applying a sort. The only implementation choice is to
   * apply operations that preserve order.
   */
  public static final RelCollation PRESERVE =
      RelCollationTraitDef.INSTANCE.canonize(
          new RelCollationImpl(ImmutableList.of(new RelFieldCollation(-1))) {
            public String toString() {
              return "PRESERVE";
            }
          });

  // ~ Instance fields --------------------------------------------------------

  private final ImmutableList<RelFieldCollation> fieldCollations;

  // ~ Constructors -----------------------------------------------------------

  protected RelCollationImpl(ImmutableList<RelFieldCollation> fieldCollations) {
    this.fieldCollations = fieldCollations;
  }

  public static RelCollation of(RelFieldCollation... fieldCollations) {
    return new RelCollationImpl(ImmutableList.copyOf(fieldCollations));
  }

  public static RelCollation of(List<RelFieldCollation> fieldCollations) {
    return new RelCollationImpl(ImmutableList.copyOf(fieldCollations));
  }

  // ~ Methods ----------------------------------------------------------------

  public RelTraitDef getTraitDef() {
    return RelCollationTraitDef.INSTANCE;
  }

  public List<RelFieldCollation> getFieldCollations() {
    return fieldCollations;
  }

  public int hashCode() {
    return fieldCollations.hashCode();
  }

  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj instanceof RelCollationImpl) {
      RelCollationImpl that = (RelCollationImpl) obj;
      return this.fieldCollations.equals(that.fieldCollations);
    }
    return false;
  }

  public void register(RelOptPlanner planner) {}

  public boolean subsumes(RelTrait trait) {
    return this == trait
        || trait instanceof RelCollationImpl
            && Util.startsWith(fieldCollations, ((RelCollationImpl) trait).fieldCollations);
  }

  /**
   * 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(' ');
    }
  }

  /** Creates a list containing one collation containing one field. */
  public static List<RelCollation> createSingleton(int fieldIndex) {
    return ImmutableList.of(
        of(
            new RelFieldCollation(
                fieldIndex,
                RelFieldCollation.Direction.ASCENDING,
                RelFieldCollation.NullDirection.UNSPECIFIED)));
  }

  /**
   * 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;
  }

  public static boolean equal(
      List<RelCollation> collationList1, List<RelCollation> collationList2) {
    return collationList1.equals(collationList2);
  }

  /** Returns the indexes of the field collations in a given collation. */
  public static List<Integer> ordinals(RelCollation collation) {
    return Lists.transform(
        collation.getFieldCollations(),
        new Function<RelFieldCollation, Integer>() {
          public Integer apply(RelFieldCollation input) {
            return input.getFieldIndex();
          }
        });
  }
}