Java Code Examples for org.apache.calcite.rex.RexBuilder#makeCast()

The following examples show how to use org.apache.calcite.rex.RexBuilder#makeCast() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClassRowTypeCache.java    From mat-calcite-plugin with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode apply(RexBuilderContext context) {
	RelOptCluster cluster = context.getCluster();
	RelDataTypeFactory typeFactory = cluster.getTypeFactory();
	final SqlFunction UDF =
			new SqlUserDefinedFunction(
					new SqlIdentifier("RESOLVE_SIMPLE", SqlParserPos.ZERO),
					ReturnTypes.explicit(typeFactory.createJavaType(Object.class)),
					null,
					OperandTypes.ANY_ANY,
					ImmutableList.of(typeFactory.createTypeWithNullability(typeFactory.createJavaType(IObject.class), false),
							typeFactory.createJavaType(int.class)),
					ScalarFunctionImpl.create(IObjectMethods.class, "resolveSimpleValue"));
	RexBuilder b = context.getBuilder();
	RexNode rexNode = b.makeCall(UDF, context.getIObject(), b.makeLiteral(name));
	return b.makeCast(dataType, rexNode);
}
 
Example 2
Source File: StandardConvertletTable.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Casts a RexNode value to the validated type of a SqlCall. If the value
 * was already of the validated type, then the value is returned without an
 * additional cast.
 */
public static RexNode castToValidatedType(SqlNode node, RexNode e,
    SqlValidator validator, RexBuilder rexBuilder) {
  final RelDataType type = validator.getValidatedNodeType(node);
  if (e.getType() == type) {
    return e;
  }
  return rexBuilder.makeCast(type, e);
}
 
Example 3
Source File: StandardConvertletTable.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Casts a RexNode value to the validated type of a SqlCall. If the value
 * was already of the validated type, then the value is returned without an
 * additional cast.
 */
public static RexNode castToValidatedType(SqlNode node, RexNode e,
    SqlValidator validator, RexBuilder rexBuilder) {
  final RelDataType type = validator.getValidatedNodeType(node);
  if (e.getType() == type) {
    return e;
  }
  return rexBuilder.makeCast(type, e);
}
 
Example 4
Source File: AggregateReduceFunctionsRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
private RexNode reduceAvg(
    Aggregate oldAggRel,
    AggregateCall oldCall,
    List<AggregateCall> newCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    List<RexNode> inputExprs) {
  final int nGroups = oldAggRel.getGroupCount();
  final RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
  final int iAvgInput = oldCall.getArgList().get(0);
  final RelDataType avgInputType =
      getFieldType(
          oldAggRel.getInput(),
          iAvgInput);
  final AggregateCall sumCall =
      AggregateCall.create(SqlStdOperatorTable.SUM,
          oldCall.isDistinct(),
          oldCall.isApproximate(),
          oldCall.getArgList(),
          oldCall.filterArg,
          oldCall.collation,
          oldAggRel.getGroupCount(),
          oldAggRel.getInput(),
          null,
          null);
  final AggregateCall countCall =
      AggregateCall.create(SqlStdOperatorTable.COUNT,
          oldCall.isDistinct(),
          oldCall.isApproximate(),
          oldCall.getArgList(),
          oldCall.filterArg,
          oldCall.collation,
          oldAggRel.getGroupCount(),
          oldAggRel.getInput(),
          null,
          null);

  // NOTE:  these references are with respect to the output
  // of newAggRel
  RexNode numeratorRef =
      rexBuilder.addAggCall(sumCall,
          nGroups,
          oldAggRel.indicator,
          newCalls,
          aggCallMapping,
          ImmutableList.of(avgInputType));
  final RexNode denominatorRef =
      rexBuilder.addAggCall(countCall,
          nGroups,
          oldAggRel.indicator,
          newCalls,
          aggCallMapping,
          ImmutableList.of(avgInputType));

  final RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();
  final RelDataType avgType = typeFactory.createTypeWithNullability(
      oldCall.getType(), numeratorRef.getType().isNullable());
  numeratorRef = rexBuilder.ensureType(avgType, numeratorRef, true);
  final RexNode divideRef =
      rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
  return rexBuilder.makeCast(oldCall.getType(), divideRef);
}
 
