Search in sources :

Example 6 with RelFieldCollation

use of org.apache.calcite.rel.RelFieldCollation in project hive by apache.

the class HiveProjectSortTransposeRule method onMatch.

//~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    final HiveProject project = call.rel(0);
    final HiveSortLimit sort = call.rel(1);
    // Determine mapping between project input and output fields. If sort
    // relies on non-trivial expressions, we can't push.
    final Mappings.TargetMapping map = RelOptUtil.permutation(project.getProjects(), project.getInput().getRowType()).inverse();
    for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
        if (map.getTarget(fc.getFieldIndex()) < 0) {
            return;
        }
    }
    // Create new collation
    final RelCollation newCollation = RelCollationTraitDef.INSTANCE.canonize(RexUtil.apply(map, sort.getCollation()));
    // New operators
    final RelNode newProject = project.copy(sort.getInput().getTraitSet(), ImmutableList.<RelNode>of(sort.getInput()));
    final HiveSortLimit newSort = sort.copy(newProject.getTraitSet(), newProject, newCollation, sort.offset, sort.fetch);
    call.transformTo(newSort);
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation) Mappings(org.apache.calcite.util.mapping.Mappings) RelNode(org.apache.calcite.rel.RelNode) HiveProject(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) HiveSortLimit(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSortLimit)

Example 7 with RelFieldCollation

use of org.apache.calcite.rel.RelFieldCollation in project drill by apache.

the class PrelUtil method getOrdering.

public static List<Ordering> getOrdering(RelCollation collation, RelDataType rowType) {
    List<Ordering> orderExpr = Lists.newArrayList();
    final List<String> childFields = rowType.getFieldNames();
    for (RelFieldCollation fc : collation.getFieldCollations()) {
        FieldReference fr = new FieldReference(childFields.get(fc.getFieldIndex()), ExpressionPosition.UNKNOWN, false);
        orderExpr.add(new Ordering(fc.getDirection(), fr, fc.nullDirection));
    }
    return orderExpr;
}
Also used : FieldReference(org.apache.drill.common.expression.FieldReference) Ordering(org.apache.drill.common.logical.data.Order.Ordering) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation)

Example 8 with RelFieldCollation

use of org.apache.calcite.rel.RelFieldCollation in project drill by apache.

the class DrillSortRel method implement.

@Override
public LogicalOperator implement(DrillImplementor implementor) {
    final Order.Builder builder = Order.builder();
    builder.setInput(implementor.visitChild(this, 0, getInput()));
    final List<String> childFields = getInput().getRowType().getFieldNames();
    for (RelFieldCollation fieldCollation : this.collation.getFieldCollations()) {
        builder.addOrdering(fieldCollation.getDirection(), new FieldReference(childFields.get(fieldCollation.getFieldIndex())), fieldCollation.nullDirection);
    }
    return builder.build();
}
Also used : Order(org.apache.drill.common.logical.data.Order) FieldReference(org.apache.drill.common.expression.FieldReference) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation)

Example 9 with RelFieldCollation

use of org.apache.calcite.rel.RelFieldCollation in project hive by apache.

the class HiveOpConverter method visit.

