Java Code Examples for org.apache.calcite.util.mapping.Mappings#TargetMapping
The following examples show how to use
org.apache.calcite.util.mapping.Mappings#TargetMapping .
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: SubstitutionVisitor.java From Bats with Apache License 2.0 | 6 votes |
@Override public UnifyResult apply(UnifyRuleCall call) { final MutableAggregate query = (MutableAggregate) call.query; final MutableAggregate target = (MutableAggregate) call.target; if (!(query.getInput() instanceof MutableProject)) { return null; } final MutableProject project = (MutableProject) query.getInput(); if (project.getInput() != target.getInput()) { return null; } final Mappings.TargetMapping mapping = project.getMapping(); if (mapping == null) { return null; } final MutableAggregate aggregate2 = permute(query, project.getInput(), mapping.inverse()); final MutableRel result = unifyAggregates(aggregate2, target); return result == null ? null : call.result(result); }
Example 2
Source File: EnumerableMergeJoin.java From calcite with Apache License 2.0 | 5 votes |
private Mappings.TargetMapping buildMapping(boolean left2Right) { ImmutableIntList sourceKeys = left2Right ? joinInfo.leftKeys : joinInfo.rightKeys; ImmutableIntList targetKeys = left2Right ? joinInfo.rightKeys : joinInfo.leftKeys; Map<Integer, Integer> keyMap = new HashMap<>(); for (int i = 0; i < joinInfo.leftKeys.size(); i++) { keyMap.put(sourceKeys.get(i), targetKeys.get(i)); } Mappings.TargetMapping mapping = Mappings.target(keyMap, (left2Right ? left : right).getRowType().getFieldCount(), (left2Right ? right : left).getRowType().getFieldCount()); return mapping; }
Example 3
Source File: RexProgram.java From calcite with Apache License 2.0 | 5 votes |
/** * 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 4
Source File: SortProjectTransposeRule.java From calcite with Apache License 2.0 | 4 votes |
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 5
Source File: RexPermuteInputsShuttle.java From calcite with Apache License 2.0 | 4 votes |
/** Creates a shuttle with an empty field list. It cannot handle GET calls but * otherwise works OK. */ public static RexPermuteInputsShuttle of(Mappings.TargetMapping mapping) { return new RexPermuteInputsShuttle(mapping, ImmutableList.of()); }
Example 6
Source File: SqlSplittableAggFunction.java From Bats with Apache License 2.0 | 4 votes |
public AggregateCall split(AggregateCall aggregateCall, Mappings.TargetMapping mapping) { return aggregateCall.transform(mapping); }
Example 7
Source File: JoinPushThroughJoinRule.java From calcite with Apache License 2.0 | 4 votes |
/** * Similar to {@link #onMatch}, but swaps the upper sibling with the left * of the two lower siblings, rather than the right. */ private void onMatchLeft(RelOptRuleCall call) { final Join topJoin = call.rel(0); final Join bottomJoin = call.rel(1); final RelNode relC = call.rel(2); final RelNode relA = bottomJoin.getLeft(); final RelNode relB = bottomJoin.getRight(); final RelOptCluster cluster = topJoin.getCluster(); // topJoin // / \ // bottomJoin C // / \ // A B final int aCount = relA.getRowType().getFieldCount(); final int bCount = relB.getRowType().getFieldCount(); final int cCount = relC.getRowType().getFieldCount(); final ImmutableBitSet aBitSet = ImmutableBitSet.range(aCount); // becomes // // newTopJoin // / \ // newBottomJoin A // / \ // C B // If either join is not inner, we cannot proceed. // (Is this too strict?) if (topJoin.getJoinType() != JoinRelType.INNER || bottomJoin.getJoinType() != JoinRelType.INNER) { return; } // Split the condition of topJoin into a conjunction. Each of the // parts that does not use columns from A can be pushed down. final List<RexNode> intersecting = new ArrayList<>(); final List<RexNode> nonIntersecting = new ArrayList<>(); split(topJoin.getCondition(), aBitSet, intersecting, nonIntersecting); // If there's nothing to push down, it's not worth proceeding. if (nonIntersecting.isEmpty()) { return; } // Split the condition of bottomJoin into a conjunction. Each of the // parts that use columns from A will need to be pulled up. final List<RexNode> bottomIntersecting = new ArrayList<>(); final List<RexNode> bottomNonIntersecting = new ArrayList<>(); split( bottomJoin.getCondition(), aBitSet, bottomIntersecting, bottomNonIntersecting); // target: | C | B | // source: | A | B | C | final Mappings.TargetMapping bottomMapping = Mappings.createShiftMapping( aCount + bCount + cCount, cCount, aCount, bCount, 0, aCount + bCount, cCount); final List<RexNode> newBottomList = new ArrayList<>(); new RexPermuteInputsShuttle(bottomMapping, relC, relB) .visitList(nonIntersecting, newBottomList); new RexPermuteInputsShuttle(bottomMapping, relC, relB) .visitList(bottomNonIntersecting, newBottomList); final RexBuilder rexBuilder = cluster.getRexBuilder(); RexNode newBottomCondition = RexUtil.composeConjunction(rexBuilder, newBottomList); final Join newBottomJoin = bottomJoin.copy(bottomJoin.getTraitSet(), newBottomCondition, relC, relB, bottomJoin.getJoinType(), bottomJoin.isSemiJoinDone()); // target: | C | B | A | // source: | A | B | C | final Mappings.TargetMapping topMapping = Mappings.createShiftMapping( aCount + bCount + cCount, cCount + bCount, 0, aCount, cCount, aCount, bCount, 0, aCount + bCount, cCount); final List<RexNode> newTopList = new ArrayList<>(); new RexPermuteInputsShuttle(topMapping, newBottomJoin, relA) .visitList(intersecting, newTopList); new RexPermuteInputsShuttle(topMapping, newBottomJoin, relA) .visitList(bottomIntersecting, newTopList); RexNode newTopCondition = RexUtil.composeConjunction(rexBuilder, newTopList); @SuppressWarnings("SuspiciousNameCombination") final Join newTopJoin = topJoin.copy(topJoin.getTraitSet(), newTopCondition, newBottomJoin, relA, topJoin.getJoinType(), topJoin.isSemiJoinDone()); final RelBuilder relBuilder = call.builder(); relBuilder.push(newTopJoin); relBuilder.project(relBuilder.fields(topMapping)); call.transformTo(relBuilder.build()); }
Example 8
Source File: SqlSplittableAggFunction.java From Bats with Apache License 2.0 | 4 votes |
AggregateCall split(AggregateCall aggregateCall, Mappings.TargetMapping mapping);
Example 9
Source File: UnionPullUpConstantsRule.java From calcite with Apache License 2.0 | 4 votes |
@Override public void onMatch(RelOptRuleCall call) { final Union union = call.rel(0); final RexBuilder rexBuilder = union.getCluster().getRexBuilder(); final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(union); if (predicates == null) { return; } final Map<Integer, RexNode> constants = new HashMap<>(); for (Map.Entry<RexNode, RexNode> e : predicates.constantMap.entrySet()) { if (e.getKey() instanceof RexInputRef) { constants.put(((RexInputRef) e.getKey()).getIndex(), e.getValue()); } } // None of the expressions are constant. Nothing to do. if (constants.isEmpty()) { return; } // Create expressions for Project operators before and after the Union List<RelDataTypeField> fields = union.getRowType().getFieldList(); List<RexNode> topChildExprs = new ArrayList<>(); List<String> topChildExprsFields = new ArrayList<>(); List<RexNode> refs = new ArrayList<>(); ImmutableBitSet.Builder refsIndexBuilder = ImmutableBitSet.builder(); for (RelDataTypeField field : fields) { final RexNode constant = constants.get(field.getIndex()); if (constant != null) { topChildExprs.add(constant); topChildExprsFields.add(field.getName()); } else { final RexNode expr = rexBuilder.makeInputRef(union, field.getIndex()); topChildExprs.add(expr); topChildExprsFields.add(field.getName()); refs.add(expr); refsIndexBuilder.set(field.getIndex()); } } ImmutableBitSet refsIndex = refsIndexBuilder.build(); // Update top Project positions final Mappings.TargetMapping mapping = RelOptUtil.permutation(refs, union.getInput(0).getRowType()).inverse(); topChildExprs = RexUtil.apply(mapping, topChildExprs); // Create new Project-Union-Project sequences final RelBuilder relBuilder = call.builder(); for (RelNode input : union.getInputs()) { List<Pair<RexNode, String>> newChildExprs = new ArrayList<>(); for (int j : refsIndex) { newChildExprs.add( Pair.of(rexBuilder.makeInputRef(input, j), input.getRowType().getFieldList().get(j).getName())); } if (newChildExprs.isEmpty()) { // At least a single item in project is required. newChildExprs.add( Pair.of(topChildExprs.get(0), topChildExprsFields.get(0))); } // Add the input with project on top relBuilder.push(input); relBuilder.project(Pair.left(newChildExprs), Pair.right(newChildExprs)); } relBuilder.union(union.all, union.getInputs().size()); // Create top Project fixing nullability of fields relBuilder.project(topChildExprs, topChildExprsFields); relBuilder.convert(union.getRowType(), false); call.transformTo(relBuilder.build()); }
Example 10
Source File: AggregateCall.java From Bats with Apache License 2.0 | 4 votes |
/** Creates a copy of this aggregate call, applying a mapping to its * arguments. */ public AggregateCall transform(Mappings.TargetMapping mapping) { return copy(Mappings.apply2((Mapping) mapping, argList), hasFilter() ? Mappings.apply(mapping, filterArg) : -1, RelCollations.permute(collation, mapping)); }
Example 11
Source File: RelBuilder.java From calcite with Apache License 2.0 | 4 votes |
/** Returns references to fields identified by a mapping. */ public ImmutableList<RexNode> fields(Mappings.TargetMapping mapping) { return fields(Mappings.asList(mapping)); }
Example 12
Source File: SqlSplittableAggFunction.java From calcite with Apache License 2.0 | 4 votes |
public AggregateCall split(AggregateCall aggregateCall, Mappings.TargetMapping mapping) { return aggregateCall.transform(mapping); }
Example 13
Source File: RelOptUtil.java From Bats with Apache License 2.0 | 4 votes |
public static RelNode createProject(RelNode child, Mappings.TargetMapping mapping, RelFactories.ProjectFactory projectFactory) { return createProject(projectFactory, child, Mappings.asList(mapping.inverse())); }
Example 14
Source File: JoinAssociateRule.java From Bats with Apache License 2.0 | 4 votes |
public void onMatch(final RelOptRuleCall call) { final Join topJoin = call.rel(0); final Join bottomJoin = call.rel(1); final RelNode relA = bottomJoin.getLeft(); final RelNode relB = bottomJoin.getRight(); final RelSubset relC = call.rel(2); final RelOptCluster cluster = topJoin.getCluster(); final RexBuilder rexBuilder = cluster.getRexBuilder(); if (relC.getConvention() != relA.getConvention()) { // relC could have any trait-set. But if we're matching say // EnumerableConvention, we're only interested in enumerable subsets. return; } // topJoin // / \ // bottomJoin C // / \ // A B final int aCount = relA.getRowType().getFieldCount(); final int bCount = relB.getRowType().getFieldCount(); final int cCount = relC.getRowType().getFieldCount(); final ImmutableBitSet aBitSet = ImmutableBitSet.range(0, aCount); final ImmutableBitSet bBitSet = ImmutableBitSet.range(aCount, aCount + bCount); if (!topJoin.getSystemFieldList().isEmpty()) { // FIXME Enable this rule for joins with system fields return; } // If either join is not inner, we cannot proceed. // (Is this too strict?) if (topJoin.getJoinType() != JoinRelType.INNER || bottomJoin.getJoinType() != JoinRelType.INNER) { return; } // Goal is to transform to // // newTopJoin // / \ // A newBottomJoin // / \ // B C // Split the condition of topJoin and bottomJoin into a conjunctions. A // condition can be pushed down if it does not use columns from A. final List<RexNode> top = new ArrayList<>(); final List<RexNode> bottom = new ArrayList<>(); JoinPushThroughJoinRule.split(topJoin.getCondition(), aBitSet, top, bottom); JoinPushThroughJoinRule.split(bottomJoin.getCondition(), aBitSet, top, bottom); // Mapping for moving conditions from topJoin or bottomJoin to // newBottomJoin. // target: | B | C | // source: | A | B | C | final Mappings.TargetMapping bottomMapping = Mappings.createShiftMapping( aCount + bCount + cCount, 0, aCount, bCount, bCount, aCount + bCount, cCount); final List<RexNode> newBottomList = new ArrayList<>(); new RexPermuteInputsShuttle(bottomMapping, relB, relC) .visitList(bottom, newBottomList); RexNode newBottomCondition = RexUtil.composeConjunction(rexBuilder, newBottomList); final Join newBottomJoin = bottomJoin.copy(bottomJoin.getTraitSet(), newBottomCondition, relB, relC, JoinRelType.INNER, false); // Condition for newTopJoin consists of pieces from bottomJoin and topJoin. // Field ordinals do not need to be changed. RexNode newTopCondition = RexUtil.composeConjunction(rexBuilder, top); @SuppressWarnings("SuspiciousNameCombination") final Join newTopJoin = topJoin.copy(topJoin.getTraitSet(), newTopCondition, relA, newBottomJoin, JoinRelType.INNER, false); call.transformTo(newTopJoin); }
Example 15
Source File: SqlSplittableAggFunction.java From calcite with Apache License 2.0 | 4 votes |
public AggregateCall split(AggregateCall aggregateCall, Mappings.TargetMapping mapping) { return aggregateCall.transform(mapping); }
Example 16
Source File: MutableProject.java From Bats with Apache License 2.0 | 4 votes |
public Mappings.TargetMapping getMapping() { return Project.getMapping(input.rowType.getFieldCount(), projects); }
Example 17
Source File: RelOptMaterialization.java From calcite with Apache License 2.0 | 4 votes |
private ProjectFilterTable(RexNode condition, Mappings.TargetMapping mapping, TableScan scan) { this.condition = condition; this.mapping = mapping; this.scan = Objects.requireNonNull(scan); }
Example 18
Source File: RelTrait.java From calcite with Apache License 2.0 | 2 votes |
/** * Applies a mapping to this trait. * * <p>Some traits may be changed if the columns order is changed by a mapping * of the {@link Project} operator. </p> * * <p>For example, if relation {@code SELECT a, b ORDER BY a, b} is sorted by * columns [0, 1], then the project {@code SELECT b, a} over this relation * will be sorted by columns [1, 0]. In the same time project {@code SELECT b} * will not be sorted at all because it doesn't contain the collation * prefix and this method will return an empty collation. </p> * * <p>Other traits are independent from the columns remapping. For example * {@link Convention} or {@link RelDistributions#SINGLETON}.</p> * * @param mapping Mapping * @return trait with mapping applied */ default <T extends RelTrait> T apply(Mappings.TargetMapping mapping) { return (T) this; }
Example 19
Source File: RexUtil.java From Bats with Apache License 2.0 | 2 votes |
/** * Applies a mapping to a collation. * * @param mapping Mapping * @param collation Collation * @return collation with mapping applied */ public static RelCollation apply(Mappings.TargetMapping mapping, RelCollation collation) { List<RelFieldCollation> fieldCollations = applyFields(mapping, collation.getFieldCollations()); return fieldCollations.equals(collation.getFieldCollations()) ? collation : RelCollations.of(fieldCollations); }
Example 20
Source File: Project.java From calcite with Apache License 2.0 | 2 votes |
/** * Returns a mapping, or null if this projection is not a mapping. * * @return Mapping, or null if this projection is not a mapping */ public Mappings.TargetMapping getMapping() { return getMapping(getInput().getRowType().getFieldCount(), exps); }