in calcite-adapter/src/main/java/software/amazon/documentdb/jdbc/query/DocumentDbQueryMappingService.java [257:304]
public RexNode convertCall(final SqlRexContext cx, final SqlCall call) {
// TIMESTAMPDIFF(unit, t1, t2) => (t2 - t1) UNIT
final RexBuilder rexBuilder = cx.getRexBuilder();
final SqlLiteral unitLiteral = call.operand(0);
TimeUnit unit = getSymbolValue(unitLiteral, TimeUnit.class);
final SqlTypeName sqlTypeName = unit == TimeUnit.NANOSECOND
? SqlTypeName.BIGINT
: SqlTypeName.INTEGER;
final BigDecimal multiplier;
final BigDecimal divider;
switch (unit) {
case MICROSECOND:
case MILLISECOND:
case NANOSECOND:
case WEEK:
multiplier = BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND);
divider = unit.multiplier;
unit = TimeUnit.SECOND;
break;
default:
multiplier = BigDecimal.ONE;
divider = BigDecimal.ONE;
}
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()));
// If dealing with year, quarter, or month we will calculate the difference using date parts
// and do not need any integer division.
if (unit == TimeUnit.YEAR || unit == TimeUnit.QUARTER || unit == TimeUnit.MONTH) {
return rexBuilder.makeReinterpretCast(intType, rexCall, rexBuilder.makeLiteral(false));
}
final RexNode e = rexBuilder.makeCast(intType, rexCall);
return rexBuilder.multiplyDivide(e, multiplier, divider);
}