mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
MDEV-36047 Package body variables are not allowed as FETCH targets
It was not possible to use a package body variable as a
fetch target:
CREATE PACKAGE BODY pkg AS
vc INT := 0;
FUNCTION f1 RETURN INT AS
CURSOR cur IS SELECT 1 AS c FROM DUAL;
BEGIN
OPEN cur;
FETCH cur INTO vc; -- this returned "Undeclared variable: vc" error.
CLOSE cur;
RETURN vc;
END;
END;
FETCH assumed that all fetch targets reside of the same sp_rcontext
instance with the cursor. This patch fixes the problem.
Now a cursor and its fetch target can reside in different sp_rcontext
instances.
Details:
- Adding a helper class sp_rcontext_addr
(a combination of Sp_rcontext_handler pointer and an offset in the rcontext)
- Adding a new class sp_fetch_target deriving from sp_rcontext_addr.
Fetch targets in "FETCH cur INTO target1, target2 ..." are now collected
into this structure instead of sp_variable.
sp_variable cannot be used any more to store fetch targets,
because it does not have a pointer to Sp_rcontext_handler
(it only has the current rcontext offset).
- Removing members sp_instr_set members m_rcontext_handler and m_offset.
Deriving sp_instr_set from sp_rcontext_addr instead.
- Renaming sp_instr_cfetch member "List<sp_variable> m_varlist"
to "List<sp_fetch_target> m_fetch_target_list".
- Fixing LEX::sp_add_cfetch() to return the pointer to the
created sp_fetch_target instance (instead of returning bool).
This helps to make the grammar in sql_yacc.c simpler
- Renaming LEX::sp_add_cfetch() to LEX::sp_add_instr_cfetch(),
as `if(sp_add_cfetch())` changed its meaning to the opposite,
to avoid automatic wrong merge from earlier versions.
- Chaning the "List<sp_variable> *vars" parameter to sp_cursor::fetch
to have the data type "List<sp_fetch_target> *".
- Changing the data type of "List<sp_variable> &vars" in
sp_cursor::Select_fetch_into_spvars::send_data_to_variable_list()
to "List<sp_fetch_target> &".
- Adding THD helper methods get_rcontext() and get_variable().
- Moving the code from sql_yacc.yy into a new LEX method
LEX::make_fetch_target().
- Simplifying the grammar in sql_yacc.yy using the new LEX method.
Changing the data type of the bison rule sp_fetch_list from "void"
to "List<sp_fetch_target> *".
This commit is contained in:
@@ -3985,6 +3985,9 @@ public:
|
||||
|
||||
sp_rcontext *spcont; // SP runtime context
|
||||
|
||||
sp_rcontext *get_rcontext(const sp_rcontext_addr &addr);
|
||||
Item_field *get_variable(const sp_rcontext_addr &addr);
|
||||
|
||||
/** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
|
||||
uint query_name_consts;
|
||||
|
||||
@@ -6330,10 +6333,11 @@ private:
|
||||
/// FETCH <cname> INTO <varlist>.
|
||||
class Select_fetch_into_spvars: public select_result_interceptor
|
||||
{
|
||||
List<sp_variable> *spvar_list;
|
||||
List<sp_fetch_target> *m_fetch_target_list;
|
||||
uint field_count;
|
||||
bool m_view_structure_only;
|
||||
bool send_data_to_variable_list(List<sp_variable> &vars, List<Item> &items);
|
||||
bool send_data_to_variable_list(List<sp_fetch_target> &vars,
|
||||
List<Item> &items);
|
||||
public:
|
||||
Select_fetch_into_spvars(THD *thd_arg, bool view_structure_only)
|
||||
:select_result_interceptor(thd_arg),
|
||||
@@ -6342,11 +6346,14 @@ private:
|
||||
void reset(THD *thd_arg)
|
||||
{
|
||||
select_result_interceptor::reinit(thd_arg);
|
||||
spvar_list= NULL;
|
||||
m_fetch_target_list= NULL;
|
||||
field_count= 0;
|
||||
}
|
||||
uint get_field_count() { return field_count; }
|
||||
void set_spvar_list(List<sp_variable> *vars) { spvar_list= vars; }
|
||||
void set_spvar_list(List<sp_fetch_target> *vars)
|
||||
{
|
||||
m_fetch_target_list= vars;
|
||||
}
|
||||
|
||||
bool send_eof() override { return FALSE; }
|
||||
int send_data(List<Item> &items) override;
|
||||
@@ -6376,7 +6383,7 @@ public:
|
||||
my_bool is_open()
|
||||
{ return MY_TEST(server_side_cursor); }
|
||||
|
||||
int fetch(THD *, List<sp_variable> *vars, bool error_on_no_data);
|
||||
int fetch(THD *, List<sp_fetch_target> *vars, bool error_on_no_data);
|
||||
|
||||
bool export_structure(THD *thd, Row_definition_list *list);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user