OmniSciDB  bf83d84833
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExtensionFunctionsBinding.cpp File Reference
#include "ExtensionFunctionsBinding.h"
#include <algorithm>
#include "ExternalExecutor.h"
+ Include dependency graph for ExtensionFunctionsBinding.cpp:

Go to the source code of this file.

Namespaces

 anonymous_namespace{ExtensionFunctionsBinding.cpp}
 

Functions

ExtArgumentType anonymous_namespace{ExtensionFunctionsBinding.cpp}::get_column_arg_elem_type (const ExtArgumentType ext_arg_column_type)
 
ExtArgumentType anonymous_namespace{ExtensionFunctionsBinding.cpp}::get_array_arg_elem_type (const ExtArgumentType ext_arg_array_type)
 
static int anonymous_namespace{ExtensionFunctionsBinding.cpp}::match_arguments (const SQLTypeInfo &arg_type, int sig_pos, const std::vector< ExtArgumentType > &sig_types, int &penalty_score)
 
bool anonymous_namespace{ExtensionFunctionsBinding.cpp}::is_valid_identifier (std::string str)
 
template<typename T >
bind_function (std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< T > &ext_funcs, const std::string processor)
 
const
table_functions::TableFunction 
bind_table_function (std::string name, Analyzer::ExpressionPtrVector input_args, const std::vector< table_functions::TableFunction > &table_funcs, const bool is_gpu)
 
ExtensionFunction bind_function (std::string name, Analyzer::ExpressionPtrVector func_args)
 
ExtensionFunction bind_function (std::string name, Analyzer::ExpressionPtrVector func_args, const bool is_gpu)
 
ExtensionFunction bind_function (const Analyzer::FunctionOper *function_oper, const bool is_gpu)
 
const
table_functions::TableFunction 
bind_table_function (std::string name, Analyzer::ExpressionPtrVector input_args, const bool is_gpu)
 
bool is_ext_arg_type_array (const ExtArgumentType ext_arg_type)
 
bool is_ext_arg_type_column (const ExtArgumentType ext_arg_type)
 
bool is_ext_arg_type_geo (const ExtArgumentType ext_arg_type)
 
bool is_ext_arg_type_pointer (const ExtArgumentType ext_arg_type)
 
bool is_ext_arg_type_scalar (const ExtArgumentType ext_arg_type)
 

Function Documentation

template<typename T >
T bind_function ( std::string  name,
Analyzer::ExpressionPtrVector  func_args,
const std::vector< T > &  ext_funcs,
const std::string  processor 
)

Definition at line 365 of file ExtensionFunctionsBinding.cpp.

References ext_arg_type_to_type_info(), logger::FATAL, anonymous_namespace{ExtensionFunctionsBinding.cpp}::is_valid_identifier(), kCOLUMN, kENCODING_NONE, LOG, anonymous_namespace{ExtensionFunctionsBinding.cpp}::match_arguments(), setup::name, omnisci.dtypes::T, and ExtensionFunctionsWhitelist::toString().

Referenced by bind_function(), CodeGenerator::codegenFunctionOper(), and RelAlgTranslator::translateFunction().

