Skip to content

Commit b329c6d

Browse files
committed
Cast tzArg to VARCHAR in DATETIME 2-arg column path
Calcite infers CHAR(N) from a literal's length, but the convert_tz yaml binds tz operands as unbounded `string` (VARCHAR). Without the cast, a user-supplied tz literal like `'+05:30'` lowers as `convert_tz(precision_timestamp, char<6>, char<6>)` — same CHAR-vs-string mismatch already fixed for the synthesised target tz literal, just from the other side. Cast the source tz to VARCHAR for symmetry; the literal target was already cast. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
1 parent ea38f7c commit b329c6d

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

  • sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion

sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/DateTimeAdapters.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,17 @@ private RexNode adaptTwoArg(RexCall original, RelOptCluster cluster) {
243243
strippedValue = value;
244244
}
245245
RexNode asTimestamp = rexBuilder.makeCall(original.getType(), LOCAL_TO_TIMESTAMP_OP, List.of(strippedValue));
246-
// makeLiteral(String) infers CHAR(N) from the literal's length; the convert_tz yaml
247-
// binds the 2nd/3rd operands as `string` (unbounded VARCHAR), so a CHAR(6) "+00:00"
248-
// would fail isthmus signature lookup (`convert_tz(precision_timestamp, char<6>, string)`).
246+
// The convert_tz yaml binds tz operands as unbounded `string` (VARCHAR). User-supplied
247+
// tz literals come in as CHAR(N) (Calcite infers length from the literal), and our
248+
// synthesised "+00:00" target would also be CHAR(6) without an explicit type — both
249+
// would mis-bind as `convert_tz(precision_timestamp, char<6>, char<6>)`. Cast both to
250+
// VARCHAR so isthmus picks the (precision_timestamp, string, string) arm.
249251
RelDataType varchar = rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR);
252+
RexNode tzArgVarchar = SqlTypeName.CHAR_TYPES.contains(tzArg.getType().getSqlTypeName())
253+
? rexBuilder.makeCast(varchar, tzArg, true)
254+
: tzArg;
250255
RexNode toTz = rexBuilder.makeLiteral("+00:00", varchar, true);
251-
return rexBuilder.makeCall(original.getType(), ConvertTzAdapter.LOCAL_CONVERT_TZ_OP, List.of(asTimestamp, tzArg, toTz));
256+
return rexBuilder.makeCall(original.getType(), ConvertTzAdapter.LOCAL_CONVERT_TZ_OP, List.of(asTimestamp, tzArgVarchar, toTz));
252257
}
253258

254259
/** Plan-time fold of DATETIME(value-literal, tz-literal). Returns a typed TIMESTAMP literal or NULL on invalid input. */

0 commit comments

Comments
 (0)