Coverage Report

Created: 2026-08-13 19:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_variant_parse.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include <cstdint>
19
20
#include "common/config.h"
21
#include "common/exception.h"
22
#include "core/assert_cast.h"
23
#include "core/column/column_nullable.h"
24
#include "core/column/column_string.h"
25
#include "core/column/column_variant.h"
26
#include "core/column/variant_v2/column_variant_v2.h"
27
#include "core/data_type/data_type_nullable.h"
28
#include "core/data_type/data_type_string.h"
29
#include "core/data_type/data_type_variant.h"
30
#include "core/data_type/data_type_variant_v2.h"
31
#include "exec/common/variant_util.h"
32
#include "exprs/function/parse/variant_string_parse.h"
33
#include "exprs/function/simple_function_factory.h"
34
#include "util/json/json_parser.h"
35
36
namespace doris {
37
namespace {
38
39
template <bool ERROR_TO_NULL>
40
class FunctionVariantParse final : public IFunction {
41
public:
42
    static constexpr auto name = ERROR_TO_NULL ? "try_parse_to_variant" : "parse_to_variant";
43
44
43
    static FunctionPtr create() { return std::make_shared<FunctionVariantParse>(); }
function_variant_parse.cpp:_ZN5doris12_GLOBAL__N_120FunctionVariantParseILb0EE6createEv
Line
Count
Source
44
25
    static FunctionPtr create() { return std::make_shared<FunctionVariantParse>(); }
function_variant_parse.cpp:_ZN5doris12_GLOBAL__N_120FunctionVariantParseILb1EE6createEv
Line
Count
Source
44
18
    static FunctionPtr create() { return std::make_shared<FunctionVariantParse>(); }
45
46
2
    String get_name() const override { return name; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE8get_nameB5cxx11Ev
Line
Count
Source
46
1
    String get_name() const override { return name; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE8get_nameB5cxx11Ev
Line
Count
Source
46
1
    String get_name() const override { return name; }
47
0
    size_t get_number_of_arguments() const override { return 1; }
Unexecuted instantiation: function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE23get_number_of_argumentsEv
Unexecuted instantiation: function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE23get_number_of_argumentsEv
48
25
    bool use_default_implementation_for_nulls() const override { return false; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE36use_default_implementation_for_nullsEv
Line
Count
Source
48
16
    bool use_default_implementation_for_nulls() const override { return false; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE36use_default_implementation_for_nullsEv
Line
Count
Source
48
9
    bool use_default_implementation_for_nulls() const override { return false; }
49
27
    bool skip_return_type_check() const override { return true; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE22skip_return_type_checkEv
Line
Count
Source
49
17
    bool skip_return_type_check() const override { return true; }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE22skip_return_type_checkEv
Line
Count
Source
49
10
    bool skip_return_type_check() const override { return true; }
50
51
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
52
0
        auto result = std::make_shared<DataTypeVariant>();
53
0
        return ERROR_TO_NULL || arguments[0]->is_nullable() ? make_nullable(std::move(result))
54
0
                                                            : std::move(result);
55
0
    }
Unexecuted instantiation: function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Unexecuted instantiation: function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
56
57
    // Keep strict/error-to-null, SQL-null, and legacy/V2 parse transitions in one auditable state machine.
58
    // NOLINTNEXTLINE(readability-function-size,readability-function-cognitive-complexity)
59
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
60
25
                        uint32_t result, size_t input_rows_count) const override {
61
25
        const ColumnPtr source =
62
25
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
63
25
        const ColumnString* strings = nullptr;
64
25
        const NullMap* input_nulls = nullptr;
65
25
        if (const auto* nullable = check_and_get_column<ColumnNullable>(source.get())) {
66
3
            strings = &assert_cast<const ColumnString&>(nullable->get_nested_column());
67
3
            input_nulls = &nullable->get_null_map_data();
68
22
        } else {
69
22
            strings = &assert_cast<const ColumnString&>(*source);
70
22
        }
71
25
        DORIS_CHECK_EQ(strings->size(), input_rows_count);
72
73
25
        const bool result_is_nullable = block.get_by_position(result).type->is_nullable();
74
25
        DORIS_CHECK_EQ(result_is_nullable, ERROR_TO_NULL || input_nulls != nullptr);
75
25
        auto result_nulls = ColumnUInt8::create(input_rows_count, uint8_t {0});
76
77
25
        const IDataType* result_type = remove_nullable(block.get_by_position(result).type).get();
78
25
        if (const auto* variant_type = dynamic_cast<const DataTypeVariant*>(result_type)) {
79
6
            const int32_t max_subcolumns_count = variant_type->variant_max_subcolumns_count();
80
6
            const bool enable_doc_mode = variant_type->enable_doc_mode();
81
6
            auto values = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
82
6
            ParseConfig parse_config;
83
6
            parse_config.check_duplicate_json_path =
84
6
                    config::variant_enable_duplicate_json_path_check;
85
6
            parse_config.parse_to = enable_doc_mode ? ParseConfig::ParseTo::OnlyDocValueColumn
86
6
                                                    : ParseConfig::ParseTo::OnlySubcolumns;
87
6
            JsonParser parser;
88
6
            const StringRef empty_json("", 0);
89
6
            if constexpr (!ERROR_TO_NULL) {
90
11
                for (size_t row = 0; row < input_rows_count; ++row) {
91
7
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
92
7
                    try {
93
7
                        variant_util::parse_json_to_variant(
94
7
                                *values, input_is_null ? empty_json : strings->get_data_at(row),
95
7
                                &parser, parse_config);
96
7
                    } catch (const Exception& exception) {
97
1
                        const Status status = exception.to_status();
98
1
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
99
0
                            return status;
100
0
                        }
101
1
                        return Status::InvalidArgument(
102
1
                                "Parse json document failed at row {}, error: {}", row,
103
1
                                status.to_string());
104
1
                    }
105
6
                    if (input_is_null) {
106
1
                        result_nulls->get_data()[row] = 1;
107
1
                    }
108
6
                }
109
5
            } else {
110
4
                for (size_t row = 0; row < input_rows_count; ++row) {
111
3
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
112
3
                    auto one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
113
3
                    try {
114
3
                        variant_util::parse_json_to_variant(
115
3
                                *one_row, input_is_null ? empty_json : strings->get_data_at(row),
116
3
                                &parser, parse_config);
117
3
                        one_row->finalize();
118
3
                    } catch (const Exception& exception) {
119
1
                        const Status status = exception.to_status();
120
1
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
121
0
                            return status;
122
0
                        }
123
1
                        one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
124
1
                        variant_util::parse_json_to_variant(*one_row, empty_json, &parser,
125
1
                                                            parse_config);
126
1
                        one_row->finalize();
127
1
                        result_nulls->get_data()[row] = 1;
128
1
                    }
129
3
                    if (input_is_null) {
130
0
                        result_nulls->get_data()[row] = 1;
131
0
                    }
132
3
                    values->insert_range_from(*one_row, 0, 1);
133
3
                }
134
1
            }
135
5
            values->finalize();
136
137
6
            ColumnPtr output;
138
6
            if (result_is_nullable) {
139
2
                output = ColumnNullable::create(std::move(values), std::move(result_nulls));
140
4
            } else {
141
4
                output = std::move(values);
142
4
            }
143
6
            DORIS_CHECK_EQ(output->size(), input_rows_count);
144
6
            block.replace_by_position(result, std::move(output));
145
6
            return Status::OK();
146
6
        }
147
19
        DORIS_CHECK(dynamic_cast<const DataTypeVariantV2*>(result_type) != nullptr);
148
149
19
        JsonStringToVariantEncoder encoder(JsonToVariantOptions::current_config());
150
19
        const StringRef null_json("null", 4);
151
47
        for (size_t row = 0; row < input_rows_count; ++row) {
152
28
            if (input_nulls != nullptr && (*input_nulls)[row] != 0) {
153
2
                encoder.add_json(null_json);
154
2
                result_nulls->get_data()[row] = 1;
155
2
                continue;
156
2
            }
157
158
26
            const Status status = encoder.try_add_json(strings->get_data_at(row));
159
26
            if (status.ok()) {
160
16
                continue;
161
16
            }
162
10
            if constexpr (!ERROR_TO_NULL) {
163
5
                return Status::InvalidArgument("Parse json document failed at row {}, error: {}",
164
5
                                               row, status.to_string());
165
5
            }
166
0
            encoder.add_json(null_json);
167
10
            result_nulls->get_data()[row] = 1;
168
10
        }
169
170
19
        VariantBatchBuilder encoded = encoder.finish_batch();
171
19
        auto values = ColumnVariantV2::create();
172
19
        values->insert_encoded_batch(encoded);
173
174
19
        ColumnPtr output;
175
19
        if (result_is_nullable) {
176
10
            output = ColumnNullable::create(std::move(values), std::move(result_nulls));
177
10
        } else {
178
9
            output = std::move(values);
179
9
        }
180
19
        DORIS_CHECK_EQ(output->size(), input_rows_count);
181
19
        block.replace_by_position(result, std::move(output));
182
19
        return Status::OK();
183
25
    }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
60
16
                        uint32_t result, size_t input_rows_count) const override {
61
16
        const ColumnPtr source =
62
16
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
63
16
        const ColumnString* strings = nullptr;
64
16
        const NullMap* input_nulls = nullptr;
65
16
        if (const auto* nullable = check_and_get_column<ColumnNullable>(source.get())) {
66
3
            strings = &assert_cast<const ColumnString&>(nullable->get_nested_column());
67
3
            input_nulls = &nullable->get_null_map_data();
68
13
        } else {
69
13
            strings = &assert_cast<const ColumnString&>(*source);
70
13
        }
71
16
        DORIS_CHECK_EQ(strings->size(), input_rows_count);
72
73
16
        const bool result_is_nullable = block.get_by_position(result).type->is_nullable();
74
16
        DORIS_CHECK_EQ(result_is_nullable, ERROR_TO_NULL || input_nulls != nullptr);
75
16
        auto result_nulls = ColumnUInt8::create(input_rows_count, uint8_t {0});
76
77
16
        const IDataType* result_type = remove_nullable(block.get_by_position(result).type).get();
78
16
        if (const auto* variant_type = dynamic_cast<const DataTypeVariant*>(result_type)) {
79
5
            const int32_t max_subcolumns_count = variant_type->variant_max_subcolumns_count();
80
5
            const bool enable_doc_mode = variant_type->enable_doc_mode();
81
5
            auto values = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
82
5
            ParseConfig parse_config;
83
5
            parse_config.check_duplicate_json_path =
84
5
                    config::variant_enable_duplicate_json_path_check;
85
5
            parse_config.parse_to = enable_doc_mode ? ParseConfig::ParseTo::OnlyDocValueColumn
86
5
                                                    : ParseConfig::ParseTo::OnlySubcolumns;
87
5
            JsonParser parser;
88
5
            const StringRef empty_json("", 0);
89
5
            if constexpr (!ERROR_TO_NULL) {
90
11
                for (size_t row = 0; row < input_rows_count; ++row) {
91
7
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
92
7
                    try {
93
7
                        variant_util::parse_json_to_variant(
94
7
                                *values, input_is_null ? empty_json : strings->get_data_at(row),
95
7
                                &parser, parse_config);
96
7
                    } catch (const Exception& exception) {
97
1
                        const Status status = exception.to_status();
98
1
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
99
0
                            return status;
100
0
                        }
101
1
                        return Status::InvalidArgument(
102
1
                                "Parse json document failed at row {}, error: {}", row,
103
1
                                status.to_string());
104
1
                    }
105
6
                    if (input_is_null) {
106
1
                        result_nulls->get_data()[row] = 1;
107
1
                    }
108
6
                }
109
            } else {
110
                for (size_t row = 0; row < input_rows_count; ++row) {
111
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
112
                    auto one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
113
                    try {
114
                        variant_util::parse_json_to_variant(
115
                                *one_row, input_is_null ? empty_json : strings->get_data_at(row),
116
                                &parser, parse_config);
117
                        one_row->finalize();
118
                    } catch (const Exception& exception) {
119
                        const Status status = exception.to_status();
120
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
121
                            return status;
122
                        }
123
                        one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
124
                        variant_util::parse_json_to_variant(*one_row, empty_json, &parser,
125
                                                            parse_config);
126
                        one_row->finalize();
127
                        result_nulls->get_data()[row] = 1;
128
                    }
129
                    if (input_is_null) {
130
                        result_nulls->get_data()[row] = 1;
131
                    }
132
                    values->insert_range_from(*one_row, 0, 1);
133
                }
134
            }
135
4
            values->finalize();
136
137
5
            ColumnPtr output;
138
5
            if (result_is_nullable) {
139
1
                output = ColumnNullable::create(std::move(values), std::move(result_nulls));
140
4
            } else {
141
4
                output = std::move(values);
142
4
            }
143
5
            DORIS_CHECK_EQ(output->size(), input_rows_count);
144
5
            block.replace_by_position(result, std::move(output));
145
5
            return Status::OK();
146
5
        }
147
11
        DORIS_CHECK(dynamic_cast<const DataTypeVariantV2*>(result_type) != nullptr);
148
149
11
        JsonStringToVariantEncoder encoder(JsonToVariantOptions::current_config());
150
11
        const StringRef null_json("null", 4);
151
28
        for (size_t row = 0; row < input_rows_count; ++row) {
152
17
            if (input_nulls != nullptr && (*input_nulls)[row] != 0) {
153
2
                encoder.add_json(null_json);
154
2
                result_nulls->get_data()[row] = 1;
155
2
                continue;
156
2
            }
157
158
15
            const Status status = encoder.try_add_json(strings->get_data_at(row));
159
15
            if (status.ok()) {
160
10
                continue;
161
10
            }
162
5
            if constexpr (!ERROR_TO_NULL) {
163
5
                return Status::InvalidArgument("Parse json document failed at row {}, error: {}",
164
5
                                               row, status.to_string());
165
5
            }
166
0
            encoder.add_json(null_json);
167
5
            result_nulls->get_data()[row] = 1;
168
5
        }
169
170
11
        VariantBatchBuilder encoded = encoder.finish_batch();
171
11
        auto values = ColumnVariantV2::create();
172
11
        values->insert_encoded_batch(encoded);
173
174
11
        ColumnPtr output;
175
11
        if (result_is_nullable) {
176
2
            output = ColumnNullable::create(std::move(values), std::move(result_nulls));
177
9
        } else {
178
9
            output = std::move(values);
179
9
        }
180
        DORIS_CHECK_EQ(output->size(), input_rows_count);
181
11
        block.replace_by_position(result, std::move(output));
182
11
        return Status::OK();
183
16
    }
function_variant_parse.cpp:_ZNK5doris12_GLOBAL__N_120FunctionVariantParseILb1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
60
9
                        uint32_t result, size_t input_rows_count) const override {
61
9
        const ColumnPtr source =
62
9
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
63
9
        const ColumnString* strings = nullptr;
64
9
        const NullMap* input_nulls = nullptr;
65
9
        if (const auto* nullable = check_and_get_column<ColumnNullable>(source.get())) {
66
0
            strings = &assert_cast<const ColumnString&>(nullable->get_nested_column());
67
0
            input_nulls = &nullable->get_null_map_data();
68
9
        } else {
69
9
            strings = &assert_cast<const ColumnString&>(*source);
70
9
        }
71
9
        DORIS_CHECK_EQ(strings->size(), input_rows_count);
72
73
9
        const bool result_is_nullable = block.get_by_position(result).type->is_nullable();
74
9
        DORIS_CHECK_EQ(result_is_nullable, ERROR_TO_NULL || input_nulls != nullptr);
75
9
        auto result_nulls = ColumnUInt8::create(input_rows_count, uint8_t {0});
76
77
9
        const IDataType* result_type = remove_nullable(block.get_by_position(result).type).get();
78
9
        if (const auto* variant_type = dynamic_cast<const DataTypeVariant*>(result_type)) {
79
1
            const int32_t max_subcolumns_count = variant_type->variant_max_subcolumns_count();
80
1
            const bool enable_doc_mode = variant_type->enable_doc_mode();
81
1
            auto values = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
82
1
            ParseConfig parse_config;
83
1
            parse_config.check_duplicate_json_path =
84
1
                    config::variant_enable_duplicate_json_path_check;
85
1
            parse_config.parse_to = enable_doc_mode ? ParseConfig::ParseTo::OnlyDocValueColumn
86
1
                                                    : ParseConfig::ParseTo::OnlySubcolumns;
87
1
            JsonParser parser;
88
1
            const StringRef empty_json("", 0);
89
            if constexpr (!ERROR_TO_NULL) {
90
                for (size_t row = 0; row < input_rows_count; ++row) {
91
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
92
                    try {
93
                        variant_util::parse_json_to_variant(
94
                                *values, input_is_null ? empty_json : strings->get_data_at(row),
95
                                &parser, parse_config);
96
                    } catch (const Exception& exception) {
97
                        const Status status = exception.to_status();
98
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
99
                            return status;
100
                        }
101
                        return Status::InvalidArgument(
102
                                "Parse json document failed at row {}, error: {}", row,
103
                                status.to_string());
104
                    }
105
                    if (input_is_null) {
106
                        result_nulls->get_data()[row] = 1;
107
                    }
108
                }
109
1
            } else {
110
4
                for (size_t row = 0; row < input_rows_count; ++row) {
111
3
                    const bool input_is_null = input_nulls != nullptr && (*input_nulls)[row] != 0;
112
3
                    auto one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
113
3
                    try {
114
3
                        variant_util::parse_json_to_variant(
115
3
                                *one_row, input_is_null ? empty_json : strings->get_data_at(row),
116
3
                                &parser, parse_config);
117
3
                        one_row->finalize();
118
3
                    } catch (const Exception& exception) {
119
1
                        const Status status = exception.to_status();
120
1
                        if (!status.is<ErrorCode::INVALID_ARGUMENT>()) {
121
0
                            return status;
122
0
                        }
123
1
                        one_row = ColumnVariant::create(max_subcolumns_count, enable_doc_mode);
124
1
                        variant_util::parse_json_to_variant(*one_row, empty_json, &parser,
125
1
                                                            parse_config);
126
1
                        one_row->finalize();
127
1
                        result_nulls->get_data()[row] = 1;
128
1
                    }
129
3
                    if (input_is_null) {
130
0
                        result_nulls->get_data()[row] = 1;
131
0
                    }
132
3
                    values->insert_range_from(*one_row, 0, 1);
133
3
                }
134
1
            }
135
1
            values->finalize();
136
137
1
            ColumnPtr output;
138
1
            if (result_is_nullable) {
139
1
                output = ColumnNullable::create(std::move(values), std::move(result_nulls));
140
1
            } else {
141
0
                output = std::move(values);
142
0
            }
143
1
            DORIS_CHECK_EQ(output->size(), input_rows_count);
144
1
            block.replace_by_position(result, std::move(output));
145
1
            return Status::OK();
146
1
        }
147
8
        DORIS_CHECK(dynamic_cast<const DataTypeVariantV2*>(result_type) != nullptr);
148
149
8
        JsonStringToVariantEncoder encoder(JsonToVariantOptions::current_config());
150
8
        const StringRef null_json("null", 4);
151
19
        for (size_t row = 0; row < input_rows_count; ++row) {
152
11
            if (input_nulls != nullptr && (*input_nulls)[row] != 0) {
153
0
                encoder.add_json(null_json);
154
0
                result_nulls->get_data()[row] = 1;
155
0
                continue;
156
0
            }
157
158
11
            const Status status = encoder.try_add_json(strings->get_data_at(row));
159
11
            if (status.ok()) {
160
6
                continue;
161
6
            }
162
            if constexpr (!ERROR_TO_NULL) {
163
                return Status::InvalidArgument("Parse json document failed at row {}, error: {}",
164
                                               row, status.to_string());
165
            }
166
5
            encoder.add_json(null_json);
167
5
            result_nulls->get_data()[row] = 1;
168
5
        }
169
170
8
        VariantBatchBuilder encoded = encoder.finish_batch();
171
8
        auto values = ColumnVariantV2::create();
172
8
        values->insert_encoded_batch(encoded);
173
174
8
        ColumnPtr output;
175
8
        if (result_is_nullable) {
176
8
            output = ColumnNullable::create(std::move(values), std::move(result_nulls));
177
8
        } else {
178
0
            output = std::move(values);
179
0
        }
180
        DORIS_CHECK_EQ(output->size(), input_rows_count);
181
8
        block.replace_by_position(result, std::move(output));
182
8
        return Status::OK();
183
9
    }
184
};
185
186
using FunctionParseToVariant = FunctionVariantParse<false>;
187
using FunctionTryParseToVariant = FunctionVariantParse<true>;
188
189
} // namespace
190
191
7
void register_function_variant_parse(SimpleFunctionFactory& factory) {
192
7
    factory.register_function<FunctionParseToVariant>();
193
7
    factory.register_function<FunctionTryParseToVariant>();
194
7
}
195
196
} // namespace doris