Search in sources :

Example 51 with RexBuilder

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

the class HiveReduceExpressionsWithStatsRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
    final RelMetadataQuery metadataProvider = RelMetadataQuery.instance();
    // 1. Recompose filter possibly by pulling out common elements from DNF
    // expressions
    RexNode newFilterCondition = RexUtil.pullFactors(rexBuilder, filter.getCondition());
    // 2. Reduce filter with stats information
    RexReplacer replacer = new RexReplacer(filter, rexBuilder, metadataProvider);
    newFilterCondition = replacer.apply(newFilterCondition);
    // 3. Transform if we have created a new filter operator
    if (!filter.getCondition().toString().equals(newFilterCondition.toString())) {
        Filter newFilter = filter.copy(filter.getTraitSet(), filter.getInput(), newFilterCondition);
        call.transformTo(newFilter);
    }
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) Filter(org.apache.calcite.rel.core.Filter) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 52 with RexBuilder

use of org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillReduceAggregatesRule method reduceAvg.

private RexNode reduceAvg(Aggregate oldAggRel, AggregateCall oldCall, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping) {
    final PlannerSettings plannerSettings = (PlannerSettings) oldAggRel.getCluster().getPlanner().getContext();
    final boolean isInferenceEnabled = plannerSettings.isTypeInferenceEnabled();
    final int nGroups = oldAggRel.getGroupCount();
    RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();
    RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
    int iAvgInput = oldCall.getArgList().get(0);
    RelDataType avgInputType = getFieldType(oldAggRel.getInput(), iAvgInput);
    RelDataType sumType = typeFactory.createTypeWithNullability(avgInputType, avgInputType.isNullable() || nGroups == 0);
    SqlAggFunction sumAgg = new SqlSumEmptyIsZeroAggFunction();
    AggregateCall sumCall = AggregateCall.create(sumAgg, oldCall.isDistinct(), oldCall.getArgList(), -1, sumType, null);
    final SqlCountAggFunction countAgg = (SqlCountAggFunction) SqlStdOperatorTable.COUNT;
    final RelDataType countType = countAgg.getReturnType(typeFactory);
    AggregateCall countCall = AggregateCall.create(countAgg, oldCall.isDistinct(), oldCall.getArgList(), -1, countType, null);
    RexNode tmpsumRef = rexBuilder.addAggCall(sumCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
    RexNode tmpcountRef = rexBuilder.addAggCall(countCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
    RexNode n = rexBuilder.makeCall(SqlStdOperatorTable.CASE, rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, tmpcountRef, rexBuilder.makeExactLiteral(BigDecimal.ZERO)), rexBuilder.constantNull(), tmpsumRef);
    // NOTE:  these references are with respect to the output
    // of newAggRel
    /*
    RexNode numeratorRef =
        rexBuilder.makeCall(CastHighOp,
          rexBuilder.addAggCall(
              sumCall,
              nGroups,
              newCalls,
              aggCallMapping,
              ImmutableList.of(avgInputType))
        );
    */
    RexNode numeratorRef = rexBuilder.makeCall(CastHighOp, n);
    RexNode denominatorRef = rexBuilder.addAggCall(countCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
    if (isInferenceEnabled) {
        return rexBuilder.makeCall(new DrillSqlOperator("divide", 2, true, oldCall.getType(), false), numeratorRef, denominatorRef);
    } else {
        final RexNode divideRef = rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
        return rexBuilder.makeCast(typeFactory.createSqlType(SqlTypeName.ANY), divideRef);
    }
}
Also used : SqlSumEmptyIsZeroAggFunction(org.apache.calcite.sql.fun.SqlSumEmptyIsZeroAggFunction) AggregateCall(org.apache.calcite.rel.core.AggregateCall) PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) SqlCountAggFunction(org.apache.calcite.sql.fun.SqlCountAggFunction) RexNode(org.apache.calcite.rex.RexNode) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator)

Example 53 with RexBuilder

use of org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillReduceAggregatesRule method reduceAggs.

/*
  private boolean isMatch(AggregateCall call) {
    if (call.getAggregation() instanceof SqlAvgAggFunction) {
      final SqlAvgAggFunction.Subtype subtype =
          ((SqlAvgAggFunction) call.getAggregation()).getSubtype();
      return (subtype == SqlAvgAggFunction.Subtype.AVG);
    }
    return false;
  }
 */
/**
   * Reduces all calls to AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP in
   * the aggregates list to.
   *
   * <p>It handles newly generated common subexpressions since this was done
   * at the sql2rel stage.
   */
private void reduceAggs(RelOptRuleCall ruleCall, Aggregate oldAggRel) {
    RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
    List<AggregateCall> oldCalls = oldAggRel.getAggCallList();
    final int nGroups = oldAggRel.getGroupCount();
    List<AggregateCall> newCalls = new ArrayList<>();
    Map<AggregateCall, RexNode> aggCallMapping = new HashMap<>();
    List<RexNode> projList = new ArrayList<>();
    // pass through group key
    for (int i = 0; i < nGroups; ++i) {
        projList.add(rexBuilder.makeInputRef(getFieldType(oldAggRel, i), i));
    }
    // List of input expressions. If a particular aggregate needs more, it
    // will add an expression to the end, and we will create an extra
    // project.
    RelNode input = oldAggRel.getInput();
    List<RexNode> inputExprs = new ArrayList<>();
    for (RelDataTypeField field : input.getRowType().getFieldList()) {
        inputExprs.add(rexBuilder.makeInputRef(field.getType(), inputExprs.size()));
    }
    // create new agg function calls and rest of project list together
    for (AggregateCall oldCall : oldCalls) {
        projList.add(reduceAgg(oldAggRel, oldCall, newCalls, aggCallMapping, inputExprs));
    }
    final int extraArgCount = inputExprs.size() - input.getRowType().getFieldCount();
    if (extraArgCount > 0) {
        input = RelOptUtil.createProject(input, inputExprs, CompositeList.of(input.getRowType().getFieldNames(), Collections.<String>nCopies(extraArgCount, null)));
    }
    Aggregate newAggRel = newAggregateRel(oldAggRel, input, newCalls);
    RelNode projectRel = RelOptUtil.createProject(newAggRel, projList, oldAggRel.getRowType().getFieldNames());
    ruleCall.transformTo(projectRel);
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) Aggregate(org.apache.calcite.rel.core.Aggregate) LogicalAggregate(org.apache.calcite.rel.logical.LogicalAggregate) RexNode(org.apache.calcite.rex.RexNode)

Example 54 with RexBuilder

use of org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillMergeFilterRule method onMatch.

//~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Filter topFilter = call.rel(0);
    Filter bottomFilter = call.rel(1);
    // use RexPrograms to merge the two FilterRels into a single program
    // so we can convert the two FilterRel conditions to directly
    // reference the bottom FilterRel's child
    RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
    RexProgram bottomProgram = createProgram(bottomFilter);
    RexProgram topProgram = createProgram(topFilter);
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());
    //    if(!RexUtil.isFlat(newCondition)){
    //      RexCall newCall = (RexCall) newCondition;
    //      newCondition = rexBuilder.makeFlatCall( newCall.getOperator(), newCall.getOperands());
    //    }
    Filter newFilterRel = (Filter) filterFactory.createFilter(bottomFilter.getInput(), RexUtil.flatten(rexBuilder, newCondition));
    call.transformTo(newFilterRel);
}
Also used : Filter(org.apache.calcite.rel.core.Filter) RexProgram(org.apache.calcite.rex.RexProgram) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 55 with RexBuilder

use of org.apache.calcite.rex.RexBuilder in project drill by apache.

the class PreProcessLogicalRel method visit.

@Override
public RelNode visit(LogicalProject project) {
    final List<RexNode> projExpr = Lists.newArrayList();
    for (RexNode rexNode : project.getChildExps()) {
        projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
    }
    project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
    List<RexNode> exprList = new ArrayList<>();
    boolean rewrite = false;
    for (RexNode rex : project.getChildExps()) {
        RexNode newExpr = rex;
        if (rex instanceof RexCall) {
            RexCall function = (RexCall) rex;
            String functionName = function.getOperator().getName();
            int nArgs = function.getOperands().size();
            // check if its a convert_from or convert_to function
            if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
                String literal;
                if (nArgs == 2) {
                    if (function.getOperands().get(1) instanceof RexLiteral) {
                        try {
                            literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
                        } catch (final ClassCastException e) {
                            // Caused by user entering a value with a non-string literal
                            throw getConvertFunctionInvalidTypeException(function);
                        }
                    } else {
                        // caused by user entering a non-literal
                        throw getConvertFunctionInvalidTypeException(function);
                    }
                } else {
                    // Second operand is missing
                    throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
                }
                RexBuilder builder = new RexBuilder(factory);
                // construct the new function name based on the input argument
                String newFunctionName = functionName + literal;
                // Look up the new function name in the drill operator table
                List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
                if (operatorList.size() == 0) {
                    // User typed in an invalid type name
                    throw getConvertFunctionException(functionName, literal);
                }
                SqlFunction newFunction = null;
                // Find the SqlFunction with the correct args
                for (SqlOperator op : operatorList) {
                    if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
                        newFunction = (SqlFunction) op;
                        break;
                    }
                }
                if (newFunction == null) {
                    // we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
                    throw getConvertFunctionException(functionName, literal);
                }
                // create the new expression to be used in the rewritten project
                newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
                rewrite = true;
            }
        }
        exprList.add(newExpr);
    }
    if (rewrite == true) {
        LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
        return visitChild(newProject, 0, project.getInput());
    }
    return visitChild(project, 0, project.getInput());
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) NlsString(org.apache.calcite.util.NlsString) RexCall(org.apache.calcite.rex.RexCall) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Aggregations

RexBuilder (org.apache.calcite.rex.RexBuilder)60 RexNode (org.apache.calcite.rex.RexNode)52 ArrayList (java.util.ArrayList)32 RelDataType (org.apache.calcite.rel.type.RelDataType)26 RelNode (org.apache.calcite.rel.RelNode)24 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)20 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)13 AggregateCall (org.apache.calcite.rel.core.AggregateCall)11 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)11 RexInputRef (org.apache.calcite.rex.RexInputRef)10 RelOptCluster (org.apache.calcite.plan.RelOptCluster)9 HashMap (java.util.HashMap)8 RelBuilder (org.apache.calcite.tools.RelBuilder)8 ImmutableList (com.google.common.collect.ImmutableList)6 BigDecimal (java.math.BigDecimal)6 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)6 RexLiteral (org.apache.calcite.rex.RexLiteral)6 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)6 Pair (org.apache.calcite.util.Pair)6 CalciteSemanticException (org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException)6