OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExtensionFunctionsBinding.cpp File Reference
#include "ExtensionFunctionsBinding.h"
#include "ExternalExecutor.h"
#include <algorithm>
+ 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_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)
 
ExtensionFunction bind_function (std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< ExtensionFunction > &ext_funcs)
 
ExtensionFunction bind_function (std::string name, Analyzer::ExpressionPtrVector func_args)
 
ExtensionFunction bind_function (const Analyzer::FunctionOper *function_oper)
 
bool is_ext_arg_type_array (const ExtArgumentType ext_arg_type)
 
bool is_ext_arg_type_geo (const ExtArgumentType ext_arg_type)
 

Function Documentation

ExtensionFunction bind_function ( std::string  name,
Analyzer::ExpressionPtrVector  func_args,
const std::vector< ExtensionFunction > &  ext_funcs 
)

Definition at line 295 of file ExtensionFunctionsBinding.cpp.

References ext_arg_type_to_type_info(), anonymous_namespace{ExtensionFunctionsBinding.cpp}::match_arguments(), and ExtensionFunctionsWhitelist::toString().

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

297  {
298  // worker function
299  /*
300  Return extension function that has the following properties
301 
302  1. each argument type in `arg_types` matches with extension
303  function argument types.
304 
305  For scalar types, the matching means that the types are either
306  equal or the argument type is smaller than the corresponding
307  the extension function argument type. This ensures that no
308  information is lost when casting of argument values is
309  required.
310 
311  For array and geo types, the matching means that the argument
312  type matches exactly with a group of extension function
313  argument types. See `match_arguments`.
314 
315  2. has minimal penalty score among all implementations of the
316  extension function with given `name`, see `get_penalty_score`
317  for the definition of penalty score.
318 
319  It is assumed that function_oper and extension functions in
320  ext_funcs have the same name.
321  */
322  int minimal_score = std::numeric_limits<int>::max();
323  int index = -1;
324  int optimal = -1;
325  for (auto ext_func : ext_funcs) {
326  index++;
327  auto ext_func_args = ext_func.getArgs();
328  /* In general, `arg_types.size() <= ext_func_args.size()` because
329  non-scalar arguments (such as arrays and geo-objects) are
330  mapped to multiple `ext_func` arguments. */
331  if (func_args.size() <= ext_func_args.size()) {
332  /* argument type must fit into the corresponding signature
333  argument type, reject signature if not */
334  int penalty_score = 0;
335  int pos = 0;
336  for (auto atype : func_args) {
337  int offset =
338  match_arguments(atype->get_type_info(), pos, ext_func_args, penalty_score);
339  if (offset < 0) {
340  // atype does not match with ext_func argument
341  pos = -1;
342  break;
343  }
344  pos += offset;
345  }
346  if (pos >= 0) {
347  // prefer smaller return types
348  penalty_score += ext_arg_type_to_type_info(ext_func.getRet()).get_logical_size();
349  if (penalty_score < minimal_score) {
350  optimal = index;
351  minimal_score = penalty_score;
352  }
353  }
354  }
355  }
356 
357  if (optimal == -1) {
358  /* no extension function found that argument types would match
359  with types in `arg_types` */
360  std::vector<SQLTypeInfo> arg_types;
361  for (size_t i = 0; i < func_args.size(); ++i) {
362  arg_types.push_back(func_args[i]->get_type_info());
363  }
364  auto sarg_types = ExtensionFunctionsWhitelist::toString(arg_types);
365  if (!ext_funcs.size()) {
366  throw NativeExecutionError("Function " + name + "(" + sarg_types +
367  ") not supported.");
368  }
369  auto choices = ExtensionFunctionsWhitelist::toString(ext_funcs, " ");
370  throw std::runtime_error(
371  "Function " + name + "(" + sarg_types +
372  ") not supported.\n Existing extension function implementations:\n" + choices);
373  }
374  return ext_funcs[optimal];
375 }
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)
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 377 of file ExtensionFunctionsBinding.cpp.

References bind_function(), and ExtensionFunctionsWhitelist::get_ext_funcs().

378  {
379  // used in RelAlgTranslator.cpp
380  std::vector<ExtensionFunction> ext_funcs =
382  return bind_function(name, func_args, ext_funcs);
383 }
static std::vector< ExtensionFunction > get_ext_funcs(const std::string &name)
ExtensionFunction bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< ExtensionFunction > &ext_funcs)

+ Here is the call graph for this function:

ExtensionFunction bind_function ( const Analyzer::FunctionOper function_oper)

Definition at line 385 of file ExtensionFunctionsBinding.cpp.

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

385  {
386  // used in ExtensionIR.cpp
387  auto name = function_oper->getName();
388  Analyzer::ExpressionPtrVector func_args = {};
389  for (size_t i = 0; i < function_oper->getArity(); ++i) {
390  func_args.push_back(function_oper->getOwnArg(i));
391  }
392  return bind_function(name, func_args);
393 }
size_t getArity() const
Definition: Analyzer.h:1361
ExtensionFunction bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< ExtensionFunction > &ext_funcs)
std::shared_ptr< Analyzer::Expr > getOwnArg(const size_t i) const
Definition: Analyzer.h:1368
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:183
std::string getName() const
Definition: Analyzer.h:1359

+ Here is the call graph for this function:

bool is_ext_arg_type_array ( const ExtArgumentType  ext_arg_type)

Definition at line 395 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_geo ( const ExtArgumentType  ext_arg_type)

Definition at line 411 of file ExtensionFunctionsBinding.cpp.

References GeoLineString, GeoMultiPolygon, GeoPoint, and GeoPolygon.

Referenced by CodeGenerator::codegenFunctionOperCastArgs().

411  {
412  switch (ext_arg_type) {
417  return true;
418 
419  default:
420  return false;
421  }
422 }

+ Here is the caller graph for this function: