예제 #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
 /** Converts a collation to an ORDER BY item. */
 public SqlNode toSql(RelFieldCollation collation) {
   SqlNode node = field(collation.getFieldIndex());
   switch (collation.getDirection()) {
     case DESCENDING:
     case STRICTLY_DESCENDING:
       node = SqlStdOperatorTable.DESC.createCall(POS, node);
   }
   switch (collation.nullDirection) {
     case FIRST:
       node = SqlStdOperatorTable.NULLS_FIRST.createCall(POS, node);
       break;
     case LAST:
       node = SqlStdOperatorTable.NULLS_LAST.createCall(POS, node);
       break;
   }
   return node;
 }
예제 #3
0
  /**
   * Creates a sorter.
   *
   * @param cluster Cluster this relational expression belongs to
   * @param traits Traits
   * @param child input relational expression
   * @param collation array of sort specifications
   * @param offset Expression for number of rows to discard before returning first row
   * @param fetch Expression for number of rows to fetch
   */
  public SortRel(
      RelOptCluster cluster,
      RelTraitSet traits,
      RelNode child,
      RelCollation collation,
      RexNode offset,
      RexNode fetch) {
    super(cluster, traits, child);
    this.collation = collation;
    this.offset = offset;
    this.fetch = fetch;

    assert traits.containsIfApplicable(collation) : "traits=" + traits + ", collation=" + collation;
    assert !(fetch == null && offset == null && collation.getFieldCollations().isEmpty())
        : "trivial sort";
    ImmutableList.Builder<RexNode> builder = ImmutableList.builder();
    for (RelFieldCollation field : collation.getFieldCollations()) {
      int index = field.getFieldIndex();
      builder.add(cluster.getRexBuilder().makeInputRef(child, index));
    }
    fieldExps = builder.build();
  }