19 #include <boost/algorithm/string.hpp>
21 #include <unordered_set>
26 namespace table_functions {
31 switch (ext_arg_type) {
54 switch (ext_arg_type) {
90 int32_t scalar_args = 0;
106 if (ann.find(
"require") != ann.end()) {
114 const size_t idx)
const {
117 static const std::map<std::string, std::string> empty = {};
124 const size_t input_arg_idx)
const {
130 const std::string& key,
131 const std::string& default_)
const {
133 const auto& it = ann.find(key);
134 if (it != ann.end()) {
141 const size_t output_arg_idx)
const {
147 const std::string& key,
148 const std::string& default_)
const {
150 const auto& it = ann.find(key);
151 if (it != ann.end()) {
162 const std::string& key,
163 const std::string& default_)
const {
165 const auto& it = ann.find(key);
166 if (it != ann.end()) {
173 const size_t sql_idx)
const {
174 std::vector<std::string> fields;
177 static const std::vector<std::string> empty = {};
180 std::string substr = line.substr(1, line.size() - 2);
181 boost::split(fields, substr, boost::is_any_of(
", "), boost::token_compress_on);
186 if (use_input_args) {
187 std::vector<std::string> arg_types;
189 for (
size_t sql_idx = 0; sql_idx <
sql_args_.size(); sql_idx++) {
190 const std::vector<std::string> cursor_fields =
getCursorFields(sql_idx);
191 if (cursor_fields.empty()) {
193 arg_types.emplace_back(
196 std::vector<std::string> vec;
197 for (
size_t i = 0; i < cursor_fields.size(); i++) {
210 std::vector<std::string> names;
211 if (use_input_args) {
212 for (
size_t idx = 0; idx <
sql_args_.size(); idx++) {
214 if (cursor_fields.empty()) {
216 names.emplace_back(name);
222 for (
size_t idx = 0; idx <
output_args_.size(); idx++) {
224 names.emplace_back(name);
233 #define PREFIX_LENGTH 5
235 auto annot = annotation.find(
"input_id");
236 if (annot == annotation.end()) {
243 return std::make_pair(lo, 0);
251 const std::string& input_id = annot->second;
253 if (input_id ==
"args<-1>") {
258 size_t comma = input_id.find(
",");
259 int32_t gt = input_id.size() - 1;
260 int32_t lo = std::stoi(input_id.substr(
PREFIX_LENGTH, comma - 1));
262 if (comma == std::string::npos) {
263 return std::make_pair(lo, 0);
265 int32_t hi = std::stoi(input_id.substr(comma + 1, gt - comma - 1));
266 return std::make_pair(lo, hi);
284 int32_t ext_arg_index = 0, sql_arg_index = 0;
291 while ((
size_t)ext_arg_index < sizer) {
292 if ((
size_t)ext_arg_index == sizer - 1)
293 return sql_arg_index;
296 const auto& sql_arg =
sql_args_[sql_arg_index];
298 if (same_kind(ext_arg, sql_arg)) {
316 static const std::unordered_set<std::string> whitelisted_table_functions = {
318 "generate_random_strings",
320 "tf_mandelbrot_float",
321 "tf_mandelbrot_cuda",
322 "tf_mandelbrot_cuda_float",
324 "tf_geo_rasterize_slope",
325 "tf_compute_dwell_times",
326 "tf_feature_similarity",
327 "tf_feature_self_similarity",
328 "tf_graph_shortest_path",
329 "tf_graph_shortest_paths_distances",
330 "tf_raster_graph_shortest_slope_weighted_path",
331 "supported_ml_frameworks",
335 "linear_reg_predict",
336 "linear_reg_fit_predict",
337 "tf_point_cloud_metadata",
338 "tf_load_point_cloud"
339 #ifdef HAVE_OMNIVERSE_CONNECTOR
341 "tf_export_ov_terrain_texture",
342 "tf_export_ov_buildings_texture",
343 "tf_export_ov_polygons_2d",
344 "tf_export_ov_polygons_3d",
345 "tf_export_ov_grid_mesh"
349 return whitelisted_table_functions.find(function_name) !=
350 whitelisted_table_functions.end();
354 const std::string&
name,
356 const std::vector<ExtArgumentType>& input_args,
357 const std::vector<ExtArgumentType>& output_args,
358 const std::vector<ExtArgumentType>& sql_args,
359 const std::vector<std::map<std::string, std::string>>& annotations,
361 static const std::map<std::string, std::string> empty = {};
363 auto func_annotations =
364 (annotations.size() == sql_args.size() + output_args.size() + 1 ? annotations.back()
366 auto mgr_annotation = func_annotations.find(
"uses_manager");
367 bool uses_manager = mgr_annotation != func_annotations.end() &&
368 boost::algorithm::to_lower_copy(mgr_annotation->second) ==
"true";
378 const auto tf_name = tf.getName(
true ,
true );
383 auto sig = tf.getSignature(
true,
false);
385 if (it->second.getName() ==
name) {
386 if (it->second.isRuntime()) {
388 <<
"Overriding existing run-time table function (reset not called?): "
392 throw std::runtime_error(
"Will not override existing load-time table function: " +
396 if (sig == it->second.getSignature(
true,
398 ((tf.isCPU() && it->second.isCPU()) || (tf.isGPU() && it->second.isGPU()))) {
400 <<
"The existing (1) and added (2) table functions have the same signature `"
402 <<
" 1: " << it->second.toString() <<
"\n 2: " << tf.toString() <<
"\n";
410 auto input_args2 = input_args;
411 input_args2.erase(input_args2.begin() + sizer.
val - 1);
413 auto sql_args2 = sql_args;
414 auto sql_sizer_pos = tf.getSqlOutputRowSizeParameter();
415 sql_args2.erase(sql_args2.begin() + sql_sizer_pos);
417 auto annotations2 = annotations;
418 annotations2.erase(annotations2.begin() + sql_sizer_pos);
428 auto sig = tf2.getSignature(
true,
false);
430 if (sig == it->second.getSignature(
true,
432 ((tf2.isCPU() && it->second.isCPU()) || (tf2.isGPU() && it->second.isGPU()))) {
434 <<
"The existing (1) and added (2) table functions have the same signature `"
436 <<
" 1: " << it->second.toString() <<
"\n 2: " << tf2.toString() <<
"\n";
455 if (it->second.isRuntime()) {
466 const auto idx = str.find(
"__");
467 if (idx == std::string::npos) {
470 CHECK_GT(idx, std::string::size_type(0));
471 return str.substr(0, idx);
488 const bool include_output)
const {
495 std::vector<std::string>
args;
496 for (
size_t sql_idx = 0; sql_idx <
sql_args_.size(); sql_idx++) {
497 const std::vector<std::string> cursor_fields =
getCursorFields(sql_idx);
498 if (cursor_fields.empty()) {
503 std::vector<std::string> vec;
504 for (
size_t i = 0; i < cursor_fields.size(); i++) {
506 const auto&
name = cursor_fields[i];
513 if (include_output) {
526 std::vector<TableFunction> table_funcs;
528 if (is_gpu ? tf.isGPU() : tf.isCPU()) {
529 table_funcs.emplace_back(tf);
536 const std::string&
name) {
537 std::vector<TableFunction> table_funcs;
538 auto table_func_name =
name;
542 if (fname == table_func_name) {
543 table_funcs.push_back(pair.second);
550 std::vector<TableFunction> table_funcs;
552 if (pair.second.isRuntime() == is_runtime) {
553 table_funcs.push_back(pair.second);
560 std::vector<TableFunction> table_funcs;
562 table_funcs.push_back(pair.second);
SQLTypeInfo getOutputSQLType(const size_t idx) const
const std::string getOutputAnnotation(const size_t output_arg_idx, const std::string &key, const std::string &default_) const
std::string drop_suffix(const std::string &str)
static std::vector< TableFunction > get_table_funcs()
bool is_ext_arg_type_scalar(const ExtArgumentType ext_arg_type)
static void add(const std::string &name, const TableFunctionOutputRowSizer sizer, const std::vector< ExtArgumentType > &input_args, const std::vector< ExtArgumentType > &output_args, const std::vector< ExtArgumentType > &sql_args, const std::vector< std::map< std::string, std::string >> &annotations, bool is_runtime=false)
bool hasUserSpecifiedOutputSizeMultiplier() const
SQLTypeInfo ext_arg_pointer_type_to_type_info(const ExtArgumentType ext_arg_type)
size_t getSqlOutputRowSizeParameter() const
SQLTypeInfo ext_arg_type_to_type_info_output(const ExtArgumentType ext_arg_type)
const std::map< std::string, std::string > getFunctionAnnotations() const
const std::vector< std::map< std::string, std::string > > annotations_
const std::vector< ExtArgumentType > output_args_
#define DEFAULT_ROW_MULTIPLIER_SUFFIX
std::pair< int32_t, int32_t > getInputID(const size_t idx) const
const std::string getFunctionAnnotation(const std::string &key, const std::string &default_) const
size_t getOutputRowSizeParameter() const
std::string getSignature(const bool include_name, const bool include_output) const
bool containsPreFlightFn() const
bool is_ext_arg_type_nonscalar(const ExtArgumentType ext_arg_type)
const std::vector< ExtArgumentType > sql_args_
SQLTypeInfo getInputSQLType(const size_t idx) const
const std::string getArgNames(const bool use_input_args) const
std::string drop_suffix_impl(const std::string &str)
int32_t countScalarArgs() const
std::string getPreFlightFnName() const
const std::map< std::string, std::string > getOutputAnnotations(const size_t output_arg_idx) const
const std::string getInputAnnotation(const size_t input_arg_idx, const std::string &key, const std::string &default_) const
bool g_enable_dev_table_functions
std::string getName(const bool drop_suffix=false, const bool lower=false) const
const std::string getArgTypes(const bool use_input_args) const
bool hasPreFlightOutputSizer() const
const std::vector< std::string > getCursorFields(const size_t sql_idx) const
const std::map< std::string, std::string > getInputAnnotations(const size_t input_arg_idx) const
static std::string toString(const std::vector< ExtensionFunction > &ext_funcs, std::string tab="")
bool is_table_function_whitelisted(const std::string &function_name)
OutputBufferSizeType type
static std::unordered_map< std::string, TableFunction > functions_
const std::vector< ExtArgumentType > input_args_
SQLTypeInfo get_elem_type() const
SQLTypeInfo ext_arg_type_to_type_info(const ExtArgumentType ext_arg_type)
bool g_enable_table_functions
const std::vector< std::map< std::string, std::string > > & getAnnotations() const