Search in sources :

Example 96 with RexCall

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

the class PlanModifierUtil method fixTopOBSchema.

protected static void fixTopOBSchema(final RelNode rootRel, Pair<RelNode, RelNode> topSelparentPair, List<FieldSchema> resultSchema, boolean replaceProject) throws CalciteSemanticException {
    if (!(topSelparentPair.getKey() instanceof Sort) || !HiveCalciteUtil.orderRelNode(topSelparentPair.getKey())) {
        return;
    }
    HiveSortLimit obRel = (HiveSortLimit) topSelparentPair.getKey();
    Project obChild = (Project) topSelparentPair.getValue();
    if (obChild.getRowType().getFieldCount() <= resultSchema.size()) {
        return;
    }
    RelDataType rt = obChild.getRowType();
    @SuppressWarnings({ "unchecked", "rawtypes" }) Set<Integer> collationInputRefs = new HashSet(RelCollations.ordinals(obRel.getCollation()));
    ImmutableMap.Builder<Integer, RexNode> inputRefToCallMapBldr = ImmutableMap.builder();
    for (int i = resultSchema.size(); i < rt.getFieldCount(); i++) {
        if (collationInputRefs.contains(i)) {
            RexNode obyExpr = obChild.getProjects().get(i);
            if (obyExpr instanceof RexCall) {
                LOG.debug("Old RexCall : " + obyExpr);
                obyExpr = adjustOBSchema((RexCall) obyExpr, obChild, resultSchema);
                LOG.debug("New RexCall : " + obyExpr);
            }
            inputRefToCallMapBldr.put(i, obyExpr);
        }
    }
    ImmutableMap<Integer, RexNode> inputRefToCallMap = inputRefToCallMapBldr.build();
    if ((obChild.getRowType().getFieldCount() - inputRefToCallMap.size()) != resultSchema.size()) {
        LOG.error(generateInvalidSchemaMessage(obChild, resultSchema, inputRefToCallMap.size()));
        throw new CalciteSemanticException("Result Schema didn't match Optimized Op Tree Schema");
    }
    if (replaceProject) {
        // This removes order-by only expressions from the projections.
        HiveProject replacementProjectRel = HiveProject.create(obChild.getInput(), obChild.getProjects().subList(0, resultSchema.size()), obChild.getRowType().getFieldNames().subList(0, resultSchema.size()));
        obRel.replaceInput(0, replacementProjectRel);
    }
    obRel.setInputRefToCallMap(inputRefToCallMap);
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) HiveSortLimit(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSortLimit) ImmutableMap(com.google.common.collect.ImmutableMap) RexCall(org.apache.calcite.rex.RexCall) Project(org.apache.calcite.rel.core.Project) HiveProject(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject) HiveProject(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject) Sort(org.apache.calcite.rel.core.Sort) CalciteSemanticException(org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException) HashSet(java.util.HashSet) RexNode(org.apache.calcite.rex.RexNode)

Example 97 with RexCall

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

the class HiveRelMdRowCount method canHandleJoin.

/*
   * 1. Join condition must be an Equality Predicate.
   * 2. both sides must reference 1 column.
   * 3. If needed flip the columns.
   */
