MCPcopy Create free account
hub / github.com/duckdb/duckdb / BindMacroFunction

Method BindMacroFunction

src/function/macro_function.cpp:44–255  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

42}
43
44MacroBindResult MacroFunction::BindMacroFunction(
45 Binder &binder, const vector<unique_ptr<MacroFunction>> &functions, const string &name,
46 FunctionExpression &function_expr, vector<unique_ptr<ParsedExpression>> &positional_arguments,
47 InsertionOrderPreservingMap<unique_ptr<ParsedExpression>> &named_arguments, idx_t depth) {
48 ExpressionBinder expr_binder(binder, binder.context);
49 expr_binder.lambda_bindings = binder.lambda_bindings;
50
51 // Figure out whether we even need to bind arguments
52 bool requires_bind = false;
53 for (auto &function : functions) {
54 for (const auto &type : function->types) {
55 if (type.id() != LogicalTypeId::UNKNOWN) {
56 requires_bind = true;
57 break;
58 }
59 }
60 if (requires_bind) {
61 break;
62 }
63 }
64
65 // Find argument types and separate positional and default arguments
66 vector<LogicalType> positional_arg_types;
67 InsertionOrderPreservingMap<LogicalType> named_arg_types;
68 for (auto &arg : function_expr.children) {
69 auto arg_copy = arg->Copy();
70 LogicalType arg_type = LogicalType::UNKNOWN;
71 if (requires_bind) {
72 const auto arg_bind_result = expr_binder.BindExpression(arg_copy, depth + 1);
73 arg_type = arg_bind_result.HasError() ? LogicalType::UNKNOWN : arg_bind_result.expression->return_type;
74 }
75 if (!arg->GetAlias().empty()) {
76 // Default argument
77 if (named_arguments.find(arg->GetAlias()) != named_arguments.end()) {
78 return MacroBindResult(
79 StringUtil::Format("Macro %s() has named argument repeated '%s'", name, arg->GetAlias()));
80 }
81 named_arg_types.insert(arg->GetAlias(), std::move(arg_type));
82 named_arguments[arg->GetAlias()] = std::move(arg);
83 } else if (!named_arguments.empty()) {
84 return MacroBindResult(
85 StringUtil::Format("Macro %s() has positional argument following named argument", name));
86 } else {
87 // Positional argument
88 positional_arguments.push_back(std::move(arg));
89 positional_arg_types.push_back(std::move(arg_type));
90 }
91 }
92
93 // Check for each macro function if it matches the number of positional arguments
94 auto lowest_cost = NumericLimits<idx_t>::Maximum();
95 vector<idx_t> result_indices;
96 for (idx_t function_idx = 0; function_idx < functions.size(); function_idx++) {
97 auto &function = functions[function_idx];
98
99 // At some point we want to guarantee that this has the same size as "parameters", but for now we fill to match
100 auto parameter_types = function->types;
101 parameter_types.resize(function->parameters.size(), LogicalType::UNKNOWN);

Callers

nothing calls this directly

Calls 15

MacroBindResultClass · 0.85
FormatMacroFunctionFunction · 0.85
idMethod · 0.80
CopyMethod · 0.45
BindExpressionMethod · 0.45
HasErrorMethod · 0.45
emptyMethod · 0.45
GetAliasMethod · 0.45
findMethod · 0.45
endMethod · 0.45
insertMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected