Fix type coercion failure with mixed positional/named parameters in p…#1174
Conversation
…ackages and subprocedures
📝 WalkthroughWalkthroughThis PR adds post-lookup type reinforcement for package and subprocedure function calls. When a function is identified as a package or subprocedure function after lookup, the code rebuilds actual argument types to align with reordered or expanded arguments. Additionally, comprehensive test coverage is introduced for mixed positional and named parameter scenarios. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/backend/parser/parse_func.c`:
- Around line 366-392: This code rebuilds actual_arg_types and sets nargs when
function_from is FUNC_FROM_PACKAGE or FUNC_FROM_SUBPROCFUNC and fdresult !=
FUNCDETAIL_NOTFOUND, which means defaults may already have been injected into
fargs; to avoid double-counting you should record that defaults were already
expanded (e.g., set a local flag like defaults_already_expanded when running the
existing branch that iterates fargs and sets actual_arg_types/nargs) and then,
in the later nargsplusdefs/argdefaults appending logic, skip appending
argdefaults if that flag is true so nargsplusdefs remains consistent with
declared_arg_types and enforce_generic_type_consistency cannot overrun or
produce spurious "too many arguments" errors; use the existing symbols
(function_from, FUNC_FROM_PACKAGE, FUNC_FROM_SUBPROCFUNC, fdresult, fargs,
actual_arg_types, nargs, argdefaults, nargsplusdefs, declared_arg_types,
enforce_generic_type_consistency) to locate where to set the flag and where to
conditionally skip the append.
| /* | ||
| * If we found a package function/procedure or subprocedure, the fargs | ||
| * list may have been reordered and expanded with default arguments. We | ||
| * need to rebuild the actual_arg_types array to match the new argument | ||
| * order, otherwise type coercion will fail when trying to match reordered | ||
| * arguments. | ||
| * | ||
| * For subprocedures, the fix in pl_subproc_function.c also rebuilds | ||
| * true_typeids (declared_arg_types) in declared order after reordering, | ||
| * so that both arrays match the reordered fargs. | ||
| */ | ||
| if ((function_from == FUNC_FROM_PACKAGE || | ||
| function_from == FUNC_FROM_SUBPROCFUNC) && | ||
| fdresult != FUNCDETAIL_NOTFOUND) | ||
| { | ||
| ListCell *lc; | ||
| int i = 0; | ||
|
|
||
| foreach(lc, fargs) | ||
| { | ||
| Node *arg = lfirst(lc); | ||
|
|
||
| actual_arg_types[i++] = exprType(arg); | ||
| } | ||
| /* Update nargs to reflect the reordered/expanded argument list */ | ||
| nargs = i; | ||
| } |
There was a problem hiding this comment.
Avoid double‑counting default argument types after expansion.
When package/subproc lookup expands fargs with defaults, this block rebuilds actual_arg_types and sets nargs to the expanded length. Later, argdefaults is still appended in the nargsplusdefs section, which can make nargsplusdefs larger than declared_arg_types and cause enforce_generic_type_consistency to read past the end (or raise spurious “too many arguments” errors). Please skip the append when defaults were already injected into fargs.
🛠️ Proposed fix (skip argdefaults when already expanded)
@@
- FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
+ FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
+ bool defaults_already_in_fargs = false;
@@
if ((function_from == FUNC_FROM_PACKAGE ||
function_from == FUNC_FROM_SUBPROCFUNC) &&
fdresult != FUNCDETAIL_NOTFOUND)
{
ListCell *lc;
- int i = 0;
+ int i = 0;
+ int original_nargs = nargs;
foreach(lc, fargs)
{
Node *arg = lfirst(lc);
actual_arg_types[i++] = exprType(arg);
}
/* Update nargs to reflect the reordered/expanded argument list */
nargs = i;
+ if (i > original_nargs && argdefaults != NIL)
+ defaults_already_in_fargs = true;
}
@@
nargsplusdefs = nargs;
- foreach(l, argdefaults)
+ if (!defaults_already_in_fargs)
+ foreach(l, argdefaults)
{
Node *expr = (Node *) lfirst(l);
...
}🤖 Prompt for AI Agents
In `@src/backend/parser/parse_func.c` around lines 366 - 392, This code rebuilds
actual_arg_types and sets nargs when function_from is FUNC_FROM_PACKAGE or
FUNC_FROM_SUBPROCFUNC and fdresult != FUNCDETAIL_NOTFOUND, which means defaults
may already have been injected into fargs; to avoid double-counting you should
record that defaults were already expanded (e.g., set a local flag like
defaults_already_expanded when running the existing branch that iterates fargs
and sets actual_arg_types/nargs) and then, in the later
nargsplusdefs/argdefaults appending logic, skip appending argdefaults if that
flag is true so nargsplusdefs remains consistent with declared_arg_types and
enforce_generic_type_consistency cannot overrun or produce spurious "too many
arguments" errors; use the existing symbols (function_from, FUNC_FROM_PACKAGE,
FUNC_FROM_SUBPROCFUNC, fdresult, fargs, actual_arg_types, nargs, argdefaults,
nargsplusdefs, declared_arg_types, enforce_generic_type_consistency) to locate
where to set the flag and where to conditionally skip the append.
…ackages and subprocedures
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.