Search in sources :

Example 86 with RexBuilder

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

the class DrillReduceAggregatesRule method reduceSum.

private RexNode reduceSum(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 arg = oldCall.getArgList().get(0);
    RelDataType argType = getFieldType(oldAggRel.getInput(), arg);
    final RelDataType sumType;
    final SqlAggFunction sumZeroAgg;
    if (isInferenceEnabled) {
        sumType = oldCall.getType();
    } else {
        sumType = typeFactory.createTypeWithNullability(oldCall.getType(), argType.isNullable());
    }
    sumZeroAgg = new DrillCalciteSqlAggFunctionWrapper(new SqlSumEmptyIsZeroAggFunction(), sumType);
    AggregateCall sumZeroCall = AggregateCall.create(sumZeroAgg, oldCall.isDistinct(), oldCall.isApproximate(), 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.isApproximate(), oldCall.getArgList(), -1, countType, null);
    // NOTE:  these references are with respect to the output
    // of newAggRel
    RexNode sumZeroRef = rexBuilder.addAggCall(sumZeroCall, nGroups, newCalls, aggCallMapping, ImmutableList.of(argType));
    if (!oldCall.getType().isNullable()) {
        // null). Therefore we translate to SUM0(x).
        return sumZeroRef;
    }
    RexNode countRef = rexBuilder.addAggCall(countCall, nGroups, newCalls, aggCallMapping, ImmutableList.of(argType));
    return rexBuilder.makeCall(SqlStdOperatorTable.CASE, rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countRef, rexBuilder.makeExactLiteral(BigDecimal.ZERO)), rexBuilder.constantNull(), sumZeroRef);
}
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) DrillCalciteSqlAggFunctionWrapper(org.apache.drill.exec.planner.sql.DrillCalciteSqlAggFunctionWrapper) RexNode(org.apache.calcite.rex.RexNode)

Example 87 with RexBuilder

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

the class DrillReduceAggregatesRule method reduceStddev.

private RexNode reduceStddev(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, boolean sqrt, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping, List<RexNode> inputExprs) {
    // stddev_pop(x) ==>
    // power(
    // (sum(x * x) - sum(x) * sum(x) / count(x))
    // / count(x),
    // .5)
    // 
    // stddev_samp(x) ==>
    // power(
    // (sum(x * x) - sum(x) * sum(x) / count(x))
    // / nullif(count(x) - 1, 0),
    // .5)
    final PlannerSettings plannerSettings = (PlannerSettings) oldAggRel.getCluster().getPlanner().getContext();
    final boolean isInferenceEnabled = plannerSettings.isTypeInferenceEnabled();
    final int nGroups = oldAggRel.getGroupCount();
    RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();
    final RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
    assert oldCall.getArgList().size() == 1 : oldCall.getArgList();
    final int argOrdinal = oldCall.getArgList().get(0);
    final RelDataType argType = getFieldType(oldAggRel.getInput(), argOrdinal);
    // final RexNode argRef = inputExprs.get(argOrdinal);
    RexNode argRef = rexBuilder.makeCall(CastHighOp, inputExprs.get(argOrdinal));
    inputExprs.set(argOrdinal, argRef);
    final RexNode argSquared = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argRef, argRef);
    final int argSquaredOrdinal = lookupOrAdd(inputExprs, argSquared);
    RelDataType sumType = TypeInferenceUtils.getDrillSqlReturnTypeInference(SqlKind.SUM.name(), ImmutableList.of()).inferReturnType(oldCall.createBinding(oldAggRel));
    sumType = typeFactory.createTypeWithNullability(sumType, true);
    final AggregateCall sumArgSquaredAggCall = AggregateCall.create(new DrillCalciteSqlAggFunctionWrapper(new SqlSumAggFunction(sumType), sumType), oldCall.isDistinct(), oldCall.isApproximate(), ImmutableIntList.of(argSquaredOrdinal), -1, sumType, null);
    final RexNode sumArgSquared = rexBuilder.addAggCall(sumArgSquaredAggCall, nGroups, newCalls, aggCallMapping, ImmutableList.of(argType));
    final AggregateCall sumArgAggCall = AggregateCall.create(new DrillCalciteSqlAggFunctionWrapper(new SqlSumAggFunction(sumType), sumType), oldCall.isDistinct(), oldCall.isApproximate(), ImmutableIntList.of(argOrdinal), -1, sumType, null);
    final RexNode sumArg = rexBuilder.addAggCall(sumArgAggCall, nGroups, newCalls, aggCallMapping, ImmutableList.of(argType));
    final RexNode sumSquaredArg = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumArg, sumArg);
    final SqlCountAggFunction countAgg = (SqlCountAggFunction) SqlStdOperatorTable.COUNT;
    final RelDataType countType = countAgg.getReturnType(typeFactory);
    final AggregateCall countArgAggCall = AggregateCall.create(countAgg, oldCall.isDistinct(), oldCall.isApproximate(), oldCall.getArgList(), -1, countType, null);
    final RexNode countArg = rexBuilder.addAggCall(countArgAggCall, nGroups, newCalls, aggCallMapping, ImmutableList.of(argType));
    final RexNode avgSumSquaredArg = rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumSquaredArg, countArg);
    final RexNode diff = rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumArgSquared, avgSumSquaredArg);
    final RexNode denominator;
    if (biased) {
        denominator = countArg;
    } else {
        final RexLiteral one = rexBuilder.makeExactLiteral(BigDecimal.ONE);
        final RexNode nul = rexBuilder.makeNullLiteral(countArg.getType());
        final RexNode countMinusOne = rexBuilder.makeCall(SqlStdOperatorTable.MINUS, countArg, one);
        final RexNode countEqOne = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, one);
        denominator = rexBuilder.makeCall(SqlStdOperatorTable.CASE, countEqOne, nul, countMinusOne);
    }
    final SqlOperator divide;
    if (isInferenceEnabled) {
        divide = new DrillSqlOperator("divide", 2, true, oldCall.getType(), false);
    } else {
        divide = SqlStdOperatorTable.DIVIDE;
    }
    final RexNode div = rexBuilder.makeCall(divide, diff, denominator);
    RexNode result = div;
    if (sqrt) {
        final RexNode half = rexBuilder.makeExactLiteral(new BigDecimal("0.5"));
        result = rexBuilder.makeCall(SqlStdOperatorTable.POWER, div, half);
    }
    if (isInferenceEnabled) {
        return result;
    } else {
        /*
      * Currently calcite's strategy to infer the return type of aggregate functions
      * is wrong because it uses the first known argument to determine output type. For
      * instance if we are performing stddev on an integer column then it interprets the
      * output type to be integer which is incorrect as it should be double. So based on
      * this if we add cast after rewriting the aggregate we add an additional cast which
      * would cause wrong results. So we simply add a cast to ANY.
      */
        return rexBuilder.makeCast(typeFactory.createSqlType(SqlTypeName.ANY), result);
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator) SqlOperator(org.apache.calcite.sql.SqlOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlCountAggFunction(org.apache.calcite.sql.fun.SqlCountAggFunction) BigDecimal(java.math.BigDecimal) DrillCalciteSqlAggFunctionWrapper(org.apache.drill.exec.planner.sql.DrillCalciteSqlAggFunctionWrapper) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) SqlSumAggFunction(org.apache.calcite.sql.fun.SqlSumAggFunction) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 88 with RexBuilder

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

the class DrillOptiqTest method testUnsupportedRexNode.

/* Method checks if we raise the appropriate error while dealing with RexNode that cannot be converted to
   * equivalent Drill expressions
   */
@Test
public void testUnsupportedRexNode() {
    try {
        // Create the data type factory.
        RelDataTypeFactory relFactory = new SqlTypeFactoryImpl(DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM);
        // Create the rex builder
        RexBuilder rex = new RexBuilder(relFactory);
        RelDataType anyType = relFactory.createSqlType(SqlTypeName.ANY);
        List<RexNode> emptyList = new LinkedList<>();
        ImmutableList<RexFieldCollation> e = ImmutableList.copyOf(new RexFieldCollation[0]);
        // create a dummy RexOver object.
        RexNode window = rex.makeOver(anyType, SqlStdOperatorTable.AVG, emptyList, emptyList, GuavaUtils.convertToUnshadedImmutableList(e), null, null, true, false, false, false);
        DrillOptiq.toDrill(null, (RelNode) null, window);
    } catch (UserException e) {
        if (e.getMessage().contains(DrillOptiq.UNSUPPORTED_REX_NODE_ERROR)) {
            // got expected error return
            return;
        }
        Assert.fail("Hit exception with unexpected error message");
    }
    Assert.fail("Failed to raise the expected exception");
}
Also used : SqlTypeFactoryImpl(org.apache.calcite.sql.type.SqlTypeFactoryImpl) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) UserException(org.apache.drill.common.exceptions.UserException) RexFieldCollation(org.apache.calcite.rex.RexFieldCollation) LinkedList(java.util.LinkedList) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test) BaseTest(org.apache.drill.test.BaseTest) PlannerTest(org.apache.drill.categories.PlannerTest)

Example 89 with RexBuilder

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

the class MapRDBStatistics method addToCache.

/*
   * Adds the statistic(row count) to the cache. Also adds the corresponding QueryCondition->RexNode
   * condition mapping.
   */
private void addToCache(RexNode condition, IndexDescriptor idx, IndexCallContext context, StatisticsPayload payload, JsonTableGroupScan jTabGrpScan, RelNode scanRel, RelDataType rowType) {
    if (condition != null && !condition.isAlwaysTrue()) {
        RexBuilder builder = scanRel.getCluster().getRexBuilder();
        PlannerSettings settings = PrelUtil.getSettings(scanRel.getCluster());
        String conditionAsStr = convertRexToString(condition, scanRel.getRowType());
        if (statsCache.get(conditionAsStr) == null && payload.getRowCount() != Statistics.ROWCOUNT_UNKNOWN) {
            Map<String, StatisticsPayload> payloadMap = new HashMap<>();
            payloadMap.put(buildUniqueIndexIdentifier(idx), payload);
            statsCache.put(conditionAsStr, payloadMap);
            logger.debug("Statistics: StatsCache:<{}, {}>", conditionAsStr, payload);
            // Always pre-process CAST conditions - Otherwise queryCondition will not be generated correctly
            RexNode preProcIdxCondition = convertToStatsCondition(condition, idx, context, scanRel, Arrays.asList(SqlKind.CAST));
            QueryCondition queryCondition = jTabGrpScan.convertToQueryCondition(convertToLogicalExpression(preProcIdxCondition, rowType, settings, builder));
            if (queryCondition != null) {
                String queryConditionAsStr = queryCondition.toString();
                if (conditionRexNodeMap.get(queryConditionAsStr) == null) {
                    conditionRexNodeMap.put(queryConditionAsStr, conditionAsStr);
                    logger.debug("Statistics: QCRNCache:<{}, {}>", queryConditionAsStr, conditionAsStr);
                }
            } else {
                logger.debug("Statistics: QCRNCache: Unable to generate QueryCondition for {}", conditionAsStr);
                logger.debug("Statistics: QCRNCache: Unable to generate QueryCondition for {}", conditionAsStr);
            }
        } else {
            Map<String, StatisticsPayload> payloadMap = statsCache.get(conditionAsStr);
            if (payloadMap != null) {
                if (payloadMap.get(buildUniqueIndexIdentifier(idx)) == null) {
                    payloadMap.put(buildUniqueIndexIdentifier(idx), payload);
                    // rowCount for the same condition should be the same on primary table or index,
                    // let us sync them to the smallest since currently both are over-estimated.
                    // DO NOT sync the leading rowCount since it is based on the leading condition and not the
                    // condition (key for this cache). Hence, for the same condition the leading condition and
                    // consequently the leading rowCount will vary with the index. Syncing them may lead to
                    // unintended side-effects e.g. given a covering index and full table scan and a condition
                    // on a non-id field which happens to be the leading key in the index, the leading rowcount
                    // for the full table scan should be the full table rowcount. Syncing them would incorrectly
                    // make the full table scan cheaper! If required, syncing should be only done based on
                    // leading condition and NOT the condition
                    double minimalRowCount = payload.getRowCount();
                    for (StatisticsPayload existing : payloadMap.values()) {
                        if (existing.getRowCount() < minimalRowCount) {
                            minimalRowCount = existing.getRowCount();
                        }
                    }
                    for (StatisticsPayload existing : payloadMap.values()) {
                        if (existing instanceof MapRDBStatisticsPayload) {
                            ((MapRDBStatisticsPayload) existing).rowCount = minimalRowCount;
                        }
                    }
                } else {
                    logger.debug("Statistics: Filter row count already exists for filter: {}. Skip!", conditionAsStr);
                }
            } else {
                logger.debug("Statistics: Filter row count is UNKNOWN for filter: {}", conditionAsStr);
            }
        }
    } else if (condition == null && idx == null) {
        fullTableScanPayload = new MapRDBStatisticsPayload(payload.getRowCount(), payload.getLeadingRowCount(), payload.getAvgRowSize());
        logger.debug("Statistics: StatsCache:<{}, {}>", "NULL", fullTableScanPayload);
    }
}
Also used : PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) HashMap(java.util.HashMap) RexBuilder(org.apache.calcite.rex.RexBuilder) QueryCondition(org.ojai.store.QueryCondition) RexNode(org.apache.calcite.rex.RexNode)

Example 90 with RexBuilder

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

the class DrillConstExecutor method reduce.

@Override
@SuppressWarnings("deprecation")
public void reduce(RexBuilder rexBuilder, List<RexNode> constExps, List<RexNode> reducedValues) {
    for (RexNode newCall : constExps) {
        LogicalExpression logEx = DrillOptiq.toDrill(new DrillParseContext(plannerSettings), (RelNode) null, /* input rel */
        newCall);
        ErrorCollectorImpl errors = new ErrorCollectorImpl();
        LogicalExpression materializedExpr = ExpressionTreeMaterializer.materialize(logEx, null, errors, funcImplReg);
        if (errors.getErrorCount() != 0) {
            String message = String.format("Failure while materializing expression in constant expression evaluator [%s].  Errors: %s", newCall.toString(), errors.toString());
            throw UserException.planError().message(message).build(logger);
        }
        if (NON_REDUCIBLE_TYPES.contains(materializedExpr.getMajorType().getMinorType())) {
            logger.debug("Constant expression not folded due to return type {}, complete expression: {}", materializedExpr.getMajorType(), ExpressionStringBuilder.toString(materializedExpr));
            reducedValues.add(newCall);
            continue;
        }
        ValueHolder output = InterpreterEvaluator.evaluateConstantExpr(udfUtilities, materializedExpr);
        RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL && TypeHelper.isNull(output)) {
            SqlTypeName sqlTypeName = TypeInferenceUtils.getCalciteTypeFromDrillType(materializedExpr.getMajorType().getMinorType());
            if (sqlTypeName == null) {
                String message = String.format("Error reducing constant expression, unsupported type: %s.", materializedExpr.getMajorType().getMinorType());
                throw UserException.unsupportedError().message(message).build(logger);
            }
            RelDataType type = TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, sqlTypeName, true);
            reducedValues.add(rexBuilder.makeNullLiteral(type));
            continue;
        }
        Function<ValueHolder, RexNode> literator = valueHolder -> {
            switch(materializedExpr.getMajorType().getMinorType()) {
                case INT:
                    {
                        int value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableIntHolder) valueHolder).value : ((IntHolder) valueHolder).value;
                        return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTEGER, newCall.getType().isNullable()), false);
                    }
                case BIGINT:
                    {
                        long value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableBigIntHolder) valueHolder).value : ((BigIntHolder) valueHolder).value;
                        return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.BIGINT, newCall.getType().isNullable()), false);
                    }
                case FLOAT4:
                    {
                        float value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableFloat4Holder) valueHolder).value : ((Float4Holder) valueHolder).value;
                        // BigDecimal cannot represent them.
                        if (!Float.isFinite(value)) {
                            return rexBuilder.makeLiteral(Float.toString(value));
                        }
                        return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.FLOAT, newCall.getType().isNullable()), false);
                    }
                case FLOAT8:
                    {
                        double value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableFloat8Holder) valueHolder).value : ((Float8Holder) valueHolder).value;
                        // BigDecimal cannot represent them.
                        if (!Double.isFinite(value)) {
                            return rexBuilder.makeLiteral(Double.toString(value));
                        }
                        return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DOUBLE, newCall.getType().isNullable()), false);
                    }
                case VARCHAR:
                    {
                        String value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? StringFunctionHelpers.getStringFromVarCharHolder((NullableVarCharHolder) valueHolder) : StringFunctionHelpers.getStringFromVarCharHolder((VarCharHolder) valueHolder);
                        RelDataType type = typeFactory.createSqlType(SqlTypeName.VARCHAR, newCall.getType().getPrecision());
                        RelDataType typeWithNullability = typeFactory.createTypeWithNullability(type, newCall.getType().isNullable());
                        return rexBuilder.makeLiteral(value, typeWithNullability, false);
                    }
                case BIT:
                    {
                        boolean value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableBitHolder) valueHolder).value == 1 : ((BitHolder) valueHolder).value == 1;
                        return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.BOOLEAN, newCall.getType().isNullable()), false);
                    }
                case DATE:
                    {
                        Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableDateHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((DateHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null);
                        return rexBuilder.makeLiteral(DateString.fromCalendarFields(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DATE, newCall.getType().isNullable()), false);
                    }
                case DECIMAL9:
                    {
                        long value;
                        int scale;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableDecimal9Holder decimal9Out = (NullableDecimal9Holder) valueHolder;
                            value = decimal9Out.value;
                            scale = decimal9Out.scale;
                        } else {
                            Decimal9Holder decimal9Out = (Decimal9Holder) valueHolder;
                            value = decimal9Out.value;
                            scale = decimal9Out.scale;
                        }
                        return rexBuilder.makeLiteral(new BigDecimal(BigInteger.valueOf(value), scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
                    }
                case DECIMAL18:
                    {
                        long value;
                        int scale;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableDecimal18Holder decimal18Out = (NullableDecimal18Holder) valueHolder;
                            value = decimal18Out.value;
                            scale = decimal18Out.scale;
                        } else {
                            Decimal18Holder decimal18Out = (Decimal18Holder) valueHolder;
                            value = decimal18Out.value;
                            scale = decimal18Out.scale;
                        }
                        return rexBuilder.makeLiteral(new BigDecimal(BigInteger.valueOf(value), scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
                    }
                case VARDECIMAL:
                    {
                        DrillBuf buffer;
                        int start;
                        int end;
                        int scale;
                        int precision;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableVarDecimalHolder varDecimalHolder = (NullableVarDecimalHolder) valueHolder;
                            buffer = varDecimalHolder.buffer;
                            start = varDecimalHolder.start;
                            end = varDecimalHolder.end;
                            scale = varDecimalHolder.scale;
                            precision = varDecimalHolder.precision;
                        } else {
                            VarDecimalHolder varDecimalHolder = (VarDecimalHolder) valueHolder;
                            buffer = varDecimalHolder.buffer;
                            start = varDecimalHolder.start;
                            end = varDecimalHolder.end;
                            scale = varDecimalHolder.scale;
                            precision = varDecimalHolder.precision;
                        }
                        return rexBuilder.makeLiteral(org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDrillBuf(buffer, start, end - start, scale), typeFactory.createSqlType(SqlTypeName.DECIMAL, precision, scale), false);
                    }
                case DECIMAL28SPARSE:
                    {
                        DrillBuf buffer;
                        int start;
                        int scale;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableDecimal28SparseHolder decimal28Out = (NullableDecimal28SparseHolder) valueHolder;
                            buffer = decimal28Out.buffer;
                            start = decimal28Out.start;
                            scale = decimal28Out.scale;
                        } else {
                            Decimal28SparseHolder decimal28Out = (Decimal28SparseHolder) valueHolder;
                            buffer = decimal28Out.buffer;
                            start = decimal28Out.start;
                            scale = decimal28Out.scale;
                        }
                        return rexBuilder.makeLiteral(org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(buffer, start * 20, 5, scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
                    }
                case DECIMAL38SPARSE:
                    {
                        DrillBuf buffer;
                        int start;
                        int scale;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableDecimal38SparseHolder decimal38Out = (NullableDecimal38SparseHolder) valueHolder;
                            buffer = decimal38Out.buffer;
                            start = decimal38Out.start;
                            scale = decimal38Out.scale;
                        } else {
                            Decimal38SparseHolder decimal38Out = (Decimal38SparseHolder) valueHolder;
                            buffer = decimal38Out.buffer;
                            start = decimal38Out.start;
                            scale = decimal38Out.scale;
                        }
                        return rexBuilder.makeLiteral(org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(buffer, start * 24, 6, scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
                    }
                case TIME:
                    {
                        Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableTimeHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((TimeHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null);
                        RelDataType type = typeFactory.createSqlType(SqlTypeName.TIME, newCall.getType().getPrecision());
                        RelDataType typeWithNullability = typeFactory.createTypeWithNullability(type, newCall.getType().isNullable());
                        return rexBuilder.makeLiteral(TimeString.fromCalendarFields(value), typeWithNullability, false);
                    }
                case TIMESTAMP:
                    {
                        Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableTimeStampHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((TimeStampHolder) valueHolder).value, DateTimeZone.UTC).toCalendar(null);
                        RelDataType type = typeFactory.createSqlType(SqlTypeName.TIMESTAMP, newCall.getType().getPrecision());
                        RelDataType typeWithNullability = typeFactory.createTypeWithNullability(type, newCall.getType().isNullable());
                        return rexBuilder.makeLiteral(TimestampString.fromCalendarFields(value), typeWithNullability, false);
                    }
                case INTERVALYEAR:
                    {
                        BigDecimal value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new BigDecimal(((NullableIntervalYearHolder) valueHolder).value) : new BigDecimal(((IntervalYearHolder) valueHolder).value);
                        return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTERVAL_YEAR_MONTH, newCall.getType().isNullable()), false);
                    }
                case INTERVALDAY:
                    {
                        int days;
                        int milliseconds;
                        if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
                            NullableIntervalDayHolder intervalDayOut = (NullableIntervalDayHolder) valueHolder;
                            days = intervalDayOut.days;
                            milliseconds = intervalDayOut.milliseconds;
                        } else {
                            IntervalDayHolder intervalDayOut = (IntervalDayHolder) valueHolder;
                            days = intervalDayOut.days;
                            milliseconds = intervalDayOut.milliseconds;
                        }
                        return rexBuilder.makeLiteral(new BigDecimal(days * (long) DateUtilities.daysToStandardMillis + milliseconds), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTERVAL_DAY, newCall.getType().isNullable()), false);
                    }
                // as new types may be added in the future.
                default:
                    logger.debug("Constant expression not folded due to return type {}, complete expression: {}", materializedExpr.getMajorType(), ExpressionStringBuilder.toString(materializedExpr));
                    return newCall;
            }
        };
        reducedValues.add(literator.apply(output));
    }
}
Also used : RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) DateTimeZone(org.joda.time.DateTimeZone) VarDecimalHolder(org.apache.drill.exec.expr.holders.VarDecimalHolder) ExpressionTreeMaterializer(org.apache.drill.exec.expr.ExpressionTreeMaterializer) UserException(org.apache.drill.common.exceptions.UserException) TypeHelper(org.apache.drill.exec.expr.TypeHelper) VarCharHolder(org.apache.drill.exec.expr.holders.VarCharHolder) StringFunctionHelpers(org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers) NullableVarCharHolder(org.apache.drill.exec.expr.holders.NullableVarCharHolder) NullableVarDecimalHolder(org.apache.drill.exec.expr.holders.NullableVarDecimalHolder) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) ExpressionStringBuilder(org.apache.drill.common.expression.ExpressionStringBuilder) NullableIntervalDayHolder(org.apache.drill.exec.expr.holders.NullableIntervalDayHolder) BigDecimal(java.math.BigDecimal) UdfUtilities(org.apache.drill.exec.ops.UdfUtilities) RexNode(org.apache.calcite.rex.RexNode) Decimal9Holder(org.apache.drill.exec.expr.holders.Decimal9Holder) DateHolder(org.apache.drill.exec.expr.holders.DateHolder) NullableIntervalYearHolder(org.apache.drill.exec.expr.holders.NullableIntervalYearHolder) DrillBuf(io.netty.buffer.DrillBuf) BigIntHolder(org.apache.drill.exec.expr.holders.BigIntHolder) BigInteger(java.math.BigInteger) NullableBigIntHolder(org.apache.drill.exec.expr.holders.NullableBigIntHolder) NullableDecimal9Holder(org.apache.drill.exec.expr.holders.NullableDecimal9Holder) Decimal18Holder(org.apache.drill.exec.expr.holders.Decimal18Holder) DateString(org.apache.calcite.util.DateString) Decimal28SparseHolder(org.apache.drill.exec.expr.holders.Decimal28SparseHolder) NullableFloat4Holder(org.apache.drill.exec.expr.holders.NullableFloat4Holder) TimestampString(org.apache.calcite.util.TimestampString) ErrorCollectorImpl(org.apache.drill.common.expression.ErrorCollectorImpl) LogicalExpression(org.apache.drill.common.expression.LogicalExpression) TypeProtos(org.apache.drill.common.types.TypeProtos) List(java.util.List) NullableTimeStampHolder(org.apache.drill.exec.expr.holders.NullableTimeStampHolder) ValueHolder(org.apache.drill.exec.expr.holders.ValueHolder) Decimal38SparseHolder(org.apache.drill.exec.expr.holders.Decimal38SparseHolder) BitHolder(org.apache.drill.exec.expr.holders.BitHolder) NullableFloat8Holder(org.apache.drill.exec.expr.holders.NullableFloat8Holder) IntervalYearHolder(org.apache.drill.exec.expr.holders.IntervalYearHolder) Float8Holder(org.apache.drill.exec.expr.holders.Float8Holder) Function(java.util.function.Function) Float4Holder(org.apache.drill.exec.expr.holders.Float4Holder) TimeString(org.apache.calcite.util.TimeString) Calendar(java.util.Calendar) InterpreterEvaluator(org.apache.drill.exec.expr.fn.interpreter.InterpreterEvaluator) TimeHolder(org.apache.drill.exec.expr.holders.TimeHolder) NullableBitHolder(org.apache.drill.exec.expr.holders.NullableBitHolder) IntHolder(org.apache.drill.exec.expr.holders.IntHolder) RexExecutor(org.apache.calcite.rex.RexExecutor) RelDataType(org.apache.calcite.rel.type.RelDataType) NullableDecimal18Holder(org.apache.drill.exec.expr.holders.NullableDecimal18Holder) DateUtilities(org.apache.drill.exec.vector.DateUtilities) NullableDecimal38SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal38SparseHolder) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) NullableDecimal28SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal28SparseHolder) TypeInferenceUtils(org.apache.drill.exec.planner.sql.TypeInferenceUtils) RexBuilder(org.apache.calcite.rex.RexBuilder) DateTime(org.joda.time.DateTime) RelNode(org.apache.calcite.rel.RelNode) NullableTimeHolder(org.apache.drill.exec.expr.holders.NullableTimeHolder) ImmutableList(org.apache.drill.shaded.guava.com.google.common.collect.ImmutableList) IntervalDayHolder(org.apache.drill.exec.expr.holders.IntervalDayHolder) NullableIntHolder(org.apache.drill.exec.expr.holders.NullableIntHolder) PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) TimeStampHolder(org.apache.drill.exec.expr.holders.TimeStampHolder) NullableDateHolder(org.apache.drill.exec.expr.holders.NullableDateHolder) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) NullableDecimal9Holder(org.apache.drill.exec.expr.holders.NullableDecimal9Holder) BitHolder(org.apache.drill.exec.expr.holders.BitHolder) NullableBitHolder(org.apache.drill.exec.expr.holders.NullableBitHolder) NullableVarDecimalHolder(org.apache.drill.exec.expr.holders.NullableVarDecimalHolder) Decimal9Holder(org.apache.drill.exec.expr.holders.Decimal9Holder) NullableDecimal9Holder(org.apache.drill.exec.expr.holders.NullableDecimal9Holder) VarDecimalHolder(org.apache.drill.exec.expr.holders.VarDecimalHolder) NullableVarDecimalHolder(org.apache.drill.exec.expr.holders.NullableVarDecimalHolder) RelDataType(org.apache.calcite.rel.type.RelDataType) DateString(org.apache.calcite.util.DateString) TimestampString(org.apache.calcite.util.TimestampString) TimeString(org.apache.calcite.util.TimeString) DateTime(org.joda.time.DateTime) NullableIntervalYearHolder(org.apache.drill.exec.expr.holders.NullableIntervalYearHolder) IntervalYearHolder(org.apache.drill.exec.expr.holders.IntervalYearHolder) ErrorCollectorImpl(org.apache.drill.common.expression.ErrorCollectorImpl) LogicalExpression(org.apache.drill.common.expression.LogicalExpression) NullableVarCharHolder(org.apache.drill.exec.expr.holders.NullableVarCharHolder) NullableIntervalYearHolder(org.apache.drill.exec.expr.holders.NullableIntervalYearHolder) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) DrillBuf(io.netty.buffer.DrillBuf) NullableIntervalDayHolder(org.apache.drill.exec.expr.holders.NullableIntervalDayHolder) Decimal18Holder(org.apache.drill.exec.expr.holders.Decimal18Holder) NullableDecimal18Holder(org.apache.drill.exec.expr.holders.NullableDecimal18Holder) NullableIntervalDayHolder(org.apache.drill.exec.expr.holders.NullableIntervalDayHolder) IntervalDayHolder(org.apache.drill.exec.expr.holders.IntervalDayHolder) Calendar(java.util.Calendar) NullableDecimal38SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal38SparseHolder) ValueHolder(org.apache.drill.exec.expr.holders.ValueHolder) BigDecimal(java.math.BigDecimal) NullableDecimal28SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal28SparseHolder) NullableDecimal18Holder(org.apache.drill.exec.expr.holders.NullableDecimal18Holder) NullableBitHolder(org.apache.drill.exec.expr.holders.NullableBitHolder) Decimal38SparseHolder(org.apache.drill.exec.expr.holders.Decimal38SparseHolder) NullableDecimal38SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal38SparseHolder) Decimal28SparseHolder(org.apache.drill.exec.expr.holders.Decimal28SparseHolder) NullableDecimal28SparseHolder(org.apache.drill.exec.expr.holders.NullableDecimal28SparseHolder) VarCharHolder(org.apache.drill.exec.expr.holders.VarCharHolder) NullableVarCharHolder(org.apache.drill.exec.expr.holders.NullableVarCharHolder) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexBuilder (org.apache.calcite.rex.RexBuilder)314 RexNode (org.apache.calcite.rex.RexNode)248 ArrayList (java.util.ArrayList)151 RelNode (org.apache.calcite.rel.RelNode)121 RelDataType (org.apache.calcite.rel.type.RelDataType)121 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)77 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)59 RexInputRef (org.apache.calcite.rex.RexInputRef)49 RelBuilder (org.apache.calcite.tools.RelBuilder)49 AggregateCall (org.apache.calcite.rel.core.AggregateCall)48 List (java.util.List)41 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)41 RelOptCluster (org.apache.calcite.plan.RelOptCluster)36 HashMap (java.util.HashMap)33 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)24 Project (org.apache.calcite.rel.core.Project)24 RexCall (org.apache.calcite.rex.RexCall)24 BigDecimal (java.math.BigDecimal)23 Collectors (java.util.stream.Collectors)23 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)22