OpAttr visit(HiveSortLimit sortRel) throws SemanticException {
    OpAttr inputOpAf = dispatch(sortRel.getInput());
    if (LOG.isDebugEnabled()) {
        LOG.debug("Translating operator rel#" + sortRel.getId() + ":" + sortRel.getRelTypeName() + " with row type: [" + sortRel.getRowType() + "]");
        if (sortRel.getCollation() == RelCollations.EMPTY) {
            LOG.debug("Operator rel#" + sortRel.getId() + ":" + sortRel.getRelTypeName() + " consists of limit");
        } else if (sortRel.fetch == null) {
            LOG.debug("Operator rel#" + sortRel.getId() + ":" + sortRel.getRelTypeName() + " consists of sort");
        } else {
            LOG.debug("Operator rel#" + sortRel.getId() + ":" + sortRel.getRelTypeName() + " consists of sort+limit");
        }
    }
    Operator<?> inputOp = inputOpAf.inputs.get(0);
    Operator<?> resultOp = inputOpAf.inputs.get(0);
    // of their columns
    if (sortRel.getCollation() != RelCollations.EMPTY) {
        // In strict mode, in the presence of order by, limit must be specified.
        if (sortRel.fetch == null) {
            String error = StrictChecks.checkNoLimit(hiveConf);
            if (error != null)
                throw new SemanticException(error);
        }
        // 1.a. Extract order for each column from collation
        // Generate sortCols and order
        ImmutableBitSet.Builder sortColsPosBuilder = ImmutableBitSet.builder();
        ImmutableBitSet.Builder sortOutputColsPosBuilder = ImmutableBitSet.builder();
        Map<Integer, RexNode> obRefToCallMap = sortRel.getInputRefToCallMap();
        List<ExprNodeDesc> sortCols = new ArrayList<ExprNodeDesc>();
        StringBuilder order = new StringBuilder();
        StringBuilder nullOrder = new StringBuilder();
        for (RelFieldCollation sortInfo : sortRel.getCollation().getFieldCollations()) {
            int sortColumnPos = sortInfo.getFieldIndex();
            ColumnInfo columnInfo = new ColumnInfo(inputOp.getSchema().getSignature().get(sortColumnPos));
            ExprNodeColumnDesc sortColumn = new ExprNodeColumnDesc(columnInfo.getType(), columnInfo.getInternalName(), columnInfo.getTabAlias(), columnInfo.getIsVirtualCol());
            sortCols.add(sortColumn);
            if (sortInfo.getDirection() == RelFieldCollation.Direction.DESCENDING) {
                order.append("-");
            } else {
                order.append("+");
            }
            if (sortInfo.nullDirection == RelFieldCollation.NullDirection.FIRST) {
                nullOrder.append("a");
            } else if (sortInfo.nullDirection == RelFieldCollation.NullDirection.LAST) {
                nullOrder.append("z");
            } else {
                // Default
                nullOrder.append(sortInfo.getDirection() == RelFieldCollation.Direction.DESCENDING ? "z" : "a");
            }
            if (obRefToCallMap != null) {
                RexNode obExpr = obRefToCallMap.get(sortColumnPos);
                sortColsPosBuilder.set(sortColumnPos);
                if (obExpr == null) {
                    sortOutputColsPosBuilder.set(sortColumnPos);
                }
            }
        }
        // Use only 1 reducer for order by
        int numReducers = 1;
        // We keep the columns only the columns that are part of the final output
        List<String> keepColumns = new ArrayList<String>();
        final ImmutableBitSet sortColsPos = sortColsPosBuilder.build();
        final ImmutableBitSet sortOutputColsPos = sortOutputColsPosBuilder.build();
        final ArrayList<ColumnInfo> inputSchema = inputOp.getSchema().getSignature();
        for (int pos = 0; pos < inputSchema.size(); pos++) {
            if ((sortColsPos.get(pos) && sortOutputColsPos.get(pos)) || (!sortColsPos.get(pos) && !sortOutputColsPos.get(pos))) {
                keepColumns.add(inputSchema.get(pos).getInternalName());
            }
        }
        // 1.b. Generate reduce sink and project operator
        resultOp = genReduceSinkAndBacktrackSelect(resultOp, sortCols.toArray(new ExprNodeDesc[sortCols.size()]), 0, new ArrayList<ExprNodeDesc>(), order.toString(), nullOrder.toString(), numReducers, Operation.NOT_ACID, hiveConf, keepColumns);
    }
    // 2. If we need to generate limit
    if (sortRel.fetch != null) {
        int limit = RexLiteral.intValue(sortRel.fetch);
        int offset = sortRel.offset == null ? 0 : RexLiteral.intValue(sortRel.offset);
        LimitDesc limitDesc = new LimitDesc(offset, limit);
        ArrayList<ColumnInfo> cinfoLst = createColInfos(resultOp);
        resultOp = OperatorFactory.getAndMakeChild(limitDesc, new RowSchema(cinfoLst), resultOp);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Generated " + resultOp + " with row schema: [" + resultOp.getSchema() + "]");
        }
    }
    // 3. Return result
    return inputOpAf.clone(resultOp);
}
Also used : RowSchema(org.apache.hadoop.hive.ql.exec.RowSchema) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) ColumnInfo(org.apache.hadoop.hive.ql.exec.ColumnInfo) LimitDesc(org.apache.hadoop.hive.ql.plan.LimitDesc) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) ExprNodeColumnDesc(org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc) ExprNodeDesc(org.apache.hadoop.hive.ql.plan.ExprNodeDesc) SemanticException(org.apache.hadoop.hive.ql.parse.SemanticException) RexNode(org.apache.calcite.rex.RexNode)

Example 10 with RelFieldCollation

use of org.apache.calcite.rel.RelFieldCollation in project hive by apache.

the class ASTConverter method convertOrderLimitToASTNode.

