MDEV-38329 Named parameters in stored procedure CALL - #4902
Conversation
ec66dad to
08491be
Compare
There was a problem hiding this comment.
Pull request overview
Adds support for invoking stored procedures with named arguments using the => syntax, allowing callers to reorder arguments and skip parameters that have defaults.
Changes:
- Parser: accept
ident => exprentries inCALL (...)argument lists and reject positional arguments after any named one. - Execution: reorder named
CALLarguments to match formal parameter order and attempt to fill omitted parameters from routine defaults. - Tests: add MTR coverage for procedure named args and (via existing
AS-alias naming mechanism) stored function named args.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/sql_yacc.yy | Extends CALL argument grammar to accept ident => expr and enforces “positional before named”. |
| sql/sql_lex.h | Adds LEX::has_named_call_param flag to track presence of named CALL args during parsing/execution. |
| sql/sql_lex.cc | Initializes has_named_call_param at CALL statement start. |
| sql/sp_head.cc | Reorders named CALL args to formal parameter positions and fills omitted params. |
| sql/item_func.cc | Adds stored-function argument reordering/default filling when named args are detected. |
| sql/item_create.cc | Removes prior rejection of named parameters in stored function calls (enabling AS-style named args). |
| mysql-test/main/sp_named_params.test | New MTR test for named procedure params + named stored-function params (via AS). |
| mysql-test/main/sp_named_params.result | Expected output for the new MTR test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| arg_array[j]= spvar->default_value; | ||
| } |
| if (arg_count && args[0]->is_explicit_name()) | ||
| { |
| } | ||
| arg_array[j]= spvar->default_value; | ||
| } |
| if (positional_count >= params) | ||
| { | ||
| my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "FUNCTION", | ||
| ErrConvDQName(m_sp).ptr(), params, arg_count); | ||
| DBUG_RETURN(TRUE); | ||
| } | ||
| arg_array[positional_count]= item; | ||
| param_assigned[positional_count]= true; | ||
| positional_count++; | ||
| } |
|
@MooSayed1 just FYI, this feature just missed 13.1, next deadline is 13.2, in 3 months. |
|
@vuvova OKay i'll try finish it before next release. |
478f46d to
786c47a
Compare
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
786c47a to
c016c1d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (2)
sql/sp_head.cc:2259
- Default parameters are being filled by copying
sp_variable::default_valueinto the caller argument array (arg_array[j]= spvar->default_value). This causesnctx->set_inited_param_count(args->elements)later to treat all parameters as initialized, sosp_instr_set_default_paraminside the routine never runs and defaults get evaluated in the caller context (breaking defaults that depend on earlier params, as well as changing scope/semantics).
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE",
ErrConvDQName(this).ptr(), params, args->elements);
DBUG_RETURN(TRUE);
}
arg_array[j]= spvar->default_value;
sql/item_func.cc:6969
- Similar to procedure CALL, missing function parameters are filled by assigning
spvar->default_valueinto the reordered args array. This makesexecute_function()bind all params as if explicitly provided (it later setsm_inited_params_counttoargcount), sosp_instr_set_default_paramwon’t execute and defaults are evaluated in the caller statement context. This breaks defaults that reference earlier parameters and changes routine semantics.
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "FUNCTION",
ErrConvDQName(m_sp).ptr(), params, arg_count);
DBUG_RETURN(TRUE);
}
arg_array[j]= spvar->default_value;
gkodinov
left a comment
There was a problem hiding this comment.
While waiting for Serg's review, can you please look into the test failure? Could it be some extra parser conflicts?
c016c1d to
796fb54
Compare
gkodinov
left a comment
There was a problem hiding this comment.
Still failing. Are you sure it's ready for review?
Add support for named parameter syntax in stored routine calls,
allowing callers to specify arguments by name and in any order.
Both stored procedures and stored functions use the => syntax:
CALL proc(a => 1, b => 2);
CALL proc(c => 3, a => 1, b => 2);
CALL proc(1, b => 2, c => 3);
SELECT func(a => 1, b => 2);
SELECT func(c => 3, a => 1, b => 2);
Parameters with default values can be omitted:
CALL proc(a => 1); -- b,c use defaults
SELECT func(a => 1, c => 3); -- b uses default
Parser: added sp_cparam rule in sql_yacc.yy to accept
ident ARROW_SYM expr in CALL argument lists, and a second
udf_expr alternative for function calls. In udf_expr both
alternatives start with remember_name: it is a dummy in the
named-argument alternative (its value is unused), but it must
be present so that both alternatives share the same empty-rule
prefix, otherwise bison reports a shift/reduce conflict on
every token that can start an ident, as it would have to
decide whether to reduce remember_name before seeing if
ARROW_SYM follows the ident.
Named args set IS_EXPLICIT_NAME and store the name in
Item::name, reusing the UDF named argument mechanism (the AS
attribute syntax from WL#1017 also continues to work and names
arguments the same way). Positional args after named args are
rejected at parse time for CALL.
Reordering for procedures: in sp_head::execute_procedure(),
named arguments are matched against sp_pcontext formal
parameters and reordered to declared positions. Omitted
params with defaults are filled from sp_variable::default_value.
Reordering for functions: in Item_func_sp::fix_fields(),
after resolving the sp_head, named arguments are matched and
reordered the same way. The has_named_parameters() rejection
in Create_sp_func::create_with_db() is removed.
Error handling:
- Unknown parameter name: ER_SP_UNDECLARED_VAR
- Duplicate parameter name: ER_SP_DUP_PARAM
- Missing required parameter: ER_SP_WRONG_NO_OF_ARGS
The main.udf test is adjusted: an unknown attribute name on a
stored function call, e.g. fn(MIN(b) xx), is now reported as
ER_SP_UNDECLARED_VAR instead of ER_WRONG_PARAMETERS_TO_STORED_FCT,
because stored functions now accept named arguments.
LEX::has_named_call_param is reset in LEX::start() for every
statement: the sp_cparam rule is also reached from Oracle-mode
assoc array element assignment, e.g. arr('x') := 1, which does
not go through call_statement_start(), so a stale flag value
from a previous statement would cause a false 'positional after
named' parse error.
796fb54 to
61a2cff
Compare
gkodinov
left a comment
There was a problem hiding this comment.
LGTM. Please keep working with your assigned final reviewer.
|
@gkodinov there's still logic problem im working on rn I'll discuss it on zulip. |
The Jira issue number for this PR is: MDEV-38329
Description
Stored routines currently require all arguments to be passed positionally.
When a routine has many parameters with defaults, there is no way to skip
middle parameters — only trailing ones can be omitted.
This patch adds named parameter invocation using the
=>syntax for bothstored procedures and stored functions:
This brings MariaDB in line with Oracle, PostgreSQL, SQL Server, and Firebird,
all of which already support named parameter invocation.
Parser changes (
sql/sql_yacc.yy):Added
sp_cparamrule to acceptident ARROW_SYM expralongside plainexprin CALL argument lists, and a second
udf_expralternative for function calls.In
udf_exprboth alternatives start withremember_name: it is a dummy inthe named-argument alternative (its value is unused), but it must be present
so both alternatives share the same empty-rule prefix — otherwise bison
reports a shift/reduce conflict on every token that can start an
ident,as it would have to decide whether to reduce
remember_namebefore seeingif
ARROW_SYMfollows. No new grammar conflicts are introduced.Named arguments set
IS_EXPLICIT_NAMEon the Item and store the parametername in
Item::name, reusing the mechanism that UDF named arguments (theWL#1017
ASattribute syntax) already use — that syntax continues to workand names arguments the same way. Positional arguments after a named argument
are rejected at parse time for CALL.
Reordering for procedures (
sql/sp_head.cc):In
sp_head::execute_procedure(), before the binding loop, named argumentsare matched against
sp_pcontext's formal parameter list by name andreordered to their declared positions. Omitted parameters with defaults are
filled from
sp_variable::default_value.Reordering for functions (
sql/item_func.cc,sql/item_create.cc):In
Item_func_sp::fix_fields(), after the sp_head is resolved, argumentsmarked with
IS_EXPLICIT_NAMEare matched and reordered the same way. Thehas_named_parameters()rejection inCreate_sp_func::create_with_db()isremoved.
Error handling:
ER_SP_UNDECLARED_VAR)ER_SP_DUP_PARAM)ER_SP_WRONG_NO_OF_ARGS)Test suite change (
mysql-test/main/udf.test):An unknown attribute name on a stored function call, e.g.
fn(MIN(b) xx),is now reported as
ER_SP_UNDECLARED_VARinstead ofER_WRONG_PARAMETERS_TO_STORED_FCT, because stored functions now acceptnamed arguments.
Current status
Done:
CALL proc(a => 1, b => 2)syntax acceptedSELECT func(a => 1)CALL proc(1, b => 2)execute_procedure()andItem_func_sp::fix_fields()CALL p(x => @var))PREPARE stmt FROM 'CALL p(a => ?)', re-execution)Still working on:
b INT DEFAULT a+1) fail withnamed invocation (
CALL p(a => 5)→Unknown column 'a'), while positionalCALL p(5)works. Filling fromsp_variable::default_valuein the caller'scontext bypasses
sp_instr_set_default_param, which normally evaluatesdefaults inside the routine context based on
sp_rcontext::m_inited_params_count. A fix keeping default evaluationinside the routine (making the inited-params tracking hole-aware for named
args) is in progress.
This PR is a work in progress. Reviews and feedback on the current approach are welcome.
Release Notes
Stored procedures and stored functions now support named parameter invocation
using the
=>syntax. Arguments can be passed by name in any order, andparameters with default values can be skipped:
CALL proc(a => 1, c => 3),SELECT func(b => 2, a => 1).How can this PR be tested?
The test covers:
Basing the PR against the correct MariaDB version
This is a new feature. The PR targets
main.PR quality check