-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathfunction_context.h
More file actions
214 lines (161 loc) · 8.49 KB
/
Copy pathfunction_context.h
File metadata and controls
214 lines (161 loc) · 8.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <gen_cpp/Types_types.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "core/arena.h"
#include "runtime/runtime_profile.h"
namespace doris {
struct ColumnPtrWrapper;
struct StringRef;
class RuntimeState;
class IDataType;
using DataTypePtr = std::shared_ptr<const IDataType>;
// The FunctionContext is passed to every UDF/UDA and is the interface for UDF to
// rest of system. It contains APIs to examine system state, report errors
// and manage memory.
class FunctionContext {
public:
enum FunctionStateScope {
/// Indicates that function state for this FunctionContext's UDF is shared across
/// plan fragment (a query is divided into multiple plan fragments, each of which
/// is responsible for a part of query execution). Within plan fragment, there
/// may be multiple instances of UDF executing concurrently with multiple
/// FunctionContexts sharing this state, meaning that the state must be
/// thread-safe. The Prepare() function for UDF may be called with this scope
/// concurrently on a single host if UDF will be evaluated in multiple plan
/// fragments on that host. In general, read-only state that doesn't need to be
/// recomputed for every UDF call should be fragment-local.
/// TODO: not yet implemented
FRAGMENT_LOCAL,
/// Indicates that function state is local to execution thread. This state
/// does not need to be thread-safe. However, this state will be initialized (via the
/// Prepare() function) once for every execution thread, so fragment-local state
/// should be used when possible for better performance. In general, inexpensive
/// shared state that is written to by the UDF (e.g. scratch space) should be
/// thread-local.
THREAD_LOCAL,
};
static std::unique_ptr<doris::FunctionContext> create_context(
RuntimeState* state, const DataTypePtr& return_type,
const std::vector<DataTypePtr>& arg_types);
/// Returns a new FunctionContext with the same constant args, fragment-local state, and
/// debug flag as this FunctionContext. The caller is responsible for calling delete on
/// it.
std::unique_ptr<doris::FunctionContext> clone();
void set_constant_cols(const std::vector<std::shared_ptr<doris::ColumnPtrWrapper>>& cols);
RuntimeState* state() { return _state; }
void set_dict_function(const TDictFunction& dict_function) { _dict_function = dict_function; }
std::optional<TDictFunction>& dict_function() { return _dict_function; };
bool check_overflow_for_decimal() const { return _check_overflow_for_decimal; }
bool enable_strict_mode() const { return _enable_strict_mode; }
bool set_check_overflow_for_decimal(bool check_overflow_for_decimal) {
return _check_overflow_for_decimal = check_overflow_for_decimal;
}
bool set_enable_strict_mode(bool enable_strict_mode) {
return _enable_strict_mode = enable_strict_mode;
}
void set_string_as_jsonb_string(bool string_as_jsonb_string) {
_string_as_jsonb_string = string_as_jsonb_string;
}
void set_jsonb_string_as_string(bool jsonb_string_as_string) {
_jsonb_string_as_string = jsonb_string_as_string;
}
void set_udf_execute_timer(RuntimeProfile::Counter* udf_execute_timer) {
_udf_execute_timer = udf_execute_timer;
}
RuntimeProfile::Counter* get_udf_execute_timer() { return _udf_execute_timer; }
// Cast flag, when enable string_as_jsonb_string, string casting to jsonb will not parse string
// instead just insert a string literal
bool string_as_jsonb_string() const { return _string_as_jsonb_string; }
// Cast flag, when enable jsonb_string_as_string, jsonb string casting to string will not parse string
// instead just insert a string literal
bool jsonb_string_as_string() const { return _jsonb_string_as_string; }
// Sets an error for this UDF. If this is called, this will trigger a
// query to fail.
// Note: when you set an error for UDFs used in Data Load, you should
// ensure that the function return value is null.
void set_error(const char* error_msg);
// Adds a warning that is returned to the user. This can include things like
// overflow or other recoverable error conditions.
// Warnings are capped at a maximum number. Returns true if the warning was
// added and false if it was ignored due to the cap.
bool add_warning(const char* warning_msg);
/// Methods for maintaining state across UDF/UDA function calls. SetFunctionState() can
/// be used to store a pointer that can then be retrieved via GetFunctionState(). If
/// GetFunctionState() is called when no pointer is set, it will return
/// nullptr. SetFunctionState() does not take ownership of 'ptr'; it is up to the UDF/UDA
/// to clean up any function state if necessary.
void set_function_state(FunctionStateScope scope, std::shared_ptr<void> ptr);
void* get_function_state(FunctionStateScope scope) const;
// Returns the return type information of this function. For UDAs, this is the final
// return type of the UDA (e.g., the type returned by the finalize function).
const DataTypePtr get_return_type() const;
// Returns the number of arguments to this function (not including the FunctionContext*
// argument).
int get_num_args() const;
// Returns type information for the arg_idx-th argument (0-indexed, not including
// the FunctionContext* argument). Returns nullptr if arg_idx is invalid.
const DataTypePtr get_arg_type(int arg_idx) const;
// Returns true if the arg_idx-th input argument (0 indexed, not including
// the FunctionContext* argument) is a constant (e.g. 5, "string", 1 + 1).
bool is_col_constant(int arg_idx) const;
// Returns a pointer to the value of the arg_idx-th input argument (0 indexed, not
// including the FunctionContext* argument). Returns nullptr if the argument is not
// constant. This function can be used to obtain user-specified constants in a UDF's
// Init() or Close() functions.
doris::ColumnPtrWrapper* get_constant_col(int arg_idx) const;
// Creates a StringRef, which memory is available when this function context is used next time
StringRef create_temp_string_val(int64_t len);
~FunctionContext() = default;
Arena& get_arena() { return arena; }
private:
FunctionContext() = default;
// Disable copy ctor and assignment operator
FunctionContext(const FunctionContext& other);
FunctionContext& operator=(const FunctionContext& other);
// We use the query's runtime state to report errors and warnings. nullptr for test
// contexts.
RuntimeState* _state = nullptr;
// Empty if there's no error
std::string _error_msg;
// The number of warnings reported.
int64_t _num_warnings;
/// The function state accessed via FunctionContext::Get/SetFunctionState()
std::shared_ptr<void> _thread_local_fn_state;
std::shared_ptr<void> _fragment_local_fn_state;
// Type descriptor for the return type of the function.
DataTypePtr _return_type;
// Type descriptors for each argument of the function.
std::vector<DataTypePtr> _arg_types;
std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> _constant_cols;
// UDF execute timer
RuntimeProfile::Counter* _udf_execute_timer = nullptr;
bool _check_overflow_for_decimal = false;
bool _enable_strict_mode = false;
bool _string_as_jsonb_string = false;
bool _jsonb_string_as_string = false;
std::string _string_result;
Arena arena;
std::optional<TDictFunction> _dict_function;
};
using doris::FunctionContext;
} // namespace doris