private void convertOrderLimitToASTNode(HiveSortLimit order) {
    if (order != null) {
        HiveSortLimit hiveSortLimit = order;
        if (!hiveSortLimit.getCollation().getFieldCollations().isEmpty()) {
            // 1 Add order by token
            ASTNode orderAst = ASTBuilder.createAST(HiveParser.TOK_ORDERBY, "TOK_ORDERBY");
            schema = new Schema(hiveSortLimit);
            Map<Integer, RexNode> obRefToCallMap = hiveSortLimit.getInputRefToCallMap();
            RexNode obExpr;
            ASTNode astCol;
            for (RelFieldCollation c : hiveSortLimit.getCollation().getFieldCollations()) {
                // 2 Add Direction token
                ASTNode directionAST = c.getDirection() == RelFieldCollation.Direction.ASCENDING ? ASTBuilder.createAST(HiveParser.TOK_TABSORTCOLNAMEASC, "TOK_TABSORTCOLNAMEASC") : ASTBuilder.createAST(HiveParser.TOK_TABSORTCOLNAMEDESC, "TOK_TABSORTCOLNAMEDESC");
                ASTNode nullDirectionAST;
                // Null direction
                if (c.nullDirection == RelFieldCollation.NullDirection.FIRST) {
                    nullDirectionAST = ASTBuilder.createAST(HiveParser.TOK_NULLS_FIRST, "TOK_NULLS_FIRST");
                    directionAST.addChild(nullDirectionAST);
                } else if (c.nullDirection == RelFieldCollation.NullDirection.LAST) {
                    nullDirectionAST = ASTBuilder.createAST(HiveParser.TOK_NULLS_LAST, "TOK_NULLS_LAST");
                    directionAST.addChild(nullDirectionAST);
                } else {
                    // Default
                    if (c.getDirection() == RelFieldCollation.Direction.ASCENDING) {
                        nullDirectionAST = ASTBuilder.createAST(HiveParser.TOK_NULLS_FIRST, "TOK_NULLS_FIRST");
                        directionAST.addChild(nullDirectionAST);
                    } else {
                        nullDirectionAST = ASTBuilder.createAST(HiveParser.TOK_NULLS_LAST, "TOK_NULLS_LAST");
                        directionAST.addChild(nullDirectionAST);
                    }
                }
                // 3 Convert OB expr (OB Expr is usually an input ref except for top
                // level OB; top level OB will have RexCall kept in a map.)
                obExpr = null;
                if (obRefToCallMap != null)
                    obExpr = obRefToCallMap.get(c.getFieldIndex());
                if (obExpr != null) {
                    astCol = obExpr.accept(new RexVisitor(schema));
                } else {
                    ColumnInfo cI = schema.get(c.getFieldIndex());
                    /*
             * The RowResolver setup for Select drops Table associations. So
             * setup ASTNode on unqualified name.
             */
                    astCol = ASTBuilder.unqualifiedName(cI.column);
                }
                // 4 buildup the ob expr AST
                nullDirectionAST.addChild(astCol);
                orderAst.addChild(directionAST);
            }
            hiveAST.order = orderAst;
        }
        RexNode offsetExpr = hiveSortLimit.getOffsetExpr();
        RexNode fetchExpr = hiveSortLimit.getFetchExpr();
        if (fetchExpr != null) {
            Object offset = (offsetExpr == null) ? new Integer(0) : ((RexLiteral) offsetExpr).getValue2();
            Object fetch = ((RexLiteral) fetchExpr).getValue2();
            hiveAST.limit = ASTBuilder.limit(offset, fetch);
        }
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) FieldSchema(org.apache.hadoop.hive.metastore.api.FieldSchema) ASTNode(org.apache.hadoop.hive.ql.parse.ASTNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) HiveSortLimit(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSortLimit) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)25 RelNode (org.apache.calcite.rel.RelNode)10 RexNode (org.apache.calcite.rex.RexNode)9 ImmutableList (com.google.common.collect.ImmutableList)8 ArrayList (java.util.ArrayList)5 FieldReference (org.apache.drill.common.expression.FieldReference)4 HiveSortLimit (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSortLimit)4 RelCollation (org.apache.calcite.rel.RelCollation)3 RexInputRef (org.apache.calcite.rex.RexInputRef)3 Mappings (org.apache.calcite.util.mapping.Mappings)3 Order (org.apache.drill.common.logical.data.Order)3 HiveRelCollation (org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelCollation)3 OrderByColumnSpec (io.druid.query.groupby.orderby.OrderByColumnSpec)2 HashMap (java.util.HashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 AggregateCall (org.apache.calcite.rel.core.AggregateCall)2 Sort (org.apache.calcite.rel.core.Sort)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 RexLiteral (org.apache.calcite.rex.RexLiteral)2 LogicalExpression (org.apache.drill.common.expression.LogicalExpression)2