maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #13124
Re: e3e59c9e38d: MDEV-28266 Crash in Field_string::type_handler when calling procedures
Hi, Oleksandr,
On Apr 10, Oleksandr Byelkin wrote:
> revision-id: e3e59c9e38d (mariadb-10.6.6-83-ge3e59c9e38d)
> parent(s): 4e1ca388381
> author: Oleksandr Byelkin
> committer: Oleksandr Byelkin
> timestamp: 2022-04-08 10:37:17 +0200
> message:
>
> MDEV-28266 Crash in Field_string::type_handler when calling procedures
>
> In case of only metadata request the cursor lack the call to redirect
> Field::orig_table to the temporary table.
>
> diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
> index 0add5845558..155346341f1 100644
> --- a/sql/sql_cursor.cc
> +++ b/sql/sql_cursor.cc
> @@ -183,6 +183,16 @@ int mysql_open_cursor(THD *thd, select_result *result,
> {
> Materialized_cursor *materialized_cursor=
> result_materialize->materialized_cursor;
> + if (result_materialize->view_structure_only())
> + {
> + /*
> + If it was view_structure_only then only send metadata call was made
> + and there was no other call. So we have to "close" the cursor
> + explicitly (which redirect orig_table in the fields, and untie
> + it with closed tables)
> + */
> + materialized_cursor->on_table_fill_finished();
> + }
>
> if ((rc= materialized_cursor->open(0)))
> {
> delete materialized_cursor;
> goto end;
> }
normally on_table_fill_finished() is called from
Select_materialize::send_eof() and
Select_materialize::abort_result_set().
Note that directly after your added code there's
materialized_cursor->open(), and there we have
int Materialized_cursor::open(JOIN *join __attribute__((unused)))
{
...
if (!rc)
{
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
result->send_eof();
}
else
{
result->abort_result_set();
}
That is, one could expect that even without your added code,
on_table_fill_finished() would be called.
The problem is that result here is sp_cursor::Select_fetch_into_spvars,
and sp_cursor::Select_fetch_into_spvars::send_eof() is simply
{ return FALSE; }
So, as a fix I'd suggest to remove on_table_fill_finished() from
send_eof/abort_result_set, and put it unconditionally after the if(),
to make it work no matter what select_result was chosen.
Like this:
======================================
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -80,19 +80,7 @@ class Select_materialize: public select_unit
Select_materialize(THD *thd_arg, select_result *result_arg):
select_unit(thd_arg), result(result_arg), materialized_cursor(0) {}
virtual bool send_result_set_metadata(List<Item> &list, uint flags);
- bool send_eof()
- {
- if (materialized_cursor)
- materialized_cursor->on_table_fill_finished();
- return false;
- }
-
- void abort_result_set()
- {
- if (materialized_cursor)
- materialized_cursor->on_table_fill_finished();
- }
-
+ bool send_eof() { return false; }
bool view_structure_only() const
{
return result->view_structure_only();
@@ -333,6 +321,8 @@ int Materialized_cursor::open(JOIN *join
result->abort_result_set();
}
+ on_table_fill_finished();
+
return rc;
}
======================================
with the commit comment saying that "on_table_fill_finished() should
always be done at the end of open(), even if result is not
Select_materialize, but, for example, Select_fetch_into_spvars"
Regards,
Sergei
VP of MariaDB Server Engineering
and security@xxxxxxxxxxx