summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r--sql/sql_class.h217
1 files changed, 139 insertions, 78 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a7c33cbc504..37e4697e708 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -632,6 +632,7 @@ typedef struct system_variables
ulong query_cache_type;
ulong tx_isolation;
ulong updatable_views_with_limit;
+ ulong alter_algorithm;
int max_user_connections;
ulong server_id;
/**
@@ -655,7 +656,6 @@ typedef struct system_variables
my_bool keep_files_on_create;
my_bool old_mode;
- my_bool old_alter_table;
my_bool old_passwords;
my_bool big_tables;
my_bool only_standard_compliant_cte;
@@ -820,8 +820,10 @@ typedef struct system_status_var
ulong feature_fulltext; /* +1 when MATCH is used */
ulong feature_gis; /* +1 opening a table with GIS features */
ulong feature_invisible_columns; /* +1 opening a table with invisible column */
+ ulong feature_json; /* +1 when JSON function appears in the statement */
ulong feature_locale; /* +1 when LOCALE is set */
ulong feature_subquery; /* +1 when subqueries are used */
+ ulong feature_system_versioning; /* +1 opening a table WITH SYSTEM VERSIONING */
ulong feature_timezone; /* +1 when XPATH is used */
ulong feature_trigger; /* +1 opening a table with triggers */
ulong feature_xml; /* +1 when XPATH is used */
@@ -1012,7 +1014,7 @@ public:
inline void* calloc(size_t size)
{
void *ptr;
- if ((ptr=alloc_root(mem_root,size)))
+ if (likely((ptr=alloc_root(mem_root,size))))
bzero(ptr, size);
return ptr;
}
@@ -1025,7 +1027,7 @@ public:
inline void *memdup_w_gap(const void *str, size_t size, size_t gap)
{
void *ptr;
- if ((ptr= alloc_root(mem_root,size+gap)))
+ if (likely((ptr= alloc_root(mem_root,size+gap))))
memcpy(ptr,str,size);
return ptr;
}
@@ -1101,21 +1103,6 @@ public:
LEX_CSTRING name; /* name for named prepared statements */
LEX *lex; // parse tree descriptor
/*
- LEX which represents current statement (conventional, SP or PS)
-
- For example during view parsing THD::lex will point to the views LEX and
- THD::stmt_lex will point to LEX of the statement where the view will be
- included
-
- Currently it is used to have always correct select numbering inside
- statement (LEX::current_select_number) without storing and restoring a
- global counter which was THD::select_number.
-
- TODO: make some unified statement representation (now SP has different)
- to store such data like LEX::current_select_number.
- */
- LEX *stmt_lex;
- /*
Points to the query associated with this statement. It's const, but
we need to declare it char * because all table handlers are written
in C and need to point to it.
@@ -1910,7 +1897,7 @@ public:
void unlink_all_closed_tables(THD *thd,
MYSQL_LOCK *lock,
size_t reopen_count);
- bool reopen_tables(THD *thd);
+ bool reopen_tables(THD *thd, bool need_reopen);
bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table,
MYSQL_LOCK *lock);
void add_back_last_deleted_lock(TABLE_LIST *dst_table_list);
@@ -2625,6 +2612,15 @@ public:
WT_THD wt; ///< for deadlock detection
Rows_log_event *m_pending_rows_event;
+ struct st_trans_time : public timeval
+ {
+ void reset(THD *thd)
+ {
+ tv_sec= thd->query_start();
+ tv_usec= (long) thd->query_start_sec_part();
+ }
+ } start_time;
+
/*
Tables changed in transaction (that must be invalidated in query cache).
List contain only transactional tables, that not invalidated in query
@@ -3068,7 +3064,7 @@ public:
/* See also thd_killed() */
inline bool check_killed()
{
- if (killed)
+ if (unlikely(killed))
return TRUE;
if (apc_target.have_apc_requests())
apc_target.process_apc_requests();
@@ -3129,8 +3125,10 @@ public:
is set if a statement accesses a temporary table created through
CREATE TEMPORARY TABLE.
*/
- bool charset_is_system_charset, charset_is_collation_connection;
+private:
+ bool charset_is_system_charset, charset_is_collation_connection;
bool charset_is_character_set_filesystem;
+public:
bool enable_slow_log; /* Enable slow log for current statement */
bool abort_on_warning;
bool got_warning; /* Set on call to push_warning() */
@@ -3434,16 +3432,13 @@ public:
{ query_start_sec_part_used=1; return start_time_sec_part; }
MYSQL_TIME query_start_TIME();
+private:
struct {
my_hrtime_t start;
my_time_t sec;
ulong sec_part;
} system_time;
- ulong systime_sec_part() { query_start_sec_part_used=1; return system_time.sec_part; }
- my_time_t systime() { return system_time.sec; }
-
-private:
void set_system_time()
{
my_hrtime_t hrtime= my_hrtime();
@@ -3468,29 +3463,16 @@ private:
}
}
- void set_system_time_from_user_time(bool with_sec_part)
+public:
+ timeval transaction_time()
{
- if (with_sec_part)
- {
- system_time.sec= start_time;
- system_time.sec_part= start_time_sec_part;
- }
- else
- {
- if (system_time.sec == start_time)
- system_time.sec_part++;
- else
- {
- system_time.sec= start_time;
- system_time.sec_part= 0;
- }
- }
+ if (!in_multi_stmt_transaction_mode())
+ transaction.start_time.reset(this);
+ return transaction.start_time;
}
-public:
inline void set_start_time()
{
- set_system_time();
if (user_time.val)
{
start_time= hrtime_to_my_time(user_time);
@@ -3498,6 +3480,7 @@ public:
}
else
{
+ set_system_time();
start_time= system_time.sec;
start_time_sec_part= system_time.sec_part;
}
@@ -3508,6 +3491,7 @@ public:
set_start_time();
start_utime= utime_after_lock= microsecond_interval_timer();
}
+ /* only used in SET @@timestamp=... */
inline void set_time(my_hrtime_t t)
{
user_time= t;
@@ -3519,15 +3503,29 @@ public:
*/
inline void set_time(my_time_t t, ulong sec_part)
{
- start_time= t;
- start_time_sec_part= sec_part > TIME_MAX_SECOND_PART ? 0 : sec_part;
- user_time.val= hrtime_from_time(start_time) + start_time_sec_part;
- if (slave_thread)
- set_system_time_from_user_time(sec_part <= TIME_MAX_SECOND_PART);
- else // BINLOG command
- set_system_time();
- PSI_CALL_set_thread_start_time(start_time);
- start_utime= utime_after_lock= microsecond_interval_timer();
+ if (opt_secure_timestamp > (slave_thread ? SECTIME_REPL : SECTIME_SUPER))
+ set_time(); // note that BINLOG itself requires SUPER
+ else
+ {
+ if (sec_part <= TIME_MAX_SECOND_PART)
+ {
+ start_time= system_time.sec= t;
+ start_time_sec_part= system_time.sec_part= sec_part;
+ }
+ else if (t != system_time.sec)
+ {
+ start_time= system_time.sec= t;
+ start_time_sec_part= system_time.sec_part= 0;
+ }
+ else
+ {
+ start_time= t;
+ start_time_sec_part= ++system_time.sec_part;
+ }
+ user_time.val= hrtime_from_time(start_time) + start_time_sec_part;
+ PSI_CALL_set_thread_start_time(start_time);
+ start_utime= utime_after_lock= microsecond_interval_timer();
+ }
}
void set_time_after_lock()
{
@@ -3657,13 +3655,34 @@ public:
lex_str->length= length;
return lex_str;
}
+ // Remove double quotes: aaa""bbb -> aaa"bbb
+ bool quote_unescape(LEX_CSTRING *dst, const LEX_CSTRING *src, char quote)
+ {
+ const char *tmp= src->str;
+ const char *tmpend= src->str + src->length;
+ char *to;
+ if (!(dst->str= to= (char *) alloc(src->length + 1)))
+ {
+ dst->length= 0; // Safety
+ return true;
+ }
+ for ( ; tmp < tmpend; )
+ {
+ if ((*to++= *tmp++) == quote)
+ tmp++; // Skip double quotes
+ }
+ *to= 0; // End null for safety
+ dst->length= to - dst->str;
+ return false;
+ }
LEX_CSTRING *make_clex_string(const char* str, size_t length)
{
LEX_CSTRING *lex_str;
char *tmp;
- if (!(lex_str= (LEX_CSTRING *)alloc_root(mem_root, sizeof(LEX_CSTRING) +
- length+1)))
+ if (unlikely(!(lex_str= (LEX_CSTRING *)alloc_root(mem_root,
+ sizeof(LEX_CSTRING) +
+ length+1))))
return 0;
tmp= (char*) (lex_str+1);
lex_str->str= tmp;
@@ -3676,7 +3695,7 @@ public:
// Allocate LEX_STRING for character set conversion
bool alloc_lex_string(LEX_STRING *dst, size_t length)
{
- if ((dst->str= (char*) alloc(length)))
+ if (likely((dst->str= (char*) alloc(length))))
return false;
dst->length= 0; // Safety
return true; // EOM
@@ -3684,6 +3703,25 @@ public:
bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
const char *from, size_t from_length,
CHARSET_INFO *from_cs);
+ bool convert_string(LEX_CSTRING *to, CHARSET_INFO *to_cs,
+ const char *from, size_t from_length,
+ CHARSET_INFO *from_cs)
+ {
+ LEX_STRING tmp;
+ bool rc= convert_string(&tmp, to_cs, from, from_length, from_cs);
+ to->str= tmp.str;
+ to->length= tmp.length;
+ return rc;
+ }
+ bool convert_string(LEX_CSTRING *to, CHARSET_INFO *tocs,
+ const LEX_CSTRING *from, CHARSET_INFO *fromcs,
+ bool simple_copy_is_possible)
+ {
+ if (!simple_copy_is_possible)
+ return unlikely(convert_string(to, tocs, from->str, from->length, fromcs));
+ *to= *from;
+ return false;
+ }
/*
Convert a strings between character sets.
Uses my_convert_fix(), which uses an mb_wc .. mc_mb loop internally.
@@ -3700,7 +3738,6 @@ public:
bool convert_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
CHARSET_INFO *srccs,
const char *src, size_t src_length);
-
/*
If either "dstcs" or "srccs" is &my_charset_bin,
then performs native copying using cs->cset->copy_fix().
@@ -3720,6 +3757,17 @@ public:
bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs);
/*
+ Check if the string is wellformed, raise an error if not wellformed.
+ @param str - The string to check.
+ @param length - the string length.
+ */
+ bool check_string_for_wellformedness(const char *str,
+ size_t length,
+ CHARSET_INFO *cs) const;
+
+ bool to_ident_sys_alloc(Lex_ident_sys_st *to, const Lex_ident_cli_st *from);
+
+ /*
Create a string literal with optional client->connection conversion.
@param str - the string in the client character set
@param length - length of the string
@@ -3735,9 +3783,29 @@ public:
Item_basic_constant *make_string_literal_nchar(const Lex_string_with_metadata_st &str);
Item_basic_constant *make_string_literal_charset(const Lex_string_with_metadata_st &str,
CHARSET_INFO *cs);
+ bool make_text_string_sys(LEX_CSTRING *to,
+ const Lex_string_with_metadata_st *from)
+ {
+ return convert_string(to, system_charset_info,
+ from, charset(), charset_is_system_charset);
+ }
+ bool make_text_string_connection(LEX_CSTRING *to,
+ const Lex_string_with_metadata_st *from)
+ {
+ return convert_string(to, variables.collation_connection,
+ from, charset(), charset_is_collation_connection);
+ }
+ bool make_text_string_filesystem(LEX_CSTRING *to,
+ const Lex_string_with_metadata_st *from)
+ {
+ return convert_string(to, variables.character_set_filesystem,
+ from, charset(), charset_is_character_set_filesystem);
+ }
void add_changed_table(TABLE *table);
void add_changed_table(const char *key, size_t key_length);
CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length);
+ void prepare_explain_fields(select_result *result, List<Item> *field_list,
+ uint8 explain_flags, bool is_analyze);
int send_explain_fields(select_result *result, uint8 explain_flags,
bool is_analyze);
void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
@@ -3824,7 +3892,7 @@ public:
void set_stmt_da(Diagnostics_area *da)
{ m_stmt_da= da; }
- inline CHARSET_INFO *charset() { return variables.character_set_client; }
+ inline CHARSET_INFO *charset() const { return variables.character_set_client; }
void update_charset();
void update_charset(CHARSET_INFO *character_set_client,
CHARSET_INFO *collation_connection)
@@ -3932,7 +4000,7 @@ public:
The worst things that can happen is that we get
a suboptimal error message.
*/
- if ((killed_err= (err_info*) alloc(sizeof(*killed_err))))
+ if (likely((killed_err= (err_info*) alloc(sizeof(*killed_err)))))
{
killed_err->no= killed_errno_arg;
::strmake((char*) killed_err->msg, killed_err_msg_arg,
@@ -4214,16 +4282,8 @@ public:
void parse_error(const char *err_text, const char *yytext)
{
Lex_input_stream *lip= &m_parser_state->m_lip;
- if (!yytext)
- {
- if (lip->lookahead_token >= 0)
- yytext= lip->get_tok_start_prev();
- else
- yytext= lip->get_tok_start();
-
- if (!yytext)
+ if (!yytext && !(yytext= lip->get_tok_start()))
yytext= "";
- }
/* Push an error into the error stack */
ErrConvString err(yytext, strlen(yytext), variables.character_set_client);
my_printf_error(ER_PARSE_ERROR, ER_THD(this, ER_PARSE_ERROR), MYF(0),
@@ -4606,7 +4666,6 @@ public:
query_id_t wsrep_last_query_id;
enum wsrep_query_state wsrep_query_state;
enum wsrep_conflict_state wsrep_conflict_state;
- mysql_mutex_t LOCK_wsrep_thd;
wsrep_trx_meta_t wsrep_trx_meta;
uint32 wsrep_rand;
Relay_log_info *wsrep_rli;
@@ -4727,7 +4786,7 @@ public:
void set_local_lex(sp_lex_local *sublex)
{
DBUG_ASSERT(lex->sphead);
- lex= stmt_lex= sublex;
+ lex= sublex;
/* Reset part of parser state which needs this. */
m_parser_state->m_yacc.reset_before_substatement();
}
@@ -4907,7 +4966,7 @@ public:
unit= u;
return 0;
}
- virtual int prepare2(void) { return 0; }
+ virtual int prepare2(JOIN *join) { return 0; }
/*
Because of peculiarities of prepared statements protocol
we need to know number of columns in the result set (if
@@ -4916,7 +4975,7 @@ public:
virtual uint field_count(List<Item> &fields) const
{ return fields.elements; }
virtual bool send_result_set_metadata(List<Item> &list, uint flags)=0;
- virtual bool initialize_tables (JOIN *join=0) { return 0; }
+ virtual bool initialize_tables (JOIN *join) { return 0; }
virtual bool send_eof()=0;
/**
Check if this query returns a result set and therefore is allowed in
@@ -5151,7 +5210,7 @@ class select_insert :public select_result_interceptor {
enum_duplicates duplic, bool ignore);
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- virtual int prepare2(void);
+ virtual int prepare2(JOIN *join);
virtual int send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; }
@@ -5203,7 +5262,7 @@ public:
// Needed for access from local class MY_HOOKS in prepare(), since thd is proteted.
const THD *get_thd(void) { return thd; }
const HA_CREATE_INFO *get_create_info() { return create_info; };
- int prepare2(void) { return 0; }
+ int prepare2(JOIN *join) { return 0; }
private:
TABLE *create_table_from_items(THD *thd,
@@ -5468,7 +5527,7 @@ public:
bool postponed_prepare(List<Item> &types);
bool send_result_set_metadata(List<Item> &list, uint flags);
int send_data(List<Item> &items);
- bool initialize_tables (JOIN *join= NULL);
+ bool initialize_tables (JOIN *join);
bool send_eof();
bool flush() { return false; }
bool check_simple_select() const
@@ -5887,6 +5946,7 @@ public:
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
+ int prepare2(JOIN *join);
int do_updates();
bool send_eof();
inline ha_rows num_found() const { return found; }
@@ -6364,7 +6424,8 @@ public:
char *tmp;
/* format: [database + dot] + name + '\0' */
dst->length= m_db.length + dot + m_name.length;
- if (!(dst->str= tmp= (char*) alloc_root(mem_root, dst->length + 1)))
+ if (unlikely(!(dst->str= tmp= (char*) alloc_root(mem_root,
+ dst->length + 1))))
return true;
sprintf(tmp, "%.*s%.*s%.*s",
(int) m_db.length, (m_db.length ? m_db.str : ""),
@@ -6380,7 +6441,7 @@ public:
{
char *tmp;
size_t length= package.length + 1 + routine.length + 1;
- if (!(tmp= (char *) alloc_root(mem_root, length)))
+ if (unlikely(!(tmp= (char *) alloc_root(mem_root, length))))
return true;
m_name.length= my_snprintf(tmp, length, "%.*s.%.*s",
(int) package.length, package.str,
@@ -6394,9 +6455,9 @@ public:
const LEX_CSTRING &package,
const LEX_CSTRING &routine)
{
- if (make_package_routine_name(mem_root, package, routine))
+ if (unlikely(make_package_routine_name(mem_root, package, routine)))
return true;
- if (!(m_db.str= strmake_root(mem_root, db.str, db.length)))
+ if (unlikely(!(m_db.str= strmake_root(mem_root, db.str, db.length))))
return true;
m_db.length= db.length;
return false;