This is an automated email from the ASF dual-hosted git repository.

morrySnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 8dca6c89bbb [fix](function) Align constant folding with BE results 
(#64881)
8dca6c89bbb is described below

commit 8dca6c89bbb80147e616a62739ab30e3e33674d5
Author: morrySnow <[email protected]>
AuthorDate: Fri Jun 26 17:45:10 2026 +0800

    [fix](function) Align constant folding with BE results (#64881)
    
    ### What problem does this PR solve?
    
    Problem Summary: FE constant folding produced results different from BE
    execution for several string, URL, time, and floating-point expressions.
    This PR aligns the FE executable folding paths with BE behavior and adds
    `testFoldConst` coverage for the mismatched expressions.
    
    The PR also makes `MD5`/`MD5SUM` folding explicitly use UTF-8 bytes,
    matching BE and avoiding JVM-default-charset dependent folding results.
---
 .../executable/DateTimeExtractAndTransform.java    |  16 +-
 .../functions/executable/StringArithmetic.java     | 357 +++++++++++++--------
 .../datetime_functions/test_func_time.groovy       |   1 +
 .../string_functions/test_string_all.groovy        |  12 +
 4 files changed, 249 insertions(+), 137 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
index 2fc25ff528f..ca55370c0d7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
@@ -747,12 +747,20 @@ public class DateTimeExtractAndTransform {
             hourValue = hourValue > 0 ? 838 : -838;
             minuteValue = 59;
             secondValue = 59;
-        } else if (Math.abs(hourValue) == 838 && secondValue > 59) {
-            secondValue = 59;
         }
 
-        return new TimeV2Literal((int) Math.abs(hourValue), (int) minuteValue, 
(int) secondValue,
-                            (int) Math.round(secondValue * 1000000) % 1000000, 
6, hourValue < 0);
+        long totalMicrosecond = Math.abs(hourValue) * 3600L * 1000000
+                + minuteValue * 60L * 1000000 + Math.round(secondValue * 
1000000);
+        long maxMicrosecond = 838L * 3600L * 1000000 + 59L * 60L * 1000000 + 
59999999L;
+        totalMicrosecond = Math.min(totalMicrosecond, maxMicrosecond);
+
+        int newHour = (int) (totalMicrosecond / 3600L / 1000000);
+        totalMicrosecond %= 3600L * 1000000;
+        int newMinute = (int) (totalMicrosecond / 60L / 1000000);
+        totalMicrosecond %= 60L * 1000000;
+        int newSecond = (int) (totalMicrosecond / 1000000);
+        int microsecond = (int) (totalMicrosecond % 1000000);
+        return new TimeV2Literal(newHour, newMinute, newSecond, microsecond, 
6, hourValue < 0);
     }
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java
index 570d0bb4b98..3bdf1aded66 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java
@@ -46,9 +46,6 @@ import com.google.common.collect.Lists;
 
 import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
@@ -56,6 +53,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.regex.Pattern;
 
 /**
@@ -136,11 +134,7 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "lower")
     public static Expression lowerVarchar(StringLikeLiteral first) {
-        StringBuilder result = new StringBuilder(first.getValue().length());
-        for (char c : first.getValue().toCharArray()) {
-            result.append(Character.toLowerCase(c));
-        }
-        return castStringLikeLiteral(first, result.toString());
+        return castStringLikeLiteral(first, 
first.getValue().toLowerCase(Locale.ROOT));
     }
 
     /**
@@ -148,11 +142,7 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "upper")
     public static Expression upperVarchar(StringLikeLiteral first) {
-        StringBuilder result = new StringBuilder(first.getValue().length());
-        for (char c : first.getValue().toCharArray()) {
-            result.append(Character.toUpperCase(c));
-        }
-        return castStringLikeLiteral(first, result.toString());
+        return castStringLikeLiteral(first, 
first.getValue().toUpperCase(Locale.ROOT));
     }
 
     private static String trimImpl(String first, String second, boolean left, 
boolean right) {
@@ -327,7 +317,8 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "right")
     public static Expression right(StringLikeLiteral first, IntegerLiteral 
second) {
-        int inputLength = first.getValue().codePointCount(0, 
first.getValue().length());
+        String input = first.getValue();
+        int inputLength = input.codePointCount(0, input.length());
         if (second.getValue() < (- inputLength) || Math.abs(second.getValue()) 
== 0) {
             return castStringLikeLiteral(first, "");
         } else if (second.getValue() >= inputLength) {
@@ -335,13 +326,11 @@ public class StringArithmetic {
         } else {
             // at here second can not be exceeding boundary
             if (second.getValue() >= 0) {
-                int index = first.getValue().offsetByCodePoints(0, 
second.getValue());
-                return castStringLikeLiteral(first, first.getValue().substring(
-                    inputLength - index, inputLength));
+                int index = input.offsetByCodePoints(0, inputLength - 
second.getValue());
+                return castStringLikeLiteral(first, input.substring(index));
             } else {
-                int index = first.getValue().offsetByCodePoints(0, 
Math.abs(second.getValue()) - 1);
-                return castStringLikeLiteral(first, first.getValue().substring(
-                    index, inputLength));
+                int index = input.offsetByCodePoints(0, 
Math.abs(second.getValue()) - 1);
+                return castStringLikeLiteral(first, input.substring(index));
             }
         }
     }
@@ -400,7 +389,11 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "instr")
     public static Expression instr(StringLikeLiteral first, StringLikeLiteral 
second) {
-        return new IntegerLiteral(first.getValue().indexOf(second.getValue()) 
+ 1);
+        int index = first.getValue().indexOf(second.getValue());
+        if (index < 0) {
+            return new IntegerLiteral(0);
+        }
+        return new IntegerLiteral(first.getValue().codePointCount(0, index) + 
1);
     }
 
     /**
@@ -431,13 +424,16 @@ public class StringArithmetic {
     @ExecFunction(name = "concat_ws")
     public static Expression concatWsVarcharArray(StringLikeLiteral first, 
ArrayLiteral second) {
         StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < second.getValue().size() - 1; i++) {
-            if (!(second.getValue().get(i) instanceof NullLiteral)) {
-                sb.append(second.getValue().get(i).getValue());
-                sb.append(first.getValue());
+        boolean hasValue = false;
+        for (Literal value : second.getValue()) {
+            if (!(value instanceof NullLiteral)) {
+                if (hasValue) {
+                    sb.append(first.getValue());
+                }
+                sb.append(value.getValue());
+                hasValue = true;
             }
         }
-        sb.append(second.getValue().get(second.getValue().size() - 
1).getValue());
         return castStringLikeLiteral(first, sb.toString());
     }
 
@@ -447,11 +443,12 @@ public class StringArithmetic {
     @ExecFunction(name = "concat_ws")
     public static Expression concatWsVarcharVarchar(StringLikeLiteral first, 
StringLikeLiteral... second) {
         StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < second.length - 1; i++) {
+        for (int i = 0; i < second.length; i++) {
+            if (i > 0) {
+                sb.append(first.getValue());
+            }
             sb.append(second[i].getValue());
-            sb.append(first.getValue());
         }
-        sb.append(second[second.length - 1].getValue());
         return castStringLikeLiteral(first, sb.toString());
     }
 
@@ -468,19 +465,22 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "initcap")
     public static Expression initCap(StringLikeLiteral first) {
-        StringBuilder result = new StringBuilder(first.getValue().length());
+        String lower = first.getValue().toLowerCase(Locale.ROOT);
+        StringBuilder result = new StringBuilder(lower.length());
         boolean capitalizeNext = true;
 
-        for (char c : first.getValue().toCharArray()) {
-            if (!Character.isLetterOrDigit(c)) {
-                result.append(c);
+        for (int i = 0; i < lower.length();) {
+            int codePoint = lower.codePointAt(i);
+            if (!Character.isLetterOrDigit(codePoint)) {
+                result.appendCodePoint(codePoint);
                 capitalizeNext = true;  // Next character should be capitalized
             } else if (capitalizeNext) {
-                result.append(Character.toUpperCase(c));
+                result.appendCodePoint(Character.toUpperCase(codePoint));
                 capitalizeNext = false;
             } else {
-                result.append(Character.toLowerCase(c));
+                result.appendCodePoint(codePoint);
             }
+            i += Character.charCount(codePoint);
         }
         return castStringLikeLiteral(first, result.toString());
     }
@@ -493,7 +493,7 @@ public class StringArithmetic {
         try {
             MessageDigest md = MessageDigest.getInstance("MD5");
             // Update the digest with the input bytes
-            md.update(first.getValue().getBytes());
+            md.update(first.getValue().getBytes(StandardCharsets.UTF_8));
             return castStringLikeLiteral(first, bytesToHex(md.digest()));
         } catch (NoSuchAlgorithmException e) {
             throw new RuntimeException(e);
@@ -516,7 +516,7 @@ public class StringArithmetic {
             }
 
             // Step 3: Convert the combined string to a byte array and pass it 
to the digest() method
-            byte[] messageDigest = 
md.digest(combinedInput.toString().getBytes());
+            byte[] messageDigest = 
md.digest(combinedInput.toString().getBytes(StandardCharsets.UTF_8));
 
             // Step 4: Convert the byte array into a hexadecimal string
             StringBuilder hexString = new StringBuilder();
@@ -554,6 +554,28 @@ public class StringArithmetic {
         return 0;
     }
 
+    private static int compareFloatLiteral(FloatLiteral first, FloatLiteral... 
second) {
+        float firstValue = first.getValue();
+        for (int i = 0; i < second.length; i++) {
+            float secondValue = second[i].getValue();
+            if (secondValue == firstValue) {
+                return i + 1;
+            }
+        }
+        return 0;
+    }
+
+    private static int compareDoubleLiteral(DoubleLiteral first, 
DoubleLiteral... second) {
+        double firstValue = first.getValue();
+        for (int i = 0; i < second.length; i++) {
+            double secondValue = second[i].getValue();
+            if (secondValue == firstValue) {
+                return i + 1;
+            }
+        }
+        return 0;
+    }
+
     /**
      * Executable arithmetic functions field
      */
@@ -599,7 +621,7 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "field")
     public static Expression fieldFloat(FloatLiteral first, FloatLiteral... 
second) {
-        return new IntegerLiteral(compareLiteral(first, second));
+        return new IntegerLiteral(compareFloatLiteral(first, second));
     }
 
     /**
@@ -607,7 +629,7 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "field")
     public static Expression fieldDouble(DoubleLiteral first, DoubleLiteral... 
second) {
-        return new IntegerLiteral(compareLiteral(first, second));
+        return new IntegerLiteral(compareDoubleLiteral(first, second));
     }
 
     /**
@@ -651,12 +673,23 @@ public class StringArithmetic {
     }
 
     private static int findStringInSet(String target, String input) {
-        String[] split = input.split(",", -1);
-        for (int i = 0; i < split.length; i++) {
-            if (split[i].equals(target)) {
-                return i + 1;
-            }
+        if (target.indexOf(',') >= 0) {
+            return 0;
         }
+
+        int tokenIndex = 1;
+        int start = 0;
+        do {
+            int end = start;
+            while (end < input.length() && input.charAt(end) != ',') {
+                ++end;
+            }
+            if (input.substring(start, end).equals(target)) {
+                return tokenIndex;
+            }
+            start = end + 1;
+            ++tokenIndex;
+        } while (start < input.length());
         return 0;
     }
 
@@ -832,7 +865,7 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "strcmp")
     public static Expression strcmp(StringLikeLiteral first, StringLikeLiteral 
second) {
-        int result = first.getValue().compareTo(second.getValue());
+        int result = compareUtf8Bytes(first.getValue(), second.getValue());
         if (result == 0) {
             return new TinyIntLiteral((byte) 0);
         } else if (result < 0) {
@@ -842,6 +875,19 @@ public class StringArithmetic {
         }
     }
 
+    private static int compareUtf8Bytes(String left, String right) {
+        byte[] leftBytes = left.getBytes(StandardCharsets.UTF_8);
+        byte[] rightBytes = right.getBytes(StandardCharsets.UTF_8);
+        int minLength = Math.min(leftBytes.length, rightBytes.length);
+        for (int i = 0; i < minLength; i++) {
+            int diff = Byte.toUnsignedInt(leftBytes[i]) - 
Byte.toUnsignedInt(rightBytes[i]);
+            if (diff != 0) {
+                return diff;
+            }
+        }
+        return leftBytes.length - rightBytes.length;
+    }
+
     /**
      * Executable arithmetic functions overlay
      */
@@ -871,93 +917,137 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "parse_url")
     public static Expression parseurl(StringLikeLiteral first, 
StringLikeLiteral second) {
-        URI uri = null;
-        try {
-            uri = new URI(first.getValue());
-        } catch (URISyntaxException e) {
-            throw new RuntimeException(e);
-        }
-        StringBuilder sb = new StringBuilder();
-        if (uri.getScheme() == null) {
+        String value = parseUrlRaw(first.getValue(), second.getValue());
+        if (value == null) {
             return new NullLiteral(first.getDataType());
         }
-        switch (second.getValue().toUpperCase()) {
+        return castStringLikeLiteral(first, value);
+    }
+
+    private static String parseUrlRaw(String url, String part) {
+        String trimmedUrl = url.trim();
+        int protocolPos = trimmedUrl.indexOf("://");
+        if (protocolPos < 0) {
+            return null;
+        }
+        String protocolEnd = trimmedUrl.substring(protocolPos + 
"://".length());
+        switch (part.toUpperCase(Locale.ROOT)) {
             case "PROTOCOL":
-                String scheme = uri.getScheme();
-                if (scheme == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(scheme); // e.g., http, https
-                break;
+                return trimmedUrl.substring(0, protocolPos);
             case "HOST":
-                String host = uri.getHost();
-                if (host == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(host);  // e.g., www.example.com
-                break;
+                return parseUrlHost(protocolEnd);
             case "PATH":
-                String path = uri.getPath();
-                if (path == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(path);  // e.g., /page
-                break;
+                return parseUrlPath(protocolEnd);
             case "REF":
-                try {
-                    String ref = uri.toURL().getRef();
-                    if (ref == null) {
-                        return new NullLiteral(first.getDataType());
-                    }
-                    sb.append(ref);  // e.g., /page
-                } catch (MalformedURLException e) {
-                    throw new RuntimeException(e);
-                }
-                break;
+                return parseUrlRef(protocolEnd);
             case "AUTHORITY":
-                String authority = uri.getAuthority();
-                if (authority == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(authority);  // e.g., param1=value1&param2=value2
-                break;
+                return parseUrlAuthority(protocolEnd);
             case "FILE":
-                try {
-                    String file = uri.toURL().getFile();
-                    if (file == null) {
-                        return new NullLiteral(first.getDataType());
-                    }
-                    sb.append(file);  // e.g., param1=value1&param2=value2
-                } catch (MalformedURLException e) {
-                    throw new RuntimeException(e);
-                }
-                break;
+                return parseUrlFile(protocolEnd);
             case "QUERY":
-                String query = uri.getQuery();
-                if (query == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(query);  // e.g., param1=value1&param2=value2
-                break;
+                return parseUrlQuery(protocolEnd);
             case "PORT":
-                int port = uri.getPort();
-                if (port == -1) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(port);
-                break;
+                return parseUrlPort(protocolEnd);
             case "USERINFO":
-                String userInfo = uri.getUserInfo();
-                if (userInfo == null) {
-                    return new NullLiteral(first.getDataType());
-                }
-                sb.append(userInfo);  // e.g., user:pass
-                break;
+                return parseUrlUserInfo(protocolEnd);
             default:
                 throw new RuntimeException("Valid URL parts are 'PROTOCOL', 
'HOST', "
                         + "'PATH', 'REF', 'AUTHORITY', 'FILE', 'USERINFO', 
'PORT' and 'QUERY'");
         }
-        return castStringLikeLiteral(first, sb.toString());
+    }
+
+    private static int firstIndexOf(String value, char first, char second) {
+        int firstIndex = value.indexOf(first);
+        int secondIndex = value.indexOf(second);
+        if (firstIndex < 0) {
+            return secondIndex;
+        }
+        if (secondIndex < 0) {
+            return firstIndex;
+        }
+        return Math.min(firstIndex, secondIndex);
+    }
+
+    private static String substringEnd(String value, int end) {
+        return end < 0 ? value : value.substring(0, end);
+    }
+
+    private static String parseUrlAuthority(String protocolEnd) {
+        return substringEnd(protocolEnd, protocolEnd.indexOf('/'));
+    }
+
+    private static String parseUrlPath(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('/');
+        if (startPos < 0) {
+            return "";
+        }
+        String pathStart = protocolEnd.substring(startPos);
+        return substringEnd(pathStart, firstIndexOf(pathStart, '?', '#'));
+    }
+
+    private static String parseUrlFile(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('/');
+        if (startPos < 0) {
+            return "";
+        }
+        String pathStart = protocolEnd.substring(startPos);
+        return substringEnd(pathStart, pathStart.indexOf('#'));
+    }
+
+    private static String parseUrlHost(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('@');
+        startPos = startPos < 0 ? 0 : startPos + 1;
+        String hostStart = protocolEnd.substring(startPos);
+        int queryStartPos = hostStart.indexOf('?');
+        if (queryStartPos > 0) {
+            hostStart = hostStart.substring(0, queryStartPos);
+        }
+        int endPos = hostStart.indexOf(':');
+        if (endPos < 0) {
+            endPos = hostStart.indexOf('/');
+        }
+        return substringEnd(hostStart, endPos);
+    }
+
+    private static String parseUrlQuery(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('?');
+        if (startPos < 0) {
+            return null;
+        }
+        String queryStart = protocolEnd.substring(startPos + 1);
+        return substringEnd(queryStart, queryStart.indexOf('#'));
+    }
+
+    private static String parseUrlRef(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('#');
+        if (startPos < 0) {
+            return null;
+        }
+        return protocolEnd.substring(startPos + 1);
+    }
+
+    private static String parseUrlUserInfo(String protocolEnd) {
+        int endPos = protocolEnd.indexOf('@');
+        if (endPos < 0) {
+            return null;
+        }
+        return protocolEnd.substring(0, endPos);
+    }
+
+    private static String parseUrlPort(String protocolEnd) {
+        int startPos = protocolEnd.indexOf('@');
+        startPos = startPos < 0 ? 0 : startPos + 1;
+        String hostStart = protocolEnd.substring(startPos);
+        int endPos = hostStart.indexOf(':');
+        if (endPos < 0) {
+            return null;
+        }
+        String portStart = hostStart.substring(endPos + 1);
+        int portEndPos = portStart.indexOf('/');
+        if (portEndPos < 0) {
+            portEndPos = portStart.indexOf('?');
+        }
+        return substringEnd(portStart, portEndPos);
     }
 
     /**
@@ -1016,25 +1106,26 @@ public class StringArithmetic {
      */
     @ExecFunction(name = "extract_url_parameter")
     public static Expression extractUrlParameter(StringLikeLiteral first, 
StringLikeLiteral second) {
-        if (first.getValue() == null || first.getValue().indexOf('?') == -1) {
+        if (second.getValue().isEmpty()) {
             return castStringLikeLiteral(first, "");
         }
-        URI uri;
-        try {
-            uri = new URI(first.getValue());
-        } catch (URISyntaxException e) {
-            throw new RuntimeException(e);
+        String trimmedUrl = first.getValue().trim();
+        int questionPos = trimmedUrl.indexOf('?');
+        if (questionPos < 0) {
+            return castStringLikeLiteral(first, "");
         }
-
-        String query = uri.getQuery();
-        if (query != null) {
-            String[] pairs = query.split("&", -1);
-
-            for (String pair : pairs) {
-                String[] keyValue = pair.split("=", -1);
-                if (second.getValue().equals(keyValue[0])) {
-                    return castStringLikeLiteral(first, keyValue[1]);
-                }
+        int hashPos = trimmedUrl.indexOf('#');
+        String subUrl = hashPos < 0
+                ? trimmedUrl.substring(questionPos + 1)
+                : trimmedUrl.substring(questionPos + 1, hashPos);
+        String[] pairs = subUrl.split("&", -1);
+        for (String pair : pairs) {
+            int eqPos = pair.indexOf('=');
+            if (eqPos < 0) {
+                continue;
+            }
+            if (second.getValue().equals(pair.substring(0, eqPos))) {
+                return castStringLikeLiteral(first, pair.substring(eqPos + 1));
             }
         }
         return castStringLikeLiteral(first, "");
diff --git 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_func_time.groovy
 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_func_time.groovy
index e1e8aeb35d8..25df49effd1 100644
--- 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_func_time.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_func_time.groovy
@@ -42,6 +42,7 @@ suite("test_func_time") {
     testFoldConst("select time(cast('2025-1-1 00:00:00.4321' as 
datetime(4)));")
     testFoldConst("select time(cast('2025-1-1 00:00:00.54321' as 
datetime(5)));")
     testFoldConst("select time(cast('2025-1-1 00:00:00.654321' as 
datetime(6)));")
+    testFoldConst("select maketime(1, 2, 3.9999995), maketime(1, 2, 
59.9999995);")
 
     def tableName = "test_time_function"
 
diff --git 
a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_all.groovy
 
b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_all.groovy
index 094014504bd..2c71c7e59cd 100644
--- 
a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_all.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_all.groovy
@@ -115,6 +115,15 @@ suite("string_functions_all") {
     testFoldConst("SELECT CONCAT_WS('x', 'ṭṛì', 'ḍḍumai'), CONCAT_WS('→', 
['ṭṛì', 'ḍḍumai', 'hello']);")
     qt_concat_ws_42 "SELECT CONCAT_WS(',', 'Name', 'Age', 'City'), 
CONCAT_WS('/', 'home', 'user', 'documents', 'file.txt');"
     testFoldConst("SELECT CONCAT_WS(',', 'Name', 'Age', 'City'), 
CONCAT_WS('/', 'home', 'user', 'documents', 'file.txt');")
+    testFoldConst("SELECT CONCAT_WS(',', ['a', NULL]), CONCAT_WS(',', [NULL, 
'a', NULL]), CONCAT_WS(',', [NULL]);")
+    testFoldConst("SELECT CONCAT_WS(',', 'a', NULL), CONCAT_WS(',', NULL, 'a', 
NULL), CONCAT_WS(',', NULL);")
+    testFoldConst("SELECT RIGHT('😀a', 1), INSTR('😀a', 'a');")
+    testFoldConst("SELECT UPPER('éßi'), LOWER('ÉİA'), INITCAP('ßETA 
İSTANBUL');")
+    testFoldConst("SELECT STRCMP('😀', ''), FIND_IN_SET('', 'a,');")
+    testFoldConst("""SELECT PARSE_URL('http://h/p%20x?q=a+b%20c&k=v#r', 
'PATH'),
+        PARSE_URL('http://h/p%20x?q=a+b%20c&k=v#r', 'QUERY'),
+        EXTRACT_URL_PARAMETER('http://h/p%20x?q=a+b%20c&k=v#r', 'q');""")
+    testFoldConst("SELECT FIELD(CAST('-0.0' AS DOUBLE), CAST('0.0' AS DOUBLE), 
CAST('-0.0' AS DOUBLE));")
 
     // CONCAT tests
     qt_concat_43 "SELECT CONCAT('a', 'b'), CONCAT('a', 'b', 'c');"
@@ -436,6 +445,9 @@ suite("string_functions_all") {
     qt_ltrim_185 "SELECT LTRIM('---text---', '-'), LTRIM('@@hello@@', '@');"
     testFoldConst("SELECT LTRIM('---text---', '-'), LTRIM('@@hello@@', '@');")
 
+    // MD5 tests
+    testFoldConst("SELECT MD5('doris'), MD5('ṭṛì'), MD5SUM('do', 'ris'), 
MD5SUM('ṭ', 'ṛ', 'ì');")
+
     // MAKE_SET tests
     qt_make_set_186 "SELECT make_set(3, 'dog', 'cat', 'bird');"
     testFoldConst("SELECT make_set(3, 'dog', 'cat', 'bird');")


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to