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 18, 2024
1 parent 15fc504 commit 02d5d98
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 88 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,45 @@
/**
* Copyright 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;


/**
* describe:
*
* @author hqbhoho
* @version [v1.0]
* @date 2024/12/18
*/
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 02d5d98

Please sign in to comment.