diff options
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r-- | sql/sql_class.h | 217 |
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; |