368  {
369  /* worker function
370 
371  Template type T must implement the following methods:
372 
373  std::vector<ExtArgumentType> getInputArgs()
374  */
375  /*
376  Return extension function/table function that has the following
377  properties
378 
379  1. each argument type in `arg_types` matches with extension
380  function argument types.
381 
382  For scalar types, the matching means that the types are either
383  equal or the argument type is smaller than the corresponding
384  the extension function argument type. This ensures that no
385  information is lost when casting of argument values is
386  required.
387 
388  For array and geo types, the matching means that the argument
389  type matches exactly with a group of extension function
390  argument types. See `match_arguments`.
391 
392  2. has minimal penalty score among all implementations of the
393  extension function with given `name`, see `get_penalty_score`
394  for the definition of penalty score.
395 
396  It is assumed that function_oper and extension functions in
397  ext_funcs have the same name.
398  */
399 
400  if (!is_valid_identifier(name)) {
401  throw NativeExecutionError(
402  "Cannot bind function with invalid UDF/UDTF function name: " + name);
403  }
404 
405  int minimal_score = std::numeric_limits<int>::max();
406  int index = -1;
407  int optimal = -1;
408 
409  std::vector<SQLTypeInfo> type_infos;
410  for (auto atype : func_args) {
411  if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
412  if (dynamic_cast<const Analyzer::ColumnVar*>(atype.get())) {
413  auto ti = SQLTypeInfo(
414  kCOLUMN, 0, 0, false, kENCODING_NONE, 0, atype->get_type_info().get_type());
415  type_infos.push_back(ti);
416  continue;
417  }
418  }
419  type_infos.push_back(atype->get_type_info());
420  }
421 
422  for (auto ext_func : ext_funcs) {
423  index++;
424  auto ext_func_args = ext_func.getInputArgs();
425  /* In general, `arg_types.size() <= ext_func_args.size()` because
426  non-scalar arguments (such as arrays and geo-objects) are
427  mapped to multiple `ext_func` arguments. */
428  if (func_args.size() <= ext_func_args.size()) {
429  /* argument type must fit into the corresponding signature
430  argument type, reject signature if not */
431  int penalty_score = 0;
432  int pos = 0;
433  for (auto ti : type_infos) {
434  int offset = match_arguments(ti, pos, ext_func_args, penalty_score);
435  if (offset < 0) {
436  // atype does not match with ext_func argument
437  pos = -1;
438  break;
439  }
440  pos += offset;
441  }
442  if (pos >= 0) {
443  // prefer smaller return types
444  penalty_score += ext_arg_type_to_type_info(ext_func.getRet()).get_logical_size();
445  if (penalty_score < minimal_score) {
446  optimal = index;
447  minimal_score = penalty_score;
448  }
449  }
450  }
451  }
452 
453  if (optimal == -1) {
454  /* no extension function found that argument types would match
455  with types in `arg_types` */
456  auto sarg_types = ExtensionFunctionsWhitelist::toString(type_infos);
457  std::string message;
458  if (!ext_funcs.size()) {
459  message = "Function " + name + "(" + sarg_types + ") not supported.";
460  throw ExtensionFunctionBindingError(message);
461  } else {
462  if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
463  message = "Could not bind " + name + "(" + sarg_types + ") to any " + processor +
464  " UDTF implementation.";
465  } else if constexpr (std::is_same_v<T, ExtensionFunction>) {
466  message = "Could not bind " + name + "(" + sarg_types + ") to any " + processor +
467  " UDF implementation.";
468  } else {
469  LOG(FATAL) << "bind_function: unknown extension function type "
470  << typeid(T).name();
471  }
472  message += "\n Existing extension function implementations:";
473  for (const auto& ext_func : ext_funcs) {
474  message += "\n " + ext_func.toStringSQL();
475  }
476  }
477  throw ExtensionFunctionBindingError(message);
478  }
479  return ext_funcs[optimal];
480 }
#define LOG(tag)
Definition: Logger.h:188
static std::string toString(const std::vector< ExtensionFunction > &ext_funcs, std::string tab="")
static int match_arguments(const SQLTypeInfo &arg_type, int sig_pos, const std::vector< ExtArgumentType > &sig_types, int &penalty_score)
string name
Definition: setup.py:35
SQLTypeInfo ext_arg_type_to_type_info(const ExtArgumentType ext_arg_type)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExtensionFunction bind_function ( std::string  name,
Analyzer::ExpressionPtrVector  func_args 
)

Definition at line 492 of file ExtensionFunctionsBinding.cpp.

References ExtensionFunctionsWhitelist::get_ext_funcs(), and setup::name.

493  {
494  // used in RelAlgTranslator.cpp, first try GPU UDFs, then fall back
495  // to CPU UDFs.
496  bool is_gpu = true;
497  std::string processor = "GPU";
498  auto ext_funcs = ExtensionFunctionsWhitelist::get_ext_funcs(name, is_gpu);
499  if (!ext_funcs.size()) {
500  is_gpu = false;
501  processor = "CPU";
503  }
504  try {
505  return bind_function<ExtensionFunction>(name, func_args, ext_funcs, processor);
506  } catch (ExtensionFunctionBindingError& e) {
507  if (is_gpu) {
508  is_gpu = false;
509  processor = "GPU|CPU";
511  return bind_function<ExtensionFunction>(name, func_args, ext_funcs, processor);
512  } else {
513  throw;
514  }
515  }
516 }
static std::vector< ExtensionFunction > get_ext_funcs(const std::string &name, const bool is_gpu)
string name
Definition: setup.py:35

+ Here is the call graph for this function:

ExtensionFunction bind_function ( std::string  name,
Analyzer::ExpressionPtrVector  func_args,
const bool  is_gpu 
)

Definition at line 518 of file ExtensionFunctionsBinding.cpp.

References ExtensionFunctionsWhitelist::get_ext_funcs(), and setup::name.

520  {
521  // used below
522  std::vector<ExtensionFunction> ext_funcs =
524  std::string processor = (is_gpu ? "GPU" : "CPU");
525  return bind_function<ExtensionFunction>(name, func_args, ext_funcs, processor);
526 }
static std::vector< ExtensionFunction > get_ext_funcs(const std::string &name, const bool is_gpu)
string name
Definition: setup.py:35

+ Here is the call graph for this function:

ExtensionFunction bind_function ( const Analyzer::FunctionOper function_oper,
const bool  is_gpu 
)

