Bug#14275000
Fixes for BUG11761686 left a flaw that managed to slip away from testing. Only effective filtering branch was actually tested with a regression test added to rpl_filter_tables_not_exist. The reason of the failure is destuction of too early mem-root-allocated memory at the end of the deferred User-var's do_apply_event(). Fixed with bypassing free_root() in the deferred execution branch. Deallocation of created in do_apply_event() items is done by the base code through THD::cleanup_after_query() -> free_items() that the parent Query can't miss.
This commit is contained in:
parent
176d6b1dca
commit
dbd63d008f
@ -5640,6 +5640,9 @@ User_var_log_event::
|
|||||||
User_var_log_event(const char* buf,
|
User_var_log_event(const char* buf,
|
||||||
const Format_description_log_event* description_event)
|
const Format_description_log_event* description_event)
|
||||||
:Log_event(buf, description_event)
|
:Log_event(buf, description_event)
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
, deferred(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* The Post-Header is empty. The Variable Data part begins immediately. */
|
/* The Post-Header is empty. The Variable Data part begins immediately. */
|
||||||
buf+= description_event->common_header_len +
|
buf+= description_event->common_header_len +
|
||||||
@ -5848,7 +5851,10 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
|
|
||||||
if (rli->deferred_events_collecting)
|
if (rli->deferred_events_collecting)
|
||||||
|
{
|
||||||
|
set_deferred();
|
||||||
return rli->deferred_events->add(this);
|
return rli->deferred_events->add(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
|
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
|
||||||
return 1;
|
return 1;
|
||||||
@ -5900,7 +5906,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item_func_set_user_var e(user_var_name, it);
|
|
||||||
|
Item_func_set_user_var *e= new Item_func_set_user_var(user_var_name, it);
|
||||||
/*
|
/*
|
||||||
Item_func_set_user_var can't substitute something else on its place =>
|
Item_func_set_user_var can't substitute something else on its place =>
|
||||||
0 can be passed as last argument (reference on item)
|
0 can be passed as last argument (reference on item)
|
||||||
@ -5909,7 +5916,7 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
crash the server, so if fix fields fails, we just return with an
|
crash the server, so if fix fields fails, we just return with an
|
||||||
error.
|
error.
|
||||||
*/
|
*/
|
||||||
if (e.fix_fields(thd, 0))
|
if (e->fix_fields(thd, 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5917,8 +5924,9 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
a single record and with a single column. Thus, like
|
a single record and with a single column. Thus, like
|
||||||
a column value, it could always have IMPLICIT derivation.
|
a column value, it could always have IMPLICIT derivation.
|
||||||
*/
|
*/
|
||||||
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
|
e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
|
||||||
free_root(thd->mem_root,0);
|
if (!is_deferred())
|
||||||
|
free_root(thd->mem_root,0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2483,11 +2483,13 @@ public:
|
|||||||
uint charset_number;
|
uint charset_number;
|
||||||
bool is_null;
|
bool is_null;
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
bool deferred;
|
||||||
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
||||||
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
||||||
uint charset_number_arg)
|
uint charset_number_arg)
|
||||||
:Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
|
:Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
|
||||||
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
|
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg),
|
||||||
|
deferred(false)
|
||||||
{ is_null= !val; }
|
{ is_null= !val; }
|
||||||
void pack_info(Protocol* protocol);
|
void pack_info(Protocol* protocol);
|
||||||
#else
|
#else
|
||||||
@ -2500,6 +2502,13 @@ public:
|
|||||||
Log_event_type get_type_code() { return USER_VAR_EVENT;}
|
Log_event_type get_type_code() { return USER_VAR_EVENT;}
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
/*
|
||||||
|
Getter and setter for deferred User-event.
|
||||||
|
Returns true if the event is not applied directly
|
||||||
|
and which case the applier adjusts execution path.
|
||||||
|
*/
|
||||||
|
bool is_deferred() { return deferred; }
|
||||||
|
void set_deferred() { deferred= val; }
|
||||||
#endif
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
bool is_valid() const { return 1; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user