Java Code Examples for org.apache.calcite.util.mapping.Mappings#create()

The following examples show how to use org.apache.calcite.util.mapping.Mappings#create() . 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: FilterNLJMergeRule.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  FilterPrel filter = call.rel(0);
  NestedLoopJoinPrel join = call.rel(1);

  if ((join.getProjectedFields() == null) || join.getProjectedFields().cardinality() == join.getInputRowType().getFieldCount()) {
    call.transformTo(NestedLoopJoinPrel.create(join.getCluster(), join.getTraitSet(), join.getLeft(), join.getRight(), join.getJoinType(), RelOptUtil.andJoinFilters(join.getCluster().getRexBuilder(), join.getCondition(), filter.getCondition()), join.getProjectedFields()));
  } else {
    // Current filter condition is written based on projected fields on join. In order to push this filter down we need to rewrite filter condition
    final ImmutableBitSet topProjectedColumns = RelOptUtil.InputFinder.bits(filter.getCondition());
    final ImmutableBitSet bottomProjectedColumns = join.getProjectedFields();

    Mapping mapping = Mappings.create(MappingType.SURJECTION, join.getRowType().getFieldCount(), join.getInputRowType().getFieldCount());
    for (Ord<Integer> ord : Ord.zip(bottomProjectedColumns)) {
      if (topProjectedColumns.get(ord.i)) {
        mapping.set(ord.i, ord.e);
      }
    }

    RexShuttle shuttle = new RexPermuteInputsShuttle(mapping);
    RexNode updatedCondition = shuttle.apply(filter.getCondition());

    call.transformTo(NestedLoopJoinPrel.create(join.getCluster(), join.getTraitSet(), join.getLeft(), join.getRight(), join.getJoinType(), RelOptUtil.andJoinFilters(join.getCluster().getRexBuilder(), join.getCondition(), updatedCondition), join.getProjectedFields()));
  }
}
 
Example 2
Source File: RelOptUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a permutation describing where output fields come from. In
 * the returned map, value of {@code map.getTargetOpt(i)} is {@code n} if
 * field {@code i} projects input field {@code n} or applies a cast on
 * {@code n}, -1 if it is another expression.
 */
public static Mappings.TargetMapping permutationIgnoreCast(
    List<RexNode> nodes,
    RelDataType inputRowType) {
  final Mappings.TargetMapping mapping =
      Mappings.create(
          MappingType.PARTIAL_FUNCTION,
          nodes.size(),
          inputRowType.getFieldCount());
  for (Ord<RexNode> node : Ord.zip(nodes)) {
    if (node.e instanceof RexInputRef) {
      mapping.set(
          node.i,
          ((RexInputRef) node.e).getIndex());
    } else if (node.e.isA(SqlKind.CAST)) {
      final RexNode operand = ((RexCall) node.e).getOperands().get(0);
      if (operand instanceof RexInputRef) {
        mapping.set(node.i, ((RexInputRef) operand).getIndex());
      }
    }
  }
  return mapping;
}
 
Example 3
Source File: Project.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a mapping of a set of project expressions.
 *
 * <p>The mapping is an inverse surjection.
 * Every target has a source field, but no
 * source has more than one target.
 * Thus you can safely call
 * {@link org.apache.calcite.util.mapping.Mappings.TargetMapping#getSourceOpt(int)}.
 *
 * @param inputFieldCount Number of input fields
 * @param projects Project expressions
 * @return Mapping of a set of project expressions, or null if projection is
 * not a mapping
 */
public static Mappings.TargetMapping getMapping(int inputFieldCount,
    List<? extends RexNode> projects) {
  if (inputFieldCount < projects.size()) {
    return null; // surjection is not possible
  }
  Mappings.TargetMapping mapping =
      Mappings.create(MappingType.INVERSE_SURJECTION,
          inputFieldCount, projects.size());
  for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) {
    if (!(exp.e instanceof RexInputRef)) {
      return null;
    }

    int source = ((RexInputRef) exp.e).getIndex();
    if (mapping.getTargetOpt(source) != -1) {
      return null;
    }
    mapping.set(source, exp.i);
  }
  return mapping;
}
 
Example 4
Source File: RelOptUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a permutation describing where output fields come from. In
 * the returned map, value of {@code map.getTargetOpt(i)} is {@code n} if
 * field {@code i} projects input field {@code n}, -1 if it is an
 * expression.
 */
public static Mappings.TargetMapping permutation(
    List<RexNode> nodes,
    RelDataType inputRowType) {
  final Mappings.TargetMapping mapping =
      Mappings.create(
          MappingType.PARTIAL_FUNCTION,
          nodes.size(),
          inputRowType.getFieldCount());
  for (Ord<RexNode> node : Ord.zip(nodes)) {
    if (node.e instanceof RexInputRef) {
      mapping.set(
          node.i,
          ((RexInputRef) node.e).getIndex());
    }
  }
  return mapping;
}
 
Example 5
Source File: RelOptUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a permutation describing where output fields come from. In
 * the returned map, value of {@code map.getTargetOpt(i)} is {@code n} if
 * field {@code i} projects input field {@code n} or applies a cast on
 * {@code n}, -1 if it is another expression.
 */
public static Mappings.TargetMapping permutationIgnoreCast(List<RexNode> nodes, RelDataType inputRowType) {
    final Mappings.TargetMapping mapping = Mappings.create(MappingType.PARTIAL_FUNCTION, nodes.size(),
            inputRowType.getFieldCount());
    for (Ord<RexNode> node : Ord.zip(nodes)) {
        if (node.e instanceof RexInputRef) {
            mapping.set(node.i, ((RexInputRef) node.e).getIndex());
        } else if (node.e.isA(SqlKind.CAST)) {
            final RexNode operand = ((RexCall) node.e).getOperands().get(0);
            if (operand instanceof RexInputRef) {
                mapping.set(node.i, ((RexInputRef) operand).getIndex());
            }
        }
    }
    return mapping;
}
 
Example 6
Source File: Project.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a mapping of a set of project expressions.
 *
 * <p>The mapping is an inverse surjection.
 * Every target has a source field, but
 * a source field may appear as zero, one, or more target fields.
 * Thus you can safely call
 * {@link org.apache.calcite.util.mapping.Mappings.TargetMapping#getTarget(int)}.
 *
 * @param inputFieldCount Number of input fields
 * @param projects Project expressions
 * @return Mapping of a set of project expressions, or null if projection is
 * not a mapping
 */
public static Mappings.TargetMapping getMapping(int inputFieldCount,
    List<? extends RexNode> projects) {
  if (inputFieldCount < projects.size()) {
    return null; // surjection is not possible
  }
  Mappings.TargetMapping mapping =
      Mappings.create(MappingType.INVERSE_SURJECTION,
          inputFieldCount, projects.size());
  for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) {
    if (!(exp.e instanceof RexInputRef)) {
      return null;
    }
    mapping.set(((RexInputRef) exp.e).getIndex(), exp.i);
  }
  return mapping;
}
 
Example 7
Source File: RexProgram.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a partial mapping of a set of project expressions.
 *
 * <p>The mapping is an inverse function.
 * Every target has a source field, but
 * a source might have 0, 1 or more targets.
 * Project expressions that do not consist of
 * a mapping are ignored.
 *
 * @param inputFieldCount Number of input fields
 * @return Mapping of a set of project expressions, never null
 */
public Mappings.TargetMapping getPartialMapping(int inputFieldCount) {
  Mappings.TargetMapping mapping =
      Mappings.create(MappingType.INVERSE_FUNCTION,
          inputFieldCount, projects.size());
  for (Ord<RexLocalRef> exp : Ord.zip(projects)) {
    RexNode rexNode = expandLocalRef(exp.e);
    if (rexNode instanceof RexInputRef) {
      mapping.set(((RexInputRef) rexNode).getIndex(), exp.i);
    }
  }
  return mapping;
}
 
Example 8
Source File: RelFieldTrimmer.java    From Bats with Apache License 2.0 5 votes vote down vote up
protected Mapping createMapping(ImmutableBitSet fieldsUsed, int fieldCount) {
    final Mapping mapping = Mappings.create(MappingType.INVERSE_SURJECTION, fieldCount, fieldsUsed.cardinality());
    int i = 0;
    for (int field : fieldsUsed) {
        mapping.set(field, i++);
    }
    return mapping;
}
 
Example 9
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a permutation describing where output fields come from. In
 * the returned map, value of {@code map.getTargetOpt(i)} is {@code n} if
 * field {@code i} projects input field {@code n}, -1 if it is an
 * expression.
 */
public static Mappings.TargetMapping permutation(List<RexNode> nodes, RelDataType inputRowType) {
    final Mappings.TargetMapping mapping = Mappings.create(MappingType.PARTIAL_FUNCTION, nodes.size(),
            inputRowType.getFieldCount());
    for (Ord<RexNode> node : Ord.zip(nodes)) {
        if (node.e instanceof RexInputRef) {
            mapping.set(node.i, ((RexInputRef) node.e).getIndex());
        }
    }
    return mapping;
}
 
Example 10
Source File: ExtendedAggregateExtractProjectRule.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Extract projects from the Aggregate and return the index mapping between the new projects
 * and it's input.
 */
private Mapping extractProjectsAndMapping(
	Aggregate aggregate,
	RelNode input,
	RelBuilder relBuilder) {

	// Compute which input fields are used.
	final ImmutableBitSet.Builder inputFieldsUsed = getInputFieldUsed(aggregate, input);

	final List<RexNode> projects = new ArrayList<>();
	final Mapping mapping =
		Mappings.create(MappingType.INVERSE_SURJECTION,
			aggregate.getInput().getRowType().getFieldCount(),
			inputFieldsUsed.cardinality());
	int j = 0;
	for (int i : inputFieldsUsed.build()) {
		projects.add(relBuilder.field(i));
		mapping.set(i, j++);
	}

	if (input instanceof Project) {
		// this will not create trivial projects
		relBuilder.project(projects);
	} else {
		relBuilder.project(projects, Collections.emptyList(), true);
	}

	return mapping;
}
 
Example 11
Source File: DremioFieldTrimmer.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for {@link ScanCrel}.
 */
@SuppressWarnings("unused")
public TrimResult trimFields(
    ScanCrel crel,
    ImmutableBitSet fieldsUsed,
    Set<RelDataTypeField> extraFields) {

  if(fieldsUsed.cardinality() == crel.getRowType().getFieldCount()) {
    return result(crel, Mappings.createIdentity(crel.getRowType().getFieldCount()));
  }

  if(fieldsUsed.cardinality() == 0) {
    // do something similar to dummy project but avoid using a scan field. This ensures the scan
    // does a skipAll operation rather than projectin a useless column.
    final RelOptCluster cluster = crel.getCluster();
    final Mapping mapping = Mappings.create(MappingType.INVERSE_SURJECTION, crel.getRowType().getFieldCount(), 1);
    final RexLiteral expr = cluster.getRexBuilder().makeExactLiteral(BigDecimal.ZERO);
    builder.push(crel);
    builder.project(ImmutableList.<RexNode>of(expr), ImmutableList.of("DUMMY"));
    return result(builder.build(), mapping);
  }

  final List<SchemaPath> paths = new ArrayList<>();
  final Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, crel.getRowType().getFieldCount(), fieldsUsed.cardinality());
  int index = 0;
  for(int i : fieldsUsed) {
    paths.add(SchemaPath.getSimplePath(crel.getRowType().getFieldList().get(i).getName()));
    m.set(i, index);
    index++;
  }

  ScanCrel newCrel = crel.cloneWithProject(paths);
  return result(newCrel, m);
}
 
Example 12
Source File: ExtendedAggregateExtractProjectRule.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Extract projects from the Aggregate and return the index mapping between the new projects
 * and it's input.
 */
private Mapping extractProjectsAndMapping(
	Aggregate aggregate,
	RelNode input,
	RelBuilder relBuilder) {

	// Compute which input fields are used.
	final ImmutableBitSet.Builder inputFieldsUsed = getInputFieldUsed(aggregate, input);

	final List<RexNode> projects = new ArrayList<>();
	final Mapping mapping =
		Mappings.create(MappingType.INVERSE_SURJECTION,
			aggregate.getInput().getRowType().getFieldCount(),
			inputFieldsUsed.cardinality());
	int j = 0;
	for (int i : inputFieldsUsed.build()) {
		projects.add(relBuilder.field(i));
		mapping.set(i, j++);
	}

	if (input instanceof Project) {
		// this will not create trivial projects
		relBuilder.project(projects);
	} else {
		relBuilder.project(projects, Collections.emptyList(), true);
	}

	return mapping;
}
 
Example 13
Source File: MutableRels.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Equivalent to
 * {@link RelOptUtil#createProject(org.apache.calcite.rel.RelNode, java.util.List)}
 * for {@link MutableRel}. */
public static MutableRel createProject(final MutableRel child,
    final List<Integer> posList) {
  final RelDataType rowType = child.rowType;
  if (Mappings.isIdentity(posList, rowType.getFieldCount())) {
    return child;
  }
  final Mapping mapping =
      Mappings.create(
          MappingType.INVERSE_SURJECTION,
          rowType.getFieldCount(),
          posList.size());
  for (int i = 0; i < posList.size(); i++) {
    mapping.set(posList.get(i), i);
  }
  return MutableProject.of(
      RelOptUtil.permute(child.cluster.getTypeFactory(), rowType, mapping),
      child,
      new AbstractList<RexNode>() {
        public int size() {
          return posList.size();
        }

        public RexNode get(int index) {
          final int pos = posList.get(index);
          return RexInputRef.of(pos, rowType);
        }
      });
}
 
Example 14
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Infers predicates for an Aggregate.
 *
 * <p>Pulls up predicates that only contains references to columns in the
 * GroupSet. For e.g.
 *
 * <blockquote><pre>
 * inputPullUpExprs : { a &gt; 7, b + c &lt; 10, a + e = 9}
 * groupSet         : { a, b}
 * pulledUpExprs    : { a &gt; 7}
 * </pre></blockquote>
 */
public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
  final RelNode input = agg.getInput();
  final RexBuilder rexBuilder = agg.getCluster().getRexBuilder();
  final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
  final List<RexNode> aggPullUpPredicates = new ArrayList<>();

  ImmutableBitSet groupKeys = agg.getGroupSet();
  if (groupKeys.isEmpty()) {
    // "GROUP BY ()" can convert an empty relation to a non-empty relation, so
    // it is not valid to pull up predicates. In particular, consider the
    // predicate "false": it is valid on all input rows (trivially - there are
    // no rows!) but not on the output (there is one row).
    return RelOptPredicateList.EMPTY;
  }
  Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
      input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());

  int i = 0;
  for (int j : groupKeys) {
    m.set(j, i++);
  }

  for (RexNode r : inputInfo.pulledUpPredicates) {
    ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
    if (groupKeys.contains(rCols)) {
      r = r.accept(new RexPermuteInputsShuttle(m, input));
      aggPullUpPredicates.add(r);
    }
  }
  return RelOptPredicateList.of(rexBuilder, aggPullUpPredicates);
}
 
Example 15
Source File: RelFieldTrimmer.java    From calcite with Apache License 2.0 5 votes vote down vote up
protected Mapping createMapping(ImmutableBitSet fieldsUsed, int fieldCount) {
  final Mapping mapping =
      Mappings.create(
          MappingType.INVERSE_SURJECTION,
          fieldCount,
          fieldsUsed.cardinality());
  int i = 0;
  for (int field : fieldsUsed) {
    mapping.set(field, i++);
  }
  return mapping;
}
 
Example 16
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Infers predicates for an Aggregate.
 *
 * <p>Pulls up predicates that only contains references to columns in the
 * GroupSet. For e.g.
 *
 * <blockquote><pre>
 * inputPullUpExprs : { a &gt; 7, b + c &lt; 10, a + e = 9}
 * groupSet         : { a, b}
 * pulledUpExprs    : { a &gt; 7}
 * </pre></blockquote>
 */
public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
  final RelNode input = agg.getInput();
  final RexBuilder rexBuilder = agg.getCluster().getRexBuilder();
  final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
  final List<RexNode> aggPullUpPredicates = new ArrayList<>();

  ImmutableBitSet groupKeys = agg.getGroupSet();
  if (groupKeys.isEmpty()) {
    // "GROUP BY ()" can convert an empty relation to a non-empty relation, so
    // it is not valid to pull up predicates. In particular, consider the
    // predicate "false": it is valid on all input rows (trivially - there are
    // no rows!) but not on the output (there is one row).
    return RelOptPredicateList.EMPTY;
  }
  Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
      input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());

  int i = 0;
  for (int j : groupKeys) {
    m.set(j, i++);
  }

  for (RexNode r : inputInfo.pulledUpPredicates) {
    ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
    if (groupKeys.contains(rCols)) {
      r = r.accept(new RexPermuteInputsShuttle(m, input));
      aggPullUpPredicates.add(r);
    }
  }
  return RelOptPredicateList.of(rexBuilder, aggPullUpPredicates);
}
 
Example 17
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Infers predicates for a project.
 *
 * <ol>
 * <li>create a mapping from input to projection. Map only positions that
 * directly reference an input column.
 * <li>Expressions that only contain above columns are retained in the
 * Project's pullExpressions list.
 * <li>For e.g. expression 'a + e = 9' below will not be pulled up because 'e'
 * is not in the projection list.
 *
 * <blockquote><pre>
 * inputPullUpExprs:      {a &gt; 7, b + c &lt; 10, a + e = 9}
 * projectionExprs:       {a, b, c, e / 2}
 * projectionPullupExprs: {a &gt; 7, b + c &lt; 10}
 * </pre></blockquote>
 *
 * </ol>
 */
public RelOptPredicateList getPredicates(Project project,
    RelMetadataQuery mq) {
  final RelNode input = project.getInput();
  final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
  final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
  final List<RexNode> projectPullUpPredicates = new ArrayList<>();

  ImmutableBitSet.Builder columnsMappedBuilder = ImmutableBitSet.builder();
  Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
      input.getRowType().getFieldCount(),
      project.getRowType().getFieldCount());

  for (Ord<RexNode> expr : Ord.zip(project.getProjects())) {
    if (expr.e instanceof RexInputRef) {
      int sIdx = ((RexInputRef) expr.e).getIndex();
      m.set(sIdx, expr.i);
      columnsMappedBuilder.set(sIdx);
    // Project can also generate constants. We need to include them.
    } else if (RexLiteral.isNullLiteral(expr.e)) {
      projectPullUpPredicates.add(
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL,
              rexBuilder.makeInputRef(project, expr.i)));
    } else if (RexUtil.isConstant(expr.e)) {
      final List<RexNode> args =
          ImmutableList.of(rexBuilder.makeInputRef(project, expr.i), expr.e);
      final SqlOperator op = args.get(0).getType().isNullable()
          || args.get(1).getType().isNullable()
          ? SqlStdOperatorTable.IS_NOT_DISTINCT_FROM
          : SqlStdOperatorTable.EQUALS;
      projectPullUpPredicates.add(rexBuilder.makeCall(op, args));
    }
  }

  // Go over childPullUpPredicates. If a predicate only contains columns in
  // 'columnsMapped' construct a new predicate based on mapping.
  final ImmutableBitSet columnsMapped = columnsMappedBuilder.build();
  for (RexNode r : inputInfo.pulledUpPredicates) {
    RexNode r2 = projectPredicate(rexBuilder, input, r, columnsMapped);
    if (!r2.isAlwaysTrue()) {
      r2 = r2.accept(new RexPermuteInputsShuttle(m, input));
      projectPullUpPredicates.add(r2);
    }
  }
  return RelOptPredicateList.of(rexBuilder, projectPullUpPredicates);
}
 
Example 18
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Infers predicates for a project.
 *
 * <ol>
 * <li>create a mapping from input to projection. Map only positions that
 * directly reference an input column.
 * <li>Expressions that only contain above columns are retained in the
 * Project's pullExpressions list.
 * <li>For e.g. expression 'a + e = 9' below will not be pulled up because 'e'
 * is not in the projection list.
 *
 * <blockquote><pre>
 * inputPullUpExprs:      {a &gt; 7, b + c &lt; 10, a + e = 9}
 * projectionExprs:       {a, b, c, e / 2}
 * projectionPullupExprs: {a &gt; 7, b + c &lt; 10}
 * </pre></blockquote>
 *
 * </ol>
 */
public RelOptPredicateList getPredicates(Project project,
    RelMetadataQuery mq) {
  final RelNode input = project.getInput();
  final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
  final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
  final List<RexNode> projectPullUpPredicates = new ArrayList<>();

  ImmutableBitSet.Builder columnsMappedBuilder = ImmutableBitSet.builder();
  Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
      input.getRowType().getFieldCount(),
      project.getRowType().getFieldCount());

  for (Ord<RexNode> expr : Ord.zip(project.getProjects())) {
    if (expr.e instanceof RexInputRef) {
      int sIdx = ((RexInputRef) expr.e).getIndex();
      m.set(sIdx, expr.i);
      columnsMappedBuilder.set(sIdx);
    // Project can also generate constants. We need to include them.
    } else if (RexLiteral.isNullLiteral(expr.e)) {
      projectPullUpPredicates.add(
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL,
              rexBuilder.makeInputRef(project, expr.i)));
    } else if (RexUtil.isConstant(expr.e)) {
      final List<RexNode> args =
          ImmutableList.of(rexBuilder.makeInputRef(project, expr.i), expr.e);
      final SqlOperator op = args.get(0).getType().isNullable()
          || args.get(1).getType().isNullable()
          ? SqlStdOperatorTable.IS_NOT_DISTINCT_FROM
          : SqlStdOperatorTable.EQUALS;
      projectPullUpPredicates.add(rexBuilder.makeCall(op, args));
    }
  }

  // Go over childPullUpPredicates. If a predicate only contains columns in
  // 'columnsMapped' construct a new predicate based on mapping.
  final ImmutableBitSet columnsMapped = columnsMappedBuilder.build();
  for (RexNode r : inputInfo.pulledUpPredicates) {
    RexNode r2 = projectPredicate(rexBuilder, input, r, columnsMapped);
    if (!r2.isAlwaysTrue()) {
      r2 = r2.accept(new RexPermuteInputsShuttle(m, input));
      projectPullUpPredicates.add(r2);
    }
  }
  return RelOptPredicateList.of(rexBuilder, projectPullUpPredicates);
}
 
Example 19
Source File: EnumerableTraitsUtils.java    From calcite with Apache License 2.0 4 votes vote down vote up
static Pair<RelTraitSet, List<RelTraitSet>> deriveTraitsForProject(
    RelTraitSet childTraits, int childId, List<RexNode> exps,
    RelDataType inputRowType, RelDataTypeFactory typeFactory, RelTraitSet currentTraits) {
  final RelCollation collation = childTraits.getCollation();
  if (collation == null || collation == RelCollations.EMPTY) {
    return null;
  }

  final int maxField = Math.max(exps.size(),
      inputRowType.getFieldCount());
  Mappings.TargetMapping mapping = Mappings
      .create(MappingType.FUNCTION, maxField, maxField);
  for (Ord<RexNode> node : Ord.zip(exps)) {
    if (node.e instanceof RexInputRef) {
      mapping.set(((RexInputRef) node.e).getIndex(), node.i);
    } else if (node.e.isA(SqlKind.CAST)) {
      final RexNode operand = ((RexCall) node.e).getOperands().get(0);
      if (operand instanceof RexInputRef) {
        mapping.set(((RexInputRef) operand).getIndex(), node.i);
      }
    }
  }

  List<RelFieldCollation> collationFieldsToDerive = new ArrayList<>();
  for (RelFieldCollation rc : collation.getFieldCollations()) {
    if (isCollationOnTrivialExpr(exps, typeFactory, mapping, rc, false)) {
      collationFieldsToDerive.add(rc);
    } else {
      break;
    }
  }

  if (collationFieldsToDerive.size() > 0) {
    final RelCollation newCollation = RelCollations
        .of(collationFieldsToDerive).apply(mapping);
    return Pair.of(currentTraits.replace(newCollation),
        ImmutableList.of(currentTraits.replace(collation)));
  } else {
    return null;
  }
}
 
Example 20
Source File: Project.java    From Bats with Apache License 2.0 3 votes vote down vote up
/**
 * Returns a partial mapping of a set of project expressions.
 *
 * <p>The mapping is an inverse function.
 * Every target has a source field, but
 * a source might have 0, 1 or more targets.
 * Project expressions that do not consist of
 * a mapping are ignored.
 *
 * @param inputFieldCount Number of input fields
 * @param projects Project expressions
 * @return Mapping of a set of project expressions, never null
 */
public static Mappings.TargetMapping getPartialMapping(int inputFieldCount,
    List<? extends RexNode> projects) {
  Mappings.TargetMapping mapping =
      Mappings.create(MappingType.INVERSE_FUNCTION,
          inputFieldCount, projects.size());
  for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) {
    if (exp.e instanceof RexInputRef) {
      mapping.set(((RexInputRef) exp.e).getIndex(), exp.i);
    }
  }
  return mapping;
}