1
0
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:
Igor Babaev
2016-08-30 16:14:51 -07:00
1739 changed files with 87430 additions and 36812 deletions

View File

@ -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);