Coverage Report

Created: 2024-11-18 12:21

/root/doris/be/src/udf/udf.h
Line
Count
Source (jump to first uncovered line)
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
// This file is copied from
18
// https://github.com/apache/impala/blob/branch-2.9.0/be/src/udf/udf.h
19
// and modified by Doris
20
21
#pragma once
22
23
#include <cstdint>
24
#include <memory>
25
#include <string>
26
#include <vector>
27
28
#include "runtime/types.h"
29
#include "vec/common/arena.h"
30
31
namespace doris {
32
33
struct ColumnPtrWrapper;
34
struct StringRef;
35
class RuntimeState;
36
37
// The FunctionContext is passed to every UDF/UDA and is the interface for the UDF to the
38
// rest of the system. It contains APIs to examine the system state, report errors
39
// and manage memory.
40
class FunctionContext {
41
public:
42
    enum FunctionStateScope {
43
        /// Indicates that the function state for this FunctionContext's UDF is shared across
44
        /// the plan fragment (a query is divided into multiple plan fragments, each of which
45
        /// is responsible for a part of the query execution). Within the plan fragment, there
46
        /// may be multiple instances of the UDF executing concurrently with multiple
47
        /// FunctionContexts sharing this state, meaning that the state must be
48
        /// thread-safe. The Prepare() function for the UDF may be called with this scope
49
        /// concurrently on a single host if the UDF will be evaluated in multiple plan
50
        /// fragments on that host. In general, read-only state that doesn't need to be
51
        /// recomputed for every UDF call should be fragment-local.
52
        /// TODO: not yet implemented
53
        FRAGMENT_LOCAL,
54
55
        /// Indicates that the function state is local to the execution thread. This state
56
        /// does not need to be thread-safe. However, this state will be initialized (via the
57
        /// Prepare() function) once for every execution thread, so fragment-local state
58
        /// should be used when possible for better performance. In general, inexpensive
59
        /// shared state that is written to by the UDF (e.g. scratch space) should be
60
        /// thread-local.
61
        THREAD_LOCAL,
62
    };
63
64
    static std::unique_ptr<doris::FunctionContext> create_context(
65
            RuntimeState* state, const doris::TypeDescriptor& return_type,
66
            const std::vector<doris::TypeDescriptor>& arg_types);
67
68
    /// Returns a new FunctionContext with the same constant args, fragment-local state, and
69
    /// debug flag as this FunctionContext. The caller is responsible for calling delete on
70
    /// it.
71
    std::unique_ptr<doris::FunctionContext> clone();
72
73
    void set_constant_cols(const std::vector<std::shared_ptr<doris::ColumnPtrWrapper>>& cols);
74
75
25
    RuntimeState* state() { return _state; }
76
77
318
    bool check_overflow_for_decimal() const { return _check_overflow_for_decimal; }
78
79
2
    bool set_check_overflow_for_decimal(bool check_overflow_for_decimal) {
80
2
        return _check_overflow_for_decimal = check_overflow_for_decimal;
81
2
    }
82
83
0
    void set_string_as_jsonb_string(bool string_as_jsonb_string) {
84
0
        _string_as_jsonb_string = string_as_jsonb_string;
85
0
    }
86
87
0
    void set_jsonb_string_as_string(bool jsonb_string_as_string) {
88
0
        _jsonb_string_as_string = jsonb_string_as_string;
89
0
    }
90
91
    // Cast flag, when enable string_as_jsonb_string, string casting to jsonb will not parse string
92
    // instead just insert a string literal
93
18
    bool string_as_jsonb_string() const { return _string_as_jsonb_string; }
94
95
    // Cast flag, when enable jsonb_string_as_string, jsonb string casting to string will not parse string
96
    // instead just insert a string literal
97
0
    bool jsonb_string_as_string() const { return _jsonb_string_as_string; }
98
99
    // Sets an error for this UDF. If this is called, this will trigger the
100
    // query to fail.
101
    // Note: when you set error for the UDFs used in Data Load, you should
102
    // ensure the function return value is null.
103
    void set_error(const char* error_msg);
104
105
    // Adds a warning that is returned to the user. This can include things like
106
    // overflow or other recoverable error conditions.
107
    // Warnings are capped at a maximum number. Returns true if the warning was
108
    // added and false if it was ignored due to the cap.
109
    bool add_warning(const char* warning_msg);
110
111
    /// Methods for maintaining state across UDF/UDA function calls. SetFunctionState() can
112
    /// be used to store a pointer that can then be retrieved via GetFunctionState(). If
113
    /// GetFunctionState() is called when no pointer is set, it will return
114
    /// nullptr. SetFunctionState() does not take ownership of 'ptr'; it is up to the UDF/UDA
115
    /// to clean up any function state if necessary.
116
    void set_function_state(FunctionStateScope scope, std::shared_ptr<void> ptr);
117
118
    void* get_function_state(FunctionStateScope scope) const;
119
120
    // Returns the return type information of this function. For UDAs, this is the final
121
    // return type of the UDA (e.g., the type returned by the finalize function).
122
    const doris::TypeDescriptor& get_return_type() const;
123
124
    // Returns the number of arguments to this function (not including the FunctionContext*
125
    // argument).
126
    int get_num_args() const;
127
128
    // Returns the type information for the arg_idx-th argument (0-indexed, not including
129
    // the FunctionContext* argument). Returns nullptr if arg_idx is invalid.
130
    const doris::TypeDescriptor* get_arg_type(int arg_idx) const;
131
132
    // Returns true if the arg_idx-th input argument (0 indexed, not including the
133
    // FunctionContext* argument) is a constant (e.g. 5, "string", 1 + 1).
134
    bool is_col_constant(int arg_idx) const;
135
136
    // Returns a pointer to the value of the arg_idx-th input argument (0 indexed, not
137
    // including the FunctionContext* argument). Returns nullptr if the argument is not
138
    // constant. This function can be used to obtain user-specified constants in a UDF's
139
    // Init() or Close() functions.
140
    doris::ColumnPtrWrapper* get_constant_col(int arg_idx) const;
141
142
    // Creates a StringRef, which memory is available when this function context is used next time
143
    StringRef create_temp_string_val(int64_t len);
144
145
666
    ~FunctionContext() = default;
146
147
0
    vectorized::Arena& get_arena() { return arena; }
148
149
private:
150
666
    FunctionContext() = default;
151
152
    // Disable copy ctor and assignment operator
153
    FunctionContext(const FunctionContext& other);
154
155
    FunctionContext& operator=(const FunctionContext& other);
156
157
    // We use the query's runtime state to report errors and warnings. nullptr for test
158
    // contexts.
159
    RuntimeState* _state = nullptr;
160
161
    // Empty if there's no error
162
    std::string _error_msg;
163
164
    // The number of warnings reported.
165
    int64_t _num_warnings;
166
167
    /// The function state accessed via FunctionContext::Get/SetFunctionState()
168
    std::shared_ptr<void> _thread_local_fn_state;
169
    std::shared_ptr<void> _fragment_local_fn_state;
170
171
    // Type descriptor for the return type of the function.
172
    doris::TypeDescriptor _return_type;
173
174
    // Type descriptors for each argument of the function.
175
    std::vector<doris::TypeDescriptor> _arg_types;
176
177
    std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> _constant_cols;
178
179
    bool _check_overflow_for_decimal = false;
180
181
    bool _string_as_jsonb_string = false;
182
    bool _jsonb_string_as_string = false;
183
184
    std::string _string_result;
185
186
    vectorized::Arena arena;
187
};
188
189
using doris::FunctionContext;
190
} // namespace doris