mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
A field of an element of an associative array of RECORDs, passed to
an OUT or INOUT parameter of a stored routine, crashed the server:
CREATE PROCEDURE p1(a OUT INT) AS BEGIN a:= 7; END;
DECLARE
TYPE rec_t IS RECORD (i INT, s VARCHAR(10));
TYPE tab_t IS TABLE OF rec_t INDEX BY INT;
t tab_t:= tab_t(1 => rec_t(0, 'x'));
BEGIN
p1(t(1).i);
END;
There were three problems:
- Item_splocal_assoc_array_element_field inherited set_value() of
Item_splocal_row_field_by_name, which treated the associative array
variable as a ROW variable (assertion failure in
sp_rcontext::virtual_tmp_table_for_row()). Added
Item_splocal_assoc_array_element_field::set_value(), which stores the
value into the field of the element.
- Before the call, sp_head::bind_input_param() destructed the whole
variable for an OUT argument, even if the argument was only a part of
the variable (a ROW field, an assoc array element or its field), so
the other elements of the array were lost: after p1(a0(2)), the array
a0(1), a0(2), a0(3) had only one element left. Added
Item_splocal::is_part_of_variable().
- sp_head::bind_output_param() evaluated the actual argument in the
context of the callee. For arguments like t(i) or t(i).field this
resolved the variables t and i in a wrong context. Now the argument
is evaluated in the context of the caller.
The second problem also affected a SYS_REFCURSOR field of a ROW variable
passed as an OUT argument: the cursors in the other fields of the ROW
variable were closed. Now they are kept.
Known limitations, not changed by this fix:
- The actual OUT argument is evaluated when the value is copied back,
not when the routine is called. If an earlier OUT argument of the same
call changes the variable used as the key, as in CALL p(i, a0(i)), the
new value of the key is used.
- For an OUT argument which is a part of a variable (a ROW field, an
assoc array element or its field), only the destruct of the whole
variable is skipped, the part itself is not destructed. A
SYS_REFCURSOR field of a ROW stays open during the call and is
released when the new value is copied back.
Tests: sp-assoc-array (OUT and INOUT elements and fields of elements,
NULL key, element deleted by the callee, ROW and RECORD fields) and
type_sys_refcursor-type_row-debug (SYS_REFCURSOR fields of a ROW
variable).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>