mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge 10.2 into 10.2-mdev9864.
This commit is contained in:
270
sql/sql_class.h
270
sql/sql_class.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2016, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -226,6 +226,7 @@ typedef struct st_copy_info {
|
||||
List<Item> *update_values;
|
||||
/* for VIEW ... WITH CHECK OPTION */
|
||||
TABLE_LIST *view;
|
||||
TABLE_LIST *table_list; /* Normal table */
|
||||
} COPY_INFO;
|
||||
|
||||
|
||||
@ -256,7 +257,7 @@ public:
|
||||
|
||||
class Alter_drop :public Sql_alloc {
|
||||
public:
|
||||
enum drop_type {KEY, COLUMN, FOREIGN_KEY };
|
||||
enum drop_type {KEY, COLUMN, FOREIGN_KEY, CHECK_CONSTRAINT };
|
||||
const char *name;
|
||||
enum drop_type type;
|
||||
bool drop_if_exists;
|
||||
@ -271,15 +272,21 @@ public:
|
||||
*/
|
||||
Alter_drop *clone(MEM_ROOT *mem_root) const
|
||||
{ return new (mem_root) Alter_drop(*this); }
|
||||
const char *type_name()
|
||||
{
|
||||
return type == COLUMN ? "COLUMN" :
|
||||
type == CHECK_CONSTRAINT ? "CONSTRAINT" :
|
||||
type == KEY ? "INDEX" : "FOREIGN KEY";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Alter_column :public Sql_alloc {
|
||||
public:
|
||||
const char *name;
|
||||
Item *def;
|
||||
Alter_column(const char *par_name,Item *literal)
|
||||
:name(par_name), def(literal) {}
|
||||
Virtual_column_info *default_value;
|
||||
Alter_column(const char *par_name, Virtual_column_info *expr)
|
||||
:name(par_name), default_value(expr) {}
|
||||
/**
|
||||
Used to make a clone of this object for ALTER/CREATE TABLE
|
||||
@sa comment for Key_part_spec::clone
|
||||
@ -818,8 +825,7 @@ typedef struct system_status_var
|
||||
Global status variables
|
||||
*/
|
||||
|
||||
extern ulong feature_files_opened_with_delayed_keys;
|
||||
|
||||
extern ulong feature_files_opened_with_delayed_keys, feature_check_constraint;
|
||||
|
||||
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
|
||||
|
||||
@ -1266,6 +1272,61 @@ enum enum_locked_tables_mode
|
||||
LTM_PRELOCKED_UNDER_LOCK_TABLES
|
||||
};
|
||||
|
||||
/**
|
||||
The following structure is an extension to TABLE_SHARE and is
|
||||
exclusively for temporary tables.
|
||||
|
||||
@note:
|
||||
Although, TDC_element has data members (like next, prev &
|
||||
all_tables) to store the list of TABLE_SHARE & TABLE objects
|
||||
related to a particular TABLE_SHARE, they cannot be moved to
|
||||
TABLE_SHARE in order to be reused for temporary tables. This
|
||||
is because, as concurrent threads iterating through hash of
|
||||
TDC_element's may need access to all_tables, but if all_tables
|
||||
is made part of TABLE_SHARE, then TDC_element->share->all_tables
|
||||
is not always guaranteed to be valid, as TDC_element can live
|
||||
longer than TABLE_SHARE.
|
||||
*/
|
||||
struct TMP_TABLE_SHARE : public TABLE_SHARE
|
||||
{
|
||||
private:
|
||||
/*
|
||||
Link to all temporary table shares. Declared as private to
|
||||
avoid direct manipulation with those objects. One should
|
||||
use methods of I_P_List template instead.
|
||||
*/
|
||||
TMP_TABLE_SHARE *tmp_next;
|
||||
TMP_TABLE_SHARE **tmp_prev;
|
||||
|
||||
friend struct All_tmp_table_shares;
|
||||
|
||||
public:
|
||||
/*
|
||||
Doubly-linked (back-linked) lists of used and unused TABLE objects
|
||||
for this share.
|
||||
*/
|
||||
All_share_tables_list all_tmp_tables;
|
||||
};
|
||||
|
||||
/**
|
||||
Helper class which specifies which members of TMP_TABLE_SHARE are
|
||||
used for participation in the list of temporary tables.
|
||||
*/
|
||||
|
||||
struct All_tmp_table_shares
|
||||
{
|
||||
static inline TMP_TABLE_SHARE **next_ptr(TMP_TABLE_SHARE *l)
|
||||
{
|
||||
return &l->tmp_next;
|
||||
}
|
||||
static inline TMP_TABLE_SHARE ***prev_ptr(TMP_TABLE_SHARE *l)
|
||||
{
|
||||
return &l->tmp_prev;
|
||||
}
|
||||
};
|
||||
|
||||
/* Also used in rpl_rli.h. */
|
||||
typedef I_P_List <TMP_TABLE_SHARE, All_tmp_table_shares> All_tmp_tables_list;
|
||||
|
||||
/**
|
||||
Class that holds information about tables which were opened and locked
|
||||
@ -1295,15 +1356,20 @@ public:
|
||||
base tables that were opened with @see open_tables().
|
||||
*/
|
||||
TABLE *open_tables;
|
||||
|
||||
/**
|
||||
List of temporary tables used by this thread. Contains user-level
|
||||
temporary tables, created with CREATE TEMPORARY TABLE, and
|
||||
internal temporary tables, created, e.g., to resolve a SELECT,
|
||||
A list of temporary tables used by this thread. This includes
|
||||
user-level temporary tables, created with CREATE TEMPORARY TABLE,
|
||||
and internal temporary tables, created, e.g., to resolve a SELECT,
|
||||
or for an intermediate table used in ALTER.
|
||||
XXX Why are internal temporary tables added to this list?
|
||||
*/
|
||||
TABLE *temporary_tables;
|
||||
All_tmp_tables_list *temporary_tables;
|
||||
|
||||
/*
|
||||
Derived tables.
|
||||
*/
|
||||
TABLE *derived_tables;
|
||||
|
||||
/*
|
||||
During a MySQL session, one can lock tables in two modes: automatic
|
||||
or manual. In automatic mode all necessary tables are locked just before
|
||||
@ -1381,8 +1447,11 @@ public:
|
||||
|
||||
void reset_open_tables_state(THD *thd)
|
||||
{
|
||||
open_tables= temporary_tables= derived_tables= 0;
|
||||
extra_lock= lock= 0;
|
||||
open_tables= 0;
|
||||
temporary_tables= 0;
|
||||
derived_tables= 0;
|
||||
extra_lock= 0;
|
||||
lock= 0;
|
||||
locked_tables_mode= LTM_NONE;
|
||||
state_flags= 0U;
|
||||
m_reprepare_observer= NULL;
|
||||
@ -1432,7 +1501,7 @@ public:
|
||||
ha_rows cuted_fields, sent_row_count, examined_row_count;
|
||||
ulonglong client_capabilities;
|
||||
ulong query_plan_flags;
|
||||
uint in_sub_stmt;
|
||||
uint in_sub_stmt; /* 0, SUB_STMT_TRIGGER or SUB_STMT_FUNCTION */
|
||||
bool enable_slow_log;
|
||||
bool last_insert_id_used;
|
||||
SAVEPOINT *savepoints;
|
||||
@ -1908,6 +1977,19 @@ private:
|
||||
inline bool is_conventional() const
|
||||
{ DBUG_ASSERT(0); return Statement::is_conventional(); }
|
||||
|
||||
void dec_thread_count(void)
|
||||
{
|
||||
DBUG_ASSERT(thread_count > 0);
|
||||
thread_safe_decrement32(const_cast<int32*>(&thread_count));
|
||||
signal_thd_deleted();
|
||||
}
|
||||
|
||||
|
||||
void inc_thread_count(void)
|
||||
{
|
||||
thread_safe_increment32(const_cast<int32*>(&thread_count));
|
||||
}
|
||||
|
||||
public:
|
||||
MDL_context mdl_context;
|
||||
|
||||
@ -2205,6 +2287,18 @@ public:
|
||||
current_stmt_binlog_format == BINLOG_FORMAT_ROW);
|
||||
return current_stmt_binlog_format == BINLOG_FORMAT_ROW;
|
||||
}
|
||||
/**
|
||||
Determine if binlogging is disabled for this session
|
||||
@retval 0 if the current statement binlogging is disabled
|
||||
(could be because of binlog closed/binlog option
|
||||
is set to false).
|
||||
@retval 1 if the current statement will be binlogged
|
||||
*/
|
||||
inline bool is_current_stmt_binlog_disabled() const
|
||||
{
|
||||
return (!(variables.option_bits & OPTION_BIN_LOG) ||
|
||||
!mysql_bin_log.is_open());
|
||||
}
|
||||
|
||||
enum binlog_filter_state
|
||||
{
|
||||
@ -2654,7 +2748,7 @@ public:
|
||||
ulong query_plan_flags;
|
||||
ulong query_plan_fsort_passes;
|
||||
pthread_t real_id; /* For debugging */
|
||||
my_thread_id thread_id;
|
||||
my_thread_id thread_id, thread_dbug_id;
|
||||
uint32 os_thread_id;
|
||||
uint tmp_table, global_disable_checkpoint;
|
||||
uint server_status,open_options;
|
||||
@ -2766,7 +2860,7 @@ public:
|
||||
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
|
||||
bool substitute_null_with_insert_id;
|
||||
bool in_lock_tables;
|
||||
bool bootstrap, cleanup_done;
|
||||
bool bootstrap, cleanup_done, free_connection_done;
|
||||
|
||||
/** is set if some thread specific value(s) used in a statement. */
|
||||
bool thread_specific_used;
|
||||
@ -2908,7 +3002,7 @@ public:
|
||||
/* Debug Sync facility. See debug_sync.cc. */
|
||||
struct st_debug_sync_control *debug_sync_control;
|
||||
#endif /* defined(ENABLED_DEBUG_SYNC) */
|
||||
THD(bool is_wsrep_applier= false);
|
||||
THD(my_thread_id id, bool is_wsrep_applier= false);
|
||||
|
||||
~THD();
|
||||
|
||||
@ -2928,6 +3022,8 @@ public:
|
||||
void change_user(void);
|
||||
void cleanup(void);
|
||||
void cleanup_after_query();
|
||||
void free_connection();
|
||||
void reset_for_reuse();
|
||||
bool store_globals();
|
||||
void reset_globals();
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
@ -2935,7 +3031,6 @@ public:
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thd_data);
|
||||
active_vio = vio;
|
||||
vio_set_thread_id(vio, pthread_self());
|
||||
mysql_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
inline void clear_active_vio()
|
||||
@ -3100,6 +3195,12 @@ public:
|
||||
}
|
||||
ulonglong current_utime() { return microsecond_interval_timer(); }
|
||||
|
||||
/* Tell SHOW PROCESSLIST to show time from this point */
|
||||
inline void set_time_for_next_stage()
|
||||
{
|
||||
utime_after_query= current_utime();
|
||||
}
|
||||
|
||||
/**
|
||||
Update server status after execution of a top level statement.
|
||||
Currently only checks if a query was slow, and assigns
|
||||
@ -3109,7 +3210,7 @@ public:
|
||||
*/
|
||||
void update_server_status()
|
||||
{
|
||||
utime_after_query= current_utime();
|
||||
set_time_for_next_stage();
|
||||
if (utime_after_query > utime_after_lock + variables.long_query_time)
|
||||
server_status|= SERVER_QUERY_WAS_SLOW;
|
||||
}
|
||||
@ -3341,6 +3442,22 @@ public:
|
||||
|
||||
inline CHARSET_INFO *charset() { return variables.character_set_client; }
|
||||
void update_charset();
|
||||
void update_charset(CHARSET_INFO *character_set_client,
|
||||
CHARSET_INFO *collation_connection)
|
||||
{
|
||||
variables.character_set_client= character_set_client;
|
||||
variables.collation_connection= collation_connection;
|
||||
update_charset();
|
||||
}
|
||||
void update_charset(CHARSET_INFO *character_set_client,
|
||||
CHARSET_INFO *collation_connection,
|
||||
CHARSET_INFO *character_set_results)
|
||||
{
|
||||
variables.character_set_client= character_set_client;
|
||||
variables.collation_connection= collation_connection;
|
||||
variables.character_set_results= character_set_results;
|
||||
update_charset();
|
||||
}
|
||||
|
||||
inline Query_arena *activate_stmt_arena_if_needed(Query_arena *backup)
|
||||
{
|
||||
@ -3532,13 +3649,13 @@ public:
|
||||
*/
|
||||
DBUG_PRINT("debug",
|
||||
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
|
||||
YESNO(temporary_tables), YESNO(in_sub_stmt),
|
||||
YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
|
||||
show_system_thread(system_thread)));
|
||||
if (in_sub_stmt == 0)
|
||||
{
|
||||
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
||||
set_current_stmt_binlog_format_row();
|
||||
else if (temporary_tables == NULL)
|
||||
else if (!has_thd_temporary_tables())
|
||||
set_current_stmt_binlog_format_stmt();
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
@ -3938,10 +4055,6 @@ private:
|
||||
LEX_STRING invoker_user;
|
||||
LEX_STRING invoker_host;
|
||||
|
||||
/* Protect against add/delete of temporary tables in parallel replication */
|
||||
void rgi_lock_temporary_tables();
|
||||
void rgi_unlock_temporary_tables();
|
||||
bool rgi_have_temporary_tables();
|
||||
public:
|
||||
/*
|
||||
Flag, mutex and condition for a thread to wait for a signal from another
|
||||
@ -3959,26 +4072,88 @@ public:
|
||||
*/
|
||||
rpl_gtid last_commit_gtid;
|
||||
|
||||
inline void lock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_lock_temporary_tables();
|
||||
}
|
||||
inline void unlock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_unlock_temporary_tables();
|
||||
}
|
||||
inline bool have_temporary_tables()
|
||||
{
|
||||
return (temporary_tables ||
|
||||
(rgi_slave && rgi_have_temporary_tables()));
|
||||
}
|
||||
|
||||
LF_PINS *tdc_hash_pins;
|
||||
LF_PINS *xid_hash_pins;
|
||||
bool fix_xid_hash_pins();
|
||||
|
||||
/* Members related to temporary tables. */
|
||||
public:
|
||||
bool has_thd_temporary_tables();
|
||||
|
||||
TABLE *create_and_open_tmp_table(handlerton *hton,
|
||||
LEX_CUSTRING *frm,
|
||||
const char *path,
|
||||
const char *db,
|
||||
const char *table_name,
|
||||
bool open_in_engine);
|
||||
|
||||
TABLE *find_temporary_table(const char *db, const char *table_name);
|
||||
TABLE *find_temporary_table(const TABLE_LIST *tl);
|
||||
|
||||
TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
|
||||
uint key_length);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const char *db,
|
||||
const char *table_name);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const TABLE_LIST *tl);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const char *key, uint key_length);
|
||||
|
||||
bool open_temporary_table(TABLE_LIST *tl);
|
||||
bool open_temporary_tables(TABLE_LIST *tl);
|
||||
|
||||
bool close_temporary_tables();
|
||||
bool rename_temporary_table(TABLE *table, const char *db,
|
||||
const char *table_name);
|
||||
bool drop_temporary_table(TABLE *table, bool *is_trans, bool delete_table);
|
||||
bool rm_temporary_table(handlerton *hton, const char *path);
|
||||
void mark_tmp_tables_as_free_for_reuse();
|
||||
void mark_tmp_table_as_free_for_reuse(TABLE *table);
|
||||
|
||||
TMP_TABLE_SHARE* save_tmp_table_share(TABLE *table);
|
||||
void restore_tmp_table_share(TMP_TABLE_SHARE *share);
|
||||
|
||||
private:
|
||||
/* Whether a lock has been acquired? */
|
||||
bool m_tmp_tables_locked;
|
||||
|
||||
/* Opened table states. */
|
||||
enum Temporary_table_state {
|
||||
TMP_TABLE_IN_USE,
|
||||
TMP_TABLE_NOT_IN_USE,
|
||||
TMP_TABLE_ANY
|
||||
};
|
||||
|
||||
bool has_temporary_tables();
|
||||
uint create_tmp_table_def_key(char *key, const char *db,
|
||||
const char *table_name);
|
||||
TMP_TABLE_SHARE *create_temporary_table(handlerton *hton, LEX_CUSTRING *frm,
|
||||
const char *path, const char *db,
|
||||
const char *table_name);
|
||||
TABLE *find_temporary_table(const char *key, uint key_length,
|
||||
Temporary_table_state state);
|
||||
TABLE *open_temporary_table(TMP_TABLE_SHARE *share, const char *alias,
|
||||
bool open_in_engine);
|
||||
bool find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table);
|
||||
bool use_temporary_table(TABLE *table, TABLE **out_table);
|
||||
void close_temporary_table(TABLE *table);
|
||||
bool log_events_and_free_tmp_shares();
|
||||
void free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table);
|
||||
void free_temporary_table(TABLE *table);
|
||||
bool lock_temporary_tables();
|
||||
void unlock_temporary_tables();
|
||||
|
||||
inline uint tmpkeyval(TMP_TABLE_SHARE *share)
|
||||
{
|
||||
return uint4korr(share->table_cache_key.str +
|
||||
share->table_cache_key.length - 4);
|
||||
}
|
||||
|
||||
inline TMP_TABLE_SHARE *tmp_table_share(TABLE *table)
|
||||
{
|
||||
DBUG_ASSERT(table->s->tmp_table);
|
||||
return static_cast<TMP_TABLE_SHARE *>(table->s);
|
||||
}
|
||||
|
||||
public:
|
||||
inline ulong wsrep_binlog_format() const
|
||||
{
|
||||
return WSREP_FORMAT(variables.binlog_format);
|
||||
@ -4085,12 +4260,12 @@ inline void add_to_active_threads(THD *thd)
|
||||
/*
|
||||
This should be called when you want to delete a thd that was not
|
||||
running any queries.
|
||||
This function will assert if the THD was not linked.
|
||||
This function will assert that the THD is linked.
|
||||
*/
|
||||
|
||||
inline void unlink_not_visible_thd(THD *thd)
|
||||
{
|
||||
thd->assert_if_linked();
|
||||
thd->assert_linked();
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
@ -4488,6 +4663,7 @@ class select_create: public select_insert {
|
||||
/* m_lock or thd->extra_lock */
|
||||
MYSQL_LOCK **m_plock;
|
||||
bool exit_done;
|
||||
TMP_TABLE_SHARE *saved_tmp_table_share;
|
||||
|
||||
public:
|
||||
select_create(THD *thd_arg, TABLE_LIST *table_arg,
|
||||
@ -4495,12 +4671,14 @@ public:
|
||||
Alter_info *alter_info_arg,
|
||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore,
|
||||
TABLE_LIST *select_tables_arg):
|
||||
select_insert(thd_arg, NULL, NULL, &select_fields, 0, 0, duplic, ignore),
|
||||
select_insert(thd_arg, table_arg, NULL, &select_fields, 0, 0, duplic,
|
||||
ignore),
|
||||
create_table(table_arg),
|
||||
create_info(create_info_par),
|
||||
select_tables(select_tables_arg),
|
||||
alter_info(alter_info_arg),
|
||||
m_plock(NULL), exit_done(0)
|
||||
m_plock(NULL), exit_done(0),
|
||||
saved_tmp_table_share(0)
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
|
Reference in New Issue
Block a user