Hisoka-X commented on code in PR #9299:
URL: https://github.com/apache/seatunnel/pull/9299#discussion_r2083759025
##########
seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/ZetaSQLFunction.java:
##########
@@ -559,9 +567,34 @@ public Object executeFunctionExpr(String functionName,
List<Object> args) {
case YEAR:
return DateTimeFunction.year(args);
case COALESCE:
- return SystemFunction.coalesce(args);
+ // Get the first argument's type from the function's expression
+ if (currentFunction != null) {
+ // Get the expected return type of the COALESCE function
+ try {
+ SeaTunnelDataType<?> targetType =
+ zetaSQLType.getExpressionType(currentFunction);
+ return SystemFunction.coalesce(args, targetType);
Review Comment:
why we should get `targetType` from `currentFunction` not `args[0]`?
##########
seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/functions/SystemFunction.java:
##########
@@ -35,19 +38,125 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
public class SystemFunction {
+ /**
+ * Enhanced version of coalesce function that takes a target type
parameter. This ensures that
+ * the result is always converted to the expected type regardless of which
argument is non-null.
+ *
+ * @param args Function arguments
+ * @param targetType The target type that the result should be converted to
+ * @return The first non-null value converted to the target type
+ */
+ public static Object coalesce(List<Object> args, SeaTunnelDataType<?>
targetType) {
+ if (args.isEmpty()) {
+ return null;
+ }
+
+ // Find the first non-null argument
+ Object firstNonNull = null;
+
+ for (Object arg : args) {
+ if (arg != null) {
+ firstNonNull = arg;
+ break;
+ }
+ }
+
+ // If all arguments are null, return null
+ if (firstNonNull == null) {
+ return null;
+ }
+
+ // Always convert the first non-null value to the target type
+ try {
+ return castAs(firstNonNull, targetType);
+ } catch (Exception e) {
+ // If conversion fails, return the original value
+ return firstNonNull;
+ }
+ }
+
+ // Original coalesce implementation - can be deprecated in the future
public static Object coalesce(List<Object> args) {
- Object v = null;
- for (Object v2 : args) {
- if (v2 != null) {
- v = v2;
+ if (args.isEmpty()) {
+ return null;
+ }
+
+ Object firstArg = args.get(0);
+
+ Object firstNonNull = null;
+ int firstNonNullIndex = -1;
+
+ for (int i = 0; i < args.size(); i++) {
+ Object arg = args.get(i);
+ if (arg != null) {
+ firstNonNull = arg;
+ firstNonNullIndex = i;
break;
}
}
- return v;
+
+ // If all arguments are null, return null
+ if (firstNonNull == null) {
+ return null;
+ }
+
+ SeaTunnelDataType<?> targetType = null;
+
+ if (firstArg != null) {
+ Function<Object, SeaTunnelDataType<?>> typeMapper =
+ TYPE_MAPPERS.get(firstArg.getClass());
Review Comment:
we can reuse `ZetaSQLType::getExpressionType`
--
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]