private static Pair<Integer, Integer> canHandleJoin(Join joinRel, List<RexNode> leftFilters, List<RexNode> rightFilters, List<RexNode> joinFilters) {
    /*
     * If after classifying filters there is more than 1 joining predicate, we
     * don't handle this. Return null.
     */
    if (joinFilters.size() != 1) {
        return null;
    }
    RexNode joinCond = joinFilters.get(0);
    int leftColIdx;
    int rightColIdx;
    if (!(joinCond instanceof RexCall)) {
        return null;
    }
    if (((RexCall) joinCond).getOperator() != SqlStdOperatorTable.EQUALS) {
        return null;
    }
    ImmutableBitSet leftCols = RelOptUtil.InputFinder.bits(((RexCall) joinCond).getOperands().get(0));
    ImmutableBitSet rightCols = RelOptUtil.InputFinder.bits(((RexCall) joinCond).getOperands().get(1));
    if (leftCols.cardinality() != 1 || rightCols.cardinality() != 1) {
        return null;
    }
    int nFieldsLeft = joinRel.getLeft().getRowType().getFieldList().size();
    int nFieldsRight = joinRel.getRight().getRowType().getFieldList().size();
    int nSysFields = joinRel.getSystemFieldList().size();
    ImmutableBitSet rightFieldsBitSet = ImmutableBitSet.range(nSysFields + nFieldsLeft, nSysFields + nFieldsLeft + nFieldsRight);
    /*
     * flip column references if join condition specified in reverse order to
     * join sources.
     */
    if (rightFieldsBitSet.contains(leftCols)) {
        ImmutableBitSet t = leftCols;
        leftCols = rightCols;
        rightCols = t;
    }
    leftColIdx = leftCols.nextSetBit(0) - nSysFields;
    rightColIdx = rightCols.nextSetBit(0) - (nSysFields + nFieldsLeft);
    return new Pair<Integer, Integer>(leftColIdx, rightColIdx);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 98 with RexCall

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

the class HiveRelDecorrelator method findCorrelationEquivalent.

/**
 * Finds a {@link RexInputRef} that is equivalent to a {@link CorRef},
 * and if found, throws a {@link Util.FoundOne}.
 */
private void findCorrelationEquivalent(CorRef correlation, RexNode e) throws Util.FoundOne {
    if (e instanceof RexCall) {
        switch(e.getKind()) {
            case AND:
                for (RexNode operand : ((RexCall) e).getOperands()) {
                    findCorrelationEquivalent(correlation, operand);
                }
            default:
                final RexCall call = (RexCall) e;
                final List<RexNode> operands = call.getOperands();
                if (operands.size() == 2) {
                    if (references(operands.get(0), correlation) && operands.get(1) instanceof RexInputRef) {
                        // required we should rather generate value generator
                        if (e.getKind() != SqlKind.EQUALS && (boolean) valueGen.peek()) {
                            return;
                        }
                        throw new Util.FoundOne(Pair.of(((RexInputRef) operands.get(1)).getIndex(), Pair.of(((RexCall) e).getOperator(), true)));
                    }
                    if (references(operands.get(1), correlation) && operands.get(0) instanceof RexInputRef) {
                        // required we should rather generate value generator
                        if (e.getKind() != SqlKind.EQUALS && (boolean) valueGen.peek()) {
                            return;
                        }
                        throw new Util.FoundOne(Pair.of(((RexInputRef) operands.get(0)).getIndex(), Pair.of(((RexCall) e).getOperator(), false)));
                    }
                    break;
                }
        }
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 99 with RexCall

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

the class HiveJdbcImplementor method convertConditionToSqlNode.

/**
 * Converts a {@link RexNode} condition into a {@link SqlNode}.
 *
 * @param node            Join condition
 * @param leftContext     Left context
 * @param rightContext    Right context
 * @param leftFieldCount  Number of fields on left result
 * @return SqlNode that represents the condition
 */
public static SqlNode convertConditionToSqlNode(RexNode node, Context leftContext, Context rightContext, int leftFieldCount) {
    // throw an Exception
    if (node.isAlwaysTrue()) {
        return SqlLiteral.createBoolean(true, POS);
    }
    if (node.isAlwaysFalse()) {
        return SqlLiteral.createBoolean(false, POS);
    }
    if (node instanceof RexInputRef) {
        Context joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
        return joinContext.toSql(null, node);
    }
    if (!(node instanceof RexCall)) {
        throw new AssertionError(node);
    }
    final List<RexNode> operands;
    final SqlOperator op;
    final Context joinContext;
    switch(node.getKind()) {
        case AND:
        case OR:
            operands = ((RexCall) node).getOperands();
            op = ((RexCall) node).getOperator();
            SqlNode sqlCondition = null;
            for (RexNode operand : operands) {
                SqlNode x = convertConditionToSqlNode(operand, leftContext, rightContext, leftFieldCount);
                if (sqlCondition == null) {
                    sqlCondition = x;
                } else {
                    sqlCondition = op.createCall(POS, sqlCondition, x);
                }
            }
            return sqlCondition;
        case EQUALS:
        case IS_NOT_DISTINCT_FROM:
        case NOT_EQUALS:
        case GREATER_THAN:
        case GREATER_THAN_OR_EQUAL:
        case LESS_THAN:
        case LESS_THAN_OR_EQUAL:
            node = stripCastFromString(node);
            operands = ((RexCall) node).getOperands();
            op = ((RexCall) node).getOperator();
            if (operands.size() == 2 && operands.get(0) instanceof RexInputRef && operands.get(1) instanceof RexInputRef) {
                final RexInputRef op0 = (RexInputRef) operands.get(0);
                final RexInputRef op1 = (RexInputRef) operands.get(1);
                if (op0.getIndex() < leftFieldCount && op1.getIndex() >= leftFieldCount) {
                    // Arguments were of form 'op0 = op1'
                    return op.createCall(POS, leftContext.field(op0.getIndex()), rightContext.field(op1.getIndex() - leftFieldCount));
                }
                if (op1.getIndex() < leftFieldCount && op0.getIndex() >= leftFieldCount) {
                    // Arguments were of form 'op1 = op0'
                    return reverseOperatorDirection(op).createCall(POS, leftContext.field(op1.getIndex()), rightContext.field(op0.getIndex() - leftFieldCount));
                }
            }
            joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
            return joinContext.toSql(null, node);
        case IS_NULL:
        case IS_NOT_NULL:
            operands = ((RexCall) node).getOperands();
            if (operands.size() == 1 && operands.get(0) instanceof RexInputRef) {
                op = ((RexCall) node).getOperator();
                final RexInputRef op0 = (RexInputRef) operands.get(0);
                if (op0.getIndex() < leftFieldCount) {
                    return op.createCall(POS, leftContext.field(op0.getIndex()));
                } else {
                    return op.createCall(POS, rightContext.field(op0.getIndex() - leftFieldCount));
                }
            }
            joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
            return joinContext.toSql(null, node);
        default:
            joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
            return joinContext.toSql(null, node);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) SqlOperator(org.apache.calcite.sql.SqlOperator) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode)

Example 100 with RexCall

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

the class HiveJdbcImplementor method stripCastFromString.

/**
 * Removes cast from string.
 *
 * <p>For example, {@code x > CAST('2015-01-07' AS DATE)}
 * becomes {@code x > '2015-01-07'}.
 */
private static RexNode stripCastFromString(RexNode node) {
    switch(node.getKind()) {
        case EQUALS:
        case IS_NOT_DISTINCT_FROM:
        case NOT_EQUALS:
        case GREATER_THAN:
        case GREATER_THAN_OR_EQUAL:
        case LESS_THAN:
        case LESS_THAN_OR_EQUAL:
            final RexCall call = (RexCall) node;
            final RexNode o0 = call.operands.get(0);
            final RexNode o1 = call.operands.get(1);
            if (o0.getKind() == SqlKind.CAST && o1.getKind() != SqlKind.CAST) {
                final RexNode o0b = ((RexCall) o0).getOperands().get(0);
                switch(o0b.getType().getSqlTypeName()) {
                    case CHAR:
                    case VARCHAR:
                        return call.clone(call.getType(), ImmutableList.of(o0b, o1));
                }
            }
            if (o1.getKind() == SqlKind.CAST && o0.getKind() != SqlKind.CAST) {
                final RexNode o1b = ((RexCall) o1).getOperands().get(0);
                switch(o1b.getType().getSqlTypeName()) {
                    case CHAR:
                    case VARCHAR:
                        return call.clone(call.getType(), ImmutableList.of(o0, o1b));
                }
            }
    }
    return node;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexCall (org.apache.calcite.rex.RexCall)213 RexNode (org.apache.calcite.rex.RexNode)172 RexInputRef (org.apache.calcite.rex.RexInputRef)61 ArrayList (java.util.ArrayList)59 RexLiteral (org.apache.calcite.rex.RexLiteral)44 Nullable (javax.annotation.Nullable)35 RelNode (org.apache.calcite.rel.RelNode)26 RelDataType (org.apache.calcite.rel.type.RelDataType)24 SqlOperator (org.apache.calcite.sql.SqlOperator)23 List (java.util.List)22 RexBuilder (org.apache.calcite.rex.RexBuilder)22 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)19 SqlKind (org.apache.calcite.sql.SqlKind)14 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)14 RelOptUtil (org.apache.calcite.plan.RelOptUtil)11 PostAggregator (org.apache.druid.query.aggregation.PostAggregator)11 RexCall (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall)10 RexTableInputRef (org.apache.calcite.rex.RexTableInputRef)10 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)9 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9