Skip to content

MDEV-38329 Named parameters in stored procedure CALL - #4902

Open
MooSayed1 wants to merge 1 commit into
MariaDB:mainfrom
MooSayed1:MDEV-38329-named-params
Open

MDEV-38329 Named parameters in stored procedure CALL#4902
MooSayed1 wants to merge 1 commit into
MariaDB:mainfrom
MooSayed1:MDEV-38329-named-params

Conversation

@MooSayed1

@MooSayed1 MooSayed1 commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

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 both
stored procedures and stored functions:

CALL proc(a => 1, b => 2, c => 3);       -- all named
CALL proc(c => 3, a => 1, b => 2);       -- any order
CALL proc(1, b => 2, c => 3);            -- mixed positional + named
CALL proc(a => 1, c => 3);               -- skip middle param with default

SELECT func(a => 1, b => 2);             -- functions too
SELECT func(c => 3, a => 1, b => 2);     -- any order

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_cparam rule to accept ident ARROW_SYM expr alongside plain 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 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. No new grammar conflicts are introduced.

Named arguments set IS_EXPLICIT_NAME on the Item and store the parameter
name in Item::name, reusing the mechanism that UDF named arguments (the
WL#1017 AS attribute syntax) already use — that syntax continues to work
and 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 arguments
are matched against sp_pcontext's formal parameter list by name and
reordered 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, arguments
marked with IS_EXPLICIT_NAME 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, including positional/named collisions (ER_SP_DUP_PARAM)
  • Missing required parameter without default (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_VAR instead of
ER_WRONG_PARAMETERS_TO_STORED_FCT, because stored functions now accept
named arguments.

Current status

Done:

  • Parser: CALL proc(a => 1, b => 2) syntax accepted
  • Named params for stored functions: SELECT func(a => 1)
  • Mixed positional + named: CALL proc(1, b => 2)
  • Parse-time rejection of positional after named
  • Argument reordering in execute_procedure() and Item_func_sp::fix_fields()
  • Default value filling for omitted parameters
  • OUT/INOUT parameter support with named args (CALL p(x => @var))
  • Prepared statement support (PREPARE stmt FROM 'CALL p(a => ?)', re-execution)
  • Error detection: unknown name, duplicate name, missing required param
  • MTR test coverage: nested calls, reserved words as param names, NULLs, expressions

Still working on:

  • Defaults referencing earlier parameters (b INT DEFAULT a+1) fail with
    named invocation (CALL p(a => 5)Unknown column 'a'), while positional
    CALL p(5) works. Filling from sp_variable::default_value in the caller's
    context bypasses sp_instr_set_default_param, which normally evaluates
    defaults inside the routine context based on
    sp_rcontext::m_inited_params_count. A fix keeping default evaluation
    inside 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, and
parameters with default values can be skipped: CALL proc(a => 1, c => 3),
SELECT func(b => 2, a => 1).

How can this PR be tested?

./mtr main.sp_named_params

The test covers:

  • All positional (no regression)
  • All named in declared order and different order, for CALL and SELECT
  • Mixed positional + named
  • Positional after named (syntax error)
  • Unknown parameter name, duplicate name (named twice, positional then named)
  • Default value: skip middle param, only required param, override all defaults
  • Missing required parameter without default
  • OUT/INOUT parameters with named args
  • Prepared statements with named args, including re-execution
  • Nested CALLs, reserved words as parameter names, NULL and expression values

Basing the PR against the correct MariaDB version

This is a new feature. The PR targets main.

PR quality check

  • I checked the CODING_STANDARDS.md file and my PR conforms to this where appropriate.
  • For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

@MooSayed1
MooSayed1 marked this pull request as draft April 5, 2026 03:21
@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Apr 6, 2026
@MooSayed1
MooSayed1 force-pushed the MDEV-38329-named-params branch 2 times, most recently from ec66dad to 08491be Compare May 18, 2026 22:22
@vuvova
vuvova requested a review from Copilot June 16, 2026 20:31
@vuvova
vuvova self-requested a review June 16, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 => expr entries in CALL (...) argument lists and reject positional arguments after any named one.
  • Execution: reorder named CALL arguments 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.

Comment thread sql/sp_head.cc
Comment on lines +2258 to +2260
}
arg_array[j]= spvar->default_value;
}
Comment thread sql/item_func.cc Outdated
Comment on lines +6887 to +6888
if (arg_count && args[0]->is_explicit_name())
{
Comment thread sql/item_func.cc
Comment on lines +6949 to +6951
}
arg_array[j]= spvar->default_value;
}
Comment thread sql/item_create.cc
Comment thread sql/item_func.cc
Comment on lines +6927 to +6936
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++;
}
@vuvova

vuvova commented Jun 18, 2026

Copy link
Copy Markdown
Member

@MooSayed1 just FYI, this feature just missed 13.1, next deadline is 13.2, in 3 months.

@MooSayed1

Copy link
Copy Markdown
Contributor Author

@vuvova OKay i'll try finish it before next release.

@MooSayed1
MooSayed1 force-pushed the MDEV-38329-named-params branch from 08491be to 478f46d Compare July 6, 2026 14:50
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.
@MooSayed1
MooSayed1 force-pushed the MDEV-38329-named-params branch from 478f46d to 786c47a Compare July 7, 2026 14:41
@MooSayed1
MooSayed1 marked this pull request as ready for review July 27, 2026 15:13
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

4 participants