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);
}
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);
}
}
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");
}
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);
}
}
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));
}
}
Aggregations