Commit 0379a691 authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

Update upstream source from tag 'upstream/5.5.64'

Update to upstream version '5.5.64'
with Debian dir b7957bbeb847da5eea7ad7ce27dbb476ae08d867
parents cbc39f88 b9a9fe5c
/* Copyright (c) 2007, 2018, Oracle and/or its affiliates.
Copyright (c) 2009, 2018, MariaDB
/* Copyright (c) 2007, 2019, Oracle and/or its affiliates.
Copyright (c) 2009, 2019, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -100,21 +100,20 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
if (open_and_lock_tables(ev_thd, rli->tables_to_lock, FALSE, 0))
{
uint actual_error= ev_thd->stmt_da->sql_errno();
if (ev_thd->is_slave_error || ev_thd->is_fatal_error)
if (ev_thd->is_error())
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
simplifications.
We should not honour --slave-skip-errors at this point as we are
having severe errors which should not be skipped.
*/
rli->report(ERROR_LEVEL, actual_error,
rli->report(ERROR_LEVEL, ev_thd->stmt_da->sql_errno(),
"Error '%s' on opening tables",
(actual_error ? ev_thd->stmt_da->message() :
"unexpected success or fatal error"));
ev_thd->stmt_da->message());
ev_thd->is_slave_error= 1;
}
const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
DBUG_RETURN(actual_error);
DBUG_RETURN(1);
}
/*
......
......@@ -7596,7 +7596,8 @@ mysqld_get_one_option(int optid,
val= p--;
while (my_isspace(mysqld_charset, *p) && p > argument)
*p-- = 0;
if (p == argument)
/* Db name can be one char also */
if (p == argument && my_isspace(mysqld_charset, *p))
{
sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
return 1;
......
......@@ -675,7 +675,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
select_lex->outer_select()->join && // 6
parent_unit->first_select()->leaf_tables.elements && // 7
!in_subs->has_strategy() && // 8
select_lex->outer_select()->leaf_tables.elements && // 9
select_lex->outer_select()->table_list.first && // 9
!((join->select_options | // 10
select_lex->outer_select()->join->select_options) // 10
& SELECT_STRAIGHT_JOIN)) // 10
......
......@@ -6511,7 +6511,7 @@ ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN
eng "Cannot define foreign key with %s clause on a computed column"
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
eng "The value specified for computed column '%s' in table '%s' ignored"
eng "The value specified for computed column '%s' in table '%s' has been ignored"
ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
eng "This is not yet supported for computed columns"
ER_CONST_EXPR_IN_VCOL
......
......@@ -563,6 +563,7 @@ sp_head::sp_head()
DBUG_ENTER("sp_head::sp_head");
m_security_ctx.init();
m_backpatch.empty();
m_cont_backpatch.empty();
m_lex.empty();
......@@ -4249,6 +4250,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
table->table_name_length= stab->table_name_length;
table->alias= table->table_name + table->table_name_length + 1;
table->lock_type= stab->lock_type;
table->updating= stab->lock_type >= TL_WRITE_ALLOW_WRITE;
table->cacheable_table= 1;
table->prelocking_placeholder= 1;
table->belong_to_view= belong_to_view;
......
......@@ -825,6 +825,14 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
goto end;
table->use_all_columns();
if (table->s->fields < 13) // number of columns in 3.21
{
sql_print_error("Fatal error: mysql.user table is damaged or in "
"unsupported 3.20 format.");
goto end;
}
username_char_length= min(table->field[1]->char_length(), USERNAME_CHAR_LENGTH);
password_length= table->field[2]->field_length /
table->field[2]->charset()->mbmaxlen;
......@@ -1150,6 +1158,20 @@ void acl_free(bool end)
}
static void fix_table_list(TABLE_LIST *tl, uint n)
{
TABLE_LIST *end;
for (end= tl + n - 1; tl < end; tl++)
{
tl->i_s_requested_object= OPEN_TABLE_ONLY;
tl->open_type= OT_BASE_ONLY;
tl->next_local= tl->next_global= tl + 1;
}
tl->i_s_requested_object= OPEN_TABLE_ONLY;
tl->open_type= OT_BASE_ONLY;
}
/*
Forget current user/db-level privileges and read new privileges
from the privilege tables.
......@@ -1191,11 +1213,7 @@ my_bool acl_reload(THD *thd)
tables[3].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("proxies_priv"),
"proxies_priv", TL_READ);
tables[0].next_local= tables[0].next_global= tables + 1;
tables[1].next_local= tables[1].next_global= tables + 2;
tables[2].next_local= tables[2].next_global= tables + 3;
tables[0].open_type= tables[1].open_type= tables[2].open_type=
tables[3].open_type= OT_BASE_ONLY;
fix_table_list(tables, 4);
tables[3].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
......@@ -1921,6 +1939,7 @@ bool change_password(THD *thd, const char *host, const char *user,
DBUG_RETURN(1);
tables.init_one_table("mysql", 5, "user", 4, "user", TL_WRITE);
fix_table_list(&tables, 1);
#ifdef HAVE_REPLICATION
/*
......@@ -2282,6 +2301,7 @@ static bool test_if_create_new_users(THD *thd)
ulong db_access;
tl.init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("user"), "user", TL_WRITE);
fix_table_list(&tl, 1);
create_new_users= 1;
db_access=acl_get(sctx->host, sctx->ip,
......@@ -3689,10 +3709,11 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("columns_priv"),
"columns_priv", TL_WRITE);
tables[0].next_local= tables[0].next_global= tables+1;
/* Don't open column table if we don't need it ! */
if (column_priv || (revoke_grant && ((rights & COL_ACLS) || columns.elements)))
tables[1].next_local= tables[1].next_global= tables+2;
fix_table_list(tables, 3);
else
fix_table_list(tables, 2);
/*
This statement will be replicated as a statement, even when using
......@@ -3930,7 +3951,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
C_STRING_WITH_LEN("user"), "user", TL_WRITE);
tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("procs_priv"), "procs_priv", TL_WRITE);
tables[0].next_local= tables[0].next_global= tables+1;
fix_table_list(tables, 2);
/*
This statement will be replicated as a statement, even when using
......@@ -4104,7 +4125,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
C_STRING_WITH_LEN("db"),
"db",
TL_WRITE);
tables[0].next_local= tables[0].next_global= tables+1;
fix_table_list(tables, 2);
/*
This statement will be replicated as a statement, even when using
......@@ -4525,10 +4546,7 @@ my_bool grant_reload(THD *thd)
tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("procs_priv"),
"procs_priv", TL_READ);
tables[0].next_local= tables[0].next_global= tables+1;
tables[1].next_local= tables[1].next_global= tables+2;
tables[0].open_type= tables[1].open_type= tables[2].open_type= OT_BASE_ONLY;
fix_table_list(tables, 3);
/*
Reload will work in the following manner:-
......@@ -5864,29 +5882,24 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables)
DBUG_RETURN(-1);
}
tables->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("user"), "user", TL_WRITE);
(tables+1)->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("db"), "db", TL_WRITE);
(tables+2)->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("tables_priv"),
"tables_priv", TL_WRITE);
(tables+3)->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[3].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("columns_priv"),
"columns_priv", TL_WRITE);
(tables+4)->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[4].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("procs_priv"),
"procs_priv", TL_WRITE);
(tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"),
tables[5].init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("proxies_priv"),
"proxies_priv", TL_WRITE);
tables[5].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
tables->next_local= tables->next_global= tables + 1;
(tables+1)->next_local= (tables+1)->next_global= tables + 2;
(tables+2)->next_local= (tables+2)->next_global= tables + 3;
(tables+3)->next_local= (tables+3)->next_global= tables + 4;
(tables+4)->next_local= (tables+4)->next_global= tables + 5;
fix_table_list(tables, 6);
#ifdef HAVE_REPLICATION
/*
......
......@@ -4468,6 +4468,45 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
DBUG_RETURN(FALSE);
}
/*
If we are not already in prelocked mode and extended table list is not
yet built we might have to build the prelocking set for this statement.
Since currently no prelocking strategy prescribes doing anything for
tables which are only read, we do below checks only if table is going
to be changed.
*/
bool extend_table_list(THD *thd, TABLE_LIST *tables,
Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list)
{
bool error= false;
LEX *lex= thd->lex;
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
! has_prelocking_list && tables->updating &&
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
{
bool need_prelocking= FALSE;
TABLE_LIST **save_query_tables_last= lex->query_tables_last;
/*
Extend statement's table list and the prelocking set with
tables and routines according to the current prelocking
strategy.
For example, for DML statements we need to add tables and routines
used by triggers which are going to be invoked for this element of
table list and also add tables required for handling of foreign keys.
*/
error= prelocking_strategy->handle_table(thd, lex, tables,
&need_prelocking);
if (need_prelocking && ! lex->requires_prelocking())
lex->mark_as_requiring_prelocking(save_query_tables_last);
}
return error;
}
/**
Handle table list element by obtaining metadata lock, opening table or view
......@@ -4496,15 +4535,14 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
*/
static bool
open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
uint *counter, uint flags,
open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list,
Open_table_context *ot_ctx,
bool has_prelocking_list, Open_table_context *ot_ctx,
MEM_ROOT *new_frm_mem)
{
bool error= FALSE;
bool safe_to_ignore_table= FALSE;
LEX *lex= thd->lex;
DBUG_ENTER("open_and_process_table");
DEBUG_SYNC(thd, "open_and_process_table");
......@@ -4654,38 +4692,9 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
if (tables->open_strategy && !tables->table)
goto end;
/*
If we are not already in prelocked mode and extended table list is not
yet built we might have to build the prelocking set for this statement.
Since currently no prelocking strategy prescribes doing anything for
tables which are only read, we do below checks only if table is going
to be changed.
*/
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
! has_prelocking_list &&
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
{
bool need_prelocking= FALSE;
TABLE_LIST **save_query_tables_last= lex->query_tables_last;
/*
Extend statement's table list and the prelocking set with
tables and routines according to the current prelocking
strategy.
For example, for DML statements we need to add tables and routines
used by triggers which are going to be invoked for this element of
table list and also add tables required for handling of foreign keys.
*/
error= prelocking_strategy->handle_table(thd, lex, tables,
&need_prelocking);
if (need_prelocking && ! lex->requires_prelocking())
lex->mark_as_requiring_prelocking(save_query_tables_last);
error= extend_table_list(thd, tables, prelocking_strategy, has_prelocking_list);
if (error)
goto end;
}
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables_mode)
{
......@@ -4994,7 +5003,8 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
@retval TRUE Error, reported.
*/
bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
bool open_tables(THD *thd, TABLE_LIST **start, uint *counter,
Sroutine_hash_entry **sroutine_to_open_list, uint flags,
Prelocking_strategy *prelocking_strategy)
{
/*
......@@ -5043,7 +5053,7 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
has_prelocking_list= thd->lex->requires_prelocking();
table_to_open= start;
sroutine_to_open= (Sroutine_hash_entry**) &thd->lex->sroutines_list.first;
sroutine_to_open= sroutine_to_open_list;
*counter= 0;
thd_proc_info(thd, "Opening tables");
......@@ -5112,10 +5122,9 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
for (tables= *table_to_open; tables;
table_to_open= &tables->next_global, tables= tables->next_global)
{
error= open_and_process_table(thd, thd->lex, tables, counter,
flags, prelocking_strategy,
has_prelocking_list, &ot_ctx,
&new_frm_mem);
error= open_and_process_table(thd, tables, counter, flags,
prelocking_strategy, has_prelocking_list,
&ot_ctx, &new_frm_mem);
if (error)
{
......
......@@ -276,7 +276,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
bool lock_table_names(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *table_list_end, ulong lock_wait_timeout,
uint flags);
bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter,
Sroutine_hash_entry **sroutine_to_open, uint flags,
Prelocking_strategy *prelocking_strategy);
/* open_and_lock_tables with optional derived handling */
bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
......@@ -498,6 +499,15 @@ class Alter_table_prelocking_strategy : public Prelocking_strategy
};
inline bool
open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)
{
return open_tables(thd, tables, counter, &thd->lex->sroutines_list.first,
flags, prelocking_strategy);
}
inline bool
open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
{
......@@ -528,6 +538,10 @@ inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
}
bool extend_table_list(THD *thd, TABLE_LIST *tables,
Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list);
/**
A context of open_tables() function, used to recover
from a failed open_table() or open_routine() attempt.
......
......@@ -37,7 +37,7 @@
#include "sql_trigger.h"
#include "transaction.h"
#include "records.h" // init_read_record,
#include "sql_derived.h" // mysql_handle_list_of_derived
#include "sql_derived.h" // mysql_handle_derived
// end_read_record
/**
Implement DELETE SQL word.
......@@ -71,9 +71,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
if (thd->lex->handle_list_of_derived(table_list, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
if (!table_list->single_table_updatable())
......
......@@ -90,6 +90,7 @@ mysql_handle_derived(LEX *lex, uint phases)
sl= sl->next_select_in_list())
{
TABLE_LIST *cursor= sl->get_table_list();
sl->changed_elements|= TOUCHED_SEL_DERIVED;
/*
DT_MERGE_FOR_INSERT is not needed for views/derived tables inside
subqueries. Views and derived tables of subqueries should be
......@@ -199,36 +200,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
}
/**
Run specified phases for derived tables/views in the given list
@param lex LEX for this thread
@param table_list list of derived tables/view to handle
@param phase_map phases to process tables/views through
@details
This function runs phases specified by the 'phases_map' on derived
tables/views found in the 'dt_list' with help of the
TABLE_LIST::handle_derived function.
'lex' is passed as an argument to the TABLE_LIST::handle_derived.
@return FALSE ok
@return TRUE error
*/
bool
mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *table_list, uint phases)
{
for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local)
{
if (tl->is_view_or_derived() &&
tl->handle_derived(lex, phases))
return TRUE;
}
return FALSE;
}
/**
Merge a derived table/view into the embedding select
......@@ -1032,7 +1003,6 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->get_unit()));
st_select_lex_unit *unit= derived->get_unit();
if (derived->table)
derived->merged_for_insert= FALSE;
unit->unclean();
unit->types.empty();
......
......@@ -22,7 +22,6 @@ struct LEX;
bool mysql_handle_derived(LEX *lex, uint phases);
bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases);
bool mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *dt_list, uint phases);
/**
Cleans up the SELECT_LEX_UNIT for the derived table (if any).
......
......@@ -1404,7 +1404,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
/*
For subqueries in VALUES() we should not see the table in which we are
......@@ -1510,7 +1510,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
}
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
select_lex->first_execution= 0;
}
/*
Only call prepare_for_posistion() if we are not performing a DELAYED
......
......@@ -1904,7 +1904,7 @@ void st_select_lex::init_query()
n_child_sum_items= 0;
subquery_in_having= explicit_limit= 0;
is_item_list_lookup= 0;
first_execution= 1;
changed_elements= 0;
first_natural_join_processing= 1;
first_cond_optimization= 1;
parsing_place= NO_MATTER;
......@@ -3367,9 +3367,10 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
Item **having_conds)
{
DBUG_ENTER("st_select_lex::fix_prepare_information");
if (!thd->stmt_arena->is_conventional() && first_execution)
if (!thd->stmt_arena->is_conventional() &&
!(changed_elements & TOUCHED_SEL_COND))
{
first_execution= 0;
changed_elements|= TOUCHED_SEL_COND;
if (group_list.first)
{
if (!group_list_ptrs)
......@@ -3593,14 +3594,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
bool st_select_lex::handle_derived(LEX *lex, uint phases)
{
for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first;
cursor;
cursor= cursor->next_local)
{
if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
return TRUE;
}
return FALSE;
return lex->handle_list_of_derived(table_list.first, phases);
}
......
......@@ -589,7 +589,7 @@ class st_select_lex_node {
enum_mdl_type mdl_type= MDL_SHARED_READ,
List<Index_hint> *hints= 0,
LEX_STRING *option= 0);
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
virtual void set_lock_for_tables(thr_lock_type lock_type, bool for_update) {}
friend class st_select_lex_unit;
friend bool mysql_new_select(LEX *lex, bool move_down);
......@@ -729,6 +729,10 @@ class st_select_lex_unit: public st_select_lex_node {
typedef class st_select_lex_unit SELECT_LEX_UNIT;
#define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */
#define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */
/*
SELECT_LEX - store information of parsed SELECT statment
*/
......@@ -876,7 +880,8 @@ class st_select_lex: public st_select_lex_node
subquery. Prepared statements work OK in that regard, as in
case of an error during prepare the PS is not created.
*/
bool first_execution;
uint8 changed_elements; // see TOUCHED_SEL_*
/* TODO: add foloowing first_* to bitmap above */
bool first_natural_join_processing;
bool first_cond_optimization;
/* do not wrap view fields with Item_ref */
......@@ -955,7 +960,7 @@ class st_select_lex: public st_select_lex_node
TABLE_LIST *convert_right_join();
List<Item>* get_item_list();
ulong get_table_join_options();
void set_lock_for_tables(thr_lock_type lock_type);
void set_lock_for_tables(thr_lock_type lock_type, bool for_update);
inline void init_order()
{
order_list.elements= 0;
......@@ -2785,6 +2790,31 @@ struct LEX: public Query_tables_list
}
bool save_prep_leaf_tables();
/*
Run specified phases for derived tables/views in the given list
@param table_list - list of derived tables/view to handle
@param phase - phases to process tables/views through
@details
This method runs phases specified by the 'phases' on derived
tables/views found in the 'table_list' with help of the
TABLE_LIST::handle_derived function.
'this' is passed as an argument to the TABLE_LIST::handle_derived.
@return false - ok
@return true - error
*/
bool handle_list_of_derived(TABLE_LIST *table_list, uint phases)
{
for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local)
{
if (tl->is_view_or_derived() && tl->handle_derived(this, phases))
return true;
}
return false;
}
};
......
......@@ -233,8 +233,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE))
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE);
if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
......@@ -250,6 +251,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
DBUG_RETURN(TRUE);
}
if (table_list->is_multitable())
{
my_error(ER_WRONG_USAGE, MYF(0), "Multi-table VIEW", "LOAD");
DBUG_RETURN(TRUE);
}
if (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd))
{
......
......@@ -2065,9 +2065,6 @@ mysql_execute_command(THD *thd)
reset_one_shot_variables(thd);
DBUG_RETURN(0);
}
for (table=all_tables; table; table=table->next_global)
table->updating= TRUE;
}
/*
......@@ -4088,6 +4085,8 @@ case SQLCOM_PREPARE:
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
goto error;
}
}
/*
If SERVER_MORE_RESULTS_EXISTS is not set,
then remember that it should be cleared
......@@ -4095,7 +4094,6 @@ case SQLCOM_PREPARE:
bits_to_be_cleared= (~thd->server_status &
SERVER_MORE_RESULTS_EXISTS);
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
if (check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, TRUE, FALSE))
......@@ -6540,9 +6538,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
query
*/
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update)
{
bool for_update= lock_type >= TL_READ_NO_INSERT;
DBUG_ENTER("set_lock_for_tables");
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
for_update));
......
......@@ -2496,7 +2496,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
for (; sl; sl= sl->next_select_in_list())
{
if (!sl->first_execution)
if (sl->changed_elements & TOUCHED_SEL_COND)
{
/* remove option which was put by mysql_explain_union() */
sl->options&= ~SELECT_DESCRIBE;
......@@ -2543,11 +2543,20 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
order->next= sl->group_list_ptrs->at(ix+1);
}
}
}
{ // no harm to do it (item_ptr set on parsing)
ORDER *order;
for (order= sl->group_list.first; order; order= order->next)
{
order->item= &order->item_ptr;
}
/* Fix ORDER list */
for (order= sl->order_list.first; order; order= order->next)
{
order->item= &order->item_ptr;
}
}
if (sl->changed_elements & TOUCHED_SEL_DERIVED)
{
#ifndef DBUG_OFF
bool res=
......@@ -2555,7 +2564,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
sl->handle_derived(lex, DT_REINIT);
DBUG_ASSERT(res == 0);
}
}
{
SELECT_LEX_UNIT *unit= sl->master_unit();
unit->unclean();
......
......@@ -7620,8 +7620,6 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
table->alias_name_used= my_strcasecmp(table_alias_charset,
table_list->schema_table_name,
table_list->alias);
table_list->table_name= table->s->table_name.str;
table_list->table_name_length= table->s->table_name.length;
table_list->table= table;
table->next= thd->derived_tables;
thd->derived_tables= table;
......
......@@ -150,15 +150,11 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table)
/* Loop over the set of foreign keys for which this table is a parent. */
while ((fk_info= it++))
{
DBUG_ASSERT(!my_strcasecmp(system_charset_info,
fk_info->referenced_db->str,
table->s->db.str));
DBUG_ASSERT(!my_strcasecmp(system_charset_info,
fk_info->referenced_table->str,
table->s->table_name.str));
if (my_strcasecmp(system_charset_info, fk_info->foreign_db->str,
if (my_strcasecmp(system_charset_info, fk_info->referenced_db->str,
table->s->db.str) ||
my_strcasecmp(system_charset_info, fk_info->referenced_table->str,
table->s->table_name.str) ||
my_strcasecmp(system_charset_info, fk_info->foreign_db->str,
table->s->db.str) ||
my_strcasecmp(system_charset_info, fk_info->foreign_table->str,
table->s->table_name.str))
......
......@@ -216,7 +216,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
shows whether this is called at the first execution of the union that
may form just a subselect.
*/
if (!fake_select_lex->first_execution && first_execution)
if ((fake_select_lex->changed_elements & TOUCHED_SEL_COND) &&
first_execution)
{
for (ORDER *order= global_parameters->order_list.first;
order;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment