zzwqqq commented on code in PR #4942:
URL: https://github.com/apache/calcite/pull/4942#discussion_r3308060851
##########
core/src/main/java/org/apache/calcite/rex/RexBuilder.java:
##########
@@ -877,6 +887,124 @@ public RexNode makeCast(
return makeAbstractCast(pos, type, exp, safe, format);
}
+ private @Nullable RexNode makeCastForTemporalLiteral(
+ SqlParserPos pos,
+ RelDataType type,
+ RexLiteral literal,
+ boolean matchNullability,
+ boolean safe,
+ RexLiteral format) {
+ if (!format.isNull()) {
+ return null;
+ }
+ if (SqlTypeUtil.isCharacter(literal.getType())) {
+ return makeCastFromCharacterLiteralToTemporal(
+ pos, type, literal, matchNullability, safe, format);
+ }
+ if (SqlTypeUtil.isCharacter(type)) {
+ return makeCastFromTemporalLiteralToCharacter(type, literal);
+ }
+ return null;
+ }
+
+ private @Nullable RexNode makeCastFromCharacterLiteralToTemporal(
+ SqlParserPos pos,
+ RelDataType type,
+ RexLiteral literal,
+ boolean matchNullability,
+ boolean safe,
+ RexLiteral format) {
+ final NlsString nlsString = literal.getValueAs(NlsString.class);
+ if (nlsString == null) {
+ return null;
+ }
+ final String value = nlsString.getValue().trim();
+ final RexNode temporalLiteral;
+ try {
+ switch (type.getSqlTypeName()) {
+ case TIME:
+ final SqlTimeLiteral timeLiteral =
+ SqlParserUtil.parseTimeLiteral(value, pos);
+ if (!isExactFractionalSecondLiteral(timeLiteral, value)) {
+ return null;
+ }
+ final TimeString time =
+ requireNonNull(timeLiteral.getValueAs(TimeString.class),
+ "timeLiteral.getValueAs(TimeString.class)");
+ temporalLiteral = makeTimeLiteral(time, type.getPrecision());
+ break;
+ case TIMESTAMP:
+ final SqlTimestampLiteral timestampLiteral =
+ SqlParserUtil.parseTimestampLiteral(value, pos);
+ if (!isExactFractionalSecondLiteral(timestampLiteral, value)) {
+ return null;
+ }
+ final TimestampString timestamp =
+ requireNonNull(timestampLiteral.getValueAs(TimestampString.class),
+ "timestampLiteral.getValueAs(TimestampString.class)");
+ temporalLiteral = makeTimestampLiteral(timestamp, type.getPrecision());
+ break;
+ default:
+ return null;
+ }
+ } catch (RuntimeException e) {
+ return safe ? makeNullLiteral(type) : null;
+ }
+ if (type.isNullable()
+ && !temporalLiteral.getType().isNullable()
+ && matchNullability) {
+ return makeAbstractCast(pos, type, temporalLiteral, safe, format);
+ }
+ return temporalLiteral;
+ }
+
+ /** Converts a TIME or TIMESTAMP literal to a character literal.
+ *
+ * <p>Returns null if the literal is not a TIME or TIMESTAMP, the literal
+ * cannot be read as the corresponding temporal string value, or the
formatted
+ * temporal value does not fit in the target character type. */
+ private @Nullable RexNode makeCastFromTemporalLiteralToCharacter(
+ RelDataType type,
+ RexLiteral literal) {
+ // Format temporal literals directly so they do not go through generated
+ // code, whose TIME/TIMESTAMP runtime values have millisecond precision.
+ final String value;
+ final int precision = literal.getType().getPrecision();
+ switch (literal.getType().getSqlTypeName()) {
+ case TIME:
+ final TimeString time = literal.getValueAs(TimeString.class);
+ if (time == null) {
+ return null;
+ }
+ value = time.toString(precision);
+ break;
+ case TIMESTAMP:
+ final TimestampString timestamp =
literal.getValueAs(TimestampString.class);
+ if (timestamp == null) {
+ return null;
+ }
+ value = timestamp.toString(precision);
+ break;
+ default:
+ return null;
+ }
+ // Only create a character literal if the formatted temporal value fits in
+ // the target type.
+ return SqlTypeUtil.comparePrecision(type.getPrecision(), value.length())
>= 0
+ ? makeLiteral(value, type, true)
+ : null;
+ }
+
+ /** Returns whether a parsed TIME or TIMESTAMP literal has explicit
+ * fractional-second precision and preserves the original character value
Review Comment:
Thanks, I updated the doc with that wording
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]