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

morningman pushed a commit to branch branch-c108335-hive-sql
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-c108335-hive-sql by 
this push:
     new da4790be099 Fix str_to_map and next_day bug and impl xpath string 
(#49470)
da4790be099 is described below

commit da4790be099154031e720697b336cd527fa002f8
Author: Socrates <suyit...@selectdb.com>
AuthorDate: Tue Mar 25 17:37:49 2025 +0800

    Fix str_to_map and next_day bug and impl xpath string (#49470)
---
 be/cmake/thirdparty.cmake                          |   2 +
 .../function_date_or_datetime_computation.cpp      |   3 +-
 .../function_date_or_datetime_computation.h        |  71 ++++----------
 be/src/vec/functions/function_map.cpp              |  29 +++++-
 be/src/vec/functions/function_string.cpp           |   1 +
 be/src/vec/functions/function_string.h             | 108 ++++++++++++---------
 .../doris/catalog/BuiltinScalarFunctions.java      |   2 +
 .../expressions/functions/scalar/NextDay.java      |   9 +-
 .../scalar/{NextDay.java => XpathString.java}      |  55 +++++------
 .../expressions/visitor/ScalarFunctionVisitor.java |   5 +
 10 files changed, 141 insertions(+), 144 deletions(-)

diff --git a/be/cmake/thirdparty.cmake b/be/cmake/thirdparty.cmake
index a165c4ab203..9f1e3aecb9d 100644
--- a/be/cmake/thirdparty.cmake
+++ b/be/cmake/thirdparty.cmake
@@ -175,3 +175,5 @@ endif()
 add_thirdparty(icuuc LIB64)
 add_thirdparty(icui18n LIB64)
 add_thirdparty(icudata LIB64)
+
+add_thirdparty(pugixml LIB64)
diff --git a/be/src/vec/functions/function_date_or_datetime_computation.cpp 
b/be/src/vec/functions/function_date_or_datetime_computation.cpp
index 736a6f48539..f60e32a3cdb 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.cpp
+++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp
@@ -127,8 +127,7 @@ void 
register_function_date_time_computation(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionMinutesDiff>();
     factory.register_function<FunctionSecondsDiff>();
 
-    factory.register_function<FunctionNextDay<DateNextDayImpl>>();
-    factory.register_function<FunctionNextDay<DateTimeNextDayImpl>>();
+    factory.register_function<FunctionNextDay>();
 
     factory.register_function<FunctionToYearWeekTwoArgs>();
     factory.register_function<FunctionToWeekTwoArgs>();
diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h 
b/be/src/vec/functions/function_date_or_datetime_computation.h
index 1c99aa5fc1f..d88fd0b1a66 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.h
+++ b/be/src/vec/functions/function_date_or_datetime_computation.h
@@ -1044,38 +1044,13 @@ public:
     String get_name() const override { return name; }
     size_t get_number_of_arguments() const override { return 2; }
     DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) 
const override {
-        return make_nullable(std::make_shared<typename 
FunctionImpl::ReturnType>());
+        return make_nullable(std::make_shared<DataTypeDateV2>());
     }
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         uint32_t result, size_t input_rows_count) const 
override {
-        // TODO: const optimize
-        return FunctionImpl::execute(context, block, arguments, result, 
input_rows_count);
-    }
-};
-
-static int day_of_week(const StringRef& weekday) {
-    static const std::unordered_map<std::string, int> weekday_map = {
-            {"SU", 1}, {"SUN", 1}, {"SUNDAY", 1},   {"MO", 2}, {"MON", 2}, 
{"MONDAY", 2},
-            {"TU", 3}, {"TUE", 3}, {"TUESDAY", 3},  {"WE", 4}, {"WED", 4}, 
{"WEDNESDAY", 4},
-            {"TH", 5}, {"THU", 5}, {"THURSDAY", 5}, {"FR", 6}, {"FRI", 6}, 
{"FRIDAY", 6},
-            {"SA", 7}, {"SAT", 7}, {"SATURDAY", 7},
-    };
-    auto weekday_upper = weekday.to_string();
-    std::transform(weekday_upper.begin(), weekday_upper.end(), 
weekday_upper.begin(), ::toupper);
-    auto it = weekday_map.find(weekday_upper);
-    if (it == weekday_map.end()) {
-        return 0;
-    }
-    return it->second;
-}
-
-struct DateNextDayImpl {
-    using ReturnType = DataTypeDateV2;
-    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                          uint32_t result, size_t input_rows_count) {
         CHECK_EQ(arguments.size(), 2);
-        auto res = ColumnVector<UInt32>::create();
+        auto res = ColumnDateV2::create();
         const auto* date_col =
                 assert_cast<const 
ColumnDateV2*>(block.get_by_position(arguments[0]).column.get());
         const auto* week_col =
@@ -1098,35 +1073,23 @@ struct DateNextDayImpl {
         block.replace_by_position(result, std::move(res));
         return Status::OK();
     }
-};
 
-struct DateTimeNextDayImpl {
-    using ReturnType = DataTypeDateTimeV2;
-    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                          uint32_t result, size_t input_rows_count) {
-        CHECK_EQ(arguments.size(), 2);
-        auto res = ColumnVector<UInt64>::create();
-        const auto* date_col = assert_cast<const ColumnDateTimeV2*>(
-                block.get_by_position(arguments[0]).column.get());
-        const auto* week_col =
-                assert_cast<const 
ColumnString*>(block.get_by_position(arguments[1]).column.get());
-        for (int i = 0; i < input_rows_count; ++i) {
-            auto date = date_col->get_element(i);
-            auto week = week_col->get_data_at(i);
-            auto week_day = day_of_week(week);
-            if (week_day == 0) {
-                return Status::InvalidArgument("Invalid weekday: {}", week);
-            } else {
-                auto dtv = binary_cast<UInt64, 
DateV2Value<DateTimeV2ValueType>>(date);
-                auto days_to_add = (week_day - dtv.day_of_week() + 7) % 7;
-                days_to_add = days_to_add == 0 ? 7 : days_to_add;
-                dtv.date_add_interval<TimeUnit::DAY>(
-                        TimeInterval(TimeUnit::DAY, days_to_add, false));
-                
res->insert_value(binary_cast<DateV2Value<DateTimeV2ValueType>, UInt64>(dtv));
-            }
+private:
+    static int day_of_week(const StringRef& weekday) {
+        static const std::unordered_map<std::string, int> weekday_map = {
+                {"SU", 1}, {"SUN", 1}, {"SUNDAY", 1},   {"MO", 2}, {"MON", 2}, 
{"MONDAY", 2},
+                {"TU", 3}, {"TUE", 3}, {"TUESDAY", 3},  {"WE", 4}, {"WED", 4}, 
{"WEDNESDAY", 4},
+                {"TH", 5}, {"THU", 5}, {"THURSDAY", 5}, {"FR", 6}, {"FRI", 6}, 
{"FRIDAY", 6},
+                {"SA", 7}, {"SAT", 7}, {"SATURDAY", 7},
+        };
+        auto weekday_upper = weekday.to_string();
+        std::transform(weekday_upper.begin(), weekday_upper.end(), 
weekday_upper.begin(),
+                       ::toupper);
+        auto it = weekday_map.find(weekday_upper);
+        if (it == weekday_map.end()) {
+            return 0;
         }
-        block.replace_by_position(result, std::move(res));
-        return Status::OK();
+        return it->second;
     }
 };
 
diff --git a/be/src/vec/functions/function_map.cpp 
b/be/src/vec/functions/function_map.cpp
index 14233c68925..3d8b84bdf37 100644
--- a/be/src/vec/functions/function_map.cpp
+++ b/be/src/vec/functions/function_map.cpp
@@ -28,6 +28,7 @@
 #include <utility>
 
 #include "common/status.h"
+#include "util/simd/vstring_function.h"
 #include "vec/aggregate_functions/aggregate_function.h"
 #include "vec/columns/column.h"
 #include "vec/columns/column_array.h"
@@ -326,9 +327,9 @@ public:
         const auto* kv_delim_column = assert_cast<const 
ColumnString*>(kv_delim_col.get());
 
         for (size_t i = 0; i < input_rows_count; ++i) {
-            auto str = str_column->get_data_at(i);
-            auto pair_delim = pair_delim_column->get_data_at(i);
-            auto kv_delim = kv_delim_column->get_data_at(i);
+            const auto str = str_column->get_data_at(i).to_string_view();
+            const auto pair_delim = 
pair_delim_column->get_data_at(i).to_string_view();
+            const auto kv_delim = 
kv_delim_column->get_data_at(i).to_string_view();
 
             auto kvs = split_pair_by_delim(str, pair_delim);
             for (const auto& kv : kvs) {
@@ -356,8 +357,21 @@ public:
 private:
     static std::vector<std::string_view> split_pair_by_delim(const 
std::string_view& str,
                                                              const 
std::string_view& delim) {
+        if (str.empty()) {
+            return {str};
+        }
+        if (delim.empty()) {
+            std::vector<std::string_view> result;
+            size_t offset = 0;
+            while (offset < str.size()) {
+                auto len = get_utf8_byte_length(str[offset]);
+                result.push_back(str.substr(offset, len));
+                offset += len;
+            }
+            return result;
+        }
         std::vector<std::string_view> result;
-        auto offset = 0;
+        size_t offset = 0;
         while (offset < str.size()) {
             auto pos = str.find(delim, offset);
             if (pos == std::string::npos) {
@@ -372,6 +386,13 @@ private:
 
     static std::vector<std::string_view> split_kv_by_delim(const 
std::string_view& str,
                                                            const 
std::string_view& delim) {
+        if (str.empty()) {
+            return {str};
+        }
+        if (delim.empty()) {
+            auto len = get_utf8_byte_length(str[0]);
+            return {str.substr(0, len), str.substr(len)};
+        }
         auto pos = str.find(delim);
         if (pos == std::string::npos) {
             return {str};
diff --git a/be/src/vec/functions/function_string.cpp 
b/be/src/vec/functions/function_string.cpp
index 9b829a8c58a..1f6341058a0 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -1286,6 +1286,7 @@ void register_function_string(SimpleFunctionFactory& 
factory) {
     factory.register_function<FunctionStrcmp>();
     factory.register_function<FunctionNgramSearch>();
     factory.register_function<FunctionPrintf>();
+    factory.register_function<FunctionXPathString>();
 
     factory.register_alias(FunctionLeft::name, "strleft");
     factory.register_alias(FunctionRight::name, "strright");
diff --git a/be/src/vec/functions/function_string.h 
b/be/src/vec/functions/function_string.h
index ab70cc6fe26..cfd6f8e845c 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -19,6 +19,7 @@
 
 #include <fmt/core.h>
 #include <fmt/printf.h>
+#include <glog/logging.h>
 #include <sys/types.h>
 
 #include <algorithm>
@@ -87,6 +88,7 @@
 #include <string_view>
 
 #include "exprs/math_functions.h"
+#include "pugixml.hpp"
 #include "udf/udf.h"
 #include "util/md5.h"
 #include "util/simd/vstring_function.h"
@@ -5015,56 +5017,74 @@ public:
             }
         }
         block.replace_by_position(result, std::move(result_col));
+    }
+};
+
+class FunctionXPathString : public IFunction {
+public:
+    static constexpr auto name = "xpath_string";
+    static FunctionPtr create() { return 
std::make_shared<FunctionXPathString>(); }
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 2; }
+    DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
+        return std::make_shared<DataTypeString>();
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        uint32_t result, size_t input_rows_count) const 
override {
+        CHECK_EQ(arguments.size(), 2);
+        auto col_res = ColumnString::create();
+        bool col_const[2];
+        ColumnPtr argument_columns[2];
+        for (int i = 0; i < 2; ++i) {
+            col_const[i] = 
is_column_const(*block.get_by_position(arguments[i]).column);
+        }
+        argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
+                                                     
*block.get_by_position(arguments[0]).column)
+                                                     .convert_to_full_column()
+                                           : 
block.get_by_position(arguments[0]).column;
+        default_preprocess_parameter_columns(argument_columns, col_const, {1}, 
block, arguments);
+
+        const auto* col_xml = assert_cast<const 
ColumnString*>(argument_columns[0].get());
+        const auto* col_xpath = assert_cast<const 
ColumnString*>(argument_columns[1].get());
+
+        for (size_t i = 0; i < input_rows_count; ++i) {
+            const auto& xml_str = col_xml->get_data_at(i);
+            const auto& xpath_str = col_xpath->get_data_at(i);
+            pugi::xml_document doc;
+            pugi::xml_parse_result result = 
doc.load_string(xml_str.to_string_view().data());
+            if (!result) {
+                return Status::InvalidArgument("Failed to parse XML string: 
{}",
+                                               result.description());
+            }
+
+            pugi::xpath_node node = 
doc.select_node(xpath_str.to_string_view().data());
+            if (!node) {
+                col_res->insert_default();
+                continue;
+            }
+            auto text = get_text(node.node());
+            col_res->insert_data(text.data(), text.size());
+        }
+        block.get_by_position(result).column = std::move(col_res);
         return Status::OK();
     }
 
 private:
-    static Status handle_format_arg(const StringRef& data, const DataTypePtr& 
type,
-                                    
fmt::dynamic_format_arg_store<fmt::printf_context>& store) {
-        switch (type->get_type_id()) {
-        case TypeIndex::Int64:
-            store.push_back(get_value_from_data<int64_t>(data));
-            return Status::OK();
-        case TypeIndex::Int32:
-            store.push_back(get_value_from_data<int32_t>(data));
-            return Status::OK();
-        case TypeIndex::Int16:
-            store.push_back(get_value_from_data<int16_t>(data));
-            return Status::OK();
-        case TypeIndex::Int8:
-            store.push_back(get_value_from_data<int8_t>(data));
-            return Status::OK();
-        case TypeIndex::UInt64:
-            store.push_back(get_value_from_data<uint64_t>(data));
-            return Status::OK();
-        case TypeIndex::UInt32:
-            store.push_back(get_value_from_data<uint32_t>(data));
-            return Status::OK();
-        case TypeIndex::UInt16:
-            store.push_back(get_value_from_data<uint16_t>(data));
-            return Status::OK();
-        case TypeIndex::UInt8:
-            store.push_back(get_value_from_data<uint8_t>(data));
-            return Status::OK();
-        case TypeIndex::Float64:
-            store.push_back(get_value_from_data<double>(data));
-            return Status::OK();
-        case TypeIndex::Float32:
-            store.push_back(get_value_from_data<float>(data));
-            return Status::OK();
-        case TypeIndex::String:
-            store.push_back(data.to_string());
-            return Status::OK();
-        default:
-            return Status::InvalidArgument("Unsupported printf type: {}", 
type->get_name());
-        }
+    // Build the text of the node and all its children.
+    static std::string get_text(const pugi::xml_node& node) {
+        std::string result;
+        build_text(node, result);
+        return result;
     }
 
-    template <typename T>
-    static T get_value_from_data(const StringRef& data) {
-        T value;
-        memcpy(&value, data.data, sizeof(value));
-        return value;
+    static void build_text(const pugi::xml_node& node, std::string& builder) {
+        if (node.first_child().type() == pugi::node_pcdata) {
+            builder += node.text().as_string();
+        }
+        for (pugi::xml_node child : node.children()) {
+            build_text(child, builder);
+        }
     }
 };
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index 2787cb0d9ca..0ce50a42631 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -481,6 +481,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksSub;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.WidthBucket;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Xor;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.XpathString;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.XxHash32;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.XxHash64;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Year;
@@ -987,6 +988,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(XxHash32.class, "xxhash_32"),
             scalar(XxHash64.class, "xxhash_64"),
             scalar(Xor.class, "xor"),
+            scalar(XpathString.class, "xpath_string"),
             scalar(Year.class, "year"),
             scalar(YearCeil.class, "year_ceil"),
             scalar(YearFloor.class, "year_floor"),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
index d47035e6d7e..9a04f515737 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
@@ -23,9 +23,6 @@ import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSi
 import 
org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args;
 import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.types.DateTimeType;
-import org.apache.doris.nereids.types.DateTimeV2Type;
-import org.apache.doris.nereids.types.DateType;
 import org.apache.doris.nereids.types.DateV2Type;
 import org.apache.doris.nereids.types.StringType;
 
@@ -53,11 +50,7 @@ import java.util.List;
 public class NextDay extends ScalarFunction
         implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullableOnDateLikeV2Args {
     private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-            FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
-                    .args(DateTimeV2Type.SYSTEM_DEFAULT, StringType.INSTANCE),
-            
FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE, 
StringType.INSTANCE),
-            
FunctionSignature.ret(DateTimeType.INSTANCE).args(DateTimeType.INSTANCE, 
StringType.INSTANCE),
-            FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE, 
StringType.INSTANCE));
+            
FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE, 
StringType.INSTANCE));
 
     public NextDay(Expression arg0, Expression arg1) {
         super("next_day", arg0, arg1);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/XpathString.java
similarity index 52%
copy from 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/XpathString.java
index d47035e6d7e..475b899a8d6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/XpathString.java
@@ -20,14 +20,11 @@ package 
org.apache.doris.nereids.trees.expressions.functions.scalar;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import 
org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.types.DateTimeType;
-import org.apache.doris.nereids.types.DateTimeV2Type;
-import org.apache.doris.nereids.types.DateType;
-import org.apache.doris.nereids.types.DateV2Type;
 import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
@@ -35,38 +32,32 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /**
- * ScalarFunction 'days_add'.
- * next_day(expr, dayOfWeek)
- * - expr: A DATE expression.
- * - dayOfWeek: A STRING expression identifying a day of the week.
- * Returns the first DATE that is later than expr and has the same day of the
- * week as dayOfWeek.
- * dayOfWeek must be one of the following (case insensitive):
- * 'SU', 'SUN', 'SUNDAY'
- * 'MO', 'MON', 'MONDAY'
- * 'TU', 'TUE', 'TUESDAY'
- * 'WE', 'WED', 'WEDNESDAY'
- * 'TH', 'THU', 'THURSDAY'
- * 'FR', 'FRI', 'FRIDAY'
- * 'SA', 'SAT', 'SATURDAY'
+ * ScalarFunction 'xpath_string'.
  */
-public class NextDay extends ScalarFunction
-        implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullableOnDateLikeV2Args {
-    private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-            FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
-                    .args(DateTimeV2Type.SYSTEM_DEFAULT, StringType.INSTANCE),
-            
FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE, 
StringType.INSTANCE),
-            
FunctionSignature.ret(DateTimeType.INSTANCE).args(DateTimeType.INSTANCE, 
StringType.INSTANCE),
-            FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE, 
StringType.INSTANCE));
+public class XpathString extends ScalarFunction
+        implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
 
-    public NextDay(Expression arg0, Expression arg1) {
-        super("next_day", arg0, arg1);
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT)
+                    .args(VarcharType.SYSTEM_DEFAULT, 
VarcharType.SYSTEM_DEFAULT),
+            FunctionSignature.ret(StringType.INSTANCE)
+                    .args(StringType.INSTANCE, StringType.INSTANCE)
+    );
+
+    /**
+     * constructor with 2 arguments.
+     */
+    public XpathString(Expression arg0, Expression arg1) {
+        super("xpath_string", arg0, arg1);
     }
 
+    /**
+     * withChildren.
+     */
     @Override
-    public NextDay withChildren(List<Expression> children) {
+    public XpathString withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 2);
-        return new NextDay(children.get(0), children.get(1));
+        return new XpathString(children.get(0), children.get(1));
     }
 
     @Override
@@ -76,6 +67,6 @@ public class NextDay extends ScalarFunction
 
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
-        return visitor.visitNextDay(this, context);
+        return visitor.visitXpathString(this, context);
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 01c51c20c43..72bd256f93a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -478,6 +478,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksSub;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.WidthBucket;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Xor;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.XpathString;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.XxHash32;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.XxHash64;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Year;
@@ -2359,6 +2360,10 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(xor, context);
     }
 
+    default R visitXpathString(XpathString xpathString, C context) {
+        return visitScalarFunction(xpathString, context);
+    }
+
     // struct function
 
     default R visitCreateStruct(CreateStruct createStruct, C context) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to