mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge branch '11.4' into 11.5
This commit is contained in:
166
sql/sql_parse.cc
166
sql/sql_parse.cc
@ -2248,6 +2248,7 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD *
|
||||
my_eof(thd);
|
||||
kill_mysql(thd);
|
||||
error=TRUE;
|
||||
DBUG_EXECUTE_IF("simulate_slow_client_at_shutdown", my_sleep(2000000););
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2405,6 +2406,11 @@ resume:
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (thd->reset_sp_cache)
|
||||
{
|
||||
thd->sp_caches_empty();
|
||||
thd->reset_sp_cache= false;
|
||||
}
|
||||
|
||||
if (do_end_of_statement)
|
||||
{
|
||||
@ -2482,6 +2488,7 @@ resume:
|
||||
MYSQL_COMMAND_DONE(res);
|
||||
}
|
||||
DEBUG_SYNC(thd,"dispatch_command_end");
|
||||
DEBUG_SYNC(thd,"dispatch_command_end2");
|
||||
|
||||
/* Check that some variables are reset properly */
|
||||
DBUG_ASSERT(thd->abort_on_warning == 0);
|
||||
@ -4497,10 +4504,15 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
|
||||
|
||||
if ((res= insert_precheck(thd, all_tables)))
|
||||
break;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED)
|
||||
bool wsrep_toi= false;
|
||||
const bool wsrep= WSREP(thd);
|
||||
|
||||
if (wsrep && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED)
|
||||
{
|
||||
thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING;
|
||||
wsrep_toi= true;
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
@ -4535,6 +4547,27 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
|
||||
if (!(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
|
||||
{
|
||||
MYSQL_INSERT_SELECT_START(thd->query());
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep && !first_table->view)
|
||||
{
|
||||
bool is_innodb= (first_table->table->file->ht->db_type == DB_TYPE_INNODB);
|
||||
|
||||
// For consistency check inserted table needs to be InnoDB
|
||||
if (!is_innodb && thd->wsrep_consistency_check != NO_CONSISTENCY_CHECK)
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
HA_ERR_UNSUPPORTED,
|
||||
"Galera cluster does support consistency check only"
|
||||
" for InnoDB tables.");
|
||||
thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK;
|
||||
}
|
||||
|
||||
// For !InnoDB we start TOI if it is not yet started and hope for the best
|
||||
if (!is_innodb && !wsrep_toi)
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/*
|
||||
Only the INSERT table should be merged. Other will be handled by
|
||||
select.
|
||||
@ -5574,7 +5607,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
|
||||
if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
|
||||
lex->spname, &sph, &pkgname))
|
||||
return true;
|
||||
if (sph->sp_cache_routine(thd, lex->spname, false, &sp))
|
||||
if (sph->sp_cache_routine(thd, lex->spname, &sp))
|
||||
goto error;
|
||||
if (!sp || sp->show_routine_code(thd))
|
||||
{
|
||||
@ -5877,13 +5910,11 @@ finish:
|
||||
if (unlikely(thd->is_error()) ||
|
||||
(thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
|
||||
{
|
||||
THD_STAGE_INFO(thd, stage_rollback);
|
||||
trans_rollback_stmt(thd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If commit fails, we should be able to reset the OK status. */
|
||||
THD_STAGE_INFO(thd, stage_commit);
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
trans_commit_stmt(thd);
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
@ -5910,7 +5941,6 @@ finish:
|
||||
one of storage engines (e.g. due to deadlock). Rollback transaction in
|
||||
all storage engines including binary log.
|
||||
*/
|
||||
THD_STAGE_INFO(thd, stage_rollback_implicit);
|
||||
trans_rollback_implicit(thd);
|
||||
thd->release_transactional_locks();
|
||||
}
|
||||
@ -5920,7 +5950,6 @@ finish:
|
||||
DBUG_ASSERT(! thd->in_sub_stmt);
|
||||
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
|
||||
{
|
||||
THD_STAGE_INFO(thd, stage_commit_implicit);
|
||||
/* If commit fails, we should be able to reset the OK status. */
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
/* Commit the normal transaction if one is active. */
|
||||
@ -5992,6 +6021,24 @@ finish:
|
||||
thd->wsrep_PA_safe= true;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/*
|
||||
Reset the connection_name to contain a null string, if the
|
||||
pointer points to the same space as that of the system variable
|
||||
default_master_connection.
|
||||
|
||||
We do this because the system variable may be updated which could
|
||||
free the pointer and create a new one, causing use-after-free for
|
||||
re-execution of prepared statements and stored procedures where
|
||||
the LEX may be reused.
|
||||
|
||||
This allows connection_name to be set again be to the system
|
||||
variable pointer in the next call of this function (see earlier in
|
||||
this function), after any possible updates to the system variable.
|
||||
*/
|
||||
if (thd->lex->mi.connection_name.str ==
|
||||
thd->variables.default_master_connection.str)
|
||||
thd->lex->mi.connection_name= null_clex_str;
|
||||
|
||||
if (lex->sql_command != SQLCOM_SET_OPTION)
|
||||
DEBUG_SYNC(thd, "end_of_statement");
|
||||
DBUG_RETURN(res || thd->is_error());
|
||||
@ -7969,7 +8016,7 @@ bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
|
||||
*/
|
||||
|
||||
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
const Table_ident *table,
|
||||
Table_ident *table,
|
||||
const LEX_CSTRING *alias,
|
||||
ulong table_options,
|
||||
thr_lock_type lock_type,
|
||||
@ -7978,9 +8025,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
List<String> *partition_names,
|
||||
LEX_STRING *option)
|
||||
{
|
||||
TABLE_LIST *ptr;
|
||||
TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */
|
||||
LEX *lex= thd->lex;
|
||||
DBUG_ENTER("add_table_to_list");
|
||||
DBUG_PRINT("enter", ("Table '%s' (%p) Select %p (%u)",
|
||||
(alias ? alias->str : table->table.str),
|
||||
@ -7990,11 +8034,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
|
||||
if (unlikely(!table))
|
||||
DBUG_RETURN(0); // End of memory
|
||||
Lex_ident_table alias_str= alias ? Lex_ident_table(*alias) :
|
||||
Lex_ident_table(table->table);
|
||||
DBUG_ASSERT(alias_str.str);
|
||||
if (!MY_TEST(table_options & TL_OPTION_ALIAS) &&
|
||||
unlikely(Lex_ident_table::check_name(table->table, false)))
|
||||
if (!(table_options & TL_OPTION_ALIAS) &&
|
||||
unlikely(Lex_ident_table::check_name(table->table, FALSE)))
|
||||
{
|
||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
|
||||
DBUG_RETURN(0);
|
||||
@ -8005,6 +8046,35 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
Lex_ident_db::check_name_with_error(table->db)))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
Lex_ident_db db{0, 0};
|
||||
bool fqtn= false;
|
||||
LEX *lex= thd->lex;
|
||||
if (table->db.str)
|
||||
{
|
||||
fqtn= TRUE;
|
||||
db= Lex_ident_db(table->db);
|
||||
}
|
||||
else if (!lex->with_cte_resolution && lex->copy_db_to(&db))
|
||||
DBUG_RETURN(0);
|
||||
else
|
||||
fqtn= FALSE;
|
||||
bool info_schema= is_infoschema_db(&db);
|
||||
if (!table->sel && info_schema &&
|
||||
(table_options & TL_OPTION_UPDATING) &&
|
||||
/* Special cases which are processed by commands itself */
|
||||
lex->sql_command != SQLCOM_CHECK &&
|
||||
lex->sql_command != SQLCOM_CHECKSUM)
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host,
|
||||
INFORMATION_SCHEMA_NAME.str);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
Lex_ident_table alias_str= alias ? Lex_ident_table(*alias) :
|
||||
Lex_ident_table(table->table);
|
||||
DBUG_ASSERT(alias_str.str);
|
||||
if (!alias) /* Alias is case sensitive */
|
||||
{
|
||||
if (unlikely(table->sel))
|
||||
@ -8017,64 +8087,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
if (unlikely(!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1))))
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (unlikely(!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))))
|
||||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
if (table->db.str)
|
||||
{
|
||||
ptr->is_fqtn= TRUE;
|
||||
ptr->db= Lex_ident_db(table->db);
|
||||
}
|
||||
else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db))
|
||||
DBUG_RETURN(0);
|
||||
else
|
||||
ptr->is_fqtn= FALSE;
|
||||
|
||||
ptr->alias= alias_str;
|
||||
ptr->is_alias= alias ? TRUE : FALSE;
|
||||
ptr->table_name= Lex_ident_table(table->table);
|
||||
bool has_alias_ptr= alias != nullptr;
|
||||
void *memregion= thd->calloc(sizeof(TABLE_LIST));
|
||||
TABLE_LIST *ptr= new (memregion) TABLE_LIST(thd, db, fqtn, alias_str,
|
||||
has_alias_ptr, table, lock_type,
|
||||
mdl_type, table_options,
|
||||
info_schema, this,
|
||||
index_hints_arg, option);
|
||||
if (!ptr->table_name.str)
|
||||
DBUG_RETURN(0); // EOM
|
||||
|
||||
if (lower_case_table_names)
|
||||
{
|
||||
if (!(ptr->table_name= thd->lex_ident_casedn(ptr->table_name)).str)
|
||||
DBUG_RETURN(0);
|
||||
if (ptr->db.length && ptr->db.str != any_db.str &&
|
||||
!(ptr->db= thd->lex_ident_casedn(ptr->db)).str)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
ptr->lock_type= lock_type;
|
||||
ptr->mdl_type= mdl_type;
|
||||
ptr->table_options= table_options;
|
||||
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
|
||||
ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
|
||||
ptr->sequence= MY_TEST(table_options & TL_OPTION_SEQUENCE);
|
||||
ptr->derived= table->sel;
|
||||
if (!ptr->derived && is_infoschema_db(&ptr->db))
|
||||
{
|
||||
if (ptr->updating &&
|
||||
/* Special cases which are processed by commands itself */
|
||||
lex->sql_command != SQLCOM_CHECK &&
|
||||
lex->sql_command != SQLCOM_CHECKSUM)
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host,
|
||||
INFORMATION_SCHEMA_NAME.str);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
ST_SCHEMA_TABLE *schema_table;
|
||||
schema_table= find_schema_table(thd, &ptr->table_name);
|
||||
ptr->schema_table_name= Lex_ident_i_s_table(ptr->table_name);
|
||||
ptr->schema_table= schema_table;
|
||||
}
|
||||
ptr->select_lex= this;
|
||||
/*
|
||||
We can't cache internal temporary tables between prepares as the
|
||||
table may be deleted before next execution.
|
||||
*/
|
||||
ptr->cacheable_table= !table->is_derived_table();
|
||||
ptr->index_hints= index_hints_arg;
|
||||
ptr->option= option ? option->str : 0;
|
||||
/* check that used name is unique. Sequences are ignored */
|
||||
if (lock_type != TL_IGNORE && !ptr->sequence)
|
||||
{
|
||||
@ -8096,6 +8119,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
}
|
||||
}
|
||||
/* Store the table reference preceding the current one. */
|
||||
TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */
|
||||
if (table_list.elements > 0 && likely(!ptr->sequence))
|
||||
{
|
||||
/*
|
||||
|
Reference in New Issue
Block a user