Example 5
Source File: AggregateReduceFunctionsRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
private RexNode reduceRegrSzz(
    Aggregate oldAggRel,
    AggregateCall oldCall,
    List<AggregateCall> newCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    List<RexNode> inputExprs,
    int xIndex,
    int yIndex,
    int nullFilterIndex) {
  // regr_sxx(x, y) ==>
  //    sum(y * y, x) - sum(y, x) * sum(y, x) / regr_count(x, y)
  //

  final RelOptCluster cluster = oldAggRel.getCluster();
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
  final RelDataType argXType = getFieldType(oldAggRel.getInput(), xIndex);
  final RelDataType argYType =
      xIndex == yIndex ? argXType : getFieldType(oldAggRel.getInput(), yIndex);
  final RelDataType nullFilterIndexType =
      nullFilterIndex == yIndex ? argYType : getFieldType(oldAggRel.getInput(), yIndex);

  final RelDataType oldCallType =
      typeFactory.createTypeWithNullability(oldCall.getType(),
          argXType.isNullable() || argYType.isNullable() || nullFilterIndexType.isNullable());

  final RexNode argX =
      rexBuilder.ensureType(oldCallType, inputExprs.get(xIndex), true);
  final RexNode argY =
      rexBuilder.ensureType(oldCallType, inputExprs.get(yIndex), true);
  final RexNode argNullFilter =
      rexBuilder.ensureType(oldCallType, inputExprs.get(nullFilterIndex), true);

  final RexNode argXArgY = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argX, argY);
  final int argSquaredOrdinal = lookupOrAdd(inputExprs, argXArgY);

  final RexNode argXAndYNotNullFilter = rexBuilder.makeCall(SqlStdOperatorTable.AND,
      rexBuilder.makeCall(SqlStdOperatorTable.AND,
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argX),
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argY)),
      rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argNullFilter));
  final int argXAndYNotNullFilterOrdinal = lookupOrAdd(inputExprs, argXAndYNotNullFilter);
  final RexNode sumXY = getSumAggregatedRexNodeWithBinding(
      oldAggRel, oldCall, newCalls, aggCallMapping, argXArgY.getType(),
      argSquaredOrdinal, argXAndYNotNullFilterOrdinal);
  final RexNode sumXYCast = rexBuilder.ensureType(oldCallType, sumXY, true);

  final RexNode sumX = getSumAggregatedRexNode(oldAggRel, oldCall,
      newCalls, aggCallMapping, rexBuilder, xIndex, argXAndYNotNullFilterOrdinal);
  final RexNode sumY = xIndex == yIndex
      ? sumX
      : getSumAggregatedRexNode(oldAggRel, oldCall, newCalls,
          aggCallMapping, rexBuilder, yIndex, argXAndYNotNullFilterOrdinal);

  final RexNode sumXSumY = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumX, sumY);

  final RexNode countArg = getRegrCountRexNode(oldAggRel, oldCall, newCalls, aggCallMapping,
      ImmutableIntList.of(xIndex), ImmutableList.of(argXType), argXAndYNotNullFilterOrdinal);

  RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
  RexNode nul = rexBuilder.constantNull();
  final RexNode avgSumXSumY = rexBuilder.makeCall(SqlStdOperatorTable.CASE,
      rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, zero), nul,
          rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumXSumY, countArg));
  final RexNode avgSumXSumYCast = rexBuilder.ensureType(oldCallType, avgSumXSumY, true);
  final RexNode result =
      rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumXYCast, avgSumXSumYCast);
  return rexBuilder.makeCast(oldCall.getType(), result);
}
 
Example 6
Source File: SqlNodeToRexConverterImpl.java    From Bats with Apache License 2.0 4 votes vote down vote up
public RexNode convertLiteral(
    SqlRexContext cx,
    SqlLiteral literal) {
  RexBuilder rexBuilder = cx.getRexBuilder();
  RelDataTypeFactory typeFactory = cx.getTypeFactory();
  SqlValidator validator = cx.getValidator();
  if (literal.getValue() == null) {
    // Since there is no eq. RexLiteral of SqlLiteral.Unknown we
    // treat it as a cast(null as boolean)
    RelDataType type;
    if (literal.getTypeName() == SqlTypeName.BOOLEAN) {
      type = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
      type = typeFactory.createTypeWithNullability(type, true);
    } else {
      type = validator.getValidatedNodeType(literal);
    }
    return rexBuilder.makeCast(
        type,
        rexBuilder.constantNull());
  }

  BitString bitString;
  SqlIntervalLiteral.IntervalValue intervalValue;
  long l;

  switch (literal.getTypeName()) {
  case DECIMAL:
    // exact number
    BigDecimal bd = literal.getValueAs(BigDecimal.class);
    return rexBuilder.makeExactLiteral(
        bd,
        literal.createSqlType(typeFactory));

  case DOUBLE:
    // approximate type
    // TODO:  preserve fixed-point precision and large integers
    return rexBuilder.makeApproxLiteral(literal.getValueAs(BigDecimal.class));

  case CHAR:
    return rexBuilder.makeCharLiteral(literal.getValueAs(NlsString.class));
  case BOOLEAN:
    return rexBuilder.makeLiteral(literal.getValueAs(Boolean.class));
  case BINARY:
    bitString = literal.getValueAs(BitString.class);
    Preconditions.checkArgument((bitString.getBitCount() % 8) == 0,
        "incomplete octet");

    // An even number of hexits (e.g. X'ABCD') makes whole number
    // of bytes.
    ByteString byteString = new ByteString(bitString.getAsByteArray());
    return rexBuilder.makeBinaryLiteral(byteString);
  case SYMBOL:
    return rexBuilder.makeFlag(literal.getValueAs(Enum.class));
  case TIMESTAMP:
    return rexBuilder.makeTimestampLiteral(
        literal.getValueAs(TimestampString.class),
        ((SqlTimestampLiteral) literal).getPrec());
  case TIME:
    return rexBuilder.makeTimeLiteral(
        literal.getValueAs(TimeString.class),
        ((SqlTimeLiteral) literal).getPrec());
  case DATE:
    return rexBuilder.makeDateLiteral(literal.getValueAs(DateString.class));

  case INTERVAL_YEAR:
  case INTERVAL_YEAR_MONTH:
  case INTERVAL_MONTH:
  case INTERVAL_DAY:
  case INTERVAL_DAY_HOUR:
  case INTERVAL_DAY_MINUTE:
  case INTERVAL_DAY_SECOND:
  case INTERVAL_HOUR:
  case INTERVAL_HOUR_MINUTE:
  case INTERVAL_HOUR_SECOND:
  case INTERVAL_MINUTE:
  case INTERVAL_MINUTE_SECOND:
  case INTERVAL_SECOND:
    SqlIntervalQualifier sqlIntervalQualifier =
        literal.getValueAs(SqlIntervalLiteral.IntervalValue.class)
            .getIntervalQualifier();
    return rexBuilder.makeIntervalLiteral(
        literal.getValueAs(BigDecimal.class),
        sqlIntervalQualifier);
  default:
    throw Util.unexpected(literal.getTypeName());
  }
}
 
Example 7
Source File: StandardConvertletTable.java    From Bats with Apache License 2.0 4 votes vote down vote up
public RexNode convertCall(SqlRexContext cx, SqlCall call) {
  // TIMESTAMPDIFF(unit, t1, t2)
  //    => (t2 - t1) UNIT
  final RexBuilder rexBuilder = cx.getRexBuilder();
  final SqlLiteral unitLiteral = call.operand(0);
  TimeUnit unit = unitLiteral.symbolValue(TimeUnit.class);
  BigDecimal multiplier = BigDecimal.ONE;
  BigDecimal divider = BigDecimal.ONE;
  SqlTypeName sqlTypeName = unit == TimeUnit.NANOSECOND
      ? SqlTypeName.BIGINT
      : SqlTypeName.INTEGER;
  switch (unit) {
  case MICROSECOND:
  case MILLISECOND:
  case NANOSECOND:
  case WEEK:
    multiplier = BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND);
    divider = unit.multiplier;
    unit = TimeUnit.SECOND;
    break;
  case QUARTER:
    divider = unit.multiplier;
    unit = TimeUnit.MONTH;
    break;
  }
  final SqlIntervalQualifier qualifier =
      new SqlIntervalQualifier(unit, null, SqlParserPos.ZERO);
  final RexNode op2 = cx.convertExpression(call.operand(2));
  final RexNode op1 = cx.convertExpression(call.operand(1));
  final RelDataType intervalType =
      cx.getTypeFactory().createTypeWithNullability(
          cx.getTypeFactory().createSqlIntervalType(qualifier),
          op1.getType().isNullable() || op2.getType().isNullable());
  final RexCall rexCall = (RexCall) rexBuilder.makeCall(
      intervalType, SqlStdOperatorTable.MINUS_DATE,
      ImmutableList.of(op2, op1));
  final RelDataType intType =
      cx.getTypeFactory().createTypeWithNullability(
          cx.getTypeFactory().createSqlType(sqlTypeName),
          SqlTypeUtil.containsNullable(rexCall.getType()));
  RexNode e = rexBuilder.makeCast(intType, rexCall);
  return rexBuilder.multiplyDivide(e, multiplier, divider);
}
 
Example 8
Source File: DrillReduceAggregatesRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
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 =
      TypeInferenceUtils.getDrillSqlReturnTypeInference(SqlKind.SUM.name(),
          ImmutableList.of())
        .inferReturnType(oldCall.createBinding(oldAggRel));
  sumType =
      typeFactory.createTypeWithNullability(
          sumType,
          sumType.isNullable() || nGroups == 0);
  SqlAggFunction sumAgg =
      new DrillCalciteSqlAggFunctionWrapper(new SqlSumEmptyIsZeroAggFunction(), sumType);
  AggregateCall sumCall = AggregateCall.create(sumAgg, 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);

  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);
  }
}
 
Example 9
Source File: AggregateReduceFunctionsRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
private RexNode reduceAvg(
    Aggregate oldAggRel,
    AggregateCall oldCall,
    List<AggregateCall> newCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    List<RexNode> inputExprs) {
  final int nGroups = oldAggRel.getGroupCount();
  final RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
  final int iAvgInput = oldCall.getArgList().get(0);
  final RelDataType avgInputType =
      getFieldType(
          oldAggRel.getInput(),
          iAvgInput);
  final AggregateCall sumCall =
      AggregateCall.create(SqlStdOperatorTable.SUM,
          oldCall.isDistinct(),
          oldCall.isApproximate(),
          oldCall.ignoreNulls(),
          oldCall.getArgList(),
          oldCall.filterArg,
          oldCall.collation,
          oldAggRel.getGroupCount(),
          oldAggRel.getInput(),
          null,
          null);
  final AggregateCall countCall =
      AggregateCall.create(SqlStdOperatorTable.COUNT,
          oldCall.isDistinct(),
          oldCall.isApproximate(),
          oldCall.ignoreNulls(),
          oldCall.getArgList(),
          oldCall.filterArg,
          oldCall.collation,
          oldAggRel.getGroupCount(),
          oldAggRel.getInput(),
          null,
          null);

  // NOTE:  these references are with respect to the output
  // of newAggRel
  RexNode numeratorRef =
      rexBuilder.addAggCall(sumCall,
          nGroups,
          newCalls,
          aggCallMapping,
          ImmutableList.of(avgInputType));
  final RexNode denominatorRef =
      rexBuilder.addAggCall(countCall,
          nGroups,
          newCalls,
          aggCallMapping,
          ImmutableList.of(avgInputType));

  final RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();
  final RelDataType avgType = typeFactory.createTypeWithNullability(
      oldCall.getType(), numeratorRef.getType().isNullable());
  numeratorRef = rexBuilder.ensureType(avgType, numeratorRef, true);
  final RexNode divideRef =
      rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
  return rexBuilder.makeCast(oldCall.getType(), divideRef);
}
 
Example 10
Source File: AggregateReduceFunctionsRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
private RexNode reduceRegrSzz(
    Aggregate oldAggRel,
    AggregateCall oldCall,
    List<AggregateCall> newCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    List<RexNode> inputExprs,
    int xIndex,
    int yIndex,
    int nullFilterIndex) {
  // regr_sxx(x, y) ==>
  //    sum(y * y, x) - sum(y, x) * sum(y, x) / regr_count(x, y)
  //

  final RelOptCluster cluster = oldAggRel.getCluster();
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
  final RelDataType argXType = getFieldType(oldAggRel.getInput(), xIndex);
  final RelDataType argYType =
      xIndex == yIndex ? argXType : getFieldType(oldAggRel.getInput(), yIndex);
  final RelDataType nullFilterIndexType =
      nullFilterIndex == yIndex ? argYType : getFieldType(oldAggRel.getInput(), yIndex);

  final RelDataType oldCallType =
      typeFactory.createTypeWithNullability(oldCall.getType(),
          argXType.isNullable() || argYType.isNullable() || nullFilterIndexType.isNullable());

  final RexNode argX =
      rexBuilder.ensureType(oldCallType, inputExprs.get(xIndex), true);
  final RexNode argY =
      rexBuilder.ensureType(oldCallType, inputExprs.get(yIndex), true);
  final RexNode argNullFilter =
      rexBuilder.ensureType(oldCallType, inputExprs.get(nullFilterIndex), true);

  final RexNode argXArgY = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argX, argY);
  final int argSquaredOrdinal = lookupOrAdd(inputExprs, argXArgY);

  final RexNode argXAndYNotNullFilter = rexBuilder.makeCall(SqlStdOperatorTable.AND,
      rexBuilder.makeCall(SqlStdOperatorTable.AND,
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argX),
          rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argY)),
      rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argNullFilter));
  final int argXAndYNotNullFilterOrdinal = lookupOrAdd(inputExprs, argXAndYNotNullFilter);
  final RexNode sumXY = getSumAggregatedRexNodeWithBinding(
      oldAggRel, oldCall, newCalls, aggCallMapping, argXArgY.getType(),
      argSquaredOrdinal, argXAndYNotNullFilterOrdinal);
  final RexNode sumXYCast = rexBuilder.ensureType(oldCallType, sumXY, true);

  final RexNode sumX = getSumAggregatedRexNode(oldAggRel, oldCall,
      newCalls, aggCallMapping, rexBuilder, xIndex, argXAndYNotNullFilterOrdinal);
  final RexNode sumY = xIndex == yIndex
      ? sumX
      : getSumAggregatedRexNode(oldAggRel, oldCall, newCalls,
          aggCallMapping, rexBuilder, yIndex, argXAndYNotNullFilterOrdinal);

  final RexNode sumXSumY = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumX, sumY);

  final RexNode countArg = getRegrCountRexNode(oldAggRel, oldCall, newCalls, aggCallMapping,
      ImmutableIntList.of(xIndex), ImmutableList.of(argXType), argXAndYNotNullFilterOrdinal);

  RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
  RexNode nul = rexBuilder.makeNullLiteral(zero.getType());
  final RexNode avgSumXSumY = rexBuilder.makeCall(SqlStdOperatorTable.CASE,
      rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, zero), nul,
          rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumXSumY, countArg));
  final RexNode avgSumXSumYCast = rexBuilder.ensureType(oldCallType, avgSumXSumY, true);
  final RexNode result =
      rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumXYCast, avgSumXSumYCast);
  return rexBuilder.makeCast(oldCall.getType(), result);
}
 
Example 11
Source File: StandardConvertletTable.java    From calcite with Apache License 2.0 4 votes vote down vote up
public RexNode convertCall(SqlRexContext cx, SqlCall call) {
  // TIMESTAMPDIFF(unit, t1, t2)
  //    => (t2 - t1) UNIT
  final RexBuilder rexBuilder = cx.getRexBuilder();
  final SqlLiteral unitLiteral = call.operand(0);
  TimeUnit unit = unitLiteral.symbolValue(TimeUnit.class);
  BigDecimal multiplier = BigDecimal.ONE;
  BigDecimal divider = BigDecimal.ONE;
  SqlTypeName sqlTypeName = unit == TimeUnit.NANOSECOND
      ? SqlTypeName.BIGINT
      : SqlTypeName.INTEGER;
  switch (unit) {
  case MICROSECOND:
  case MILLISECOND:
  case NANOSECOND:
  case WEEK:
    multiplier = BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND);
    divider = unit.multiplier;
    unit = TimeUnit.SECOND;
    break;
  case QUARTER:
    divider = unit.multiplier;
    unit = TimeUnit.MONTH;
    break;
  }
  final SqlIntervalQualifier qualifier =
      new SqlIntervalQualifier(unit, null, SqlParserPos.ZERO);
  final RexNode op2 = cx.convertExpression(call.operand(2));
  final RexNode op1 = cx.convertExpression(call.operand(1));
  final RelDataType intervalType =
      cx.getTypeFactory().createTypeWithNullability(
          cx.getTypeFactory().createSqlIntervalType(qualifier),
          op1.getType().isNullable() || op2.getType().isNullable());
  final RexCall rexCall = (RexCall) rexBuilder.makeCall(
      intervalType, SqlStdOperatorTable.MINUS_DATE,
      ImmutableList.of(op2, op1));
  final RelDataType intType =
      cx.getTypeFactory().createTypeWithNullability(
          cx.getTypeFactory().createSqlType(sqlTypeName),
          SqlTypeUtil.containsNullable(rexCall.getType()));
  RexNode e = rexBuilder.makeCast(intType, rexCall);
  return rexBuilder.multiplyDivide(e, multiplier, divider);
}