Search in sources :

Example 11 with RexLiteral

use of org.apache.calcite.rex.RexLiteral 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)

Example 12 with RexLiteral

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

the class HiveRelMdPredicates method getPredicates.

/**
   * 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.
   *
   * <pre>
   * childPullUpExprs:      {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>
   *
   * </ol>
   */
public RelOptPredicateList getPredicates(Project project, RelMetadataQuery mq) {
    RelNode child = project.getInput();
    final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
    RelOptPredicateList childInfo = mq.getPulledUpPredicates(child);
    List<RexNode> projectPullUpPredicates = new ArrayList<RexNode>();
    HashMultimap<Integer, Integer> inpIndxToOutIndxMap = HashMultimap.create();
    ImmutableBitSet.Builder columnsMappedBuilder = ImmutableBitSet.builder();
    Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, child.getRowType().getFieldCount(), project.getRowType().getFieldCount());
    for (Ord<RexNode> o : Ord.zip(project.getProjects())) {
        if (o.e instanceof RexInputRef) {
            int sIdx = ((RexInputRef) o.e).getIndex();
            m.set(sIdx, o.i);
            inpIndxToOutIndxMap.put(sIdx, o.i);
            columnsMappedBuilder.set(sIdx);
        }
    }
    // 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 : childInfo.pulledUpPredicates) {
        ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
        if (columnsMapped.contains(rCols)) {
            r = r.accept(new RexPermuteInputsShuttle(m, child));
            projectPullUpPredicates.add(r);
        }
    }
    // Project can also generate constants. We need to include them.
    for (Ord<RexNode> expr : Ord.zip(project.getProjects())) {
        if (RexLiteral.isNullLiteral(expr.e)) {
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, rexBuilder.makeInputRef(project, expr.i)));
        } else if (expr.e instanceof RexLiteral) {
            final RexLiteral literal = (RexLiteral) expr.e;
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef(project, expr.i), literal));
        } else if (expr.e instanceof RexCall && HiveCalciteUtil.isDeterministicFuncOnLiterals(expr.e)) {
            //TODO: Move this to calcite
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef(project, expr.i), expr.e));
        }
    }
    return RelOptPredicateList.of(projectPullUpPredicates);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) Mapping(org.apache.calcite.util.mapping.Mapping) RexCall(org.apache.calcite.rex.RexCall) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RexPermuteInputsShuttle(org.apache.calcite.rex.RexPermuteInputsShuttle) RexNode(org.apache.calcite.rex.RexNode)

Example 13 with RexLiteral

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

the class HiveRelDecorrelator method decorrelateRel.

/**
   * Rewrites a {@link LogicalAggregate}.
   *
   * @param rel Aggregate to rewrite
   */
public Frame decorrelateRel(LogicalAggregate rel) throws SemanticException {
    if (rel.getGroupType() != Aggregate.Group.SIMPLE) {
        throw new AssertionError(Bug.CALCITE_461_FIXED);
    }
    // Aggregate itself should not reference cor vars.
    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;
    // map from newInput
    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 = Lists.newArrayList();
    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;
        }
        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 = HiveProject.create(newInput, Pair.left(projects), Pair.right(projects));
    // update mappings:
    // oldInput ----> newInput
    //
    //                newProject
    //                   |
    // oldInput ----> newInput
    //
    // is transformed to
    //
    // oldInput ----> newProject
    //                   |
    //                newInput
    Map<Integer, Integer> combinedMap = Maps.newHashMap();
    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 = Lists.newArrayList();
    List<AggregateCall> oldAggCalls = rel.getAggCallList();
    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 = Lists.newArrayList();
        // 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.
        combinedMap.put(oldInputOutputFieldCount + i, newInputOutputFieldCount + i);
    }
    relBuilder.push(LogicalAggregate.create(newProject, false, newGroupSet, null, newAggCalls));
    if (!omittedConstants.isEmpty()) {
        final List<RexNode> postProjects = new ArrayList<>(relBuilder.fields());
        for (Map.Entry<Integer, RexLiteral> entry : omittedConstants.descendingMap().entrySet()) {
            postProjects.add(entry.getKey() + frame.corDefOutputs.size(), entry.getValue());
        }
        relBuilder.project(postProjects);
    }
    // located at the same position as the input newProject.
    return register(rel, relBuilder.build(), combinedMap, 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)

Example 14 with RexLiteral

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

the class HiveExceptRewriteRule method makeExprForExceptAll.

