mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix for bug #6849 "Crash while preparing query containing const expr with
IN and CONVERT_TZ()" (with after review changes). Now we add implicitly used time zone tables to global table list right at the parsing stage instead of doing it later in mysql_execute_command() or in check_prepared_statement(). No special test-case needed since this bug also manifests itself as timezone2.test failure if one runs it with --ps-protocol option.
This commit is contained in:
@ -1864,8 +1864,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||||||
|
|
||||||
static void relink_tables_for_multidelete(THD *thd)
|
static void relink_tables_for_multidelete(THD *thd)
|
||||||
{
|
{
|
||||||
if (thd->lex->all_selects_list->next_select_in_list() ||
|
if (thd->lex->all_selects_list->next_select_in_list())
|
||||||
thd->lex->time_zone_tables_used)
|
|
||||||
{
|
{
|
||||||
for (SELECT_LEX *sl= thd->lex->all_selects_list;
|
for (SELECT_LEX *sl= thd->lex->all_selects_list;
|
||||||
sl;
|
sl;
|
||||||
|
@ -30,15 +30,6 @@
|
|||||||
*/
|
*/
|
||||||
sys_var_long_ptr trg_new_row_fake_var(0, 0);
|
sys_var_long_ptr trg_new_row_fake_var(0, 0);
|
||||||
|
|
||||||
/*
|
|
||||||
Fake table list object, pointer to which is used as special value for
|
|
||||||
st_lex::time_zone_tables_used indicating that we implicitly use time
|
|
||||||
zone tables in this statement but real table list was not yet created.
|
|
||||||
Pointer to it is also returned by my_tz_get_tables_list() as indication
|
|
||||||
of transient error;
|
|
||||||
*/
|
|
||||||
TABLE_LIST fake_time_zone_tables_list;
|
|
||||||
|
|
||||||
/* Macros to look like lex */
|
/* Macros to look like lex */
|
||||||
|
|
||||||
#define yyGet() *(lex->ptr++)
|
#define yyGet() *(lex->ptr++)
|
||||||
@ -1880,6 +1871,31 @@ void st_lex::first_lists_tables_same()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add implicitly used time zone description tables to global table list
|
||||||
|
(if needed).
|
||||||
|
|
||||||
|
SYNOPSYS
|
||||||
|
st_lex::add_time_zone_tables_to_query_tables()
|
||||||
|
thd - pointer to current thread context
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
TRUE - error
|
||||||
|
FALSE - success
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool st_lex::add_time_zone_tables_to_query_tables(THD *thd)
|
||||||
|
{
|
||||||
|
/* We should not add these tables twice */
|
||||||
|
if (!time_zone_tables_used)
|
||||||
|
{
|
||||||
|
time_zone_tables_used= my_tz_get_table_list(thd, &query_tables_last);
|
||||||
|
if (time_zone_tables_used == &fake_time_zone_tables_list)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Link table back that was unlinked with unlink_first_table()
|
Link table back that was unlinked with unlink_first_table()
|
||||||
|
|
||||||
|
@ -735,9 +735,8 @@ typedef struct st_lex
|
|||||||
/* Names of user variables holding parameters (in EXECUTE) */
|
/* Names of user variables holding parameters (in EXECUTE) */
|
||||||
List<LEX_STRING> prepared_stmt_params;
|
List<LEX_STRING> prepared_stmt_params;
|
||||||
/*
|
/*
|
||||||
If points to fake_time_zone_tables_list indicates that time zone
|
Points to part of global table list which contains time zone tables
|
||||||
tables are implicitly used by statement, also is used for holding
|
implicitly used by the statement.
|
||||||
list of those tables after they are opened.
|
|
||||||
*/
|
*/
|
||||||
TABLE_LIST *time_zone_tables_used;
|
TABLE_LIST *time_zone_tables_used;
|
||||||
sp_head *sphead;
|
sp_head *sphead;
|
||||||
@ -802,6 +801,7 @@ typedef struct st_lex
|
|||||||
*(table->prev_global= query_tables_last)= table;
|
*(table->prev_global= query_tables_last)= table;
|
||||||
query_tables_last= &table->next_global;
|
query_tables_last= &table->next_global;
|
||||||
}
|
}
|
||||||
|
bool add_time_zone_tables_to_query_tables(THD *thd);
|
||||||
|
|
||||||
bool can_be_merged();
|
bool can_be_merged();
|
||||||
bool can_use_merged();
|
bool can_use_merged();
|
||||||
@ -810,7 +810,6 @@ typedef struct st_lex
|
|||||||
bool need_correct_ident();
|
bool need_correct_ident();
|
||||||
} LEX;
|
} LEX;
|
||||||
|
|
||||||
extern TABLE_LIST fake_time_zone_tables_list;
|
|
||||||
struct st_lex_local: public st_lex
|
struct st_lex_local: public st_lex
|
||||||
{
|
{
|
||||||
static void *operator new(size_t size)
|
static void *operator new(size_t size)
|
||||||
|
@ -2114,19 +2114,6 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_REPLICATION */
|
#endif /* !HAVE_REPLICATION */
|
||||||
|
|
||||||
if (lex->time_zone_tables_used)
|
|
||||||
{
|
|
||||||
TABLE_LIST *tmp;
|
|
||||||
if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) ==
|
|
||||||
&fake_time_zone_tables_list)
|
|
||||||
{
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
lex->time_zone_tables_used= tmp;
|
|
||||||
if (!all_tables)
|
|
||||||
all_tables= tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When option readonly is set deny operations which change tables.
|
When option readonly is set deny operations which change tables.
|
||||||
Except for the replication thread and the 'super' users.
|
Except for the replication thread and the 'super' users.
|
||||||
|
@ -4266,7 +4266,8 @@ simple_expr:
|
|||||||
{ $$= create_func_contains($3, $5); }
|
{ $$= create_func_contains($3, $5); }
|
||||||
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
|
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
|
||||||
{
|
{
|
||||||
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
|
if (Lex->add_time_zone_tables_to_query_tables(YYTHD))
|
||||||
|
YYABORT;
|
||||||
$$= new Item_func_convert_tz($3, $5, $7);
|
$$= new Item_func_convert_tz($3, $5, $7);
|
||||||
}
|
}
|
||||||
| CURDATE optional_braces
|
| CURDATE optional_braces
|
||||||
@ -7276,8 +7277,9 @@ internal_variable_name:
|
|||||||
If this is time_zone variable we should open time zone
|
If this is time_zone variable we should open time zone
|
||||||
describing tables
|
describing tables
|
||||||
*/
|
*/
|
||||||
if (tmp == &sys_time_zone)
|
if (tmp == &sys_time_zone &&
|
||||||
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
|
lex->add_time_zone_tables_to_query_tables(YYTHD))
|
||||||
|
YYABORT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1439,6 +1439,12 @@ tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fake table list object, pointer to which is returned by
|
||||||
|
my_tz_get_tables_list() as indication of error.
|
||||||
|
*/
|
||||||
|
TABLE_LIST fake_time_zone_tables_list;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create table list with time zone related tables and add it to the end
|
Create table list with time zone related tables and add it to the end
|
||||||
of global table list.
|
of global table list.
|
||||||
|
@ -64,6 +64,7 @@ extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
|
|||||||
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
|
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
|
||||||
extern void my_tz_free();
|
extern void my_tz_free();
|
||||||
|
|
||||||
|
extern TABLE_LIST fake_time_zone_tables_list;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if we have pointer to the beggining of list of implictly used
|
Check if we have pointer to the beggining of list of implictly used
|
||||||
|
Reference in New Issue
Block a user