Definition at line 528 of file ExtensionFunctionsBinding.cpp.

References bind_function(), Analyzer::FunctionOper::getArity(), Analyzer::FunctionOper::getName(), Analyzer::FunctionOper::getOwnArg(), and setup::name.

529  {
530  // used in ExtensionsIR.cpp
531  auto name = function_oper->getName();
532  Analyzer::ExpressionPtrVector func_args = {};
533  for (size_t i = 0; i < function_oper->getArity(); ++i) {
534  func_args.push_back(function_oper->getOwnArg(i));
535  }
536  return bind_function(name, func_args, is_gpu);
537 }
size_t getArity() const
Definition: Analyzer.h:1360
std::shared_ptr< Analyzer::Expr > getOwnArg(const size_t i) const
Definition: Analyzer.h:1367
T bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< T > &ext_funcs, const std::string processor)
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:182
std::string getName() const
Definition: Analyzer.h:1358
string name
Definition: setup.py:35

+ Here is the call graph for this function:

const table_functions::TableFunction bind_table_function ( std::string  name,
Analyzer::ExpressionPtrVector  input_args,
const std::vector< table_functions::TableFunction > &  table_funcs,
const bool  is_gpu 
)

Definition at line 482 of file ExtensionFunctionsBinding.cpp.

References setup::name.

Referenced by bind_table_function(), and RelAlgExecutor::createTableFunctionWorkUnit().

486  {
487  std::string processor = (is_gpu ? "GPU" : "CPU");
488  return bind_function<table_functions::TableFunction>(
489  name, input_args, table_funcs, processor);
490 }
string name
Definition: setup.py:35

+ Here is the caller graph for this function:

const table_functions::TableFunction bind_table_function ( std::string  name,
Analyzer::ExpressionPtrVector  input_args,
const bool  is_gpu 
)

Definition at line 539 of file ExtensionFunctionsBinding.cpp.

References bind_table_function(), and table_functions::TableFunctionsFactory::get_table_funcs().

542  {
543  // used in RelAlgExecutor.cpp
544  std::vector<table_functions::TableFunction> table_funcs =
546  return bind_table_function(name, input_args, table_funcs, is_gpu);
547 }
const table_functions::TableFunction bind_table_function(std::string name, Analyzer::ExpressionPtrVector input_args, const std::vector< table_functions::TableFunction > &table_funcs, const bool is_gpu)
static std::vector< TableFunction > get_table_funcs(const std::string &name, const bool is_gpu)
string name
Definition: setup.py:35

+ Here is the call graph for this function:

bool is_ext_arg_type_array ( const ExtArgumentType  ext_arg_type)

Definition at line 549 of file ExtensionFunctionsBinding.cpp.

References ArrayBool, ArrayDouble, ArrayFloat, ArrayInt16, ArrayInt32, ArrayInt64, and ArrayInt8.

Referenced by CodeGenerator::codegenFunctionOperCastArgs(), ExtensionFunctionsWhitelist::getLLVMDeclarations(), and anonymous_namespace{ExtensionFunctionsBinding.cpp}::match_arguments().

+ Here is the caller graph for this function:

bool is_ext_arg_type_column ( const ExtArgumentType  ext_arg_type)

Definition at line 565 of file ExtensionFunctionsBinding.cpp.

References ColumnBool, ColumnDouble, ColumnFloat, ColumnInt16, ColumnInt32, ColumnInt64, and ColumnInt8.

Referenced by anonymous_namespace{ExtensionFunctionsBinding.cpp}::match_arguments().

+ Here is the caller graph for this function:

bool is_ext_arg_type_geo ( const ExtArgumentType  ext_arg_type)

Definition at line 581 of file ExtensionFunctionsBinding.cpp.

References GeoLineString, GeoMultiPolygon, GeoPoint, and GeoPolygon.

Referenced by CodeGenerator::codegenFunctionOperCastArgs().

581  {
582  switch (ext_arg_type) {
587  return true;
588 
589  default:
590  return false;
591  }
592 }

+ Here is the caller graph for this function:

bool is_ext_arg_type_pointer ( const ExtArgumentType  ext_arg_type)

Definition at line 594 of file ExtensionFunctionsBinding.cpp.

References PBool, PDouble, PFloat, PInt16, PInt32, PInt64, and PInt8.

Referenced by CodeGenerator::codegenFunctionOperCastArgs().

+ Here is the caller graph for this function:

bool is_ext_arg_type_scalar ( const ExtArgumentType  ext_arg_type)

Definition at line 610 of file ExtensionFunctionsBinding.cpp.

References Bool, Double, Float, Int16, Int32, Int64, and Int8.

610  {
611  switch (ext_arg_type) {
619  return true;
620 
621  default:
622  return false;
623  }
624 }