552 "Cannot bind function with invalid UDF/UDTF function name: " +
name);
555 int minimal_score = std::numeric_limits<int>::max();
558 int optimal_variant = -1;
560 std::vector<SQLTypeInfo> type_infos_input;
561 std::vector<bool> args_are_constants;
562 for (
auto atype : func_args) {
563 if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
564 if (dynamic_cast<const Analyzer::ColumnVar*>(atype.get())) {
567 if (ti.get_subtype() ==
kNULLT) {
568 throw std::runtime_error(std::string(__FILE__) +
"#" +
570 ": column support for type info " +
571 type_info.
to_string() +
" is not implemented");
573 type_infos_input.push_back(ti);
578 type_infos_input.push_back(atype->get_type_info());
579 if (dynamic_cast<const Analyzer::Constant*>(atype.get())) {
580 args_are_constants.push_back(
true);
582 args_are_constants.push_back(
false);
585 CHECK_EQ(type_infos_input.size(), args_are_constants.size());
587 if (type_infos_input.size() == 0 && ext_funcs.size() > 0) {
588 CHECK_EQ(ext_funcs.size(),
static_cast<size_t>(1));
589 CHECK_EQ(ext_funcs[0].getInputArgs().size(), static_cast<size_t>(0));
590 if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
591 CHECK(ext_funcs[0].hasNonUserSpecifiedOutputSize());
593 std::vector<SQLTypeInfo> empty_type_info_variant(0);
594 return {ext_funcs[0], empty_type_info_variant};
652 bool ext_funcs_allow_column_lists{
false};
653 for (
const auto& ext_func : ext_funcs) {
654 auto ext_func_args = ext_func.getInputArgs();
655 for (
const auto& arg : ext_func_args) {
657 ext_funcs_allow_column_lists =
true;
661 if (ext_funcs_allow_column_lists) {
666 std::vector<std::vector<SQLTypeInfo>> type_infos_variants;
667 if (ext_funcs_allow_column_lists) {
668 for (
const auto& ti : type_infos_input) {
669 if (type_infos_variants.begin() == type_infos_variants.end()) {
670 type_infos_variants.push_back({ti});
671 if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
672 if (ti.is_column()) {
674 if (mti.get_subtype() ==
kNULLT) {
677 mti.set_dimension(1);
678 type_infos_variants.push_back({mti});
683 std::vector<std::vector<SQLTypeInfo>> new_type_infos_variants;
684 for (
auto& type_infos : type_infos_variants) {
685 if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
686 if (ti.is_column()) {
687 auto new_type_infos = type_infos;
688 const auto& last = type_infos.back();
689 if (last.is_column_list() && last.has_same_itemtype(ti)) {
691 new_type_infos.back().set_dimension(last.get_dimension() + 1);
695 if (mti.get_subtype() ==
kNULLT) {
697 type_infos.push_back(ti);
700 mti.set_dimension(1);
701 new_type_infos.push_back(mti);
703 new_type_infos_variants.push_back(new_type_infos);
706 type_infos.push_back(ti);
708 type_infos_variants.insert(type_infos_variants.end(),
709 new_type_infos_variants.begin(),
710 new_type_infos_variants.end());
713 type_infos_variants.emplace_back(type_infos_input);
718 for (
const auto& ext_func : ext_funcs) {
721 const auto& ext_func_args = ext_func.getInputArgs();
722 int index_variant = -1;
723 for (
const auto& type_infos : type_infos_variants) {
725 int penalty_score = 0;
727 int original_input_idx = 0;
728 CHECK_LE(type_infos.size(), args_are_constants.size());
729 for (
const auto& ti : type_infos) {
731 args_are_constants[original_input_idx],
741 original_input_idx += ti.get_dimension();
743 original_input_idx++;
748 if ((
size_t)pos == ext_func_args.size()) {
749 CHECK_EQ(args_are_constants.size(), original_input_idx);
752 if (penalty_score < minimal_score) {
754 minimal_score = penalty_score;
755 optimal_variant = index_variant;
766 if (!ext_funcs.size()) {
767 message =
"Function " +
name +
"(" + sarg_types +
") not supported.";
770 if constexpr (std::is_same_v<T, table_functions::TableFunction>) {
771 message =
"Could not bind " +
name +
"(" + sarg_types +
") to any " + processor +
772 " UDTF implementation.";
773 }
else if constexpr (std::is_same_v<T, ExtensionFunction>) {
774 message =
"Could not bind " +
name +
"(" + sarg_types +
") to any " + processor +
775 " UDF implementation.";
777 LOG(
FATAL) <<
"bind_function: unknown extension function type "
780 message +=
"\n Existing extension function implementations:";
781 for (
const auto& ext_func : ext_funcs) {
783 if constexpr (std::is_same_v<T, table_functions::TableFunction>)
784 if (ext_func.useDefaultSizer())
786 message += "\
n " + ext_func.toStringSQL();
793 if constexpr (std::is_same_v<
T, table_functions::
TableFunction>) {
794 if (ext_funcs[optimal].hasUserSpecifiedOutputSizeMultiplier() &&
795 ext_funcs[optimal].useDefaultSizer()) {
796 std::string
name = ext_funcs[optimal].getName();
799 for (
size_t i = 0; i < ext_funcs.size(); i++) {
800 if (ext_funcs[i].getName() ==
name) {
802 std::vector<SQLTypeInfo> type_info = type_infos_variants[optimal_variant];
803 size_t sizer = ext_funcs[optimal].getOutputRowSizeParameter();
804 type_info.insert(type_info.begin() + sizer - 1,
SQLTypeInfo(
kINT,
true));
805 return {ext_funcs[optimal], type_info};
812 return {ext_funcs[optimal], type_infos_variants[optimal_variant]};
static int match_arguments(const SQLTypeInfo &arg_type, const bool is_arg_literal, int sig_pos, const std::vector< ExtArgumentType > &sig_types, int &penalty_score)
#define DEFAULT_ROW_MULTIPLIER_SUFFIX
HOST DEVICE SQLTypes get_type() const
std::string to_string() const
bool is_ext_arg_type_column_list(const ExtArgumentType ext_arg_type)
auto generate_column_type(const SQLTypeInfo &elem_ti)
auto generate_column_list_type(const SQLTypeInfo &elem_ti)
static std::string toString(const std::vector< ExtensionFunction > &ext_funcs, std::string tab="")
bool is_valid_identifier(std::string str)
SQLTypeInfo ext_arg_type_to_type_info(const ExtArgumentType ext_arg_type)