Java Code Examples for org.apache.calcite.rel.core.Sort#copy()

The following examples show how to use org.apache.calcite.rel.core.Sort#copy() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: OLAPLimitRule.java    From kylin with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    if (sort.offset == null && sort.fetch == null) {
        return;
    }

    RelTraitSet origTraitSet = sort.getTraitSet();
    RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();

    RelNode input = sort.getInput();
    if (!sort.getCollation().getFieldCollations().isEmpty()) {
        // Create a sort with the same sort key, but no offset or fetch.
        input = sort.copy(sort.getTraitSet(), input, sort.getCollation(), null, null);
    }
    RelNode x = convert(input, input.getTraitSet().replace(OLAPRel.CONVENTION));
    call.transformTo(new OLAPLimitRel(sort.getCluster(), traitSet, x, sort.offset, sort.fetch));
}
 
Example 2
Source File: EnumerableLimitRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  if (sort.offset == null && sort.fetch == null) {
    return;
  }
  RelNode input = sort.getInput();
  if (!sort.getCollation().getFieldCollations().isEmpty()) {
    // Create a sort with the same sort key, but no offset or fetch.
    input = sort.copy(
        sort.getTraitSet(),
        input,
        sort.getCollation(),
        null,
        null);
  }
  call.transformTo(
      EnumerableLimit.create(
          convert(input, input.getTraitSet().replace(EnumerableConvention.INSTANCE)),
          sort.offset,
          sort.fetch));
}
 
Example 3
Source File: ProjectSortTransposeRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Project project = call.rel(0);
  final Sort sort = call.rel(1);
  if (sort.getClass() != Sort.class) {
    return;
  }
  RelNode newProject =
      project.copy(
          project.getTraitSet(), ImmutableList.of(sort.getInput()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet(),
          newProject,
          sort.getCollation(),
          sort.offset,
          sort.fetch);
  call.transformTo(newSort);
}
 
Example 4
Source File: DruidRules.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final DruidQuery query = call.rel(1);
  if (!DruidQuery.isValidSignature(query.signature() + 'l')) {
    return;
  }
  // Either it is:
  // - a pure limit above a query of type scan
  // - a sort and limit on a dimension/metric part of the druid group by query
  if (sort.offset != null && RexLiteral.intValue(sort.offset) != 0) {
    // offset not supported by Druid
    return;
  }
  if (query.getQueryType() == QueryType.SCAN && !RelOptUtil.isPureLimit(sort)) {
    return;
  }

  final RelNode newSort = sort
      .copy(sort.getTraitSet(), ImmutableList.of(Util.last(query.rels)));
  call.transformTo(DruidQuery.extendQuery(query, newSort));
}
 
Example 5
Source File: OLAPLimitRule.java    From kylin-on-parquet-v2 with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    if (sort.offset == null && sort.fetch == null) {
        return;
    }

    RelTraitSet origTraitSet = sort.getTraitSet();
    RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();

    RelNode input = sort.getInput();
    if (!sort.getCollation().getFieldCollations().isEmpty()) {
        // Create a sort with the same sort key, but no offset or fetch.
        input = sort.copy(sort.getTraitSet(), input, sort.getCollation(), null, null);
    }
    RelNode x = convert(input, input.getTraitSet().replace(OLAPRel.CONVENTION));
    call.transformTo(new OLAPLimitRel(sort.getCluster(), traitSet, x, sort.offset, sort.fetch));
}
 
Example 6
Source File: DrillLimitRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  final Sort incomingSort = call.rel(0);
  final RelTraitSet incomingTraits = incomingSort.getTraitSet();
  RelNode input = incomingSort.getInput();

  // if the Optiq sort rel includes a collation and a limit, we need to create a copy the sort rel that excludes the
  // limit information.
  if (!incomingSort.getCollation().getFieldCollations().isEmpty()) {
    input = incomingSort.copy(incomingTraits, input, incomingSort.getCollation(), null, null);
  }

  RelNode convertedInput = convert(input, input.getTraitSet().plus(DrillRel.DRILL_LOGICAL).simplify());
  call.transformTo(new DrillLimitRel(
      incomingSort.getCluster(), convertedInput.getTraitSet().plus(DrillRel.DRILL_LOGICAL),
      convertedInput, incomingSort.offset, incomingSort.fetch));
}
 
Example 7
Source File: ProjectSortTransposeRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Project project = call.rel(0);
  final Sort sort = call.rel(1);
  if (sort.getClass() != Sort.class) {
    return;
  }
  RelNode newProject =
      project.copy(
          project.getTraitSet(), ImmutableList.of(sort.getInput()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet(),
          newProject,
          sort.getCollation(),
          sort.offset,
          sort.fetch);
  call.transformTo(newSort);
}
 
Example 8
Source File: SortRemoveConstantKeysRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final RelMetadataQuery mq = call.getMetadataQuery();
  final RelNode input = sort.getInput();
  final RelOptPredicateList predicates = mq.getPulledUpPredicates(input);
  if (predicates == null) {
    return;
  }

  final RexBuilder rexBuilder = sort.getCluster().getRexBuilder();
  final List<RelFieldCollation> collationsList =
      sort.getCollation().getFieldCollations().stream()
          .filter(fc ->
              !predicates.constantMap.containsKey(
                  rexBuilder.makeInputRef(input, fc.getFieldIndex())))
          .collect(Collectors.toList());

  if (collationsList.size() == sort.collation.getFieldCollations().size()) {
    return;
  }

  // No active collations. Remove the sort completely
  if (collationsList.isEmpty() && sort.offset == null && sort.fetch == null) {
    call.transformTo(input);
    call.getPlanner().setImportance(sort, 0.0);
    return;
  }

  final Sort result =
      sort.copy(sort.getTraitSet(), input, RelCollations.of(collationsList));
  call.transformTo(result);
  call.getPlanner().setImportance(sort, 0.0);
}
 
Example 9
Source File: LimitRule.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  final Sort incomingSort = call.rel(0);
  final RelTraitSet incomingTraits = incomingSort.getTraitSet();
  RelNode input = incomingSort.getInput();

  // if the calcite sort rel includes a collation and a limit, we need to create a copy the sort rel that excludes the
  // limit information.
  if (!incomingSort.getCollation().getFieldCollations().isEmpty()) {
    input = incomingSort.copy(incomingTraits, input, incomingSort.getCollation(), null, null);
  }

  RelNode convertedInput = convert(input, input.getTraitSet().plus(Rel.LOGICAL).simplify());
  call.transformTo(LimitRel.create(incomingSort.getCluster(), convertedInput.getTraitSet().plus(Rel.LOGICAL), convertedInput, incomingSort.offset, incomingSort.fetch));
}
 
Example 10
Source File: SortUnionTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Union union = call.rel(1);
  List<RelNode> inputs = new ArrayList<>();
  // Thus we use 'ret' as a flag to identify if we have finished pushing the
  // sort past a union.
  boolean ret = true;
  final RelMetadataQuery mq = call.getMetadataQuery();
  for (RelNode input : union.getInputs()) {
    if (!RelMdUtil.checkInputForCollationAndLimit(mq, input,
        sort.getCollation(), sort.offset, sort.fetch)) {
      ret = false;
      Sort branchSort = sort.copy(sort.getTraitSet(), input,
          sort.getCollation(), sort.offset, sort.fetch);
      inputs.add(branchSort);
    } else {
      inputs.add(input);
    }
  }
  // there is nothing to change
  if (ret) {
    return;
  }
  // create new union and sort
  Union unionCopy = (Union) union
      .copy(union.getTraitSet(), inputs, union.all);
  Sort result = sort.copy(sort.getTraitSet(), unionCopy, sort.getCollation(),
      sort.offset, sort.fetch);
  call.transformTo(result);
}
 
Example 11
Source File: SortUnionTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Union union = call.rel(1);
  List<RelNode> inputs = new ArrayList<>();
  // Thus we use 'ret' as a flag to identify if we have finished pushing the
  // sort past a union.
  boolean ret = true;
  final RelMetadataQuery mq = call.getMetadataQuery();
  for (RelNode input : union.getInputs()) {
    if (!RelMdUtil.checkInputForCollationAndLimit(mq, input,
        sort.getCollation(), sort.offset, sort.fetch)) {
      ret = false;
      Sort branchSort = sort.copy(sort.getTraitSet(), input,
          sort.getCollation(), sort.offset, sort.fetch);
      inputs.add(branchSort);
    } else {
      inputs.add(input);
    }
  }
  // there is nothing to change
  if (ret) {
    return;
  }
  // create new union and sort
  Union unionCopy = (Union) union
      .copy(union.getTraitSet(), inputs, union.all);
  Sort result = sort.copy(sort.getTraitSet(), unionCopy, sort.getCollation(),
      sort.offset, sort.fetch);
  call.transformTo(result);
}
 
Example 12
Source File: SortRemoveConstantKeysRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final RelMetadataQuery mq = call.getMetadataQuery();
  final RelNode input = sort.getInput();
  final RelOptPredicateList predicates = mq.getPulledUpPredicates(input);
  if (predicates == null) {
    return;
  }

  final RexBuilder rexBuilder = sort.getCluster().getRexBuilder();
  final List<RelFieldCollation> collationsList =
      sort.getCollation().getFieldCollations().stream()
          .filter(fc ->
              !predicates.constantMap.containsKey(
                  rexBuilder.makeInputRef(input, fc.getFieldIndex())))
          .collect(Collectors.toList());

  if (collationsList.size() == sort.collation.getFieldCollations().size()) {
    return;
  }

  // No active collations. Remove the sort completely
  if (collationsList.isEmpty() && sort.offset == null && sort.fetch == null) {
    call.transformTo(input);
    call.getPlanner().prune(sort);
    return;
  }

  final Sort result =
      sort.copy(sort.getTraitSet(), input, RelCollations.of(collationsList));
  call.transformTo(result);
  call.getPlanner().prune(sort);
}
 
Example 13
Source File: SortProjectTransposeRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Project project = call.rel(1);
  final RelOptCluster cluster = project.getCluster();

  if (sort.getConvention() != project.getConvention()) {
    return;
  }

  // Determine mapping between project input and output fields. If sort
  // relies on non-trivial expressions, we can't push.
  final Mappings.TargetMapping map =
      RelOptUtil.permutationIgnoreCast(
          project.getProjects(), project.getInput().getRowType());
  for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
    if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
      return;
    }
    final RexNode node = project.getProjects().get(fc.getFieldIndex());
    if (node.isA(SqlKind.CAST)) {
      // Check whether it is a monotonic preserving cast, otherwise we cannot push
      final RexCall cast = (RexCall) node;
      final RexCallBinding binding =
          RexCallBinding.create(cluster.getTypeFactory(), cast,
              ImmutableList.of(RelCollations.of(RexUtil.apply(map, fc))));
      if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
        return;
      }
    }
  }
  final RelCollation newCollation =
      cluster.traitSet().canonize(
          RexUtil.apply(map, sort.getCollation()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet().replace(newCollation),
          project.getInput(),
          newCollation,
          sort.offset,
          sort.fetch);
  RelNode newProject =
      project.copy(
          sort.getTraitSet(),
          ImmutableList.of(newSort));
  // Not only is newProject equivalent to sort;
  // newSort is equivalent to project's input
  // (but only if the sort is not also applying an offset/limit).
  Map<RelNode, RelNode> equiv;
  if (sort.offset == null
      && sort.fetch == null
      && cluster.getPlanner().getRelTraitDefs()
          .contains(RelCollationTraitDef.INSTANCE)) {
    equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
  } else {
    equiv = ImmutableMap.of();
  }
  call.transformTo(newProject, equiv);
}
 
Example 14
Source File: SortJoinTransposeRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Join join = call.rel(1);

  // We create a new sort operator on the corresponding input
  final RelNode newLeftInput;
  final RelNode newRightInput;
  final RelMetadataQuery mq = call.getMetadataQuery();
  if (join.getJoinType() == JoinRelType.LEFT) {
    // If the input is already sorted and we are not reducing the number of tuples,
    // we bail out
    if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getLeft(),
        sort.getCollation(), sort.offset, sort.fetch)) {
      return;
    }
    newLeftInput = sort.copy(sort.getTraitSet(), join.getLeft(), sort.getCollation(),
        sort.offset, sort.fetch);
    newRightInput = join.getRight();
  } else {
    final RelCollation rightCollation =
        RelCollationTraitDef.INSTANCE.canonize(
            RelCollations.shift(sort.getCollation(),
                -join.getLeft().getRowType().getFieldCount()));
    // If the input is already sorted and we are not reducing the number of tuples,
    // we bail out
    if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getRight(),
        rightCollation, sort.offset, sort.fetch)) {
      return;
    }
    newLeftInput = join.getLeft();
    newRightInput = sort.copy(sort.getTraitSet().replace(rightCollation),
        join.getRight(), rightCollation, sort.offset, sort.fetch);
  }
  // We copy the join and the top sort operator
  final RelNode joinCopy = join.copy(join.getTraitSet(), join.getCondition(), newLeftInput,
      newRightInput, join.getJoinType(), join.isSemiJoinDone());
  final RelNode sortCopy = sort.copy(sort.getTraitSet(), joinCopy, sort.getCollation(),
      sort.offset, sort.fetch);

  call.transformTo(sortCopy);
}
 
Example 15
Source File: SortProjectTransposeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Project project = call.rel(1);
  final RelOptCluster cluster = project.getCluster();

  if (sort.getConvention() != project.getConvention()) {
    return;
  }

  // Determine mapping between project input and output fields. If sort
  // relies on non-trivial expressions, we can't push.
  final Mappings.TargetMapping map =
      RelOptUtil.permutationIgnoreCast(
          project.getProjects(), project.getInput().getRowType());
  for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
    if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
      return;
    }
    final RexNode node = project.getProjects().get(fc.getFieldIndex());
    if (node.isA(SqlKind.CAST)) {
      // Check whether it is a monotonic preserving cast, otherwise we cannot push
      final RexCall cast = (RexCall) node;
      RelFieldCollation newFc = Objects.requireNonNull(RexUtil.apply(map, fc));
      final RexCallBinding binding =
          RexCallBinding.create(cluster.getTypeFactory(), cast,
              ImmutableList.of(RelCollations.of(newFc)));
      if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
        return;
      }
    }
  }
  final RelCollation newCollation =
      cluster.traitSet().canonize(
          RexUtil.apply(map, sort.getCollation()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet().replace(newCollation),
          project.getInput(),
          newCollation,
          sort.offset,
          sort.fetch);
  RelNode newProject =
      project.copy(
          sort.getTraitSet(),
          ImmutableList.of(newSort));
  // Not only is newProject equivalent to sort;
  // newSort is equivalent to project's input
  // (but only if the sort is not also applying an offset/limit).
  Map<RelNode, RelNode> equiv;
  if (sort.offset == null
      && sort.fetch == null
      && cluster.getPlanner().getRelTraitDefs()
          .contains(RelCollationTraitDef.INSTANCE)) {
    equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
  } else {
    equiv = ImmutableMap.of();
  }
  call.transformTo(newProject, equiv);
}
 
Example 16
Source File: SortJoinCopyRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Join join = call.rel(1);
  final RelMetadataQuery metadataQuery = call.getMetadataQuery();

  final RelNode newLeftInput;
  final RelNode newRightInput;

  final List<RelFieldCollation> leftFieldCollation = new ArrayList<>();
  final List<RelFieldCollation> rightFieldCollation = new ArrayList<>();

  // Decompose sort collations into left and right collations
  for (RelFieldCollation relFieldCollation : sort.getCollation().getFieldCollations()) {
    if (relFieldCollation.getFieldIndex() >= join.getLeft().getRowType().getFieldCount()) {
      rightFieldCollation.add(relFieldCollation);
    } else {
      leftFieldCollation.add(relFieldCollation);
    }
  }

  // Add sort to new left node only if sort collations
  // contained fields from left table
  if (leftFieldCollation.isEmpty()) {
    newLeftInput = join.getLeft();
  } else {
    final RelCollation leftCollation = RelCollationTraitDef.INSTANCE.canonize(
        RelCollations.of(leftFieldCollation));
    // If left table already sorted don't add a sort
    if (RelMdUtil.checkInputForCollationAndLimit(
        metadataQuery,
        join.getLeft(),
        leftCollation,
        null,
        null)) {
      newLeftInput = join.getLeft();
    } else {
      newLeftInput = sort.copy(
          sort.getTraitSet().replaceIf(
              RelCollationTraitDef.INSTANCE,
              () -> leftCollation),
          join.getLeft(),
          leftCollation,
          null,
          null);
    }
  }
  // Add sort to new right node only if sort collations
  // contained fields from right table
  if (rightFieldCollation.isEmpty()) {
    newRightInput = join.getRight();
  } else {
    final RelCollation rightCollation = RelCollationTraitDef.INSTANCE.canonize(
        RelCollations.shift(
            RelCollations.of(rightFieldCollation),
            -join.getLeft().getRowType().getFieldCount()));
    // If right table already sorted don't add a sort
    if (RelMdUtil.checkInputForCollationAndLimit(
        metadataQuery,
        join.getRight(),
        rightCollation,
        null,
        null)) {
      newRightInput = join.getRight();
    } else {
      newRightInput = sort.copy(
          sort.getTraitSet().replaceIf(
              RelCollationTraitDef.INSTANCE,
              () -> rightCollation),
          join.getRight(),
          rightCollation,
          null,
          null);
    }
  }
  // If no change was made no need to apply the rule
  if (newLeftInput == join.getLeft() && newRightInput == join.getRight()) {
    return;
  }

  final RelNode joinCopy = join.copy(
      join.getTraitSet(),
      join.getCondition(),
      newLeftInput,
      newRightInput,
      join.getJoinType(),
      join.isSemiJoinDone());
  final RelNode sortCopy = sort.copy(
      sort.getTraitSet(),
      joinCopy,
      sort.getCollation(),
      sort.offset,
      sort.fetch);

  call.transformTo(sortCopy);
}
 
Example 17
Source File: SortJoinTransposeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Join join = call.rel(1);

  // We create a new sort operator on the corresponding input
  final RelNode newLeftInput;
  final RelNode newRightInput;
  final RelMetadataQuery mq = call.getMetadataQuery();
  if (join.getJoinType() == JoinRelType.LEFT) {
    // If the input is already sorted and we are not reducing the number of tuples,
    // we bail out
    if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getLeft(),
        sort.getCollation(), sort.offset, sort.fetch)) {
      return;
    }
    newLeftInput = sort.copy(sort.getTraitSet(), join.getLeft(), sort.getCollation(),
        sort.offset, sort.fetch);
    newRightInput = join.getRight();
  } else {
    final RelCollation rightCollation =
        RelCollationTraitDef.INSTANCE.canonize(
            RelCollations.shift(sort.getCollation(),
                -join.getLeft().getRowType().getFieldCount()));
    // If the input is already sorted and we are not reducing the number of tuples,
    // we bail out
    if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getRight(),
        rightCollation, sort.offset, sort.fetch)) {
      return;
    }
    newLeftInput = join.getLeft();
    newRightInput = sort.copy(sort.getTraitSet().replace(rightCollation),
        join.getRight(), rightCollation, sort.offset, sort.fetch);
  }
  // We copy the join and the top sort operator
  final RelNode joinCopy = join.copy(join.getTraitSet(), join.getCondition(), newLeftInput,
      newRightInput, join.getJoinType(), join.isSemiJoinDone());
  final RelNode sortCopy = sort.copy(sort.getTraitSet(), joinCopy, sort.getCollation(),
      sort.offset, sort.fetch);

  call.transformTo(sortCopy);
}