Search in sources :

Example 96 with Pair

use of org.apache.calcite.util.Pair in project calcite by apache.

the class RelOptMaterializations method useMaterializedViews.

/**
 * Returns a list of RelNode transformed from all possible combination of
 * materialized view uses. Big queries will likely have more than one
 * transformed RelNode, e.g., (t1 group by c1) join (t2 group by c2).
 * @param rel               the original RelNode
 * @param materializations  the materialized view list
 * @return the list of transformed RelNode together with their corresponding
 *         materialized views used in the transformation.
 */
public static List<Pair<RelNode, List<RelOptMaterialization>>> useMaterializedViews(final RelNode rel, List<RelOptMaterialization> materializations) {
    final List<RelOptMaterialization> applicableMaterializations = getApplicableMaterializations(rel, materializations);
    final List<Pair<RelNode, List<RelOptMaterialization>>> applied = new ArrayList<>();
    applied.add(Pair.<RelNode, List<RelOptMaterialization>>of(rel, ImmutableList.<RelOptMaterialization>of()));
    for (RelOptMaterialization m : applicableMaterializations) {
        int count = applied.size();
        for (int i = 0; i < count; i++) {
            Pair<RelNode, List<RelOptMaterialization>> current = applied.get(i);
            List<RelNode> sub = substitute(current.left, m);
            if (!sub.isEmpty()) {
                ImmutableList.Builder<RelOptMaterialization> builder = ImmutableList.builder();
                builder.addAll(current.right);
                builder.add(m);
                List<RelOptMaterialization> uses = builder.build();
                for (RelNode rel2 : sub) {
                    applied.add(Pair.of(rel2, uses));
                }
            }
        }
    }
    return applied.subList(1, applied.size());
}
Also used : RelNode(org.apache.calcite.rel.RelNode) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Pair(org.apache.calcite.util.Pair)

Example 97 with Pair

use of org.apache.calcite.util.Pair in project calcite by apache.

the class SplunkPushDownRule method appendSearchString.

/**
 * Appends a search string.
 *
 * @param toAppend Search string to append
 * @param splunkRel Relational expression
 * @param topProj Top projection
 * @param bottomProj Bottom projection
 */
protected RelNode appendSearchString(String toAppend, SplunkTableScan splunkRel, LogicalProject topProj, LogicalProject bottomProj, RelDataType topRow, RelDataType bottomRow) {
    final RelOptCluster cluster = splunkRel.getCluster();
    StringBuilder updateSearchStr = new StringBuilder(splunkRel.search);
    if (!toAppend.isEmpty()) {
        updateSearchStr.append(" ").append(toAppend);
    }
    List<RelDataTypeField> bottomFields = bottomRow == null ? null : bottomRow.getFieldList();
    List<RelDataTypeField> topFields = topRow == null ? null : topRow.getFieldList();
    if (bottomFields == null) {
        bottomFields = splunkRel.getRowType().getFieldList();
    }
    // handle bottom projection (ie choose a subset of the table fields)
    if (bottomProj != null) {
        List<RelDataTypeField> tmp = new ArrayList<RelDataTypeField>();
        List<RelDataTypeField> dRow = bottomProj.getRowType().getFieldList();
        for (RexNode rn : bottomProj.getProjects()) {
            RelDataTypeField rdtf;
            if (rn instanceof RexSlot) {
                RexSlot rs = (RexSlot) rn;
                rdtf = bottomFields.get(rs.getIndex());
            } else {
                rdtf = dRow.get(tmp.size());
            }
            tmp.add(rdtf);
        }
        bottomFields = tmp;
    }
    // field renaming: to -> from
    List<Pair<String, String>> renames = new LinkedList<Pair<String, String>>();
    // handle top projection (ie reordering and renaming)
    List<RelDataTypeField> newFields = bottomFields;
    if (topProj != null) {
        LOGGER.debug("topProj: {}", String.valueOf(topProj.getPermutation()));
        newFields = new ArrayList<RelDataTypeField>();
        int i = 0;
        for (RexNode rn : topProj.getProjects()) {
            RexInputRef rif = (RexInputRef) rn;
            RelDataTypeField field = bottomFields.get(rif.getIndex());
            if (!bottomFields.get(rif.getIndex()).getName().equals(topFields.get(i).getName())) {
                renames.add(Pair.of(bottomFields.get(rif.getIndex()).getName(), topFields.get(i).getName()));
                field = topFields.get(i);
            }
            newFields.add(field);
        }
    }
    if (!renames.isEmpty()) {
        updateSearchStr.append("| rename ");
        for (Pair<String, String> p : renames) {
            updateSearchStr.append(p.left).append(" AS ").append(p.right).append(" ");
        }
    }
    RelDataType resultType = cluster.getTypeFactory().createStructType(newFields);
    String searchWithFilter = updateSearchStr.toString();
    RelNode rel = new SplunkTableScan(cluster, splunkRel.getTable(), splunkRel.splunkTable, searchWithFilter, splunkRel.earliest, splunkRel.latest, resultType.getFieldNames());
    LOGGER.debug("end of appendSearchString fieldNames: {}", rel.getRowType().getFieldNames());
    return rel;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) LinkedList(java.util.LinkedList) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexSlot(org.apache.calcite.rex.RexSlot) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 98 with Pair

use of org.apache.calcite.util.Pair in project flink by apache.

the class RelDecorrelator method projectJoinOutputWithNullability.

/**
 * Pulls project above the join from its RHS input. Enforces nullability for join output.
 *
 * @param join Join
 * @param project Original project as the right-hand input of the join
 * @param nullIndicatorPos Position of null indicator
 * @return the subtree with the new Project at the root
 */
private RelNode projectJoinOutputWithNullability(Join join, Project project, int nullIndicatorPos) {
    final RelDataTypeFactory typeFactory = join.getCluster().getTypeFactory();
    final RelNode left = join.getLeft();
    final JoinRelType joinType = join.getJoinType();
    RexInputRef nullIndicator = new RexInputRef(nullIndicatorPos, typeFactory.createTypeWithNullability(join.getRowType().getFieldList().get(nullIndicatorPos).getType(), true));
    // now create the new project
    List<Pair<RexNode, String>> newProjExprs = new ArrayList<>();
    // project everything from the LHS and then those from the original
    // projRel
    List<RelDataTypeField> leftInputFields = left.getRowType().getFieldList();
    for (int i = 0; i < leftInputFields.size(); i++) {
        newProjExprs.add(RexInputRef.of2(i, leftInputFields));
    }
    // Marked where the projected expr is coming from so that the types will
    // become nullable for the original projections which are now coming out
    // of the nullable side of the OJ.
    boolean projectPulledAboveLeftCorrelator = joinType.generatesNullsOnRight();
    for (Pair<RexNode, String> pair : project.getNamedProjects()) {
        RexNode newProjExpr = removeCorrelationExpr(pair.left, projectPulledAboveLeftCorrelator, nullIndicator);
        newProjExprs.add(Pair.of(newProjExpr, pair.right));
    }
    return relBuilder.push(join).projectNamed(Pair.left(newProjExprs), Pair.right(newProjExprs), true).build();
}
Also used : ArrayList(java.util.ArrayList) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexInputRef(org.apache.calcite.rex.RexInputRef) Pair(org.apache.calcite.util.Pair) RexNode(org.apache.calcite.rex.RexNode)

Example 99 with Pair

use of org.apache.calcite.util.Pair in project flink by apache.

the class RelDecorrelator method decorrelateRel.

public Frame decorrelateRel(Project rel) {
    // 
    // Rewrite logic:
    // 
    // 1. Pass along any correlated variables coming from the input.
    // 
    final RelNode oldInput = rel.getInput();
    Frame frame = getInvoke(oldInput, rel);
    if (frame == null) {
        // If input has not been rewritten, do not rewrite this rel.
        return null;
    }
    final List<RexNode> oldProjects = rel.getProjects();
    final List<RelDataTypeField> relOutput = rel.getRowType().getFieldList();
    // Project projects the original expressions,
    // plus any correlated variables the input wants to pass along.
    final List<Pair<RexNode, String>> projects = new ArrayList<>();
    // and produce the correlated variables in the new output.
    if (cm.mapRefRelToCorRef.containsKey(rel)) {
        frame = decorrelateInputWithValueGenerator(rel, frame);
    }
    // Project projects the original expressions
    final Map<Integer, Integer> mapOldToNewOutputs = new HashMap<>();
    int newPos;
    for (newPos = 0; newPos < oldProjects.size(); newPos++) {
        projects.add(newPos, Pair.of(decorrelateExpr(currentRel, map, cm, oldProjects.get(newPos)), relOutput.get(newPos).getName()));
        mapOldToNewOutputs.put(newPos, newPos);
    }
    // Project any correlated variables the input wants to pass along.
    final SortedMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
    for (Map.Entry<CorDef, Integer> entry : frame.corDefOutputs.entrySet()) {
        projects.add(RexInputRef.of2(entry.getValue(), frame.r.getRowType().getFieldList()));
        corDefOutputs.put(entry.getKey(), newPos);
        newPos++;
    }
    RelNode newProject = relBuilder.push(frame.r).projectNamed(Pair.left(projects), Pair.right(projects), true).build();
    newProject = RelOptUtil.copyRelHints(rel, newProject);
    return register(rel, newProject, mapOldToNewOutputs, corDefOutputs);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) ImmutableMap(com.google.common.collect.ImmutableMap) NavigableMap(java.util.NavigableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 100 with Pair

use of org.apache.calcite.util.Pair in project flink by apache.

the class RelDecorrelator method decorrelateRel.

public Frame decorrelateRel(Aggregate rel) {
    // Aggregate itself should not reference corVars.
    assert !cm.mapRefRelToCorRef.containsKey(rel);
    final RelNode oldInput = rel.getInput();
    final Frame frame = getInvoke(oldInput, rel);
    if (frame == null) {
        // If input has not been rewritten, do not rewrite this rel.
        return null;
    }
    final RelNode newInput = frame.r;
    // aggregate outputs mapping: group keys and aggregates
    final Map<Integer, Integer> outputMap = new HashMap<>();
    // map from newInput
    final Map<Integer, Integer> mapNewInputToProjOutputs = new HashMap<>();
    final int oldGroupKeyCount = rel.getGroupSet().cardinality();
    // Project projects the original expressions,
    // plus any correlated variables the input wants to pass along.
    final List<Pair<RexNode, String>> projects = new ArrayList<>();
    List<RelDataTypeField> newInputOutput = newInput.getRowType().getFieldList();
    int newPos = 0;
    // oldInput has the original group by keys in the front.
    final NavigableMap<Integer, RexLiteral> omittedConstants = new TreeMap<>();
    for (int i = 0; i < oldGroupKeyCount; i++) {
        final RexLiteral constant = projectedLiteral(newInput, i);
        if (constant != null) {
            // Exclude constants. Aggregate({true}) occurs because Aggregate({})
            // would generate 1 row even when applied to an empty table.
            omittedConstants.put(i, constant);
            continue;
        }
        // add mapping of group keys.
        outputMap.put(i, newPos);
        int newInputPos = frame.oldToNewOutputs.get(i);
        projects.add(RexInputRef.of2(newInputPos, newInputOutput));
        mapNewInputToProjOutputs.put(newInputPos, newPos);
        newPos++;
    }
    final SortedMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
    if (!frame.corDefOutputs.isEmpty()) {
        // position oldGroupKeyCount.
        for (Map.Entry<CorDef, Integer> entry : frame.corDefOutputs.entrySet()) {
            projects.add(RexInputRef.of2(entry.getValue(), newInputOutput));
            corDefOutputs.put(entry.getKey(), newPos);
            mapNewInputToProjOutputs.put(entry.getValue(), newPos);
            newPos++;
        }
    }
    // add the remaining fields
    final int newGroupKeyCount = newPos;
    for (int i = 0; i < newInputOutput.size(); i++) {
        if (!mapNewInputToProjOutputs.containsKey(i)) {
            projects.add(RexInputRef.of2(i, newInputOutput));
            mapNewInputToProjOutputs.put(i, newPos);
            newPos++;
        }
    }
    assert newPos == newInputOutput.size();
    // This Project will be what the old input maps to,
    // replacing any previous mapping from old input).
    RelNode newProject = relBuilder.push(newInput).projectNamed(Pair.left(projects), Pair.right(projects), true).build();
    newProject = RelOptUtil.copyRelHints(newInput, newProject);
    // update mappings:
    // oldInput ----> newInput
    // 
    // newProject
    // |
    // oldInput ----> newInput
    // 
    // is transformed to
    // 
    // oldInput ----> newProject
    // |
    // newInput
    Map<Integer, Integer> combinedMap = new HashMap<>();
    for (Integer oldInputPos : frame.oldToNewOutputs.keySet()) {
        combinedMap.put(oldInputPos, mapNewInputToProjOutputs.get(frame.oldToNewOutputs.get(oldInputPos)));
    }
    register(oldInput, newProject, combinedMap, corDefOutputs);
    // now it's time to rewrite the Aggregate
    final ImmutableBitSet newGroupSet = ImmutableBitSet.range(newGroupKeyCount);
    List<AggregateCall> newAggCalls = new ArrayList<>();
    List<AggregateCall> oldAggCalls = rel.getAggCallList();
    final Iterable<ImmutableBitSet> newGroupSets;
    if (rel.getGroupType() == Aggregate.Group.SIMPLE) {
        newGroupSets = null;
    } else {
        final ImmutableBitSet addedGroupSet = ImmutableBitSet.range(oldGroupKeyCount, newGroupKeyCount);
        newGroupSets = ImmutableBitSet.ORDERING.immutableSortedCopy(Util.transform(rel.getGroupSets(), bitSet -> bitSet.union(addedGroupSet)));
    }
    int oldInputOutputFieldCount = rel.getGroupSet().cardinality();
    int newInputOutputFieldCount = newGroupSet.cardinality();
    int i = -1;
    for (AggregateCall oldAggCall : oldAggCalls) {
        ++i;
        List<Integer> oldAggArgs = oldAggCall.getArgList();
        List<Integer> aggArgs = new ArrayList<>();
        // for the argument.
        for (int oldPos : oldAggArgs) {
            aggArgs.add(combinedMap.get(oldPos));
        }
        final int filterArg = oldAggCall.filterArg < 0 ? oldAggCall.filterArg : combinedMap.get(oldAggCall.filterArg);
        newAggCalls.add(oldAggCall.adaptTo(newProject, aggArgs, filterArg, oldGroupKeyCount, newGroupKeyCount));
        // The old to new output position mapping will be the same as that
        // of newProject, plus any aggregates that the oldAgg produces.
        outputMap.put(oldInputOutputFieldCount + i, newInputOutputFieldCount + i);
    }
    relBuilder.push(newProject).aggregate(newGroupSets == null ? relBuilder.groupKey(newGroupSet) : relBuilder.groupKey(newGroupSet, newGroupSets), newAggCalls);
    if (!omittedConstants.isEmpty()) {
        final List<RexNode> postProjects = new ArrayList<>(relBuilder.fields());
        for (Map.Entry<Integer, RexLiteral> entry : omittedConstants.descendingMap().entrySet()) {
            int index = entry.getKey() + frame.corDefOutputs.size();
            postProjects.add(index, entry.getValue());
            // Shift the outputs whose index equals with or bigger than the added index
            // with 1 offset.
            shiftMapping(outputMap, index, 1);
            // Then add the constant key mapping.
            outputMap.put(entry.getKey(), index);
        }
        relBuilder.project(postProjects);
    }
    RelNode newRel = RelOptUtil.copyRelHints(rel, relBuilder.build());
    // located at the same position as the input newProject.
    return register(rel, newRel, outputMap, corDefOutputs);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Pair(org.apache.calcite.util.Pair) TreeMap(java.util.TreeMap) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) ImmutableMap(com.google.common.collect.ImmutableMap) NavigableMap(java.util.NavigableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

Pair (org.apache.calcite.util.Pair)112 RexNode (org.apache.calcite.rex.RexNode)72 ArrayList (java.util.ArrayList)70 RelNode (org.apache.calcite.rel.RelNode)59 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)55 RexInputRef (org.apache.calcite.rex.RexInputRef)29 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)29 HashMap (java.util.HashMap)26 RexBuilder (org.apache.calcite.rex.RexBuilder)23 Map (java.util.Map)21 AggregateCall (org.apache.calcite.rel.core.AggregateCall)20 List (java.util.List)19 RelDataType (org.apache.calcite.rel.type.RelDataType)19 ImmutableList (com.google.common.collect.ImmutableList)18 JoinRelType (org.apache.calcite.rel.core.JoinRelType)16 TreeMap (java.util.TreeMap)14 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)13 RelBuilder (org.apache.calcite.tools.RelBuilder)13 ImmutableMap (com.google.common.collect.ImmutableMap)12 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)12