Skip to content

Commit

Permalink
[CALCITE-2980] Implement the FORMAT clause of the CAST operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthrino committed Apr 11, 2024
1 parent e7c1f0c commit c2f6806
Show file tree
Hide file tree
Showing 16 changed files with 839 additions and 417 deletions.
2 changes: 2 additions & 0 deletions core/src/main/codegen/templates/Parser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -6216,6 +6216,7 @@ SqlNode BuiltinFunctionCall() :
final SqlNode node;
final SqlLiteral style; // mssql convert 'style' operand
final SqlFunction f;
final SqlNode format;
}
{
//~ FUNCTIONS WITH SPECIAL SYNTAX ---------------------------------------
Expand All @@ -6232,6 +6233,7 @@ SqlNode BuiltinFunctionCall() :
|
<INTERVAL> e = IntervalQualifier() { args.add(e); }
)
[ <FORMAT> format = StringLiteral() { args.add(format); } ]
<RPAREN> {
return f.createCall(s.end(this), args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2792,7 +2792,7 @@ private static class FormatDatetimeImplementor
method = BuiltInMethod.FORMAT_TIMESTAMP.method;
}
return implementSafe(method,
ImmutableList.of(translator.getRoot(), operand0, operand1));
ImmutableList.of(operand0, operand1));
}
}

Expand Down Expand Up @@ -3283,11 +3283,23 @@ private static class CastImplementor extends AbstractRexCallImplementor {

@Override Expression implementSafe(final RexToLixTranslator translator,
final RexCall call, final List<Expression> argValueList) {
assert call.getOperands().size() == 1;
assert call.operandCount() <= 2;
final RelDataType sourceType = call.getOperands().get(0).getType();

// Short-circuit if no cast is required
RexNode arg = call.getOperands().get(0);
ConstantExpression formatExpr;

// Check for FORMAT clause if second operand is available in RexCall.
if (call.operandCount() == 2) {
RexLiteral format = (RexLiteral) translator.deref(call.getOperands().get(1));
formatExpr =
(ConstantExpression) RexToLixTranslator.translateLiteral(format, format.getType(),
translator.typeFactory, NullAs.NULL);
} else {
formatExpr = NULL_EXPR;
}

// Short-circuit if no cast is required
if (call.getType().equals(sourceType)) {
// No cast required, omit cast
return argValueList.get(0);
Expand All @@ -3303,7 +3315,7 @@ private static class CastImplementor extends AbstractRexCallImplementor {
nullifyType(translator.typeFactory, call.getType(), false);
boolean safe = call.getKind() == SqlKind.SAFE_CAST;
return translator.translateCast(sourceType,
targetType, argValueList.get(0), safe);
targetType, argValueList.get(0), safe, formatExpr);
}

private static RelDataType nullifyType(JavaTypeFactory typeFactory,
Expand Down
Loading

0 comments on commit c2f6806

Please sign in to comment.