Skip to content

Commit

Permalink
[Coral-Trino] use 'TRY_CAST' instead of 'CAST'
Browse files Browse the repository at this point in the history
  • Loading branch information
hqbhoho committed Dec 19, 2024
1 parent 15fc504 commit bf86d94
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ public class JsonTransformSqlCallTransformer extends SourceOperatorMatchSqlCallT
OP_MAP.put("%", SqlStdOperatorTable.MOD);
OP_MAP.put("date", new SqlUserDefinedFunction(new SqlIdentifier("date", SqlParserPos.ZERO), ReturnTypes.DATE, null,
OperandTypes.STRING, null, null));
OP_MAP.put("timestamp", new SqlUserDefinedFunction(new SqlIdentifier("timestamp", SqlParserPos.ZERO),
OP_MAP.put("trino_timestamp", new SqlUserDefinedFunction(new SqlIdentifier("trino_timestamp", SqlParserPos.ZERO),
FunctionReturnTypes.TIMESTAMP, null, OperandTypes.STRING, null, null) {
@Override
public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
// for timestamp operator, we need to construct `CAST(x AS TIMESTAMP)`
// for timestamp operator, we need to construct `TRY_CAST(x AS TIMESTAMP)`
Preconditions.checkState(call.operandCount() == 1);
final SqlWriter.Frame frame = writer.startFunCall("CAST");
final SqlWriter.Frame frame = writer.startFunCall("TRY_CAST");
call.operand(0).unparse(writer, 0, 0);
writer.sep("AS");
writer.literal("TIMESTAMP");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ protected SqlCall transform(SqlCall sqlCall) {
"[{\"regex\":\"(?i)('utf-8')\", \"input\":2, \"name\":\"from_utf8\"}]", "[{\"input\":1}]", null, null),
new JsonTransformSqlCallTransformer(hiveToCoralSqlOperator("date_add"), 2, "date_add",
"[{\"value\": 'day'}, {\"input\": 2}, "
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"timestamp\", \"operands\":[{\"input\": 1}]}]}]",
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"trino_timestamp\", \"operands\":[{\"input\": 1}]}]}]",
null, null),
new JsonTransformSqlCallTransformer(hiveToCoralSqlOperator("date_sub"), 2, "date_add",
"[{\"value\": 'day'}, " + "{\"op\": \"*\", \"operands\":[{\"input\": 2}, {\"value\": -1}]}, "
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"timestamp\", \"operands\":[{\"input\": 1}]}]}]",
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"trino_timestamp\", \"operands\":[{\"input\": 1}]}]}]",
null, null),
new JsonTransformSqlCallTransformer(hiveToCoralSqlOperator("datediff"), 2, "date_diff",
"[{\"value\": 'day'}, {\"op\": \"date\", \"operands\":[{\"op\": \"timestamp\", \"operands\":[{\"input\": 2}]}]}, "
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"timestamp\", \"operands\":[{\"input\": 1}]}]}]",
"[{\"value\": 'day'}, {\"op\": \"date\", \"operands\":[{\"op\": \"trino_timestamp\", \"operands\":[{\"input\": 2}]}]}, "
+ "{\"op\": \"date\", \"operands\":[{\"op\": \"trino_timestamp\", \"operands\":[{\"input\": 1}]}]}]",
null, null),
new ToDateOperatorTransformer(configs.getOrDefault(AVOID_TRANSFORM_TO_DATE_UDF, false)),
new CurrentTimestampTransformer(), new FromUnixtimeOperatorTransformer(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2017-2023 LinkedIn Corporation. All rights reserved.
* Copyright 2017-2024 LinkedIn Corporation. All rights reserved.
* Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
Expand All @@ -14,6 +14,7 @@
import org.apache.calcite.sql.parser.SqlParserPos;

import static com.linkedin.coral.hive.hive2rel.functions.TimestampFromUnixtime.TIMESTAMP_FROM_UNIXTIME;
import static com.linkedin.coral.trino.rel2trino.functions.TrinoTryCastFunction.TRY_CAST;


public class TrinoSqlDialect extends SqlDialect {
Expand Down Expand Up @@ -76,8 +77,11 @@ public void unparseCall(SqlWriter writer, SqlCall call, int leftPrec, int rightP
unparseMapValueConstructor(writer, call, leftPrec, rightPrec);
break;
default:
if (call.getOperator().getName().equals("timestamp_from_unixtime")) {
String operateName = call.getOperator().getName();
if (operateName.equals("timestamp_from_unixtime")) {
TIMESTAMP_FROM_UNIXTIME.unparse(writer, call, leftPrec, rightPrec);
} else if (operateName.equalsIgnoreCase("cast")) {
TRY_CAST.unparse(writer, call, leftPrec, rightPrec);
} else {
super.unparseCall(writer, call, leftPrec, rightPrec);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2019-2023 LinkedIn Corporation. All rights reserved.
* Copyright 2019-2024 LinkedIn Corporation. All rights reserved.
* Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
Expand All @@ -21,6 +21,6 @@
*/
public class TrinoStructCastRowFunction extends GenericTemplateFunction {
public TrinoStructCastRowFunction(RelDataType structDataType) {
super(structDataType, "cast");
super(structDataType, "try_cast");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2019-2024 LinkedIn Corporation. All rights reserved.
* Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
package com.linkedin.coral.trino.rel2trino.functions;

import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;


public class TrinoTryCastFunction extends SqlFunction {
public static final TrinoTryCastFunction TRY_CAST = new TrinoTryCastFunction();

public TrinoTryCastFunction() {
super("try_cast", SqlKind.CAST, SqlStdOperatorTable.CAST::inferReturnType, null, null,
SqlFunctionCategory.USER_DEFINED_FUNCTION);
}

public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
assert call.operandCount() == 2;

SqlWriter.Frame frame = writer.startFunCall(this.getName());
call.operand(0).unparse(writer, 0, 0);
writer.sep("AS");
if (call.operand(1) instanceof SqlIntervalQualifier) {
writer.sep("INTERVAL");
}

call.operand(1).unparse(writer, 0, 0);
writer.endFunCall(frame);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2023 LinkedIn Corporation. All rights reserved.
* Copyright 2023-2024 LinkedIn Corporation. All rights reserved.
* Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
Expand Down Expand Up @@ -303,7 +303,7 @@ private String arrayDataTypeArgumentString(ArraySqlType fromDataType, ArraySqlTy
*/
private String structDataTypeString(RelRecordType fromDataType, RelRecordType toDataType, String fieldNameReference) {
String structDataTypeArgumentString = structDataTypeArgumentString(fromDataType, toDataType, fieldNameReference);
return (String.format("cast(%s)", structDataTypeArgumentString));
return (String.format("TRY_CAST(%s)", structDataTypeArgumentString));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2023 LinkedIn Corporation. All rights reserved.
* Copyright 2023-2024 LinkedIn Corporation. All rights reserved.
* Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
Expand Down Expand Up @@ -37,13 +37,13 @@ public class ToDateOperatorTransformer extends SqlCallTransformer {
private static final String TO_OPERATOR_NAME = "date";
private static final int NUM_OPERANDS = 1;
private static final SqlOperator TIMESTAMP_OPERATOR =
new SqlUserDefinedFunction(new SqlIdentifier("timestamp", SqlParserPos.ZERO), FunctionReturnTypes.TIMESTAMP, null,
OperandTypes.STRING, null, null) {
new SqlUserDefinedFunction(new SqlIdentifier("trino_timestamp", SqlParserPos.ZERO), FunctionReturnTypes.TIMESTAMP,
null, OperandTypes.STRING, null, null) {
@Override
public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
// for timestamp operator, we need to construct `CAST(x AS TIMESTAMP)`
// for timestamp operator, we need to construct `TRY_CAST(x AS TIMESTAMP)`
Preconditions.checkState(call.operandCount() == 1);
final SqlWriter.Frame frame = writer.startFunCall("CAST");
final SqlWriter.Frame frame = writer.startFunCall("TRY_CAST");
call.operand(0).unparse(writer, 0, 0);
writer.sep("AS");
writer.literal("TIMESTAMP");
Expand Down
Loading

0 comments on commit bf86d94

Please sign in to comment.