Search in sources :

Example 1 with RexOver

use of org.apache.calcite.rex.RexOver in project hive by apache.

the class HiveRelColumnsAlignment method align.

public RelNode align(Project rel, List<RelFieldCollation> collations) {
    // 1) We extract the collations indices
    boolean containsWindowing = false;
    for (RexNode childExp : rel.getChildExps()) {
        if (childExp instanceof RexOver) {
            // TODO: support propagation for partitioning/ordering in windowing
            containsWindowing = true;
            break;
        }
    }
    ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder();
    if (!containsWindowing) {
        for (RelFieldCollation c : collations) {
            RexNode rexNode = rel.getChildExps().get(c.getFieldIndex());
            if (rexNode instanceof RexInputRef) {
                int newIdx = ((RexInputRef) rexNode).getIndex();
                propagateCollations.add(c.copy((newIdx)));
            }
        }
    }
    // 2) We propagate
    final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build());
    // 3) Return new Project
    return rel.copy(rel.getTraitSet(), ImmutableList.of(child));
}
Also used : RexOver(org.apache.calcite.rex.RexOver) RelNode(org.apache.calcite.rel.RelNode) ImmutableList(com.google.common.collect.ImmutableList) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with RexOver

use of org.apache.calcite.rex.RexOver in project hive by apache.

the class HiveWindowingFixRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Project project = call.rel(0);
    Aggregate aggregate = call.rel(1);
    // 1. We go over the expressions in the project operator
    //    and we separate the windowing nodes that are result
    //    of an aggregate expression from the rest of nodes
    final int groupingFields = aggregate.getGroupCount() + aggregate.getIndicatorCount();
    Set<String> projectExprsDigest = new HashSet<String>();
    Map<String, RexNode> windowingExprsDigestToNodes = new HashMap<String, RexNode>();
    for (RexNode r : project.getChildExps()) {
        if (r instanceof RexOver) {
            RexOver rexOverNode = (RexOver) r;
            // Operands
            for (RexNode operand : rexOverNode.getOperands()) {
                if (operand instanceof RexInputRef && ((RexInputRef) operand).getIndex() >= groupingFields) {
                    windowingExprsDigestToNodes.put(operand.toString(), operand);
                }
            }
            // Partition keys
            for (RexNode partitionKey : rexOverNode.getWindow().partitionKeys) {
                if (partitionKey instanceof RexInputRef && ((RexInputRef) partitionKey).getIndex() >= groupingFields) {
                    windowingExprsDigestToNodes.put(partitionKey.toString(), partitionKey);
                }
            }
            // Order keys
            for (RexFieldCollation orderKey : rexOverNode.getWindow().orderKeys) {
                if (orderKey.left instanceof RexInputRef && ((RexInputRef) orderKey.left).getIndex() >= groupingFields) {
                    windowingExprsDigestToNodes.put(orderKey.left.toString(), orderKey.left);
                }
            }
        } else {
            projectExprsDigest.add(r.toString());
        }
    }
    // 2. We check whether there is a column needed by the
    //    windowing operation that is missing in the
    //    project expressions. For instance, if the windowing
    //    operation is over an aggregation column, Hive expects
    //    that column to be in the Select clause of the query.
    //    The idea is that if there is a column missing, we will
    //    replace the old project operator by two new project
    //    operators:
    //    - a project operator containing the original columns
    //      of the project operator plus all the columns that were
    //      missing
    //    - a project on top of the previous one, that will take
    //      out the columns that were missing and were added by the
    //      previous project
    // These data structures are needed to create the new project
    // operator (below)
    final List<RexNode> belowProjectExprs = new ArrayList<RexNode>();
    final List<String> belowProjectColumnNames = new ArrayList<String>();
    // This data structure is needed to create the new project
    // operator (top)
    final List<RexNode> topProjectExprs = new ArrayList<RexNode>();
    final int projectCount = project.getChildExps().size();
    for (int i = 0; i < projectCount; i++) {
        belowProjectExprs.add(project.getChildExps().get(i));
        belowProjectColumnNames.add(project.getRowType().getFieldNames().get(i));
        topProjectExprs.add(RexInputRef.of(i, project.getRowType()));
    }
    boolean windowingFix = false;
    for (Entry<String, RexNode> windowingExpr : windowingExprsDigestToNodes.entrySet()) {
        if (!projectExprsDigest.contains(windowingExpr.getKey())) {
            windowingFix = true;
            belowProjectExprs.add(windowingExpr.getValue());
            int colIndex = 0;
            String alias = "window_col_" + colIndex;
            while (belowProjectColumnNames.contains(alias)) {
                alias = "window_col_" + (colIndex++);
            }
            belowProjectColumnNames.add(alias);
        }
    }
    if (!windowingFix) {
        // We do not need to do anything, we bail out
        return;
    }
    // 3. We need to fix it, we create the two replacement project
    //    operators
    RelNode newProjectRel = projectFactory.createProject(aggregate, belowProjectExprs, belowProjectColumnNames);
    RelNode newTopProjectRel = projectFactory.createProject(newProjectRel, topProjectExprs, project.getRowType().getFieldNames());
    call.transformTo(newTopProjectRel);
}
Also used : RexOver(org.apache.calcite.rex.RexOver) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RexFieldCollation(org.apache.calcite.rex.RexFieldCollation) Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) Aggregate(org.apache.calcite.rel.core.Aggregate) HashSet(java.util.HashSet) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with RexOver

use of org.apache.calcite.rex.RexOver in project hive by apache.

the class HiveFilterProjectTransposeRule method getCommonPartitionCols.

private static Set<Integer> getCommonPartitionCols(List<RexNode> projections) {
    RexOver overClause;
    boolean firstOverClause = true;
    Set<Integer> commonPartitionKeys = new HashSet<Integer>();
    for (RexNode expr : projections) {
        if (expr instanceof RexOver) {
            overClause = (RexOver) expr;
            if (firstOverClause) {
                firstOverClause = false;
                commonPartitionKeys.addAll(getPartitionCols(overClause.getWindow().partitionKeys));
            } else {
                commonPartitionKeys.retainAll(getPartitionCols(overClause.getWindow().partitionKeys));
            }
        }
    }
    return commonPartitionKeys;
}
Also used : RexOver(org.apache.calcite.rex.RexOver) HashSet(java.util.HashSet) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with RexOver

use of org.apache.calcite.rex.RexOver in project hive by apache.

the class HiveProjectMergeRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    // Currently we do not support merging windowing functions with other
    // windowing functions i.e. embedding windowing functions within each
    // other
    final Project topProject = call.rel(0);
    final Project bottomProject = call.rel(1);
    for (RexNode expr : topProject.getChildExps()) {
        if (expr instanceof RexOver) {
            Set<Integer> positions = HiveCalciteUtil.getInputRefs(expr);
            for (int pos : positions) {
                if (bottomProject.getChildExps().get(pos) instanceof RexOver) {
                    return false;
                }
            }
        }
    }
    return super.matches(call);
}
Also used : RexOver(org.apache.calcite.rex.RexOver) Project(org.apache.calcite.rel.core.Project) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexNode (org.apache.calcite.rex.RexNode)4 RexOver (org.apache.calcite.rex.RexOver)4 HashSet (java.util.HashSet)2 RelNode (org.apache.calcite.rel.RelNode)2 Project (org.apache.calcite.rel.core.Project)2 RexInputRef (org.apache.calcite.rex.RexInputRef)2 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 Aggregate (org.apache.calcite.rel.core.Aggregate)1 RexFieldCollation (org.apache.calcite.rex.RexFieldCollation)1