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

Go to the source code of this file.

Namespaces

 anonymous_namespace{ExtensionFunctionsBinding.cpp}
 

Functions

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 254 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().

256  {
257  // worker function
258  /*
259  Return extension function that has the following properties
260 
261  1. each argument type in `arg_types` matches with extension
262  function argument types.
263 
264  For scalar types, the matching means that the types are either
265  equal or the argument type is smaller than the corresponding
266  the extension function argument type. This ensures that no
267  information is lost when casting of argument values is
268  required.
269 
270  For array and geo types, the matching means that the argument
271  type matches exactly with a group of extension function
272  argument types. See `match_arguments`.
273 
274  2. has minimal penalty score among all implementations of the
275  extension function with given `name`, see `get_penalty_score`
276  for the definition of penalty score.
277 
278  It is assumed that function_oper and extension functions in
279  ext_funcs have the same name.
280  */
281  int minimal_score = std::numeric_limits<int>::max();
282  int index = -1;
283  int optimal = -1;
284  for (auto ext_func : ext_funcs) {
285  index++;
286  auto ext_func_args = ext_func.getArgs();
287  /* In general, `arg_types.size() <= ext_func_args.size()` because
288  non-scalar arguments (such as arrays and geo-objects) are
289  mapped to multiple `ext_func` arguments. */
290  if (func_args.size() <= ext_func_args.size()) {
291  /* argument type must fit into the corresponding signature
292  argument type, reject signature if not */
293  int penalty_score = 0;
294  int pos = 0;
295  for (auto atype : func_args) {
296  int offset =
297  match_arguments(atype->get_type_info(), pos, ext_func_args, penalty_score);
298  if (offset < 0) {
299  // atype does not match with ext_func argument
300  pos = -1;
301  break;
302  }
303  pos += offset;
304  }
305  if (pos >= 0) {
306  // prefer smaller return types
307  penalty_score += ext_arg_type_to_type_info(ext_func.getRet()).get_logical_size();
308  if (penalty_score < minimal_score) {
309  optimal = index;
310  minimal_score = penalty_score;
311  }
312  }
313  }
314  }
315 
316  if (optimal == -1) {
317  /* no extension function found that argument types would match
318  with types in `arg_types` */
319  std::vector<SQLTypeInfo> arg_types;
320  for (size_t i = 0; i < func_args.size(); ++i) {
321  arg_types.push_back(func_args[i]->get_type_info());
322  }
323  auto sarg_types = ExtensionFunctionsWhitelist::toString(arg_types);
324  if (!ext_funcs.size()) {
325  throw std::runtime_error("Function " + name + "(" + sarg_types +
326  ") not supported.");
327  }
328  auto choices = ExtensionFunctionsWhitelist::toString(ext_funcs, " ");
329  throw std::runtime_error(
330  "Function " + name + "(" + sarg_types +
331  ") not supported.\n Existing extension function implementations:\n" + choices);
332  }
333  return ext_funcs[optimal];
334 }
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 336 of file ExtensionFunctionsBinding.cpp.

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

337  {
338  // used in RelAlgTranslator.cpp
339  std::vector<ExtensionFunction> ext_funcs =
341  return bind_function(name, func_args, ext_funcs);
342 }
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 344 of file ExtensionFunctionsBinding.cpp.

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

344  {
345  // used in ExtensionIR.cpp
346  auto name = function_oper->getName();
347  Analyzer::ExpressionPtrVector func_args = {};
348  for (size_t i = 0; i < function_oper->getArity(); ++i) {
349  func_args.push_back(function_oper->getOwnArg(i));
350  }
351  return bind_function(name, func_args);
352 }
size_t getArity() const
Definition: Analyzer.h:1309
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:1316
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:182
std::string getName() const
Definition: Analyzer.h:1307

+ Here is the call graph for this function:

bool is_ext_arg_type_array ( const ExtArgumentType  ext_arg_type)

Definition at line 354 of file ExtensionFunctionsBinding.cpp.

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

Referenced by CodeGenerator::codegenFunctionOperCastArgs(), 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 369 of file ExtensionFunctionsBinding.cpp.

References GeoLineString, GeoPoint, and GeoPolygon.

Referenced by CodeGenerator::codegenFunctionOperCastArgs().

369  {
370  switch (ext_arg_type) {
374  return true;
375 
376  default:
377  return false;
378  }
379 }

+ Here is the caller graph for this function: