Anthrino commented on code in PR #3677:
URL: https://github.com/apache/calcite/pull/3677#discussion_r1498174614
##########
core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java:
##########
@@ -647,58 +541,225 @@ private static Expression checkExpressionPadTruncate(
}
}
+ private Expression translateCastToDate(RelDataType sourceType,
+ Expression operand, ConstantExpression format,
+ Supplier<Expression> defaultExpression) {
+
+ switch (sourceType.getSqlTypeName()) {
+ case CHAR:
+ case VARCHAR:
+ // If format string is supplied, parse formatted string into date
+ return Expressions.isConstantNull(format)
+ ? Expressions.call(BuiltInMethod.STRING_TO_DATE.method, operand)
+ :
Expressions.call(Expressions.new_(BuiltInMethod.PARSE_DATE.method.getDeclaringClass()),
+ BuiltInMethod.PARSE_DATE.method, format, operand);
+
+ case TIMESTAMP:
+ return
+ Expressions.convert_(
+ Expressions.call(BuiltInMethod.FLOOR_DIV.method,
+ operand, Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
+ int.class);
+
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_DATE.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+
+ default:
+ return defaultExpression.get();
+ }
+ }
+
private Expression translateCastToTime(RelDataType sourceType,
- Expression operand, Supplier<Expression> defaultExpression) {
+ Expression operand, ConstantExpression format, Supplier<Expression>
defaultExpression) {
+
switch (sourceType.getSqlTypeName()) {
case CHAR:
case VARCHAR:
- return Expressions.call(BuiltInMethod.STRING_TO_TIME.method, operand);
+ // If format string is supplied, parse formatted string into time
+ return Expressions.isConstantNull(format)
+ ? Expressions.call(BuiltInMethod.STRING_TO_TIME.method, operand)
+ :
Expressions.call(Expressions.new_(BuiltInMethod.PARSE_TIME.method.getDeclaringClass()),
+ BuiltInMethod.PARSE_TIME.method, format, operand);
case TIME_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIME_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIME_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
case TIMESTAMP:
- return Expressions.convert_(
- Expressions.call(BuiltInMethod.FLOOR_MOD.method,
- operand,
- Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
- int.class);
+ return
+ Expressions.convert_(
+ Expressions.call(BuiltInMethod.FLOOR_MOD.method,
+ operand,
+ Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
+ int.class);
+
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
default:
return defaultExpression.get();
}
}
- private Expression translateCastToDate(RelDataType sourceType,
+ private Expression translateCastToTimeWithLocalTimeZone(RelDataType
sourceType,
Expression operand, Supplier<Expression> defaultExpression) {
+
switch (sourceType.getSqlTypeName()) {
case CHAR:
case VARCHAR:
- return Expressions.call(BuiltInMethod.STRING_TO_DATE.method, operand);
+ return
+
Expressions.call(BuiltInMethod.STRING_TO_TIME_WITH_LOCAL_TIME_ZONE.method,
operand);
+
+ case TIME:
+ return
+
Expressions.call(BuiltInMethod.TIME_STRING_TO_TIME_WITH_LOCAL_TIME_ZONE.method,
+ RexImpTable.optimize2(operand,
+ Expressions.call(BuiltInMethod.UNIX_TIME_TO_STRING.method,
+ operand)),
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root));
case TIMESTAMP:
- return Expressions.convert_(
- Expressions.call(BuiltInMethod.FLOOR_DIV.method,
- operand, Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
- int.class);
+ return
+
Expressions.call(BuiltInMethod.TIMESTAMP_STRING_TO_TIMESTAMP_WITH_LOCAL_TIME_ZONE.method,
+ RexImpTable.optimize2(operand,
+
Expressions.call(BuiltInMethod.UNIX_TIMESTAMP_TO_STRING.method,
+ operand)),
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root));
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_DATE.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod
+
.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME_WITH_LOCAL_TIME_ZONE
+ .method,
+ operand));
+
+ default:
+ return defaultExpression.get();
+ }
+ }
+
+ private Expression translateCastToTimeStamp(RelDataType sourceType,
+ Expression operand, ConstantExpression format, Supplier<Expression>
defaultExpression) {
+
+ switch (sourceType.getSqlTypeName()) {
+ case CHAR:
+ case VARCHAR:
+ // If format string is supplied, parse formatted string into timestamp
+ return Expressions.isConstantNull(format)
Review Comment:
That's right, the reason for the many switch cases are because we need to
evaluate the expressions based on each combination of source and target data
types (e.g. `CAST VARCHAR to TIME/DATE/NUMERIC..`), and each combination has an
individual `BuiltInMethod` implementation so the calls have to made explicit.
We could look at moving the method selection (based on `format` condition)
out of the returned method call, but it'll be the same number of lines to
assign the respective method under each case, so I dont think it would reduce
the clutter by much. Lack of generalizability is due to the number of cases and
individual built in methods for each case.
##########
core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java:
##########
@@ -647,58 +541,225 @@ private static Expression checkExpressionPadTruncate(
}
}
+ private Expression translateCastToDate(RelDataType sourceType,
+ Expression operand, ConstantExpression format,
+ Supplier<Expression> defaultExpression) {
+
+ switch (sourceType.getSqlTypeName()) {
+ case CHAR:
+ case VARCHAR:
+ // If format string is supplied, parse formatted string into date
+ return Expressions.isConstantNull(format)
+ ? Expressions.call(BuiltInMethod.STRING_TO_DATE.method, operand)
+ :
Expressions.call(Expressions.new_(BuiltInMethod.PARSE_DATE.method.getDeclaringClass()),
+ BuiltInMethod.PARSE_DATE.method, format, operand);
+
+ case TIMESTAMP:
+ return
+ Expressions.convert_(
+ Expressions.call(BuiltInMethod.FLOOR_DIV.method,
+ operand, Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
+ int.class);
+
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_DATE.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+
+ default:
+ return defaultExpression.get();
+ }
+ }
+
private Expression translateCastToTime(RelDataType sourceType,
- Expression operand, Supplier<Expression> defaultExpression) {
+ Expression operand, ConstantExpression format, Supplier<Expression>
defaultExpression) {
+
switch (sourceType.getSqlTypeName()) {
case CHAR:
case VARCHAR:
- return Expressions.call(BuiltInMethod.STRING_TO_TIME.method, operand);
+ // If format string is supplied, parse formatted string into time
+ return Expressions.isConstantNull(format)
+ ? Expressions.call(BuiltInMethod.STRING_TO_TIME.method, operand)
+ :
Expressions.call(Expressions.new_(BuiltInMethod.PARSE_TIME.method.getDeclaringClass()),
+ BuiltInMethod.PARSE_TIME.method, format, operand);
case TIME_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIME_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIME_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
case TIMESTAMP:
- return Expressions.convert_(
- Expressions.call(BuiltInMethod.FLOOR_MOD.method,
- operand,
- Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
- int.class);
+ return
+ Expressions.convert_(
+ Expressions.call(BuiltInMethod.FLOOR_MOD.method,
+ operand,
+ Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
+ int.class);
+
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
default:
return defaultExpression.get();
}
}
- private Expression translateCastToDate(RelDataType sourceType,
+ private Expression translateCastToTimeWithLocalTimeZone(RelDataType
sourceType,
Expression operand, Supplier<Expression> defaultExpression) {
+
switch (sourceType.getSqlTypeName()) {
case CHAR:
case VARCHAR:
- return Expressions.call(BuiltInMethod.STRING_TO_DATE.method, operand);
+ return
+
Expressions.call(BuiltInMethod.STRING_TO_TIME_WITH_LOCAL_TIME_ZONE.method,
operand);
+
+ case TIME:
+ return
+
Expressions.call(BuiltInMethod.TIME_STRING_TO_TIME_WITH_LOCAL_TIME_ZONE.method,
+ RexImpTable.optimize2(operand,
+ Expressions.call(BuiltInMethod.UNIX_TIME_TO_STRING.method,
+ operand)),
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root));
case TIMESTAMP:
- return Expressions.convert_(
- Expressions.call(BuiltInMethod.FLOOR_DIV.method,
- operand, Expressions.constant(DateTimeUtils.MILLIS_PER_DAY)),
- int.class);
+ return
+
Expressions.call(BuiltInMethod.TIMESTAMP_STRING_TO_TIMESTAMP_WITH_LOCAL_TIME_ZONE.method,
+ RexImpTable.optimize2(operand,
+
Expressions.call(BuiltInMethod.UNIX_TIMESTAMP_TO_STRING.method,
+ operand)),
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, root));
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- return RexImpTable.optimize2(operand,
- Expressions.call(
- BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_DATE.method,
- operand,
- Expressions.call(BuiltInMethod.TIME_ZONE.method, root)));
+ return
+ RexImpTable.optimize2(
+ operand, Expressions.call(
+ BuiltInMethod
+
.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIME_WITH_LOCAL_TIME_ZONE
+ .method,
+ operand));
+
+ default:
+ return defaultExpression.get();
+ }
+ }
+
+ private Expression translateCastToTimeStamp(RelDataType sourceType,
+ Expression operand, ConstantExpression format, Supplier<Expression>
defaultExpression) {
+
+ switch (sourceType.getSqlTypeName()) {
+ case CHAR:
+ case VARCHAR:
+ // If format string is supplied, parse formatted string into timestamp
+ return Expressions.isConstantNull(format)
Review Comment:
That's right, the reason for the many switch cases are because we need to
evaluate the expressions based on each combination of source and target data
types (e.g. `CAST VARCHAR to TIME/DATE/NUMERIC..`), and each combination has an
individual `BuiltInMethod` implementation so the calls have to made explicit.
We could look at moving the method selection (based on `format` condition)
out of the returned method call, but it'll be the same number of lines to
assign the respective method under each case, so I dont think it would reduce
the clutter by much. Lack of generalizability is due to the number of cases and
individual built in methods for each case.
--
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]