private RexNode makeExprForExceptAll(HiveRelNode input, int columnSize, RelOptCluster cluster, RexBuilder rexBuilder) throws CalciteSemanticException {
    List<RexNode> childRexNodeLst = new ArrayList<RexNode>();
    ImmutableList.Builder<RelDataType> calciteArgTypesBldr = new ImmutableList.Builder<RelDataType>();
    calciteArgTypesBldr.add(TypeConverter.convert(TypeInfoFactory.longTypeInfo, cluster.getTypeFactory()));
    calciteArgTypesBldr.add(TypeConverter.convert(TypeInfoFactory.longTypeInfo, cluster.getTypeFactory()));
    RexInputRef a = rexBuilder.makeInputRef(input, columnSize - 2);
    RexLiteral three = rexBuilder.makeBigintLiteral(new BigDecimal(3));
    childRexNodeLst.add(three);
    childRexNodeLst.add(a);
    RexNode threea = rexBuilder.makeCall(SqlFunctionConverter.getCalciteFn("*", calciteArgTypesBldr.build(), TypeConverter.convert(TypeInfoFactory.longTypeInfo, cluster.getTypeFactory()), false), childRexNodeLst);
    RexLiteral two = rexBuilder.makeBigintLiteral(new BigDecimal(2));
    RexInputRef b = rexBuilder.makeInputRef(input, columnSize - 1);
    // 2*b
    childRexNodeLst = new ArrayList<RexNode>();
    childRexNodeLst.add(two);
    childRexNodeLst.add(b);
    RexNode twob = rexBuilder.makeCall(SqlFunctionConverter.getCalciteFn("*", calciteArgTypesBldr.build(), TypeConverter.convert(TypeInfoFactory.longTypeInfo, cluster.getTypeFactory()), false), childRexNodeLst);
    // 2b-3a
    childRexNodeLst = new ArrayList<RexNode>();
    childRexNodeLst.add(twob);
    childRexNodeLst.add(threea);
    return rexBuilder.makeCall(SqlFunctionConverter.getCalciteFn("-", calciteArgTypesBldr.build(), TypeConverter.convert(TypeInfoFactory.longTypeInfo, cluster.getTypeFactory()), false), childRexNodeLst);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableList(com.google.common.collect.ImmutableList) RelBuilder(org.apache.calcite.tools.RelBuilder) RexBuilder(org.apache.calcite.rex.RexBuilder) Builder(com.google.common.collect.ImmutableList.Builder) ArrayList(java.util.ArrayList) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) BigDecimal(java.math.BigDecimal) RexNode(org.apache.calcite.rex.RexNode)

Example 15 with RexLiteral

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

the class HiveCalciteUtil method getExprNodes.

public static List<ExprNodeDesc> getExprNodes(List<Integer> inputRefs, RelNode inputRel, String inputTabAlias) {
    List<ExprNodeDesc> exprNodes = new ArrayList<ExprNodeDesc>();
    List<RexNode> rexInputRefs = getInputRef(inputRefs, inputRel);
    List<RexNode> exprs = inputRel.getChildExps();
    // TODO: Change ExprNodeConverter to be independent of Partition Expr
    ExprNodeConverter exprConv = new ExprNodeConverter(inputTabAlias, inputRel.getRowType(), new HashSet<Integer>(), inputRel.getCluster().getTypeFactory());
    for (int index = 0; index < rexInputRefs.size(); index++) {
        //check the corresponding expression in exprs to see if it is literal
        if (exprs != null && index < exprs.size() && exprs.get(inputRefs.get(index)) instanceof RexLiteral) {
            //because rexInputRefs represent ref expr corresponding to value in inputRefs it is used to get
            //  corresponding index
            ExprNodeDesc exprNodeDesc = exprConv.visitLiteral((RexLiteral) exprs.get(inputRefs.get(index)));
            exprNodes.add(exprNodeDesc);
        } else {
            RexNode iRef = rexInputRefs.get(index);
            exprNodes.add(iRef.accept(exprConv));
        }
    }
    return exprNodes;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ArrayList(java.util.ArrayList) ExprNodeDesc(org.apache.hadoop.hive.ql.plan.ExprNodeDesc) RexNode(org.apache.calcite.rex.RexNode) ExprNodeConverter(org.apache.hadoop.hive.ql.optimizer.calcite.translator.ExprNodeConverter)

Aggregations

RexLiteral (org.apache.calcite.rex.RexLiteral)23 RexNode (org.apache.calcite.rex.RexNode)19 ArrayList (java.util.ArrayList)10 RexCall (org.apache.calcite.rex.RexCall)8 RexBuilder (org.apache.calcite.rex.RexBuilder)6 RexInputRef (org.apache.calcite.rex.RexInputRef)6 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)6 BigDecimal (java.math.BigDecimal)5 AggregateCall (org.apache.calcite.rel.core.AggregateCall)5 RelDataType (org.apache.calcite.rel.type.RelDataType)5 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)5 RelNode (org.apache.calcite.rel.RelNode)4 ImmutableList (com.google.common.collect.ImmutableList)3 Builder (com.google.common.collect.ImmutableList.Builder)3 AndDimFilter (io.druid.query.filter.AndDimFilter)3 DimFilter (io.druid.query.filter.DimFilter)3 NotDimFilter (io.druid.query.filter.NotDimFilter)3 Project (org.apache.calcite.rel.core.Project)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)2