My Project
|
00001 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights 00002 reserved. 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; version 2 of the License. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00016 00017 #ifndef SQL_CLASS_INCLUDED 00018 #define SQL_CLASS_INCLUDED 00019 00020 /* Classes in mysql */ 00021 00022 #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ 00023 #ifdef MYSQL_SERVER 00024 #include "unireg.h" // REQUIRED: for other includes 00025 #endif 00026 #include "sql_const.h" 00027 #include <mysql/plugin_audit.h> 00028 #include "log.h" 00029 #include "rpl_tblmap.h" 00030 #include "mdl.h" 00031 #include "sql_locale.h" /* my_locale_st */ 00032 #include "sql_profile.h" /* PROFILING */ 00033 #include "scheduler.h" /* thd_scheduler */ 00034 #include "protocol.h" /* Protocol_text, Protocol_binary */ 00035 #include "violite.h" /* vio_is_connected */ 00036 #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA, 00037 THR_LOCK_INFO */ 00038 #include "opt_trace_context.h" /* Opt_trace_context */ 00039 #include "rpl_gtid.h" 00040 00041 #include "sql_digest_stream.h" // sql_digest_state 00042 00043 #include <mysql/psi/mysql_stage.h> 00044 #include <mysql/psi/mysql_statement.h> 00045 #include <mysql/psi/mysql_idle.h> 00046 #include <mysql_com_server.h> 00047 #include "sql_data_change.h" 00048 #include "my_atomic.h" 00049 00050 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") 00051 00056 extern "C" 00057 const char *set_thd_proc_info(void *thd_arg, const char *info, 00058 const char *calling_func, 00059 const char *calling_file, 00060 const unsigned int calling_line); 00061 00062 #define thd_proc_info(thd, msg) \ 00063 set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__) 00064 00065 extern "C" 00066 void set_thd_stage_info(void *thd, 00067 const PSI_stage_info *new_stage, 00068 PSI_stage_info *old_stage, 00069 const char *calling_func, 00070 const char *calling_file, 00071 const unsigned int calling_line); 00072 00073 #define THD_STAGE_INFO(thd, stage) \ 00074 (thd)->enter_stage(& stage, NULL, __func__, __FILE__, __LINE__) 00075 00076 class Reprepare_observer; 00077 class Relay_log_info; 00078 00079 class Query_log_event; 00080 class Load_log_event; 00081 class sp_rcontext; 00082 class sp_cache; 00083 class Parser_state; 00084 class Rows_log_event; 00085 class Sroutine_hash_entry; 00086 class User_level_lock; 00087 class user_var_entry; 00088 00089 enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; 00090 00091 enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, 00092 DELAY_KEY_WRITE_ALL }; 00093 enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT, 00094 SLAVE_EXEC_MODE_IDEMPOTENT, 00095 SLAVE_EXEC_MODE_LAST_BIT }; 00096 enum enum_slave_type_conversions { SLAVE_TYPE_CONVERSIONS_ALL_LOSSY, 00097 SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY, 00098 SLAVE_TYPE_CONVERSIONS_ALL_UNSIGNED, 00099 SLAVE_TYPE_CONVERSIONS_ALL_SIGNED}; 00100 enum enum_slave_rows_search_algorithms { SLAVE_ROWS_TABLE_SCAN = (1U << 0), 00101 SLAVE_ROWS_INDEX_SCAN = (1U << 1), 00102 SLAVE_ROWS_HASH_SCAN = (1U << 2)}; 00103 00104 enum enum_mark_columns 00105 { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE}; 00106 enum enum_filetype { FILETYPE_CSV, FILETYPE_XML }; 00107 00108 /* Bits for different SQL modes modes (including ANSI mode) */ 00109 #define MODE_REAL_AS_FLOAT 1 00110 #define MODE_PIPES_AS_CONCAT 2 00111 #define MODE_ANSI_QUOTES 4 00112 #define MODE_IGNORE_SPACE 8 00113 #define MODE_NOT_USED 16 00114 #define MODE_ONLY_FULL_GROUP_BY 32 00115 #define MODE_NO_UNSIGNED_SUBTRACTION 64 00116 #define MODE_NO_DIR_IN_CREATE 128 00117 #define MODE_POSTGRESQL 256 00118 #define MODE_ORACLE 512 00119 #define MODE_MSSQL 1024 00120 #define MODE_DB2 2048 00121 #define MODE_MAXDB 4096 00122 #define MODE_NO_KEY_OPTIONS 8192 00123 #define MODE_NO_TABLE_OPTIONS 16384 00124 #define MODE_NO_FIELD_OPTIONS 32768 00125 #define MODE_MYSQL323 65536L 00126 #define MODE_MYSQL40 (MODE_MYSQL323*2) 00127 #define MODE_ANSI (MODE_MYSQL40*2) 00128 #define MODE_NO_AUTO_VALUE_ON_ZERO (MODE_ANSI*2) 00129 #define MODE_NO_BACKSLASH_ESCAPES (MODE_NO_AUTO_VALUE_ON_ZERO*2) 00130 #define MODE_STRICT_TRANS_TABLES (MODE_NO_BACKSLASH_ESCAPES*2) 00131 #define MODE_STRICT_ALL_TABLES (MODE_STRICT_TRANS_TABLES*2) 00132 #define MODE_NO_ZERO_IN_DATE (MODE_STRICT_ALL_TABLES*2) 00133 #define MODE_NO_ZERO_DATE (MODE_NO_ZERO_IN_DATE*2) 00134 #define MODE_INVALID_DATES (MODE_NO_ZERO_DATE*2) 00135 #define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2) 00136 #define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*2) 00137 #define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2) 00138 #define MODE_HIGH_NOT_PRECEDENCE (MODE_NO_AUTO_CREATE_USER*2) 00139 #define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2) 00140 #define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31) 00141 00142 extern char internal_table_name[2]; 00143 extern char empty_c_string[1]; 00144 extern LEX_STRING EMPTY_STR; 00145 extern LEX_STRING NULL_STR; 00146 extern MYSQL_PLUGIN_IMPORT const char **errmesg; 00147 00148 extern bool volatile shutdown_in_progress; 00149 00150 extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd); 00151 extern "C" char **thd_query(MYSQL_THD thd); 00152 00157 class CSET_STRING 00158 { 00159 private: 00160 LEX_STRING string; 00161 const CHARSET_INFO *cs; 00162 public: 00163 CSET_STRING() : cs(&my_charset_bin) 00164 { 00165 string.str= NULL; 00166 string.length= 0; 00167 } 00168 CSET_STRING(char *str_arg, size_t length_arg, const CHARSET_INFO *cs_arg) : 00169 cs(cs_arg) 00170 { 00171 DBUG_ASSERT(cs_arg != NULL); 00172 string.str= str_arg; 00173 string.length= length_arg; 00174 } 00175 00176 inline char *str() const { return string.str; } 00177 inline size_t length() const { return string.length; } 00178 const CHARSET_INFO *charset() const { return cs; } 00179 00180 friend LEX_STRING * thd_query_string (MYSQL_THD thd); 00181 friend char **thd_query(MYSQL_THD thd); 00182 }; 00183 00184 00185 #define TC_LOG_PAGE_SIZE 8192 00186 #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE) 00187 00188 #define TC_HEURISTIC_RECOVER_COMMIT 1 00189 #define TC_HEURISTIC_RECOVER_ROLLBACK 2 00190 extern ulong tc_heuristic_recover; 00191 00192 typedef struct st_user_var_events 00193 { 00194 user_var_entry *user_var_event; 00195 char *value; 00196 ulong length; 00197 Item_result type; 00198 uint charset_number; 00199 bool unsigned_flag; 00200 } BINLOG_USER_VAR_EVENT; 00201 00202 00203 class Key_part_spec :public Sql_alloc { 00204 public: 00205 LEX_STRING field_name; 00206 uint length; 00207 Key_part_spec(const LEX_STRING &name, uint len) 00208 : field_name(name), length(len) 00209 {} 00210 Key_part_spec(const char *name, const size_t name_len, uint len) 00211 : length(len) 00212 { field_name.str= (char *)name; field_name.length= name_len; } 00213 bool operator==(const Key_part_spec& other) const; 00223 Key_part_spec *clone(MEM_ROOT *mem_root) const 00224 { return new (mem_root) Key_part_spec(*this); } 00225 }; 00226 00227 00228 class Alter_drop :public Sql_alloc { 00229 public: 00230 enum drop_type {KEY, COLUMN, FOREIGN_KEY }; 00231 const char *name; 00232 enum drop_type type; 00233 Alter_drop(enum drop_type par_type,const char *par_name) 00234 :name(par_name), type(par_type) 00235 { 00236 DBUG_ASSERT(par_name != NULL); 00237 } 00242 Alter_drop *clone(MEM_ROOT *mem_root) const 00243 { return new (mem_root) Alter_drop(*this); } 00244 }; 00245 00246 00247 class Alter_column :public Sql_alloc { 00248 public: 00249 const char *name; 00250 Item *def; 00251 Alter_column(const char *par_name,Item *literal) 00252 :name(par_name), def(literal) {} 00257 Alter_column *clone(MEM_ROOT *mem_root) const 00258 { return new (mem_root) Alter_column(*this); } 00259 }; 00260 00261 00262 class Key :public Sql_alloc { 00263 public: 00264 enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; 00265 enum Keytype type; 00266 KEY_CREATE_INFO key_create_info; 00267 List<Key_part_spec> columns; 00268 LEX_STRING name; 00269 bool generated; 00270 00271 Key(enum Keytype type_par, const LEX_STRING &name_arg, 00272 KEY_CREATE_INFO *key_info_arg, 00273 bool generated_arg, List<Key_part_spec> &cols) 00274 :type(type_par), key_create_info(*key_info_arg), columns(cols), 00275 name(name_arg), generated(generated_arg) 00276 {} 00277 Key(enum Keytype type_par, const char *name_arg, size_t name_len_arg, 00278 KEY_CREATE_INFO *key_info_arg, bool generated_arg, 00279 List<Key_part_spec> &cols) 00280 :type(type_par), key_create_info(*key_info_arg), columns(cols), 00281 generated(generated_arg) 00282 { 00283 name.str= (char *)name_arg; 00284 name.length= name_len_arg; 00285 } 00286 Key(const Key &rhs, MEM_ROOT *mem_root); 00287 virtual ~Key() {} 00288 /* Equality comparison of keys (ignoring name) */ 00289 friend bool foreign_key_prefix(Key *a, Key *b); 00294 virtual Key *clone(MEM_ROOT *mem_root) const 00295 { return new (mem_root) Key(*this, mem_root); } 00296 }; 00297 00298 class Table_ident; 00299 00300 class Foreign_key: public Key { 00301 public: 00302 enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, 00303 FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; 00304 enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, 00305 FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; 00306 00307 LEX_STRING ref_db; 00308 LEX_STRING ref_table; 00309 List<Key_part_spec> ref_columns; 00310 uint delete_opt, update_opt, match_opt; 00311 Foreign_key(const LEX_STRING &name_arg, List<Key_part_spec> &cols, 00312 const LEX_STRING &ref_db_arg, const LEX_STRING &ref_table_arg, 00313 List<Key_part_spec> &ref_cols, 00314 uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) 00315 :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), 00316 ref_db(ref_db_arg), ref_table(ref_table_arg), ref_columns(ref_cols), 00317 delete_opt(delete_opt_arg), update_opt(update_opt_arg), 00318 match_opt(match_opt_arg) 00319 { 00320 // We don't check for duplicate FKs. 00321 key_create_info.check_for_duplicate_indexes= false; 00322 } 00323 Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root); 00328 virtual Key *clone(MEM_ROOT *mem_root) const 00329 { return new (mem_root) Foreign_key(*this, mem_root); } 00330 }; 00331 00332 typedef struct st_mysql_lock 00333 { 00334 TABLE **table; 00335 uint table_count,lock_count; 00336 THR_LOCK_DATA **locks; 00337 } MYSQL_LOCK; 00338 00339 00340 class LEX_COLUMN : public Sql_alloc 00341 { 00342 public: 00343 String column; 00344 uint rights; 00345 LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} 00346 }; 00347 00348 class MY_LOCALE; 00349 00354 struct Query_cache_block; 00355 00356 struct Query_cache_tls 00357 { 00358 /* 00359 'first_query_block' should be accessed only via query cache 00360 functions and methods to maintain proper locking. 00361 */ 00362 Query_cache_block *first_query_block; 00363 void set_first_query_block(Query_cache_block *first_query_block_arg) 00364 { 00365 first_query_block= first_query_block_arg; 00366 } 00367 00368 Query_cache_tls() :first_query_block(NULL) {} 00369 }; 00370 00371 /* SIGNAL / RESIGNAL / GET DIAGNOSTICS */ 00372 00377 typedef enum enum_diag_condition_item_name 00378 { 00379 /* 00380 Conditions that can be set by the user (SIGNAL/RESIGNAL), 00381 and by the server implementation. 00382 */ 00383 00384 DIAG_CLASS_ORIGIN= 0, 00385 FIRST_DIAG_SET_PROPERTY= DIAG_CLASS_ORIGIN, 00386 DIAG_SUBCLASS_ORIGIN= 1, 00387 DIAG_CONSTRAINT_CATALOG= 2, 00388 DIAG_CONSTRAINT_SCHEMA= 3, 00389 DIAG_CONSTRAINT_NAME= 4, 00390 DIAG_CATALOG_NAME= 5, 00391 DIAG_SCHEMA_NAME= 6, 00392 DIAG_TABLE_NAME= 7, 00393 DIAG_COLUMN_NAME= 8, 00394 DIAG_CURSOR_NAME= 9, 00395 DIAG_MESSAGE_TEXT= 10, 00396 DIAG_MYSQL_ERRNO= 11, 00397 LAST_DIAG_SET_PROPERTY= DIAG_MYSQL_ERRNO 00398 } Diag_condition_item_name; 00399 00404 extern const LEX_STRING Diag_condition_item_names[]; 00405 00406 #include "sql_lex.h" /* Must be here */ 00407 00408 extern LEX_CSTRING sql_statement_names[(uint) SQLCOM_END + 1]; 00409 class Delayed_insert; 00410 class select_result; 00411 class Time_zone; 00412 00413 #define THD_SENTRY_MAGIC 0xfeedd1ff 00414 #define THD_SENTRY_GONE 0xdeadbeef 00415 00416 #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) 00417 00418 typedef ulonglong sql_mode_t; 00419 00420 typedef struct system_variables 00421 { 00422 /* 00423 How dynamically allocated system variables are handled: 00424 00425 The global_system_variables and max_system_variables are "authoritative" 00426 They both should have the same 'version' and 'size'. 00427 When attempting to access a dynamic variable, if the session version 00428 is out of date, then the session version is updated and realloced if 00429 neccessary and bytes copied from global to make up for missing data. 00430 */ 00431 ulong dynamic_variables_version; 00432 char* dynamic_variables_ptr; 00433 uint dynamic_variables_head; /* largest valid variable offset */ 00434 uint dynamic_variables_size; /* how many bytes are in use */ 00435 LIST *dynamic_variables_allocs; /* memory hunks for PLUGIN_VAR_MEMALLOC */ 00436 00437 ulonglong max_heap_table_size; 00438 ulonglong tmp_table_size; 00439 ulonglong long_query_time; 00440 my_bool end_markers_in_json; 00441 /* A bitmap for switching optimizations on/off */ 00442 ulonglong optimizer_switch; 00443 ulonglong optimizer_trace; 00444 ulonglong optimizer_trace_features; 00445 long optimizer_trace_offset; 00446 long optimizer_trace_limit; 00447 ulong optimizer_trace_max_mem_size; 00448 sql_mode_t sql_mode; 00449 ulonglong option_bits; 00450 ha_rows select_limit; 00451 ha_rows max_join_size; 00452 ulong auto_increment_increment, auto_increment_offset; 00453 ulong bulk_insert_buff_size; 00454 uint eq_range_index_dive_limit; 00455 ulong join_buff_size; 00456 ulong lock_wait_timeout; 00457 ulong max_allowed_packet; 00458 ulong max_error_count; 00459 ulong max_length_for_sort_data; 00460 ulong max_sort_length; 00461 ulong max_tmp_tables; 00462 ulong max_insert_delayed_threads; 00463 ulong min_examined_row_limit; 00464 ulong multi_range_count; 00465 ulong myisam_repair_threads; 00466 ulong myisam_sort_buff_size; 00467 ulong myisam_stats_method; 00468 ulong net_buffer_length; 00469 ulong net_interactive_timeout; 00470 ulong net_read_timeout; 00471 ulong net_retry_count; 00472 ulong net_wait_timeout; 00473 ulong net_write_timeout; 00474 ulong optimizer_prune_level; 00475 ulong optimizer_search_depth; 00476 ulong preload_buff_size; 00477 ulong profiling_history_size; 00478 ulong read_buff_size; 00479 ulong read_rnd_buff_size; 00480 ulong div_precincrement; 00481 ulong sortbuff_size; 00482 ulong max_sp_recursion_depth; 00483 ulong default_week_format; 00484 ulong max_seeks_for_key; 00485 ulong range_alloc_block_size; 00486 ulong query_alloc_block_size; 00487 ulong query_prealloc_size; 00488 ulong trans_alloc_block_size; 00489 ulong trans_prealloc_size; 00490 ulong group_concat_max_len; 00491 00492 ulong binlog_format; 00493 my_bool binlog_direct_non_trans_update; 00494 ulong binlog_row_image; 00495 my_bool sql_log_bin; 00496 ulong completion_type; 00497 ulong query_cache_type; 00498 ulong tx_isolation; 00499 ulong updatable_views_with_limit; 00500 uint max_user_connections; 00501 ulong my_aes_mode; 00502 00507 my_thread_id pseudo_thread_id; 00511 my_bool tx_read_only; 00512 my_bool low_priority_updates; 00513 my_bool new_mode; 00514 my_bool query_cache_wlock_invalidate; 00515 my_bool engine_condition_pushdown; 00516 my_bool keep_files_on_create; 00517 00518 my_bool old_alter_table; 00519 uint old_passwords; 00520 my_bool big_tables; 00521 00522 plugin_ref table_plugin; 00523 plugin_ref temp_table_plugin; 00524 00525 /* Only charset part of these variables is sensible */ 00526 const CHARSET_INFO *character_set_filesystem; 00527 const CHARSET_INFO *character_set_client; 00528 const CHARSET_INFO *character_set_results; 00529 00530 /* Both charset and collation parts of these variables are important */ 00531 const CHARSET_INFO *collation_server; 00532 const CHARSET_INFO *collation_database; 00533 const CHARSET_INFO *collation_connection; 00534 00535 /* Error messages */ 00536 MY_LOCALE *lc_messages; 00537 /* Locale Support */ 00538 MY_LOCALE *lc_time_names; 00539 00540 Time_zone *time_zone; 00541 /* 00542 TIMESTAMP fields are by default created with DEFAULT clauses 00543 implicitly without users request. This flag when set, disables 00544 implicit default values and expect users to provide explicit 00545 default clause. i.e., when set columns are defined as NULL, 00546 instead of NOT NULL by default. 00547 */ 00548 my_bool explicit_defaults_for_timestamp; 00549 00550 my_bool sysdate_is_now; 00551 my_bool binlog_rows_query_log_events; 00552 00553 double long_query_time_double; 00554 00555 my_bool pseudo_slave_mode; 00556 00557 Gtid_specification gtid_next; 00558 Gtid_set_or_null gtid_next_list; 00564 my_bool show_old_temporals; 00565 } SV; 00566 00567 00574 typedef struct system_status_var 00575 { 00576 ulonglong created_tmp_disk_tables; 00577 ulonglong created_tmp_tables; 00578 ulonglong ha_commit_count; 00579 ulonglong ha_delete_count; 00580 ulonglong ha_read_first_count; 00581 ulonglong ha_read_last_count; 00582 ulonglong ha_read_key_count; 00583 ulonglong ha_read_next_count; 00584 ulonglong ha_read_prev_count; 00585 ulonglong ha_read_rnd_count; 00586 ulonglong ha_read_rnd_next_count; 00587 /* 00588 This number doesn't include calls to the default implementation and 00589 calls made by range access. The intent is to count only calls made by 00590 BatchedKeyAccess. 00591 */ 00592 ulonglong ha_multi_range_read_init_count; 00593 ulonglong ha_rollback_count; 00594 ulonglong ha_update_count; 00595 ulonglong ha_write_count; 00596 ulonglong ha_prepare_count; 00597 ulonglong ha_discover_count; 00598 ulonglong ha_savepoint_count; 00599 ulonglong ha_savepoint_rollback_count; 00600 ulonglong ha_external_lock_count; 00601 ulonglong opened_tables; 00602 ulonglong opened_shares; 00603 ulonglong table_open_cache_hits; 00604 ulonglong table_open_cache_misses; 00605 ulonglong table_open_cache_overflows; 00606 ulonglong select_full_join_count; 00607 ulonglong select_full_range_join_count; 00608 ulonglong select_range_count; 00609 ulonglong select_range_check_count; 00610 ulonglong select_scan_count; 00611 ulonglong long_query_count; 00612 ulonglong filesort_merge_passes; 00613 ulonglong filesort_range_count; 00614 ulonglong filesort_rows; 00615 ulonglong filesort_scan_count; 00616 /* Prepared statements and binary protocol */ 00617 ulonglong com_stmt_prepare; 00618 ulonglong com_stmt_reprepare; 00619 ulonglong com_stmt_execute; 00620 ulonglong com_stmt_send_long_data; 00621 ulonglong com_stmt_fetch; 00622 ulonglong com_stmt_reset; 00623 ulonglong com_stmt_close; 00624 00625 ulonglong bytes_received; 00626 ulonglong bytes_sent; 00627 /* 00628 Number of statements sent from the client 00629 */ 00630 ulonglong questions; 00631 00632 ulong com_other; 00633 ulong com_stat[(uint) SQLCOM_END]; 00634 00635 /* 00636 IMPORTANT! 00637 SEE last_system_status_var DEFINITION BELOW. 00638 Below 'last_system_status_var' are all variables that cannot be handled 00639 automatically by add_to_status()/add_diff_to_status(). 00640 */ 00641 double last_query_cost; 00642 ulonglong last_query_partial_plans; 00643 } STATUS_VAR; 00644 00645 /* 00646 This is used for 'SHOW STATUS'. It must be updated to the last ulong 00647 variable in system_status_var which is makes sens to add to the global 00648 counter 00649 */ 00650 00651 #define last_system_status_var questions 00652 00653 00662 inline CHARSET_INFO * 00663 mysqld_collation_get_by_name(const char *name, 00664 CHARSET_INFO *name_cs= system_charset_info) 00665 { 00666 CHARSET_INFO *cs; 00667 MY_CHARSET_LOADER loader; 00668 my_charset_loader_init_mysys(&loader); 00669 if (!(cs= my_collation_get_by_name(&loader, name, MYF(0)))) 00670 { 00671 ErrConvString err(name, name_cs); 00672 my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr()); 00673 if (loader.error[0]) 00674 push_warning_printf(current_thd, 00675 Sql_condition::WARN_LEVEL_WARN, 00676 ER_UNKNOWN_COLLATION, "%s", loader.error); 00677 } 00678 return cs; 00679 } 00680 00681 00682 #ifdef MYSQL_SERVER 00683 00684 void free_tmp_table(THD *thd, TABLE *entry); 00685 00686 00687 /* The following macro is to make init of Query_arena simpler */ 00688 #ifndef DBUG_OFF 00689 #define INIT_ARENA_DBUG_INFO is_backup_arena= 0; is_reprepared= FALSE; 00690 #else 00691 #define INIT_ARENA_DBUG_INFO 00692 #endif 00693 00694 class Query_arena 00695 { 00696 public: 00697 /* 00698 List of items created in the parser for this query. Every item puts 00699 itself to the list on creation (see Item::Item() for details)) 00700 */ 00701 Item *free_list; 00702 MEM_ROOT *mem_root; // Pointer to current memroot 00703 #ifndef DBUG_OFF 00704 bool is_backup_arena; /* True if this arena is used for backup. */ 00705 bool is_reprepared; 00706 #endif 00707 /* 00708 The states relfects three diffrent life cycles for three 00709 different types of statements: 00710 Prepared statement: STMT_INITIALIZED -> STMT_PREPARED -> STMT_EXECUTED. 00711 Stored procedure: STMT_INITIALIZED_FOR_SP -> STMT_EXECUTED. 00712 Other statements: STMT_CONVENTIONAL_EXECUTION never changes. 00713 */ 00714 enum enum_state 00715 { 00716 STMT_INITIALIZED= 0, STMT_INITIALIZED_FOR_SP= 1, STMT_PREPARED= 2, 00717 STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, STMT_ERROR= -1 00718 }; 00719 00720 enum_state state; 00721 00722 /* We build without RTTI, so dynamic_cast can't be used. */ 00723 enum Type 00724 { 00725 STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE 00726 }; 00727 00728 Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) : 00729 free_list(0), mem_root(mem_root_arg), state(state_arg) 00730 { INIT_ARENA_DBUG_INFO; } 00731 /* 00732 This constructor is used only when Query_arena is created as 00733 backup storage for another instance of Query_arena. 00734 */ 00735 Query_arena() { INIT_ARENA_DBUG_INFO; } 00736 00737 virtual Type type() const; 00738 virtual ~Query_arena() {}; 00739 00740 inline bool is_stmt_prepare() const { return state == STMT_INITIALIZED; } 00741 inline bool is_stmt_prepare_or_first_sp_execute() const 00742 { return (int)state < (int)STMT_PREPARED; } 00743 inline bool is_stmt_prepare_or_first_stmt_execute() const 00744 { return (int)state <= (int)STMT_PREPARED; } 00745 inline bool is_conventional() const 00746 { return state == STMT_CONVENTIONAL_EXECUTION; } 00747 00748 inline void* alloc(size_t size) { return alloc_root(mem_root,size); } 00749 inline void* calloc(size_t size) 00750 { 00751 void *ptr; 00752 if ((ptr=alloc_root(mem_root,size))) 00753 memset(ptr, 0, size); 00754 return ptr; 00755 } 00756 inline char *strdup(const char *str) 00757 { return strdup_root(mem_root,str); } 00758 inline char *strmake(const char *str, size_t size) 00759 { return strmake_root(mem_root,str,size); } 00760 inline void *memdup(const void *str, size_t size) 00761 { return memdup_root(mem_root,str,size); } 00762 inline void *memdup_w_gap(const void *str, size_t size, uint gap) 00763 { 00764 void *ptr; 00765 if ((ptr= alloc_root(mem_root,size+gap))) 00766 memcpy(ptr,str,size); 00767 return ptr; 00768 } 00769 00770 void set_query_arena(Query_arena *set); 00771 00772 void free_items(); 00773 /* Close the active state associated with execution of this statement */ 00774 virtual void cleanup_stmt(); 00775 }; 00776 00777 00778 class Server_side_cursor; 00779 00796 class Statement: public Query_arena 00797 { 00798 Statement(const Statement &rhs); /* not implemented: */ 00799 Statement &operator=(const Statement &rhs); /* non-copyable */ 00800 public: 00801 /* 00802 Uniquely identifies each statement object in thread scope; change during 00803 statement lifetime. FIXME: must be const 00804 */ 00805 ulong id; 00806 00807 /* 00808 MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to 00809 handler of fields used is set 00810 MARK_COLUMNS_READ: Means a bit in read set is set to inform handler 00811 that the field is to be read. If field list contains 00812 duplicates, then thd->dup_field is set to point 00813 to the last found duplicate. 00814 MARK_COLUMNS_WRITE: Means a bit is set in write set to inform handler 00815 that it needs to update this field in write_row 00816 and update_row. 00817 */ 00818 enum enum_mark_columns mark_used_columns; 00819 00820 LEX_STRING name; /* name for named prepared statements */ 00821 LEX *lex; // parse tree descriptor 00822 /* 00823 Points to the query associated with this statement. It's const, but 00824 we need to declare it char * because all table handlers are written 00825 in C and need to point to it. 00826 00827 Note that if we set query = NULL, we must at the same time set 00828 query_length = 0, and protect the whole operation with 00829 LOCK_thd_data mutex. To avoid crashes in races, if we do not 00830 know that thd->query cannot change at the moment, we should print 00831 thd->query like this: 00832 (1) reserve the LOCK_thd_data mutex; 00833 (2) print or copy the value of query and query_length 00834 (3) release LOCK_thd_data mutex. 00835 This printing is needed at least in SHOW PROCESSLIST and SHOW 00836 ENGINE INNODB STATUS. 00837 */ 00838 CSET_STRING query_string; 00839 00840 /* 00841 In some cases, we may want to modify the query (i.e. replace 00842 passwords with their hashes before logging the statement etc.). 00843 00844 In case the query was rewritten, the original query will live in 00845 query_string, while the rewritten query lives in rewritten_query. 00846 If rewritten_query is empty, query_string should be logged. 00847 If rewritten_query is non-empty, the rewritten query it contains 00848 should be used in logs (general log, slow query log, binary log). 00849 00850 Currently, password obfuscation is the only rewriting we do; more 00851 may follow at a later date, both pre- and post parsing of the query. 00852 Rewriting of binloggable statements must preserve all pertinent 00853 information. 00854 */ 00855 String rewritten_query; 00856 00857 inline char *query() const { return query_string.str(); } 00858 inline uint32 query_length() const { return (uint32)query_string.length(); } 00859 const CHARSET_INFO *query_charset() const { return query_string.charset(); } 00860 void set_query_inner(const CSET_STRING &string_arg) 00861 { 00862 query_string= string_arg; 00863 } 00864 void set_query_inner(char *query_arg, uint32 query_length_arg, 00865 const CHARSET_INFO *cs_arg) 00866 { 00867 set_query_inner(CSET_STRING(query_arg, query_length_arg, cs_arg)); 00868 } 00869 void reset_query_inner() 00870 { 00871 set_query_inner(CSET_STRING()); 00872 } 00886 char *db; 00887 size_t db_length; 00888 00889 public: 00890 00891 /* This constructor is called for backup statements */ 00892 Statement() {} 00893 00894 Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, 00895 enum_state state_arg, ulong id_arg); 00896 virtual ~Statement(); 00897 00898 /* Assign execution context (note: not all members) of given stmt to self */ 00899 virtual void set_statement(Statement *stmt); 00900 void set_n_backup_statement(Statement *stmt, Statement *backup); 00901 void restore_backup_statement(Statement *stmt, Statement *backup); 00902 /* return class type */ 00903 virtual Type type() const; 00904 }; 00905 00906 00918 class Statement_map 00919 { 00920 public: 00921 Statement_map(); 00922 00923 int insert(THD *thd, Statement *statement); 00924 00925 Statement *find_by_name(LEX_STRING *name) 00926 { 00927 Statement *stmt; 00928 stmt= (Statement*)my_hash_search(&names_hash, (uchar*)name->str, 00929 name->length); 00930 return stmt; 00931 } 00932 00933 Statement *find(ulong id) 00934 { 00935 if (last_found_statement == 0 || id != last_found_statement->id) 00936 { 00937 Statement *stmt; 00938 stmt= (Statement *) my_hash_search(&st_hash, (uchar *) &id, sizeof(id)); 00939 if (stmt && stmt->name.str) 00940 return NULL; 00941 last_found_statement= stmt; 00942 } 00943 return last_found_statement; 00944 } 00945 /* 00946 Close all cursors of this connection that use tables of a storage 00947 engine that has transaction-specific state and therefore can not 00948 survive COMMIT or ROLLBACK. Currently all but MyISAM cursors are closed. 00949 CURRENTLY NOT IMPLEMENTED! 00950 */ 00951 void close_transient_cursors(); 00952 void erase(Statement *statement); 00953 /* Erase all statements (calls Statement destructor) */ 00954 void reset(); 00955 ~Statement_map(); 00956 private: 00957 HASH st_hash; 00958 HASH names_hash; 00959 Statement *last_found_statement; 00960 }; 00961 00962 class Ha_trx_info; 00963 00964 struct THD_TRANS 00965 { 00966 /* true is not all entries in the ht[] support 2pc */ 00967 bool no_2pc; 00968 int rw_ha_count; 00969 /* storage engines that registered in this transaction */ 00970 Ha_trx_info *ha_list; 00971 00972 private: 00973 /* 00974 The purpose of this member variable (i.e. flag) is to keep track of 00975 statements which cannot be rolled back safely(completely). 00976 For example, 00977 00978 * statements that modified non-transactional tables. The value 00979 MODIFIED_NON_TRANS_TABLE is set within mysql_insert, mysql_update, 00980 mysql_delete, etc if a non-transactional table is modified. 00981 00982 * 'DROP TEMPORARY TABLE' and 'CREATE TEMPORARY TABLE' statements. 00983 The former sets the value CREATED_TEMP_TABLE is set and the latter 00984 the value DROPPED_TEMP_TABLE. 00985 00986 The tracked statements are modified in scope of: 00987 00988 * transaction, when the variable is a member of THD::transaction.all 00989 00990 * top-level statement or sub-statement, when the variable is a 00991 member of THD::transaction.stmt 00992 00993 This member has the following life cycle: 00994 00995 * stmt.m_unsafe_rollback_flags is used to keep track of top-level statements 00996 which cannot be rolled back safely. At the end of the statement, the value 00997 of stmt.m_unsafe_rollback_flags is merged with all.m_unsafe_rollback_flags 00998 and gets reset. 00999 01000 * all.cannot_safely_rollback is reset at the end of transaction 01001 01002 * Since we do not have a dedicated context for execution of a sub-statement, 01003 to keep track of non-transactional changes in a sub-statement, we re-use 01004 stmt.m_unsafe_rollback_flags. At entrance into a sub-statement, a copy of 01005 the value of stmt.m_unsafe_rollback_flags (containing the changes of the 01006 outer statement) is saved on stack. Then stmt.m_unsafe_rollback_flags is 01007 reset to 0 and the substatement is executed. Then the new value is merged 01008 with the saved value. 01009 */ 01010 01011 unsigned int m_unsafe_rollback_flags; 01012 /* 01013 Define the type of statemens which cannot be rolled back safely. 01014 Each type occupies one bit in m_unsafe_rollback_flags. 01015 */ 01016 static unsigned int const MODIFIED_NON_TRANS_TABLE= 0x01; 01017 static unsigned int const CREATED_TEMP_TABLE= 0x02; 01018 static unsigned int const DROPPED_TEMP_TABLE= 0x04; 01019 01020 public: 01021 #ifndef DBUG_OFF 01022 void dbug_unsafe_rollback_flags(const char* msg) const 01023 { 01024 DBUG_PRINT("debug", ("%s.unsafe_rollback_flags: %s%s%s", 01025 msg, 01026 FLAGSTR(m_unsafe_rollback_flags, MODIFIED_NON_TRANS_TABLE), 01027 FLAGSTR(m_unsafe_rollback_flags, CREATED_TEMP_TABLE), 01028 FLAGSTR(m_unsafe_rollback_flags, DROPPED_TEMP_TABLE))); 01029 } 01030 #endif 01031 01032 bool cannot_safely_rollback() const 01033 { 01034 return m_unsafe_rollback_flags > 0; 01035 } 01036 unsigned int get_unsafe_rollback_flags() const 01037 { 01038 return m_unsafe_rollback_flags; 01039 } 01040 void set_unsafe_rollback_flags(unsigned int flags) 01041 { 01042 DBUG_PRINT("debug", ("set_unsafe_rollback_flags: %d", flags)); 01043 m_unsafe_rollback_flags= flags; 01044 } 01045 void add_unsafe_rollback_flags(unsigned int flags) 01046 { 01047 DBUG_PRINT("debug", ("add_unsafe_rollback_flags: %d", flags)); 01048 m_unsafe_rollback_flags|= flags; 01049 } 01050 void reset_unsafe_rollback_flags() 01051 { 01052 DBUG_PRINT("debug", ("reset_unsafe_rollback_flags")); 01053 m_unsafe_rollback_flags= 0; 01054 } 01055 void mark_modified_non_trans_table() 01056 { 01057 DBUG_PRINT("debug", ("mark_modified_non_trans_table")); 01058 m_unsafe_rollback_flags|= MODIFIED_NON_TRANS_TABLE; 01059 } 01060 bool has_modified_non_trans_table() const 01061 { 01062 return m_unsafe_rollback_flags & MODIFIED_NON_TRANS_TABLE; 01063 } 01064 void mark_created_temp_table() 01065 { 01066 DBUG_PRINT("debug", ("mark_created_temp_table")); 01067 m_unsafe_rollback_flags|= CREATED_TEMP_TABLE; 01068 } 01069 bool has_created_temp_table() const 01070 { 01071 return m_unsafe_rollback_flags & CREATED_TEMP_TABLE; 01072 } 01073 void mark_dropped_temp_table() 01074 { 01075 DBUG_PRINT("debug", ("mark_dropped_temp_table")); 01076 m_unsafe_rollback_flags|= DROPPED_TEMP_TABLE; 01077 } 01078 bool has_dropped_temp_table() const 01079 { 01080 return m_unsafe_rollback_flags & DROPPED_TEMP_TABLE; 01081 } 01082 01083 void reset() 01084 { 01085 no_2pc= FALSE; 01086 rw_ha_count= 0; 01087 reset_unsafe_rollback_flags(); 01088 } 01089 bool is_empty() const { return ha_list == NULL; } 01090 }; 01091 01109 class Ha_trx_info 01110 { 01111 #ifndef DBUG_OFF 01112 friend const char * 01113 ha_list_names(Ha_trx_info *ha_list, char *const buf_arg) 01114 { 01115 char *buf = buf_arg; 01116 while (ha_list) 01117 { 01118 buf += sprintf(buf, "%s", ha_legacy_type_name(ha_list->m_ht->db_type)); 01119 ha_list = ha_list->m_next; 01120 if (ha_list) 01121 buf += sprintf(buf, ", "); 01122 } 01123 if (buf == buf_arg) 01124 sprintf(buf, "<NONE>"); 01125 return buf_arg; 01126 } 01127 #endif 01128 01129 public: 01131 void register_ha(THD_TRANS *trans, handlerton *ht_arg) 01132 { 01133 DBUG_ENTER("Ha_trx_info::register_ha"); 01134 DBUG_PRINT("enter", ("trans: 0x%llx, ht: 0x%llx (%s)", 01135 (ulonglong) trans, (ulonglong) ht_arg, 01136 ha_legacy_type_name(ht_arg->db_type))); 01137 DBUG_ASSERT(m_flags == 0); 01138 DBUG_ASSERT(m_ht == NULL); 01139 DBUG_ASSERT(m_next == NULL); 01140 01141 m_ht= ht_arg; 01142 m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */ 01143 01144 m_next= trans->ha_list; 01145 trans->ha_list= this; 01146 DBUG_VOID_RETURN; 01147 } 01148 01150 void reset() 01151 { 01152 DBUG_ENTER("Ha_trx_info::reset"); 01153 m_next= NULL; 01154 m_ht= NULL; 01155 m_flags= 0; 01156 DBUG_VOID_RETURN; 01157 } 01158 01159 Ha_trx_info() { reset(); } 01160 01161 void set_trx_read_write() 01162 { 01163 DBUG_ASSERT(is_started()); 01164 m_flags|= (int) TRX_READ_WRITE; 01165 } 01166 bool is_trx_read_write() const 01167 { 01168 DBUG_ASSERT(is_started()); 01169 return m_flags & (int) TRX_READ_WRITE; 01170 } 01171 bool is_started() const { return m_ht != NULL; } 01173 void coalesce_trx_with(const Ha_trx_info *stmt_trx) 01174 { 01175 /* 01176 Must be called only after the transaction has been started. 01177 Can be called many times, e.g. when we have many 01178 read-write statements in a transaction. 01179 */ 01180 DBUG_ASSERT(is_started()); 01181 if (stmt_trx->is_trx_read_write()) 01182 set_trx_read_write(); 01183 } 01184 Ha_trx_info *next() const 01185 { 01186 DBUG_ASSERT(is_started()); 01187 return m_next; 01188 } 01189 handlerton *ht() const 01190 { 01191 DBUG_ASSERT(is_started()); 01192 return m_ht; 01193 } 01194 private: 01195 enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 }; 01197 Ha_trx_info *m_next; 01203 handlerton *m_ht; 01209 uchar m_flags; 01210 }; 01211 01212 struct st_savepoint { 01213 struct st_savepoint *prev; 01214 char *name; 01215 uint length; 01216 Ha_trx_info *ha_list; 01218 MDL_savepoint mdl_savepoint; 01219 }; 01220 01221 enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY}; 01222 extern const char *xa_state_names[]; 01223 01224 typedef struct st_xid_state { 01225 /* For now, this is only used to catch duplicated external xids */ 01226 XID xid; // transaction identifier 01227 enum xa_states xa_state; // used by external XA only 01228 bool in_thd; 01229 /* Error reported by the Resource Manager (RM) to the Transaction Manager. */ 01230 uint rm_error; 01231 } XID_STATE; 01232 01233 extern mysql_mutex_t LOCK_xid_cache; 01234 extern HASH xid_cache; 01235 bool xid_cache_init(void); 01236 void xid_cache_free(void); 01237 XID_STATE *xid_cache_search(XID *xid); 01238 bool xid_cache_insert(XID *xid, enum xa_states xa_state); 01239 bool xid_cache_insert(XID_STATE *xid_state); 01240 void xid_cache_delete(XID_STATE *xid_state); 01241 01247 class Security_context { 01248 private: 01249 01250 String host; 01251 String ip; 01252 String external_user; 01253 public: 01254 Security_context() {} /* Remove gcc warning */ 01255 /* 01256 host - host of the client 01257 user - user of the client, set to NULL until the user has been read from 01258 the connection 01259 priv_user - The user privilege we are using. May be "" for anonymous user. 01260 ip - client IP 01261 */ 01262 char *user; 01263 char priv_user[USERNAME_LENGTH]; 01264 char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5]; 01265 /* The host privilege we are using */ 01266 char priv_host[MAX_HOSTNAME]; 01267 /* points to host if host is available, otherwise points to ip */ 01268 const char *host_or_ip; 01269 ulong master_access; /* Global privileges from mysql.user */ 01270 ulong db_access; /* Privileges for current db */ 01271 /* 01272 This flag is set according to connecting user's context and not the 01273 effective user. 01274 */ 01275 bool password_expired; /* password expiration flag */ 01276 01277 void init(); 01278 void destroy(); 01279 void skip_grants(); 01280 inline char *priv_host_name() 01281 { 01282 return (*priv_host ? priv_host : (char *)"%"); 01283 } 01284 01285 bool set_user(char *user_arg); 01286 String *get_host(); 01287 String *get_ip(); 01288 String *get_external_user(); 01289 void set_host(const char *p); 01290 void set_ip(const char *p); 01291 void set_external_user(const char *p); 01292 void set_host(const char *str, size_t len); 01293 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01294 bool 01295 change_security_context(THD *thd, 01296 LEX_STRING *definer_user, 01297 LEX_STRING *definer_host, 01298 LEX_STRING *db, 01299 Security_context **backup); 01300 01301 void 01302 restore_security_context(THD *thd, Security_context *backup); 01303 #endif 01304 bool user_matches(Security_context *); 01305 }; 01306 01307 01313 class Log_throttle 01314 { 01318 ulonglong window_end; 01319 01324 const ulong window_size; 01325 01332 ulong count; 01333 01334 protected: 01339 const char *summary_template; 01340 01344 void new_window(ulonglong now); 01345 01354 bool inc_log_count(ulong rate) { return (++count > rate); } 01355 01361 bool in_window(ulonglong now) const { return (now < window_end); }; 01362 01373 ulong prepare_summary(ulong rate); 01374 01379 Log_throttle(ulong window_usecs, const char *msg) 01380 : window_end(0), window_size(window_usecs), 01381 count(0), summary_template(msg) 01382 {} 01383 01384 public: 01389 static const ulong LOG_THROTTLE_WINDOW_SIZE= 60000000; 01390 }; 01391 01392 01398 class Slow_log_throttle : public Log_throttle 01399 { 01400 private: 01407 Security_context aggregate_sctx; 01408 01413 ulonglong total_exec_time; 01414 01419 ulonglong total_lock_time; 01420 01425 ulong *rate; 01426 01431 bool (*log_summary)(THD *, const char *, uint); 01432 01436 mysql_mutex_t *LOCK_log_throttle; 01437 01441 void new_window(ulonglong now); 01442 01446 void print_summary(THD *thd, ulong suppressed, 01447 ulonglong print_lock_time, 01448 ulonglong print_exec_time); 01449 01450 public: 01451 01458 Slow_log_throttle(ulong *threshold, mysql_mutex_t *lock, ulong window_usecs, 01459 bool (*logger)(THD *, const char *, uint), 01460 const char *msg); 01461 01475 bool flush(THD *thd); 01476 01484 bool log(THD *thd, bool eligible); 01485 }; 01486 01487 01493 class Error_log_throttle : public Log_throttle 01494 { 01495 private: 01499 void (*log_summary)(const char *, ...); 01500 01504 void print_summary(ulong suppressed) 01505 { 01506 (*log_summary)(summary_template, suppressed); 01507 } 01508 01509 public: 01515 Error_log_throttle(ulong window_usecs, 01516 void (*logger)(const char*, ...), 01517 const char *msg) 01518 : Log_throttle(window_usecs, msg), log_summary(logger) 01519 {} 01520 01531 bool flush(THD *thd); 01532 01539 bool log(THD *thd); 01540 }; 01541 01542 01543 extern Slow_log_throttle log_throttle_qni; 01544 01545 01553 struct Item_change_record: public ilink<Item_change_record> 01554 { 01555 Item **place; 01556 Item *old_value; 01557 }; 01558 01559 typedef I_List<Item_change_record> Item_change_list; 01560 01561 01567 enum enum_locked_tables_mode 01568 { 01569 LTM_NONE= 0, 01570 LTM_LOCK_TABLES, 01571 LTM_PRELOCKED, 01572 LTM_PRELOCKED_UNDER_LOCK_TABLES 01573 }; 01574 01575 01582 class Open_tables_state 01583 { 01584 private: 01605 Dynamic_array<Reprepare_observer *> m_reprepare_observers; 01606 01607 public: 01608 Reprepare_observer *get_reprepare_observer() const 01609 { 01610 return 01611 m_reprepare_observers.elements() > 0 ? 01612 *m_reprepare_observers.back() : 01613 NULL; 01614 } 01615 01616 void push_reprepare_observer(Reprepare_observer *o) 01617 { m_reprepare_observers.append(o); } 01618 01619 Reprepare_observer *pop_reprepare_observer() 01620 { return m_reprepare_observers.pop(); } 01621 01622 void reset_reprepare_observers() 01623 { m_reprepare_observers.clear(); } 01624 01625 public: 01630 TABLE *open_tables; 01638 TABLE *temporary_tables; 01639 TABLE *derived_tables; 01640 /* 01641 During a MySQL session, one can lock tables in two modes: automatic 01642 or manual. In automatic mode all necessary tables are locked just before 01643 statement execution, and all acquired locks are stored in 'lock' 01644 member. Unlocking takes place automatically as well, when the 01645 statement ends. 01646 Manual mode comes into play when a user issues a 'LOCK TABLES' 01647 statement. In this mode the user can only use the locked tables. 01648 Trying to use any other tables will give an error. 01649 The locked tables are also stored in this member, however, 01650 thd->locked_tables_mode is turned on. Manual locking is described in 01651 the 'LOCK_TABLES' chapter of the MySQL manual. 01652 See also lock_tables() for details. 01653 */ 01654 MYSQL_LOCK *lock; 01655 01656 /* 01657 CREATE-SELECT keeps an extra lock for the table being 01658 created. This field is used to keep the extra lock available for 01659 lower level routines, which would otherwise miss that lock. 01660 */ 01661 MYSQL_LOCK *extra_lock; 01662 01663 /* 01664 Enum enum_locked_tables_mode and locked_tables_mode member are 01665 used to indicate whether the so-called "locked tables mode" is on, 01666 and what kind of mode is active. 01667 01668 Locked tables mode is used when it's necessary to open and 01669 lock many tables at once, for usage across multiple 01670 (sub-)statements. 01671 This may be necessary either for queries that use stored functions 01672 and triggers, in which case the statements inside functions and 01673 triggers may be executed many times, or for implementation of 01674 LOCK TABLES, in which case the opened tables are reused by all 01675 subsequent statements until a call to UNLOCK TABLES. 01676 01677 The kind of locked tables mode employed for stored functions and 01678 triggers is also called "prelocked mode". 01679 In this mode, first open_tables() call to open the tables used 01680 in a statement analyses all functions used by the statement 01681 and adds all indirectly used tables to the list of tables to 01682 open and lock. 01683 It also marks the parse tree of the statement as requiring 01684 prelocking. After that, lock_tables() locks the entire list 01685 of tables and changes THD::locked_tables_modeto LTM_PRELOCKED. 01686 All statements executed inside functions or triggers 01687 use the prelocked tables, instead of opening their own ones. 01688 Prelocked mode is turned off automatically once close_thread_tables() 01689 of the main statement is called. 01690 */ 01691 enum enum_locked_tables_mode locked_tables_mode; 01692 uint current_tablenr; 01693 01694 enum enum_flags { 01695 BACKUPS_AVAIL = (1U << 0) /* There are backups available */ 01696 }; 01697 01698 /* 01699 Flags with information about the open tables state. 01700 */ 01701 uint state_flags; 01708 Open_tables_state() : state_flags(0U) { } 01709 01710 void set_open_tables_state(Open_tables_state *state); 01711 01712 void reset_open_tables_state(); 01713 }; 01714 01715 01722 class Open_tables_backup: public Open_tables_state 01723 { 01724 public: 01732 MDL_savepoint mdl_system_tables_svp; 01733 }; 01734 01740 /* Defines used for Sub_statement_state::in_sub_stmt */ 01741 01742 #define SUB_STMT_TRIGGER 1 01743 #define SUB_STMT_FUNCTION 2 01744 01745 01746 class Sub_statement_state 01747 { 01748 public: 01749 ulonglong option_bits; 01750 ulonglong first_successful_insert_id_in_prev_stmt; 01751 ulonglong first_successful_insert_id_in_cur_stmt, insert_id_for_cur_row; 01752 Discrete_interval auto_inc_interval_for_cur_row; 01753 Discrete_intervals_list auto_inc_intervals_forced; 01754 ulonglong limit_found_rows; 01755 ha_rows cuted_fields, sent_row_count, examined_row_count; 01756 ulong client_capabilities; 01757 uint in_sub_stmt; 01758 bool enable_slow_log; 01759 bool last_insert_id_used; 01760 SAVEPOINT *savepoints; 01761 enum enum_check_fields count_cuted_fields; 01762 }; 01763 01764 01765 /* Flags for the THD::system_thread variable */ 01766 enum enum_thread_type 01767 { 01768 NON_SYSTEM_THREAD= 0, 01769 SYSTEM_THREAD_DELAYED_INSERT= 1, 01770 SYSTEM_THREAD_SLAVE_IO= 2, 01771 SYSTEM_THREAD_SLAVE_SQL= 4, 01772 SYSTEM_THREAD_NDBCLUSTER_BINLOG= 8, 01773 SYSTEM_THREAD_EVENT_SCHEDULER= 16, 01774 SYSTEM_THREAD_EVENT_WORKER= 32, 01775 SYSTEM_THREAD_INFO_REPOSITORY= 64, 01776 SYSTEM_THREAD_SLAVE_WORKER= 128 01777 }; 01778 01779 inline char const * 01780 show_system_thread(enum_thread_type thread) 01781 { 01782 #define RETURN_NAME_AS_STRING(NAME) case (NAME): return #NAME 01783 switch (thread) { 01784 static char buf[64]; 01785 RETURN_NAME_AS_STRING(NON_SYSTEM_THREAD); 01786 RETURN_NAME_AS_STRING(SYSTEM_THREAD_DELAYED_INSERT); 01787 RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_IO); 01788 RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_SQL); 01789 RETURN_NAME_AS_STRING(SYSTEM_THREAD_NDBCLUSTER_BINLOG); 01790 RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER); 01791 RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER); 01792 RETURN_NAME_AS_STRING(SYSTEM_THREAD_INFO_REPOSITORY); 01793 RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_WORKER); 01794 default: 01795 sprintf(buf, "<UNKNOWN SYSTEM THREAD: %d>", thread); 01796 return buf; 01797 } 01798 #undef RETURN_NAME_AS_STRING 01799 } 01800 01806 class Internal_error_handler 01807 { 01808 protected: 01809 Internal_error_handler() : 01810 m_prev_internal_handler(NULL) 01811 {} 01812 01813 virtual ~Internal_error_handler() {} 01814 01815 public: 01840 virtual bool handle_condition(THD *thd, 01841 uint sql_errno, 01842 const char* sqlstate, 01843 Sql_condition::enum_warning_level level, 01844 const char* msg, 01845 Sql_condition ** cond_hdl) = 0; 01846 01847 private: 01848 Internal_error_handler *m_prev_internal_handler; 01849 friend class THD; 01850 }; 01851 01852 01858 class Dummy_error_handler : public Internal_error_handler 01859 { 01860 public: 01861 bool handle_condition(THD *thd, 01862 uint sql_errno, 01863 const char* sqlstate, 01864 Sql_condition::enum_warning_level level, 01865 const char* msg, 01866 Sql_condition ** cond_hdl) 01867 { 01868 /* Ignore error */ 01869 return TRUE; 01870 } 01871 }; 01872 01873 01881 class Drop_table_error_handler : public Internal_error_handler 01882 { 01883 public: 01884 Drop_table_error_handler() {} 01885 01886 public: 01887 bool handle_condition(THD *thd, 01888 uint sql_errno, 01889 const char* sqlstate, 01890 Sql_condition::enum_warning_level level, 01891 const char* msg, 01892 Sql_condition ** cond_hdl); 01893 01894 private: 01895 }; 01896 01897 01923 class Locked_tables_list 01924 { 01925 private: 01926 MEM_ROOT m_locked_tables_root; 01927 TABLE_LIST *m_locked_tables; 01928 TABLE_LIST **m_locked_tables_last; 01930 TABLE **m_reopen_array; 01937 size_t m_locked_tables_count; 01938 public: 01939 Locked_tables_list() 01940 :m_locked_tables(NULL), 01941 m_locked_tables_last(&m_locked_tables), 01942 m_reopen_array(NULL), 01943 m_locked_tables_count(0) 01944 { 01945 init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0); 01946 } 01947 void unlock_locked_tables(THD *thd); 01948 ~Locked_tables_list() 01949 { 01950 unlock_locked_tables(0); 01951 } 01952 bool init_locked_tables(THD *thd); 01953 TABLE_LIST *locked_tables() { return m_locked_tables; } 01954 void unlink_from_list(THD *thd, TABLE_LIST *table_list, 01955 bool remove_from_locked_tables); 01956 void unlink_all_closed_tables(THD *thd, 01957 MYSQL_LOCK *lock, 01958 size_t reopen_count); 01959 bool reopen_tables(THD *thd); 01960 }; 01961 01962 01967 struct Ha_data 01968 { 01973 void *ha_ptr; 01984 Ha_trx_info ha_info[2]; 01989 plugin_ref lock; 01990 Ha_data() :ha_ptr(NULL) {} 01991 }; 01992 01998 class Global_read_lock 01999 { 02000 public: 02001 enum enum_grl_state 02002 { 02003 GRL_NONE, 02004 GRL_ACQUIRED, 02005 GRL_ACQUIRED_AND_BLOCKS_COMMIT 02006 }; 02007 02008 Global_read_lock() 02009 : m_state(GRL_NONE), 02010 m_mdl_global_shared_lock(NULL), 02011 m_mdl_blocks_commits_lock(NULL) 02012 {} 02013 02014 bool lock_global_read_lock(THD *thd); 02015 void unlock_global_read_lock(THD *thd); 02016 02021 static bool global_read_lock_active() 02022 { 02023 return my_atomic_load32(&m_active_requests) ? true : false; 02024 } 02025 02030 bool can_acquire_protection() const 02031 { 02032 if (m_state) 02033 { 02034 my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); 02035 return TRUE; 02036 } 02037 return FALSE; 02038 } 02039 bool make_global_read_lock_block_commit(THD *thd); 02040 bool is_acquired() const { return m_state != GRL_NONE; } 02041 void set_explicit_lock_duration(THD *thd); 02042 private: 02043 volatile static int32 m_active_requests; 02044 enum_grl_state m_state; 02050 MDL_ticket *m_mdl_global_shared_lock; 02056 MDL_ticket *m_mdl_blocks_commits_lock; 02057 }; 02058 02059 extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); 02060 02061 02062 /* 02063 Convert microseconds since epoch to timeval. 02064 @param micro_time Microseconds. 02065 @param OUT tm A timeval variable to write to. 02066 */ 02067 static inline void 02068 my_micro_time_to_timeval(ulonglong micro_time, struct timeval *tm) 02069 { 02070 tm->tv_sec= (long) (micro_time / 1000000); 02071 tm->tv_usec= (long) (micro_time % 1000000); 02072 } 02073 02080 class THD :public MDL_context_owner, 02081 public Statement, 02082 public Open_tables_state 02083 { 02084 private: 02085 inline bool is_stmt_prepare() const 02086 { DBUG_ASSERT(0); return Statement::is_stmt_prepare(); } 02087 02088 inline bool is_stmt_prepare_or_first_sp_execute() const 02089 { DBUG_ASSERT(0); return Statement::is_stmt_prepare_or_first_sp_execute(); } 02090 02091 inline bool is_stmt_prepare_or_first_stmt_execute() const 02092 { DBUG_ASSERT(0); return Statement::is_stmt_prepare_or_first_stmt_execute(); } 02093 02094 inline bool is_conventional() const 02095 { DBUG_ASSERT(0); return Statement::is_conventional(); } 02096 02097 public: 02098 MDL_context mdl_context; 02099 02100 /* Used to execute base64 coded binlog events in MySQL server */ 02101 Relay_log_info* rli_fake; 02102 /* Slave applier execution context */ 02103 Relay_log_info* rli_slave; 02104 02105 void reset_for_next_command(); 02106 /* 02107 Constant for THD::where initialization in the beginning of every query. 02108 02109 It's needed because we do not save/restore THD::where normally during 02110 primary (non subselect) query execution. 02111 */ 02112 static const char * const DEFAULT_WHERE; 02113 02114 #ifdef EMBEDDED_LIBRARY 02115 struct st_mysql *mysql; 02116 unsigned long client_stmt_id; 02117 unsigned long client_param_count; 02118 struct st_mysql_bind *client_params; 02119 char *extra_data; 02120 ulong extra_length; 02121 struct st_mysql_data *cur_data; 02122 struct st_mysql_data *first_data; 02123 struct st_mysql_data **data_tail; 02124 void clear_data_list(); 02125 struct st_mysql_data *alloc_new_dataset(); 02126 /* 02127 In embedded server it points to the statement that is processed 02128 in the current query. We store some results directly in statement 02129 fields then. 02130 */ 02131 struct st_mysql_stmt *current_stmt; 02132 #endif 02133 #ifdef HAVE_QUERY_CACHE 02134 Query_cache_tls query_cache_tls; 02135 #endif 02136 NET net; // client connection descriptor 02138 NET_SERVER m_net_server_extension; 02139 Protocol *protocol; // Current protocol 02140 Protocol_text protocol_text; // Normal protocol 02141 Protocol_binary protocol_binary; // Binary protocol 02142 HASH user_vars; // hash for user variables 02143 String packet; // dynamic buffer for network I/O 02144 String convert_buffer; // buffer for charset conversions 02145 struct rand_struct rand; // used for authentication 02146 struct system_variables variables; // Changeable local variables 02147 struct system_status_var status_var; // Per thread statistic vars 02148 struct system_status_var *initial_status_var; /* used by show status */ 02149 THR_LOCK_INFO lock_info; // Locking info of this thread 02157 mysql_mutex_t LOCK_thd_data; 02158 02159 /* all prepared statements and cursors of this connection */ 02160 Statement_map stmt_map; 02161 /* 02162 A pointer to the stack frame of handle_one_connection(), 02163 which is called first in the thread for handling a client 02164 */ 02165 char *thread_stack; 02166 02170 char *catalog; 02171 02185 Security_context main_security_ctx; 02186 Security_context *security_ctx; 02187 02188 /* 02189 Points to info-string that we show in SHOW PROCESSLIST 02190 You are supposed to update thd->proc_info only if you have coded 02191 a time-consuming piece that MySQL can get stuck in for a long time. 02192 02193 Set it using the thd_proc_info(THD *thread, const char *message) 02194 macro/function. 02195 02196 This member is accessed and assigned without any synchronization. 02197 Therefore, it may point only to constant (statically 02198 allocated) strings, which memory won't go away over time. 02199 */ 02200 const char *proc_info; 02201 02202 private: 02203 unsigned int m_current_stage_key; 02204 02205 public: 02206 void enter_stage(const PSI_stage_info *stage, 02207 PSI_stage_info *old_stage, 02208 const char *calling_func, 02209 const char *calling_file, 02210 const unsigned int calling_line); 02211 02212 const char *get_proc_info() const 02213 { return proc_info; } 02214 02215 /* 02216 Used in error messages to tell user in what part of MySQL we found an 02217 error. E. g. when where= "having clause", if fix_fields() fails, user 02218 will know that the error was in having clause. 02219 */ 02220 const char *where; 02221 02222 ulong client_capabilities; /* What the client supports */ 02223 ulong max_client_packet_length; 02224 02225 HASH handler_tables_hash; 02226 /* 02227 One thread can hold up to one named user-level lock. This variable 02228 points to a lock object if the lock is present. See item_func.cc and 02229 chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK. 02230 */ 02231 User_level_lock *ull; 02232 #ifndef DBUG_OFF 02233 uint dbug_sentry; // watch out for memory corruption 02234 #endif 02235 struct st_my_thread_var *mysys_var; 02236 02237 private: 02242 enum enum_server_command m_command; 02243 02244 public: 02245 uint32 unmasked_server_id; 02246 uint32 server_id; 02247 uint32 file_id; // for LOAD DATA INFILE 02248 /* remote (peer) port */ 02249 uint16 peer_port; 02250 struct timeval start_time; 02251 struct timeval user_time; 02252 // track down slow pthread_create 02253 ulonglong prior_thr_create_utime, thr_create_utime; 02254 ulonglong start_utime, utime_after_lock; 02255 02256 thr_lock_type update_lock_default; 02257 Delayed_insert *di; 02258 02259 /* <> 0 if we are inside of trigger or stored function. */ 02260 uint in_sub_stmt; 02261 02270 uint fill_status_recursion_level; 02271 uint fill_variables_recursion_level; 02272 02273 /* container for handler's private per-connection data */ 02274 Ha_data ha_data[MAX_HA]; 02275 02276 /* 02277 Position of first event in Binlog 02278 *after* last event written by this 02279 thread. 02280 */ 02281 event_coordinates binlog_next_event_pos; 02282 void set_next_event_pos(const char* _filename, ulonglong _pos); 02283 void clear_next_event_pos(); 02284 02285 /* 02286 Ptr to row event extra data to be written to Binlog / 02287 received from Binlog. 02288 02289 */ 02290 uchar* binlog_row_event_extra_data; 02291 static bool binlog_row_event_extra_data_eq(const uchar* a, 02292 const uchar* b); 02293 02294 #ifndef MYSQL_CLIENT 02295 int binlog_setup_trx_data(); 02296 02297 /* 02298 Public interface to write RBR events to the binlog 02299 */ 02300 int binlog_write_table_map(TABLE *table, bool is_transactional, 02301 bool binlog_rows_query); 02302 int binlog_write_row(TABLE* table, bool is_transactional, 02303 const uchar *new_data, 02304 const uchar* extra_row_info); 02305 int binlog_delete_row(TABLE* table, bool is_transactional, 02306 const uchar *old_data, 02307 const uchar* extra_row_info); 02308 int binlog_update_row(TABLE* table, bool is_transactional, 02309 const uchar *old_data, const uchar *new_data, 02310 const uchar* extra_row_info); 02311 void binlog_prepare_row_images(TABLE* table); 02312 02313 void set_server_id(uint32 sid) { server_id = sid; } 02314 02315 /* 02316 Member functions to handle pending event for row-level logging. 02317 */ 02318 template <class RowsEventT> Rows_log_event* 02319 binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, 02320 size_t needed, 02321 bool is_transactional, 02322 RowsEventT* hint, 02323 const uchar* extra_row_info); 02324 Rows_log_event* binlog_get_pending_rows_event(bool is_transactional) const; 02325 inline int binlog_flush_pending_rows_event(bool stmt_end) 02326 { 02327 return (binlog_flush_pending_rows_event(stmt_end, FALSE) || 02328 binlog_flush_pending_rows_event(stmt_end, TRUE)); 02329 } 02330 int binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional); 02331 02340 int is_current_stmt_binlog_format_row() const { 02341 DBUG_ASSERT(current_stmt_binlog_format == BINLOG_FORMAT_STMT || 02342 current_stmt_binlog_format == BINLOG_FORMAT_ROW); 02343 return current_stmt_binlog_format == BINLOG_FORMAT_ROW; 02344 } 02346 inline bool optimizer_switch_flag(ulonglong flag) const 02347 { 02348 return (variables.optimizer_switch & flag); 02349 } 02350 02351 enum binlog_filter_state 02352 { 02353 BINLOG_FILTER_UNKNOWN, 02354 BINLOG_FILTER_CLEAR, 02355 BINLOG_FILTER_SET 02356 }; 02357 02358 inline void reset_binlog_local_stmt_filter() 02359 { 02360 m_binlog_filter_state= BINLOG_FILTER_UNKNOWN; 02361 } 02362 02363 inline void clear_binlog_local_stmt_filter() 02364 { 02365 DBUG_ASSERT(m_binlog_filter_state == BINLOG_FILTER_UNKNOWN); 02366 m_binlog_filter_state= BINLOG_FILTER_CLEAR; 02367 } 02368 02369 inline void set_binlog_local_stmt_filter() 02370 { 02371 DBUG_ASSERT(m_binlog_filter_state == BINLOG_FILTER_UNKNOWN); 02372 m_binlog_filter_state= BINLOG_FILTER_SET; 02373 } 02374 02375 inline binlog_filter_state get_binlog_local_stmt_filter() 02376 { 02377 return m_binlog_filter_state; 02378 } 02379 02380 private: 02388 binlog_filter_state m_binlog_filter_state; 02389 02394 enum_binlog_format current_stmt_binlog_format; 02395 02408 uint32 binlog_unsafe_warning_flags; 02409 02410 /* 02411 Number of outstanding table maps, i.e., table maps in the 02412 transaction cache. 02413 */ 02414 uint binlog_table_maps; 02415 /* 02416 MTS: db names listing to be updated by the query databases 02417 */ 02418 List<char> *binlog_accessed_db_names; 02419 02434 const char *m_trans_log_file; 02435 char *m_trans_fixed_log_file; 02436 my_off_t m_trans_end_pos; 02439 public: 02440 void issue_unsafe_warnings(); 02441 02442 uint get_binlog_table_maps() const { 02443 return binlog_table_maps; 02444 } 02445 void clear_binlog_table_maps() { 02446 binlog_table_maps= 0; 02447 } 02448 02449 /* 02450 MTS: accessor to binlog_accessed_db_names list 02451 */ 02452 List<char> * get_binlog_accessed_db_names() 02453 { 02454 return binlog_accessed_db_names; 02455 } 02456 02457 /* 02458 MTS: resetter of binlog_accessed_db_names list normally 02459 at the end of the query execution 02460 */ 02461 void clear_binlog_accessed_db_names() { binlog_accessed_db_names= NULL; } 02462 02463 /* MTS: method inserts a new unique name into binlog_updated_dbs */ 02464 void add_to_binlog_accessed_dbs(const char *db); 02465 02466 #endif /* MYSQL_CLIENT */ 02467 02468 public: 02469 02470 struct st_transactions { 02471 SAVEPOINT *savepoints; 02472 THD_TRANS all; // Trans since BEGIN WORK 02473 THD_TRANS stmt; // Trans for current statement 02474 XID_STATE xid_state; 02475 Rows_log_event *m_pending_rows_event; 02476 02477 /* 02478 Tables changed in transaction (that must be invalidated in query cache). 02479 List contain only transactional tables, that not invalidated in query 02480 cache (instead of full list of changed in transaction tables). 02481 */ 02482 CHANGED_TABLE_LIST* changed_tables; 02483 MEM_ROOT mem_root; // Transaction-life memory allocation pool 02484 02485 /* 02486 (Mostly) binlog-specific fields use while flushing the caches 02487 and committing transactions. 02488 We don't use bitfield any more in the struct. Modification will 02489 be lost when concurrently updating multiple bit fields. It will 02490 cause a race condition in a multi-threaded application. And we 02491 already caught a race condition case between xid_written and 02492 ready_preempt in MYSQL_BIN_LOG::ordered_commit. 02493 */ 02494 struct { 02495 bool enabled; // see ha_enable_transaction() 02496 bool pending; // Is the transaction commit pending? 02497 bool xid_written; // The session wrote an XID 02498 bool real_commit; // Is this a "real" commit? 02499 bool commit_low; // see MYSQL_BIN_LOG::ordered_commit 02500 bool run_hooks; // Call the after_commit hook 02501 #ifndef DBUG_OFF 02502 bool ready_preempt; // internal in MYSQL_BIN_LOG::ordered_commit 02503 #endif 02504 } flags; 02505 02506 void cleanup() 02507 { 02508 DBUG_ENTER("THD::st_transaction::cleanup"); 02509 changed_tables= 0; 02510 savepoints= 0; 02511 02512 /* 02513 If rm_error is raised, it means that this piece of a distributed 02514 transaction has failed and must be rolled back. But the user must 02515 rollback it explicitly, so don't start a new distributed XA until 02516 then. 02517 */ 02518 if (!xid_state.rm_error) 02519 xid_state.xid.null(); 02520 free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); 02521 DBUG_VOID_RETURN; 02522 } 02523 my_bool is_active() 02524 { 02525 return (all.ha_list != NULL); 02526 } 02527 st_transactions() 02528 { 02529 memset(this, 0, sizeof(*this)); 02530 xid_state.xid.null(); 02531 init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); 02532 } 02533 void push_unsafe_rollback_warnings(THD *thd) 02534 { 02535 if (all.has_modified_non_trans_table()) 02536 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 02537 ER_WARNING_NOT_COMPLETE_ROLLBACK, 02538 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); 02539 02540 if (all.has_created_temp_table()) 02541 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 02542 ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE, 02543 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE)); 02544 02545 if (all.has_dropped_temp_table()) 02546 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 02547 ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE, 02548 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE)); 02549 } 02550 void merge_unsafe_rollback_flags() 02551 { 02552 /* 02553 Merge stmt.unsafe_rollback_flags to all.unsafe_rollback_flags. If 02554 the statement cannot be rolled back safely, the transaction including 02555 this statement definitely cannot rolled back safely. 02556 */ 02557 all.add_unsafe_rollback_flags(stmt.get_unsafe_rollback_flags()); 02558 } 02559 } transaction; 02560 Global_read_lock global_read_lock; 02561 Field *dup_field; 02562 #ifndef __WIN__ 02563 sigset_t signals; 02564 #endif 02565 #ifdef SIGNAL_WITH_VIO_SHUTDOWN 02566 Vio* active_vio; 02567 #endif 02568 /* 02569 This is to track items changed during execution of a prepared 02570 statement/stored procedure. It's created by 02571 register_item_tree_change() in memory root of THD, and freed in 02572 rollback_item_tree_changes(). For conventional execution it's always 02573 empty. 02574 */ 02575 Item_change_list change_list; 02576 02577 /* 02578 A permanent memory area of the statement. For conventional 02579 execution, the parsed tree and execution runtime reside in the same 02580 memory root. In this case stmt_arena points to THD. In case of 02581 a prepared statement or a stored procedure statement, thd->mem_root 02582 conventionally points to runtime memory, and thd->stmt_arena 02583 points to the memory of the PS/SP, where the parsed tree of the 02584 statement resides. Whenever you need to perform a permanent 02585 transformation of a parsed tree, you should allocate new memory in 02586 stmt_arena, to allow correct re-execution of PS/SP. 02587 Note: in the parser, stmt_arena == thd, even for PS/SP. 02588 */ 02589 Query_arena *stmt_arena; 02590 02591 /* 02592 map for tables that will be updated for a multi-table update query 02593 statement, for other query statements, this will be zero. 02594 */ 02595 table_map table_map_for_update; 02596 02597 /* Tells if LAST_INSERT_ID(#) was called for the current statement */ 02598 bool arg_of_last_insert_id_function; 02599 /* 02600 ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for 02601 insertion into an auto_increment column". 02602 */ 02603 /* 02604 This is the first autogenerated insert id which was *successfully* 02605 inserted by the previous statement (exactly, if the previous statement 02606 didn't successfully insert an autogenerated insert id, then it's the one 02607 of the statement before, etc). 02608 It can also be set by SET LAST_INSERT_ID=# or SELECT LAST_INSERT_ID(#). 02609 It is returned by LAST_INSERT_ID(). 02610 */ 02611 ulonglong first_successful_insert_id_in_prev_stmt; 02612 /* 02613 Variant of the above, used for storing in statement-based binlog. The 02614 difference is that the one above can change as the execution of a stored 02615 function progresses, while the one below is set once and then does not 02616 change (which is the value which statement-based binlog needs). 02617 */ 02618 ulonglong first_successful_insert_id_in_prev_stmt_for_binlog; 02619 /* 02620 This is the first autogenerated insert id which was *successfully* 02621 inserted by the current statement. It is maintained only to set 02622 first_successful_insert_id_in_prev_stmt when statement ends. 02623 */ 02624 ulonglong first_successful_insert_id_in_cur_stmt; 02625 /* 02626 We follow this logic: 02627 - when stmt starts, first_successful_insert_id_in_prev_stmt contains the 02628 first insert id successfully inserted by the previous stmt. 02629 - as stmt makes progress, handler::insert_id_for_cur_row changes; 02630 every time get_auto_increment() is called, 02631 auto_inc_intervals_in_cur_stmt_for_binlog is augmented with the 02632 reserved interval (if statement-based binlogging). 02633 - at first successful insertion of an autogenerated value, 02634 first_successful_insert_id_in_cur_stmt is set to 02635 handler::insert_id_for_cur_row. 02636 - when stmt goes to binlog, 02637 auto_inc_intervals_in_cur_stmt_for_binlog is binlogged if 02638 non-empty. 02639 - when stmt ends, first_successful_insert_id_in_prev_stmt is set to 02640 first_successful_insert_id_in_cur_stmt. 02641 */ 02642 /* 02643 stmt_depends_on_first_successful_insert_id_in_prev_stmt is set when 02644 LAST_INSERT_ID() is used by a statement. 02645 If it is set, first_successful_insert_id_in_prev_stmt_for_binlog will be 02646 stored in the statement-based binlog. 02647 This variable is CUMULATIVE along the execution of a stored function or 02648 trigger: if one substatement sets it to 1 it will stay 1 until the 02649 function/trigger ends, thus making sure that 02650 first_successful_insert_id_in_prev_stmt_for_binlog does not change anymore 02651 and is propagated to the caller for binlogging. 02652 */ 02653 bool stmt_depends_on_first_successful_insert_id_in_prev_stmt; 02654 /* 02655 List of auto_increment intervals reserved by the thread so far, for 02656 storage in the statement-based binlog. 02657 Note that its minimum is not first_successful_insert_id_in_cur_stmt: 02658 assuming a table with an autoinc column, and this happens: 02659 INSERT INTO ... VALUES(3); 02660 SET INSERT_ID=3; INSERT IGNORE ... VALUES (NULL); 02661 then the latter INSERT will insert no rows 02662 (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3" 02663 in the binlog is still needed; the list's minimum will contain 3. 02664 This variable is cumulative: if several statements are written to binlog 02665 as one (stored functions or triggers are used) this list is the 02666 concatenation of all intervals reserved by all statements. 02667 */ 02668 Discrete_intervals_list auto_inc_intervals_in_cur_stmt_for_binlog; 02669 /* Used by replication and SET INSERT_ID */ 02670 Discrete_intervals_list auto_inc_intervals_forced; 02671 /* 02672 There is BUG#19630 where statement-based replication of stored 02673 functions/triggers with two auto_increment columns breaks. 02674 We however ensure that it works when there is 0 or 1 auto_increment 02675 column; our rules are 02676 a) on master, while executing a top statement involving substatements, 02677 first top- or sub- statement to generate auto_increment values wins the 02678 exclusive right to see its values be written to binlog (the write 02679 will be done by the statement or its caller), and the losers won't see 02680 their values be written to binlog. 02681 b) on slave, while replicating a top statement involving substatements, 02682 first top- or sub- statement to need to read auto_increment values from 02683 the master's binlog wins the exclusive right to read them (so the losers 02684 won't read their values from binlog but instead generate on their own). 02685 a) implies that we mustn't backup/restore 02686 auto_inc_intervals_in_cur_stmt_for_binlog. 02687 b) implies that we mustn't backup/restore auto_inc_intervals_forced. 02688 02689 If there are more than 1 auto_increment columns, then intervals for 02690 different columns may mix into the 02691 auto_inc_intervals_in_cur_stmt_for_binlog list, which is logically wrong, 02692 but there is no point in preventing this mixing by preventing intervals 02693 from the secondly inserted column to come into the list, as such 02694 prevention would be wrong too. 02695 What will happen in the case of 02696 INSERT INTO t1 (auto_inc) VALUES(NULL); 02697 where t1 has a trigger which inserts into an auto_inc column of t2, is 02698 that in binlog we'll store the interval of t1 and the interval of t2 (when 02699 we store intervals, soon), then in slave, t1 will use both intervals, t2 02700 will use none; if t1 inserts the same number of rows as on master, 02701 normally the 2nd interval will not be used by t1, which is fine. t2's 02702 values will be wrong if t2's internal auto_increment counter is different 02703 from what it was on master (which is likely). In 5.1, in mixed binlogging 02704 mode, row-based binlogging is used for such cases where two 02705 auto_increment columns are inserted. 02706 */ 02707 inline void record_first_successful_insert_id_in_cur_stmt(ulonglong id_arg) 02708 { 02709 if (first_successful_insert_id_in_cur_stmt == 0) 02710 first_successful_insert_id_in_cur_stmt= id_arg; 02711 } 02712 inline ulonglong read_first_successful_insert_id_in_prev_stmt(void) 02713 { 02714 if (!stmt_depends_on_first_successful_insert_id_in_prev_stmt) 02715 { 02716 /* It's the first time we read it */ 02717 first_successful_insert_id_in_prev_stmt_for_binlog= 02718 first_successful_insert_id_in_prev_stmt; 02719 stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1; 02720 } 02721 return first_successful_insert_id_in_prev_stmt; 02722 } 02723 /* 02724 Used by Intvar_log_event::do_apply_event() and by "SET INSERT_ID=#" 02725 (mysqlbinlog). We'll soon add a variant which can take many intervals in 02726 argument. 02727 */ 02728 inline void force_one_auto_inc_interval(ulonglong next_id) 02729 { 02730 auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID 02731 auto_inc_intervals_forced.append(next_id, ULONGLONG_MAX, 0); 02732 } 02733 02734 ulonglong limit_found_rows; 02735 02736 private: 02766 longlong m_row_count_func; /* For the ROW_COUNT() function */ 02767 02768 public: 02769 inline longlong get_row_count_func() const 02770 { 02771 return m_row_count_func; 02772 } 02773 02774 inline void set_row_count_func(longlong row_count_func) 02775 { 02776 m_row_count_func= row_count_func; 02777 } 02778 02779 ha_rows cuted_fields; 02780 02781 private: 02786 ha_rows m_sent_row_count; 02787 02798 ha_rows m_examined_row_count; 02799 02800 private: 02801 USER_CONN *m_user_connect; 02802 02803 public: 02804 void set_user_connect(USER_CONN *uc); 02805 const USER_CONN* get_user_connect() 02806 { return m_user_connect; } 02807 02808 void increment_user_connections_counter(); 02809 void decrement_user_connections_counter(); 02810 02811 void increment_con_per_hour_counter(); 02812 02813 void increment_updates_counter(); 02814 02815 void increment_questions_counter(); 02816 02817 void time_out_user_resource_limits(); 02818 02819 public: 02820 ha_rows get_sent_row_count() const 02821 { return m_sent_row_count; } 02822 02823 ha_rows get_examined_row_count() const 02824 { return m_examined_row_count; } 02825 02826 void set_sent_row_count(ha_rows count); 02827 void set_examined_row_count(ha_rows count); 02828 02829 void inc_sent_row_count(ha_rows count); 02830 void inc_examined_row_count(ha_rows count); 02831 02832 void inc_status_created_tmp_disk_tables(); 02833 void inc_status_created_tmp_files(); 02834 void inc_status_created_tmp_tables(); 02835 void inc_status_select_full_join(); 02836 void inc_status_select_full_range_join(); 02837 void inc_status_select_range(); 02838 void inc_status_select_range_check(); 02839 void inc_status_select_scan(); 02840 void inc_status_sort_merge_passes(); 02841 void inc_status_sort_range(); 02842 void inc_status_sort_rows(ha_rows count); 02843 void inc_status_sort_scan(); 02844 void set_status_no_index_used(); 02845 void set_status_no_good_index_used(); 02846 02847 const CHARSET_INFO *db_charset; 02848 #if defined(ENABLED_PROFILING) 02849 PROFILING profiling; 02850 #endif 02851 02853 sql_digest_state *m_digest; 02855 unsigned char *m_token_array; 02857 sql_digest_state m_digest_state; 02858 02860 PSI_statement_locker *m_statement_psi; 02861 #ifdef HAVE_PSI_STATEMENT_INTERFACE 02862 02863 PSI_statement_locker_state m_statement_state; 02864 #endif /* HAVE_PSI_STATEMENT_INTERFACE */ 02865 02866 PSI_idle_locker *m_idle_psi; 02867 #ifdef HAVE_PSI_IDLE_INTERFACE 02868 02869 PSI_idle_locker_state m_idle_state; 02870 #endif /* HAVE_PSI_IDLE_INTERFACE */ 02871 02872 bool m_server_idle; 02873 02874 /* 02875 Id of current query. Statement can be reused to execute several queries 02876 query_id is global in context of the whole MySQL server. 02877 ID is automatically generated from mutex-protected counter. 02878 It's used in handler code for various purposes: to check which columns 02879 from table are necessary for this select, to check if it's necessary to 02880 update auto-updatable fields (like auto_increment and timestamp). 02881 */ 02882 query_id_t query_id; 02883 ulong col_access; 02884 02885 /* Statement id is thread-wide. This counter is used to generate ids */ 02886 ulong statement_id_counter; 02887 ulong rand_saved_seed1, rand_saved_seed2; 02888 pthread_t real_id; /* For debugging */ 02889 my_thread_id thread_id; 02890 uint tmp_table; 02891 uint server_status,open_options; 02892 enum enum_thread_type system_thread; 02893 uint select_number; //number of select (used for EXPLAIN) 02894 /* 02895 Current or next transaction isolation level. 02896 When a connection is established, the value is taken from 02897 @@session.tx_isolation (default transaction isolation for 02898 the session), which is in turn taken from @@global.tx_isolation 02899 (the global value). 02900 If there is no transaction started, this variable 02901 holds the value of the next transaction's isolation level. 02902 When a transaction starts, the value stored in this variable 02903 becomes "actual". 02904 At transaction commit or rollback, we assign this variable 02905 again from @@session.tx_isolation. 02906 The only statement that can otherwise change the value 02907 of this variable is SET TRANSACTION ISOLATION LEVEL. 02908 Its purpose is to effect the isolation level of the next 02909 transaction in this session. When this statement is executed, 02910 the value in this variable is changed. However, since 02911 this statement is only allowed when there is no active 02912 transaction, this assignment (naturally) only affects the 02913 upcoming transaction. 02914 At the end of the current active transaction the value is 02915 be reset again from @@session.tx_isolation, as described 02916 above. 02917 */ 02918 enum_tx_isolation tx_isolation; 02919 /* 02920 Current or next transaction access mode. 02921 See comment above regarding tx_isolation. 02922 */ 02923 bool tx_read_only; 02924 enum_check_fields count_cuted_fields; 02925 02926 DYNAMIC_ARRAY user_var_events; /* For user variables replication */ 02927 MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ 02928 02933 THD *next_to_commit; 02934 02942 void set_trans_pos(const char *file, my_off_t pos) 02943 { 02944 DBUG_ENTER("THD::set_trans_pos"); 02945 DBUG_ASSERT(((file == 0) && (pos == 0)) || ((file != 0) && (pos != 0))); 02946 if (file) 02947 { 02948 DBUG_PRINT("enter", ("file: %s, pos: %llu", file, pos)); 02949 // Only the file name should be used, not the full path 02950 m_trans_log_file= file + dirname_length(file); 02951 if (!m_trans_fixed_log_file) 02952 m_trans_fixed_log_file= (char*) alloc_root(&main_mem_root, FN_REFLEN+1); 02953 DBUG_ASSERT(strlen(m_trans_log_file) <= FN_REFLEN); 02954 strcpy(m_trans_fixed_log_file, m_trans_log_file); 02955 } 02956 else 02957 { 02958 m_trans_log_file= NULL; 02959 m_trans_fixed_log_file= NULL; 02960 } 02961 02962 m_trans_end_pos= pos; 02963 DBUG_PRINT("return", ("m_trans_log_file: %s, m_trans_fixed_log_file: %s, " 02964 "m_trans_end_pos: %llu", m_trans_log_file, 02965 m_trans_fixed_log_file, m_trans_end_pos)); 02966 DBUG_VOID_RETURN; 02967 } 02968 02969 void get_trans_pos(const char **file_var, my_off_t *pos_var) const 02970 { 02971 DBUG_ENTER("THD::get_trans_pos"); 02972 if (file_var) 02973 *file_var = m_trans_log_file; 02974 if (pos_var) 02975 *pos_var= m_trans_end_pos; 02976 DBUG_PRINT("return", ("file: %s, pos: %llu", 02977 file_var ? *file_var : "<none>", 02978 pos_var ? *pos_var : 0)); 02979 DBUG_VOID_RETURN; 02980 } 02981 02982 void get_trans_fixed_pos(const char **file_var, my_off_t *pos_var) const 02983 { 02984 DBUG_ENTER("THD::get_trans_fixed_pos"); 02985 if (file_var) 02986 *file_var = m_trans_fixed_log_file; 02987 if (pos_var) 02988 *pos_var= m_trans_end_pos; 02989 DBUG_PRINT("return", ("file: %s, pos: %llu", 02990 file_var ? *file_var : "<none>", 02991 pos_var ? *pos_var : 0)); 02992 DBUG_VOID_RETURN; 02993 } 02997 /* 02998 Error code from committing or rolling back the transaction. 02999 */ 03000 enum Commit_error 03001 { 03002 CE_NONE= 0, 03003 CE_FLUSH_ERROR, 03004 CE_COMMIT_ERROR, 03005 CE_ERROR_COUNT 03006 } commit_error; 03007 03008 /* 03009 Define durability properties that engines may check to 03010 improve performance. 03011 */ 03012 enum durability_properties durability_property; 03013 03014 /* 03015 If checking this in conjunction with a wait condition, please 03016 include a check after enter_cond() if you want to avoid a race 03017 condition. For details see the implementation of awake(), 03018 especially the "broadcast" part. 03019 */ 03020 enum killed_state 03021 { 03022 NOT_KILLED=0, 03023 KILL_BAD_DATA=1, 03024 KILL_CONNECTION=ER_SERVER_SHUTDOWN, 03025 KILL_QUERY=ER_QUERY_INTERRUPTED, 03026 KILLED_NO_VALUE /* means neither of the states */ 03027 }; 03028 killed_state volatile killed; 03029 03030 /* scramble - random string sent to client on handshake */ 03031 char scramble[SCRAMBLE_LENGTH+1]; 03032 03034 bool slave_thread, one_shot_set; 03035 bool no_errors; 03036 uchar password; 03044 bool is_fatal_error; 03050 bool transaction_rollback_request; 03062 bool is_fatal_sub_stmt_error; 03063 bool query_start_used, query_start_usec_used; 03064 bool rand_used, time_zone_used; 03065 /* for IS NULL => = last_insert_id() fix in remove_eq_conds() */ 03066 bool substitute_null_with_insert_id; 03067 bool in_lock_tables; 03074 bool is_slave_error; 03075 bool bootstrap; 03076 03078 bool thread_specific_used; 03083 bool charset_is_system_charset, charset_is_collation_connection; 03084 bool charset_is_character_set_filesystem; 03085 bool enable_slow_log; /* enable slow log for current statement */ 03086 bool abort_on_warning; 03087 bool got_warning; /* Set on call to push_warning() */ 03088 /* set during loop of derived table processing */ 03089 bool derived_tables_processing; 03090 my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ 03091 03093 sp_rcontext *sp_runtime_ctx; 03094 sp_cache *sp_proc_cache; 03095 sp_cache *sp_func_cache; 03096 03098 uint query_name_consts; 03099 03100 /* 03101 If we do a purge of binary logs, log index info of the threads 03102 that are currently reading it needs to be adjusted. To do that 03103 each thread that is using LOG_INFO needs to adjust the pointer to it 03104 */ 03105 LOG_INFO* current_linfo; 03106 NET* slave_net; // network connection from slave -> m. 03107 /* Used by the sys_var class to store temporary values */ 03108 union 03109 { 03110 my_bool my_bool_value; 03111 long long_value; 03112 ulong ulong_value; 03113 ulonglong ulonglong_value; 03114 double double_value; 03115 } sys_var_tmp; 03116 03117 struct { 03118 /* 03119 If true, mysql_bin_log::write(Log_event) call will not write events to 03120 binlog, and maintain 2 below variables instead (use 03121 mysql_bin_log.start_union_events to turn this on) 03122 */ 03123 bool do_union; 03124 /* 03125 If TRUE, at least one mysql_bin_log::write(Log_event) call has been 03126 made after last mysql_bin_log.start_union_events() call. 03127 */ 03128 bool unioned_events; 03129 /* 03130 If TRUE, at least one mysql_bin_log::write(Log_event e), where 03131 e.cache_stmt == TRUE call has been made after last 03132 mysql_bin_log.start_union_events() call. 03133 */ 03134 bool unioned_events_trans; 03135 03136 /* 03137 'queries' (actually SP statements) that run under inside this binlog 03138 union have thd->query_id >= first_query_id. 03139 */ 03140 query_id_t first_query_id; 03141 } binlog_evt_union; 03142 03148 Parser_state *m_parser_state; 03149 03150 Locked_tables_list locked_tables_list; 03151 03152 #ifdef WITH_PARTITION_STORAGE_ENGINE 03153 partition_info *work_part_info; 03154 #endif 03155 03156 #ifndef EMBEDDED_LIBRARY 03157 03162 DYNAMIC_ARRAY audit_class_plugins; 03167 unsigned long audit_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; 03168 #endif 03169 03170 #if defined(ENABLED_DEBUG_SYNC) 03171 /* Debug Sync facility. See debug_sync.cc. */ 03172 struct st_debug_sync_control *debug_sync_control; 03173 #endif /* defined(ENABLED_DEBUG_SYNC) */ 03174 03175 // We don't want to load/unload plugins for unit tests. 03176 bool m_enable_plugins; 03177 03178 THD(bool enable_plugins= true); 03179 03180 /* 03181 The THD dtor is effectively split in two: 03182 THD::release_resources() and ~THD(). 03183 03184 We want to minimize the time we hold LOCK_thread_count, 03185 so when destroying a global thread, do: 03186 03187 thd->release_resources() 03188 remove_global_thread(thd); 03189 delete thd; 03190 */ 03191 ~THD(); 03192 03193 void release_resources(); 03194 bool release_resources_done() const { return m_release_resources_done; } 03195 03196 private: 03197 bool m_release_resources_done; 03198 bool cleanup_done; 03199 void cleanup(void); 03200 03201 public: 03202 void init(void); 03203 /* 03204 Initialize memory roots necessary for query processing and (!) 03205 pre-allocate memory for it. We can't do that in THD constructor because 03206 there are use cases (acl_init, delayed inserts, watcher threads, 03207 killing mysqld) where it's vital to not allocate excessive and not used 03208 memory. Note, that we still don't return error from init_for_queries(): 03209 if preallocation fails, we should notice that at the first call to 03210 alloc_root. 03211 */ 03212 void init_for_queries(Relay_log_info *rli= NULL); 03213 void change_user(void); 03214 void cleanup_after_query(); 03215 bool store_globals(); 03216 bool restore_globals(); 03217 #ifdef SIGNAL_WITH_VIO_SHUTDOWN 03218 inline void set_active_vio(Vio* vio) 03219 { 03220 mysql_mutex_lock(&LOCK_thd_data); 03221 active_vio = vio; 03222 mysql_mutex_unlock(&LOCK_thd_data); 03223 } 03224 inline void clear_active_vio() 03225 { 03226 mysql_mutex_lock(&LOCK_thd_data); 03227 active_vio = 0; 03228 mysql_mutex_unlock(&LOCK_thd_data); 03229 } 03230 void shutdown_active_vio(); 03231 #endif 03232 void awake(THD::killed_state state_to_set); 03233 03235 void disconnect(); 03236 03237 #ifndef MYSQL_CLIENT 03238 enum enum_binlog_query_type { 03239 /* The query can be logged in row format or in statement format. */ 03240 ROW_QUERY_TYPE, 03241 03242 /* The query has to be logged in statement format. */ 03243 STMT_QUERY_TYPE, 03244 03245 QUERY_TYPE_COUNT 03246 }; 03247 03248 int binlog_query(enum_binlog_query_type qtype, 03249 char const *query, ulong query_len, bool is_trans, 03250 bool direct, bool suppress_use, 03251 int errcode); 03252 #endif 03253 03254 // Begin implementation of MDL_context_owner interface. 03255 03256 inline void 03257 enter_cond(mysql_cond_t *cond, mysql_mutex_t* mutex, 03258 const PSI_stage_info *stage, PSI_stage_info *old_stage, 03259 const char *src_function, const char *src_file, 03260 int src_line) 03261 { 03262 DBUG_ENTER("THD::enter_cond"); 03263 mysql_mutex_assert_owner(mutex); 03264 DBUG_PRINT("debug", ("thd: 0x%llx, mysys_var: 0x%llx, current_mutex: 0x%llx -> 0x%llx", 03265 (ulonglong) this, 03266 (ulonglong) mysys_var, 03267 (ulonglong) mysys_var->current_mutex, 03268 (ulonglong) mutex)); 03269 mysys_var->current_mutex = mutex; 03270 mysys_var->current_cond = cond; 03271 enter_stage(stage, old_stage, src_function, src_file, src_line); 03272 DBUG_VOID_RETURN; 03273 } 03274 inline void exit_cond(const PSI_stage_info *stage, 03275 const char *src_function, const char *src_file, 03276 int src_line) 03277 { 03278 DBUG_ENTER("THD::exit_cond"); 03279 /* 03280 Putting the mutex unlock in thd->exit_cond() ensures that 03281 mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is 03282 locked (if that would not be the case, you'll get a deadlock if someone 03283 does a THD::awake() on you). 03284 */ 03285 DBUG_PRINT("debug", ("thd: 0x%llx, mysys_var: 0x%llx, current_mutex: 0x%llx -> 0x%llx", 03286 (ulonglong) this, 03287 (ulonglong) mysys_var, 03288 (ulonglong) mysys_var->current_mutex, 03289 0ULL)); 03290 mysql_mutex_unlock(mysys_var->current_mutex); 03291 mysql_mutex_lock(&mysys_var->mutex); 03292 mysys_var->current_mutex = 0; 03293 mysys_var->current_cond = 0; 03294 enter_stage(stage, NULL, src_function, src_file, src_line); 03295 mysql_mutex_unlock(&mysys_var->mutex); 03296 DBUG_VOID_RETURN; 03297 } 03298 03299 virtual int is_killed() { return killed; } 03300 virtual THD* get_thd() { return this; } 03301 03325 virtual bool notify_shared_lock(MDL_context_owner *ctx_in_use, 03326 bool needs_thr_lock_abort); 03327 03328 // End implementation of MDL_context_owner interface. 03329 03330 inline sql_mode_t datetime_flags() const 03331 { 03332 return variables.sql_mode & 03333 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES); 03334 } 03335 inline bool is_strict_mode() const 03336 { 03337 return MY_TEST(variables.sql_mode & (MODE_STRICT_TRANS_TABLES | 03338 MODE_STRICT_ALL_TABLES)); 03339 } 03340 inline Time_zone *time_zone() 03341 { 03342 time_zone_used= 1; 03343 return variables.time_zone; 03344 } 03345 inline time_t query_start() 03346 { 03347 query_start_used= 1; 03348 return start_time.tv_sec; 03349 } 03350 inline long query_start_usec() 03351 { 03352 query_start_usec_used= 1; 03353 return start_time.tv_usec; 03354 } 03355 inline timeval query_start_timeval() 03356 { 03357 query_start_used= query_start_usec_used= true; 03358 return start_time; 03359 } 03360 timeval query_start_timeval_trunc(uint decimals); 03361 inline void set_time() 03362 { 03363 start_utime= utime_after_lock= my_micro_time(); 03364 if (user_time.tv_sec || user_time.tv_usec) 03365 { 03366 start_time= user_time; 03367 } 03368 else 03369 my_micro_time_to_timeval(start_utime, &start_time); 03370 03371 #ifdef HAVE_PSI_THREAD_INTERFACE 03372 PSI_THREAD_CALL(set_thread_start_time)(start_time.tv_sec); 03373 #endif 03374 } 03375 inline void set_current_time() 03376 { 03377 my_micro_time_to_timeval(my_micro_time(), &start_time); 03378 #ifdef HAVE_PSI_THREAD_INTERFACE 03379 PSI_THREAD_CALL(set_thread_start_time)(start_time.tv_sec); 03380 #endif 03381 } 03382 inline void set_time(const struct timeval *t) 03383 { 03384 start_time= user_time= *t; 03385 start_utime= utime_after_lock= my_micro_time(); 03386 #ifdef HAVE_PSI_THREAD_INTERFACE 03387 PSI_THREAD_CALL(set_thread_start_time)(start_time.tv_sec); 03388 #endif 03389 } 03390 /*TODO: this will be obsolete when we have support for 64 bit my_time_t */ 03391 inline bool is_valid_time() 03392 { 03393 return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time.tv_sec)); 03394 } 03395 void set_time_after_lock() 03396 { 03397 utime_after_lock= my_micro_time(); 03398 MYSQL_SET_STATEMENT_LOCK_TIME(m_statement_psi, (utime_after_lock - start_utime)); 03399 } 03400 ulonglong current_utime() { return my_micro_time(); } 03409 void update_server_status() 03410 { 03411 ulonglong end_utime_of_query= current_utime(); 03412 if (end_utime_of_query > utime_after_lock + variables.long_query_time) 03413 server_status|= SERVER_QUERY_WAS_SLOW; 03414 } 03415 inline ulonglong found_rows(void) 03416 { 03417 return limit_found_rows; 03418 } 03442 inline bool in_multi_stmt_transaction_mode() const 03443 { 03444 return variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN); 03445 } 03479 inline bool in_active_multi_stmt_transaction() const 03480 { 03481 return server_status & SERVER_STATUS_IN_TRANS; 03482 } 03483 inline bool fill_derived_tables() 03484 { 03485 return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure(); 03486 } 03487 inline bool fill_information_schema_tables() 03488 { 03489 return !stmt_arena->is_stmt_prepare(); 03490 } 03491 inline void* trans_alloc(unsigned int size) 03492 { 03493 return alloc_root(&transaction.mem_root,size); 03494 } 03495 03496 LEX_STRING *make_lex_string(LEX_STRING *lex_str, 03497 const char* str, uint length, 03498 bool allocate_lex_string); 03499 03500 bool convert_string(LEX_STRING *to, const CHARSET_INFO *to_cs, 03501 const char *from, uint from_length, 03502 const CHARSET_INFO *from_cs); 03503 03504 bool convert_string(String *s, const CHARSET_INFO *from_cs, 03505 const CHARSET_INFO *to_cs); 03506 03507 void add_changed_table(TABLE *table); 03508 void add_changed_table(const char *key, long key_length); 03509 CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); 03510 int send_explain_fields(select_result *result); 03511 03519 inline void clear_error() 03520 { 03521 DBUG_ENTER("clear_error"); 03522 if (get_stmt_da()->is_error()) 03523 get_stmt_da()->reset_diagnostics_area(); 03524 is_slave_error= 0; 03525 DBUG_VOID_RETURN; 03526 } 03527 #ifndef EMBEDDED_LIBRARY 03528 inline bool vio_ok() const { return net.vio != 0; } 03530 bool is_connected() 03531 { 03532 /* 03533 All system threads (e.g., the slave IO thread) are connected but 03534 not using vio. So this function always returns true for all 03535 system threads. 03536 */ 03537 return system_thread || (vio_ok() ? vio_is_connected(net.vio) : FALSE); 03538 } 03539 #else 03540 inline bool vio_ok() const { return TRUE; } 03541 inline bool is_connected() { return TRUE; } 03542 #endif 03543 03548 inline void fatal_error() 03549 { 03550 DBUG_ASSERT(get_stmt_da()->is_error() || killed); 03551 is_fatal_error= 1; 03552 DBUG_PRINT("error",("Fatal error set")); 03553 } 03567 inline bool is_error() const { return get_stmt_da()->is_error(); } 03568 03570 Diagnostics_area *get_stmt_da() 03571 { return m_stmt_da; } 03572 03574 const Diagnostics_area *get_stmt_da() const 03575 { return m_stmt_da; } 03576 03578 void set_stmt_da(Diagnostics_area *da) 03579 { m_stmt_da= da; } 03580 03581 public: 03582 inline const CHARSET_INFO *charset() 03583 { return variables.character_set_client; } 03584 void update_charset(); 03585 03586 void change_item_tree(Item **place, Item *new_value) 03587 { 03588 /* TODO: check for OOM condition here */ 03589 if (!stmt_arena->is_conventional()) 03590 { 03591 DBUG_PRINT("info", 03592 ("change_item_tree place %p old_value %p new_value %p", 03593 place, *place, new_value)); 03594 if (new_value) 03595 new_value->set_runtime_created(); /* Note the change of item tree */ 03596 nocheck_register_item_tree_change(place, *place, mem_root); 03597 } 03598 *place= new_value; 03599 } 03600 03601 /* 03602 Find and update change record of an underlying item. 03603 03604 @param old_ref The old place of moved expression. 03605 @param new_ref The new place of moved expression. 03606 @details 03607 During permanent transformations, e.g. join flattening in simplify_joins, 03608 a condition could be moved from one place to another, e.g. from on_expr 03609 to WHERE condition. If the moved condition has replaced some other with 03610 change_item_tree() function, the change record will restore old value 03611 to the wrong place during rollback_item_tree_changes. This function goes 03612 through the list of change records, and replaces Item_change_record::place. 03613 */ 03614 void change_item_tree_place(Item **old_ref, Item **new_ref); 03615 void nocheck_register_item_tree_change(Item **place, Item *old_value, 03616 MEM_ROOT *runtime_memroot); 03617 void rollback_item_tree_changes(); 03618 03619 /* 03620 Cleanup statement parse state (parse tree, lex) and execution 03621 state after execution of a non-prepared SQL statement. 03622 */ 03623 void end_statement(); 03624 inline int killed_errno() const 03625 { 03626 killed_state killed_val; /* to cache the volatile 'killed' */ 03627 return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0; 03628 } 03629 inline void send_kill_message() const 03630 { 03631 int err= killed_errno(); 03632 if (err && !get_stmt_da()->is_set()) 03633 { 03634 if ((err == KILL_CONNECTION) && !shutdown_in_progress) 03635 err = KILL_QUERY; 03636 /* 03637 KILL is fatal because: 03638 - if a condition handler was allowed to trap and ignore a KILL, one 03639 could create routines which the DBA could not kill 03640 - INSERT/UPDATE IGNORE should fail: if KILL arrives during 03641 JOIN::optimize(), statement cannot possibly run as its caller expected 03642 => "OK" would be misleading the caller. 03643 */ 03644 my_message(err, ER(err), MYF(ME_FATALERROR)); 03645 } 03646 } 03647 /* return TRUE if we will abort query if we make a warning now */ 03648 inline bool really_abort_on_warning() 03649 { 03650 return (abort_on_warning && 03651 (!transaction.stmt.cannot_safely_rollback() || 03652 (variables.sql_mode & MODE_STRICT_ALL_TABLES))); 03653 } 03654 void set_status_var_init(); 03655 void reset_n_backup_open_tables_state(Open_tables_backup *backup); 03656 void restore_backup_open_tables_state(Open_tables_backup *backup); 03657 void reset_sub_statement_state(Sub_statement_state *backup, uint new_state); 03658 void restore_sub_statement_state(Sub_statement_state *backup); 03659 void set_n_backup_active_arena(Query_arena *set, Query_arena *backup); 03660 void restore_active_arena(Query_arena *set, Query_arena *backup); 03661 03662 /* 03663 @todo Make these methods private or remove them completely. Only 03664 decide_logging_format should call them. /Sven 03665 */ 03666 inline void set_current_stmt_binlog_format_row_if_mixed() 03667 { 03668 DBUG_ENTER("set_current_stmt_binlog_format_row_if_mixed"); 03669 /* 03670 This should only be called from decide_logging_format. 03671 03672 @todo Once we have ensured this, uncomment the following 03673 statement, remove the big comment below that, and remove the 03674 in_sub_stmt==0 condition from the following 'if'. 03675 */ 03676 /* DBUG_ASSERT(in_sub_stmt == 0); */ 03677 /* 03678 If in a stored/function trigger, the caller should already have done the 03679 change. We test in_sub_stmt to prevent introducing bugs where people 03680 wouldn't ensure that, and would switch to row-based mode in the middle 03681 of executing a stored function/trigger (which is too late, see also 03682 reset_current_stmt_binlog_format_row()); this condition will make their 03683 tests fail and so force them to propagate the 03684 lex->binlog_row_based_if_mixed upwards to the caller. 03685 */ 03686 if ((variables.binlog_format == BINLOG_FORMAT_MIXED) && 03687 (in_sub_stmt == 0)) 03688 set_current_stmt_binlog_format_row(); 03689 03690 DBUG_VOID_RETURN; 03691 } 03692 inline void set_current_stmt_binlog_format_row() 03693 { 03694 DBUG_ENTER("set_current_stmt_binlog_format_row"); 03695 current_stmt_binlog_format= BINLOG_FORMAT_ROW; 03696 DBUG_VOID_RETURN; 03697 } 03698 inline void clear_current_stmt_binlog_format_row() 03699 { 03700 DBUG_ENTER("clear_current_stmt_binlog_format_row"); 03701 current_stmt_binlog_format= BINLOG_FORMAT_STMT; 03702 DBUG_VOID_RETURN; 03703 } 03704 inline void reset_current_stmt_binlog_format_row() 03705 { 03706 DBUG_ENTER("reset_current_stmt_binlog_format_row"); 03707 /* 03708 If there are temporary tables, don't reset back to 03709 statement-based. Indeed it could be that: 03710 CREATE TEMPORARY TABLE t SELECT UUID(); # row-based 03711 # and row-based does not store updates to temp tables 03712 # in the binlog. 03713 INSERT INTO u SELECT * FROM t; # stmt-based 03714 and then the INSERT will fail as data inserted into t was not logged. 03715 So we continue with row-based until the temp table is dropped. 03716 If we are in a stored function or trigger, we mustn't reset in the 03717 middle of its execution (as the binary logging way of a stored function 03718 or trigger is decided when it starts executing, depending for example on 03719 the caller (for a stored function: if caller is SELECT or 03720 INSERT/UPDATE/DELETE...). 03721 */ 03722 DBUG_PRINT("debug", 03723 ("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s", 03724 YESNO(temporary_tables), YESNO(in_sub_stmt), 03725 show_system_thread(system_thread))); 03726 if (in_sub_stmt == 0) 03727 { 03728 if (variables.binlog_format == BINLOG_FORMAT_ROW) 03729 set_current_stmt_binlog_format_row(); 03730 else if (temporary_tables == NULL) 03731 clear_current_stmt_binlog_format_row(); 03732 } 03733 DBUG_VOID_RETURN; 03734 } 03735 03737 Gtid_set *get_gtid_next_list() 03738 { 03739 return variables.gtid_next_list.is_non_null ? 03740 variables.gtid_next_list.gtid_set : NULL; 03741 } 03742 03744 const Gtid_set *get_gtid_next_list_const() const 03745 { 03746 return const_cast<THD *>(this)->get_gtid_next_list(); 03747 } 03748 03754 Group_cache *get_group_cache(bool is_transactional); 03755 03762 Gtid owned_gtid; 03768 Gtid_set owned_gtid_set; 03769 03770 void clear_owned_gtids() 03771 { 03772 if (owned_gtid.sidno == -1) 03773 { 03774 #ifdef HAVE_GTID_NEXT_LIST 03775 owned_gtid_set.clear(); 03776 #else 03777 DBUG_ASSERT(0); 03778 #endif 03779 } 03780 owned_gtid.sidno= 0; 03781 } 03782 03783 /* 03784 There are some statements (like OPTIMIZE TABLE, ANALYZE TABLE and 03785 REPAIR TABLE) that might call trans_rollback_stmt() and also will be 03786 sucessfully executed and will have to go to the binary log. 03787 For these statements, the skip_gtid_rollback flag must be set to avoid 03788 problems when the statement is executed with a GTID_NEXT set to GTID_GROUP 03789 (like the SQL thread do when applying events from other server). 03790 When this flag is set, a call to gtid_rollback() will do nothing. 03791 */ 03792 bool skip_gtid_rollback; 03793 03815 bool set_db(const char *new_db, size_t new_db_len) 03816 { 03817 bool result; 03818 /* 03819 Acquiring mutex LOCK_thd_data as we either free the memory allocated 03820 for the database and reallocating the memory for the new db or memcpy 03821 the new_db to the db. 03822 */ 03823 mysql_mutex_lock(&LOCK_thd_data); 03824 /* Do not reallocate memory if current chunk is big enough. */ 03825 if (db && new_db && db_length >= new_db_len) 03826 memcpy(db, new_db, new_db_len+1); 03827 else 03828 { 03829 my_free(db); 03830 if (new_db) 03831 db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR)); 03832 else 03833 db= NULL; 03834 } 03835 db_length= db ? new_db_len : 0; 03836 mysql_mutex_unlock(&LOCK_thd_data); 03837 result= new_db && !db; 03838 #ifdef HAVE_PSI_THREAD_INTERFACE 03839 if (result) 03840 PSI_THREAD_CALL(set_thread_db)(new_db, static_cast<int>(new_db_len)); 03841 #endif 03842 return result; 03843 } 03844 03856 void reset_db(char *new_db, size_t new_db_len) 03857 { 03858 db= new_db; 03859 db_length= new_db_len; 03860 #ifdef HAVE_PSI_THREAD_INTERFACE 03861 PSI_THREAD_CALL(set_thread_db)(new_db, static_cast<int>(new_db_len)); 03862 #endif 03863 } 03864 /* 03865 Copy the current database to the argument. Use the current arena to 03866 allocate memory for a deep copy: current database may be freed after 03867 a statement is parsed but before it's executed. 03868 */ 03869 bool copy_db_to(char **p_db, size_t *p_db_length) 03870 { 03871 if (db == NULL) 03872 { 03873 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); 03874 return TRUE; 03875 } 03876 *p_db= strmake(db, db_length); 03877 *p_db_length= db_length; 03878 return FALSE; 03879 } 03880 thd_scheduler scheduler; 03881 03882 public: 03883 inline Internal_error_handler *get_internal_handler() 03884 { return m_internal_handler; } 03885 03890 void push_internal_handler(Internal_error_handler *handler); 03891 03892 private: 03902 bool handle_condition(uint sql_errno, 03903 const char* sqlstate, 03904 Sql_condition::enum_warning_level level, 03905 const char* msg, 03906 Sql_condition ** cond_hdl); 03907 03908 public: 03912 Internal_error_handler *pop_internal_handler(); 03913 03914 Opt_trace_context opt_trace; 03915 03919 void raise_error(uint code); 03920 03925 void raise_error_printf(uint code, ...); 03926 03931 void raise_warning(uint code); 03932 03937 void raise_warning_printf(uint code, ...); 03938 03943 void raise_note(uint code); 03944 03949 void raise_note_printf(uint code, ...); 03950 03951 private: 03952 /* 03953 Only the implementation of the SIGNAL and RESIGNAL statements 03954 is permitted to raise SQL conditions in a generic way, 03955 or to raise them by bypassing handlers (RESIGNAL). 03956 To raise a SQL condition, the code should use the public 03957 raise_error() or raise_warning() methods provided by class THD. 03958 */ 03959 friend class Sql_cmd_common_signal; 03960 friend class Sql_cmd_signal; 03961 friend class Sql_cmd_resignal; 03962 friend void push_warning(THD*, Sql_condition::enum_warning_level, uint, const char*); 03963 friend void my_message_sql(uint, const char *, myf); 03964 03973 Sql_condition* 03974 raise_condition(uint sql_errno, 03975 const char* sqlstate, 03976 Sql_condition::enum_warning_level level, 03977 const char* msg); 03978 03979 public: 03981 virtual void set_statement(Statement *stmt); 03982 03983 void set_command(enum enum_server_command command); 03984 03985 inline enum enum_server_command get_command() const 03986 { return m_command; } 03987 03992 void set_query(char *query_arg, uint32 query_length_arg, 03993 const CHARSET_INFO *cs_arg) 03994 { 03995 set_query(CSET_STRING(query_arg, query_length_arg, cs_arg)); 03996 } 03997 void set_query(char *query_arg, uint32 query_length_arg) /*Mutex protected*/ 03998 { 03999 set_query(CSET_STRING(query_arg, query_length_arg, charset())); 04000 } 04001 void set_query(const CSET_STRING &str); /* Mutex protected */ 04002 void reset_query() /* Mutex protected */ 04003 { set_query(CSET_STRING()); } 04004 void set_query_and_id(char *query_arg, uint32 query_length_arg, 04005 const CHARSET_INFO *cs, query_id_t new_query_id); 04006 void set_query_id(query_id_t new_query_id); 04007 void set_open_tables(TABLE *open_tables_arg) 04008 { 04009 mysql_mutex_lock(&LOCK_thd_data); 04010 open_tables= open_tables_arg; 04011 mysql_mutex_unlock(&LOCK_thd_data); 04012 } 04013 void set_mysys_var(struct st_my_thread_var *new_mysys_var); 04014 void enter_locked_tables_mode(enum_locked_tables_mode mode_arg) 04015 { 04016 DBUG_ASSERT(locked_tables_mode == LTM_NONE); 04017 04018 if (mode_arg == LTM_LOCK_TABLES) 04019 { 04020 /* 04021 When entering LOCK TABLES mode we should set explicit duration 04022 for all metadata locks acquired so far in order to avoid releasing 04023 them till UNLOCK TABLES statement. 04024 We don't do this when entering prelocked mode since sub-statements 04025 don't release metadata locks and restoring status-quo after leaving 04026 prelocking mode gets complicated. 04027 */ 04028 mdl_context.set_explicit_duration_for_all_locks(); 04029 } 04030 04031 locked_tables_mode= mode_arg; 04032 } 04033 void leave_locked_tables_mode(); 04034 int decide_logging_format(TABLE_LIST *tables); 04075 bool 04076 is_dml_gtid_compatible(bool transactional_table, 04077 bool non_transactional_table, 04078 bool non_transactional_tmp_tables) const; 04079 bool is_ddl_gtid_compatible() const; 04080 void binlog_invoker() { m_binlog_invoker= TRUE; } 04081 bool need_binlog_invoker() { return m_binlog_invoker; } 04082 void get_definer(LEX_USER *definer); 04083 void set_invoker(const LEX_STRING *user, const LEX_STRING *host) 04084 { 04085 invoker_user= *user; 04086 invoker_host= *host; 04087 } 04088 LEX_STRING get_invoker_user() { return invoker_user; } 04089 LEX_STRING get_invoker_host() { return invoker_host; } 04090 bool has_invoker() { return invoker_user.str != NULL; } 04091 04092 void mark_transaction_to_rollback(bool all); 04093 04094 #ifndef DBUG_OFF 04095 private: 04096 int gis_debug; // Storage for "SELECT ST_GIS_DEBUG(param);" 04097 public: 04098 int get_gis_debug() { return gis_debug; } 04099 void set_gis_debug(int arg) { gis_debug= arg; } 04100 #endif 04101 04102 private: 04103 04105 Internal_error_handler *m_internal_handler; 04106 04113 LEX main_lex; 04122 MEM_ROOT main_mem_root; 04123 Diagnostics_area main_da; 04124 Diagnostics_area *m_stmt_da; 04125 04134 bool m_binlog_invoker; 04135 04142 LEX_STRING invoker_user; 04143 LEX_STRING invoker_host; 04144 public: 04151 bool duplicate_slave_uuid; 04152 }; 04153 04154 04159 class Prepared_stmt_arena_holder 04160 { 04161 public: 04170 Prepared_stmt_arena_holder(THD *thd, bool activate_now_if_needed= true) 04171 :m_thd(thd), 04172 m_arena(NULL) 04173 { 04174 if (activate_now_if_needed && 04175 !m_thd->stmt_arena->is_conventional() && 04176 m_thd->mem_root != m_thd->stmt_arena->mem_root) 04177 { 04178 m_thd->set_n_backup_active_arena(m_thd->stmt_arena, &m_backup); 04179 m_arena= m_thd->stmt_arena; 04180 } 04181 } 04182 04187 ~Prepared_stmt_arena_holder() 04188 { 04189 if (is_activated()) 04190 m_thd->restore_active_arena(m_arena, &m_backup); 04191 } 04192 04193 bool is_activated() const 04194 { return m_arena != NULL; } 04195 04196 private: 04198 THD *const m_thd; 04199 04201 Query_arena *m_arena; 04202 04204 Query_arena m_backup; 04205 }; 04206 04207 04210 inline void 04211 my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0, 04212 const char *message= NULL) 04213 { 04214 thd->set_row_count_func(affected_rows); 04215 thd->get_stmt_da()->set_ok_status(affected_rows, id, message); 04216 } 04217 04218 04221 inline void 04222 my_eof(THD *thd) 04223 { 04224 thd->set_row_count_func(-1); 04225 thd->get_stmt_da()->set_eof_status(thd); 04226 } 04227 04228 #define tmp_disable_binlog(A) \ 04229 {ulonglong tmp_disable_binlog__save_options= (A)->variables.option_bits; \ 04230 (A)->variables.option_bits&= ~OPTION_BIN_LOG 04231 04232 #define reenable_binlog(A) (A)->variables.option_bits= tmp_disable_binlog__save_options;} 04233 04234 04235 LEX_STRING * 04236 make_lex_string_root(MEM_ROOT *mem_root, 04237 LEX_STRING *lex_str, const char* str, uint length, 04238 bool allocate_lex_string); 04239 04240 /* 04241 Used to hold information about file and file structure in exchange 04242 via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) 04243 XXX: We never call destructor for objects of this class. 04244 */ 04245 04246 class sql_exchange :public Sql_alloc 04247 { 04248 public: 04249 enum enum_filetype filetype; /* load XML, Added by Arnold & Erik */ 04250 char *file_name; 04251 const String *field_term, *enclosed, *line_term, *line_start, *escaped; 04252 bool opt_enclosed; 04253 bool dumpfile; 04254 ulong skip_lines; 04255 const CHARSET_INFO *cs; 04256 sql_exchange(char *name, bool dumpfile_flag, 04257 enum_filetype filetype_arg= FILETYPE_CSV); 04258 bool escaped_given(void); 04259 }; 04260 04261 /* 04262 This is used to get result from a select 04263 */ 04264 04265 class JOIN; 04266 04267 class select_result :public Sql_alloc { 04268 protected: 04269 THD *thd; 04270 SELECT_LEX_UNIT *unit; 04271 public: 04276 ha_rows estimated_rowcount; 04277 select_result(); 04278 virtual ~select_result() {}; 04279 virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u) 04280 { 04281 unit= u; 04282 return 0; 04283 } 04284 virtual int prepare2(void) { return 0; } 04285 /* 04286 Because of peculiarities of prepared statements protocol 04287 we need to know number of columns in the result set (if 04288 there is a result set) apart from sending columns metadata. 04289 */ 04290 virtual uint field_count(List<Item> &fields) const 04291 { return fields.elements; } 04292 virtual bool send_result_set_metadata(List<Item> &list, uint flags)=0; 04293 virtual bool send_data(List<Item> &items)=0; 04294 virtual bool initialize_tables (JOIN *join=0) { return 0; } 04295 virtual void send_error(uint errcode,const char *err); 04296 virtual bool send_eof()=0; 04304 virtual bool check_simple_select() const; 04305 virtual void abort_result_set() {} 04306 /* 04307 Cleanup instance of this class for next execution of a prepared 04308 statement/stored procedure. 04309 */ 04310 virtual void cleanup(); 04311 void set_thd(THD *thd_arg) { thd= thd_arg; } 04312 04318 void reset_offset_limit_cnt() { unit->offset_limit_cnt= 0; } 04319 04320 #ifdef EMBEDDED_LIBRARY 04321 virtual void begin_dataset() {} 04322 #else 04323 void begin_dataset() {} 04324 #endif 04325 }; 04326 04327 04328 /* 04329 Base class for select_result descendands which intercept and 04330 transform result set rows. As the rows are not sent to the client, 04331 sending of result set metadata should be suppressed as well. 04332 */ 04333 04334 class select_result_interceptor: public select_result 04335 { 04336 public: 04337 select_result_interceptor() {} /* Remove gcc warning */ 04338 uint field_count(List<Item> &fields) const { return 0; } 04339 bool send_result_set_metadata(List<Item> &fields, uint flag) { return FALSE; } 04340 }; 04341 04342 04343 class select_send :public select_result { 04349 bool is_result_set_started; 04350 public: 04351 select_send() :is_result_set_started(FALSE) {} 04352 bool send_result_set_metadata(List<Item> &list, uint flags); 04353 bool send_data(List<Item> &items); 04354 bool send_eof(); 04355 virtual bool check_simple_select() const { return FALSE; } 04356 void abort_result_set(); 04357 virtual void cleanup(); 04358 }; 04359 04360 04361 class select_to_file :public select_result_interceptor { 04362 protected: 04363 sql_exchange *exchange; 04364 File file; 04365 IO_CACHE cache; 04366 ha_rows row_count; 04367 char path[FN_REFLEN]; 04368 04369 public: 04370 select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) 04371 { path[0]=0; } 04372 ~select_to_file(); 04373 void send_error(uint errcode,const char *err); 04374 bool send_eof(); 04375 void cleanup(); 04376 }; 04377 04378 04379 #define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape 04380 04381 04382 /* 04383 List of all possible characters of a numeric value text representation. 04384 */ 04385 #define NUMERIC_CHARS ".0123456789e+-" 04386 04387 04388 class select_export :public select_to_file { 04389 uint field_term_length; 04390 int field_sep_char,escape_char,line_sep_char; 04391 int field_term_char; // first char of FIELDS TERMINATED BY or MAX_INT 04392 /* 04393 The is_ambiguous_field_sep field is true if a value of the field_sep_char 04394 field is one of the 'n', 't', 'r' etc characters 04395 (see the READ_INFO::unescape method and the ESCAPE_CHARS constant value). 04396 */ 04397 bool is_ambiguous_field_sep; 04398 /* 04399 The is_ambiguous_field_term is true if field_sep_char contains the first 04400 char of the FIELDS TERMINATED BY (ENCLOSED BY is empty), and items can 04401 contain this character. 04402 */ 04403 bool is_ambiguous_field_term; 04404 /* 04405 The is_unsafe_field_sep field is true if a value of the field_sep_char 04406 field is one of the '0'..'9', '+', '-', '.' and 'e' characters 04407 (see the NUMERIC_CHARS constant value). 04408 */ 04409 bool is_unsafe_field_sep; 04410 bool fixed_row_size; 04411 const CHARSET_INFO *write_cs; // output charset 04412 public: 04413 select_export(sql_exchange *ex) :select_to_file(ex) {} 04414 ~select_export(); 04415 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 04416 bool send_data(List<Item> &items); 04417 }; 04418 04419 04420 class select_dump :public select_to_file { 04421 public: 04422 select_dump(sql_exchange *ex) :select_to_file(ex) {} 04423 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 04424 bool send_data(List<Item> &items); 04425 }; 04426 04432 class select_insert :public select_result_interceptor { 04433 public: 04434 TABLE_LIST *table_list; 04435 TABLE *table; 04436 private: 04442 List<Item> *fields; 04443 protected: 04445 bool bulk_insert_started; 04446 public: 04447 ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not 04448 COPY_INFO info; 04449 COPY_INFO update; 04450 bool insert_into_view; 04451 04500 select_insert(TABLE_LIST *table_list_par, 04501 TABLE *table_par, 04502 List<Item> *target_columns, 04503 List<Item> *target_or_source_columns, 04504 List<Item> *update_fields, 04505 List<Item> *update_values, 04506 enum_duplicates duplic, 04507 bool ignore) 04508 :table_list(table_list_par), 04509 table(table_par), 04510 fields(target_or_source_columns), 04511 bulk_insert_started(false), 04512 autoinc_value_of_last_inserted_row(0), 04513 info(COPY_INFO::INSERT_OPERATION, 04514 target_columns, 04515 // manage_defaults 04516 (target_columns == NULL || target_columns->elements != 0), 04517 duplic, 04518 ignore), 04519 update(COPY_INFO::UPDATE_OPERATION, 04520 update_fields, 04521 update_values), 04522 insert_into_view(table_list_par && table_list_par->view != 0) 04523 { 04524 DBUG_ASSERT(target_or_source_columns != NULL); 04525 DBUG_ASSERT(target_columns == target_or_source_columns || 04526 target_columns == NULL); 04527 } 04528 04529 04530 public: 04531 ~select_insert(); 04532 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 04533 virtual int prepare2(void); 04534 bool send_data(List<Item> &items); 04535 virtual void store_values(List<Item> &values); 04536 void send_error(uint errcode,const char *err); 04537 bool send_eof(); 04538 virtual void abort_result_set(); 04539 /* not implemented: select_insert is never re-used in prepared statements */ 04540 void cleanup(); 04541 }; 04542 04543 04550 class select_create: public select_insert { 04551 ORDER *group; 04552 TABLE_LIST *create_table; 04553 HA_CREATE_INFO *create_info; 04554 TABLE_LIST *select_tables; 04555 Alter_info *alter_info; 04556 Field **field; 04557 /* lock data for tmp table */ 04558 MYSQL_LOCK *m_lock; 04559 /* m_lock or thd->extra_lock */ 04560 MYSQL_LOCK **m_plock; 04561 public: 04562 select_create (TABLE_LIST *table_arg, 04563 HA_CREATE_INFO *create_info_par, 04564 Alter_info *alter_info_arg, 04565 List<Item> &select_fields,enum_duplicates duplic, bool ignore, 04566 TABLE_LIST *select_tables_arg) 04567 :select_insert (NULL, // table_list_par 04568 NULL, // table_par 04569 NULL, // target_columns 04570 &select_fields, 04571 NULL, // update_fields 04572 NULL, // update_values 04573 duplic, 04574 ignore), 04575 create_table(table_arg), 04576 create_info(create_info_par), 04577 select_tables(select_tables_arg), 04578 alter_info(alter_info_arg), 04579 m_plock(NULL) 04580 {} 04581 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 04582 04583 int binlog_show_create_table(TABLE **tables, uint count); 04584 void store_values(List<Item> &values); 04585 void send_error(uint errcode,const char *err); 04586 bool send_eof(); 04587 virtual void abort_result_set(); 04588 04589 // Needed for access from local class MY_HOOKS in prepare(), since thd is proteted. 04590 const THD *get_thd(void) { return thd; } 04591 const HA_CREATE_INFO *get_create_info() { return create_info; }; 04592 int prepare2(void); 04593 }; 04594 04595 #include <myisam.h> 04596 04597 /* 04598 Param to create temporary tables when doing SELECT:s 04599 NOTE 04600 This structure is copied using memcpy as a part of JOIN. 04601 */ 04602 04603 class TMP_TABLE_PARAM :public Sql_alloc 04604 { 04605 public: 04606 List<Item> copy_funcs; 04607 Copy_field *copy_field, *copy_field_end; 04608 uchar *group_buff; 04609 Item **items_to_copy; /* Fields in tmp table */ 04610 MI_COLUMNDEF *recinfo,*start_recinfo; 04611 KEY *keyinfo; 04612 ha_rows end_write_records; 04620 uint field_count; 04629 uint func_count; 04638 uint sum_func_count; 04639 uint hidden_field_count; 04640 uint group_parts,group_length,group_null_parts; 04641 uint quick_group; 04648 uint outer_sum_func_count; 04655 bool using_outer_summary_function; 04656 CHARSET_INFO *table_charset; 04657 bool schema_table; 04658 /* 04659 True if GROUP BY and its aggregate functions are already computed 04660 by a table access method (e.g. by loose index scan). In this case 04661 query execution should not perform aggregation and should treat 04662 aggregate functions as normal functions. 04663 */ 04664 bool precomputed_group_by; 04665 bool force_copy_fields; 04672 bool skip_create_table; 04673 /* 04674 If TRUE, create_tmp_field called from create_tmp_table will convert 04675 all BIT fields to 64-bit longs. This is a workaround the limitation 04676 that MEMORY tables cannot index BIT columns. 04677 */ 04678 bool bit_fields_as_long; 04679 04680 TMP_TABLE_PARAM() 04681 :copy_field(0), copy_field_end(0), group_parts(0), 04682 group_length(0), group_null_parts(0), outer_sum_func_count(0), 04683 using_outer_summary_function(0), 04684 schema_table(0), precomputed_group_by(0), force_copy_fields(0), 04685 skip_create_table(FALSE), bit_fields_as_long(0) 04686 {} 04687 ~TMP_TABLE_PARAM() 04688 { 04689 cleanup(); 04690 } 04691 void init(void); 04692 inline void cleanup(void) 04693 { 04694 if (copy_field) /* Fix for Intel compiler */ 04695 { 04696 delete [] copy_field; 04697 copy_field= NULL; 04698 copy_field_end= NULL; 04699 } 04700 } 04701 }; 04702 04703 class select_union :public select_result_interceptor 04704 { 04705 TMP_TABLE_PARAM tmp_table_param; 04706 public: 04707 TABLE *table; 04708 04709 select_union() :table(0) {} 04710 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 04711 bool send_data(List<Item> &items); 04712 bool send_eof(); 04713 bool flush(); 04714 void cleanup(); 04715 bool create_result_table(THD *thd, List<Item> *column_types, 04716 bool is_distinct, ulonglong options, 04717 const char *alias, bool bit_fields_as_long, 04718 bool create_table); 04719 friend bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived); 04720 }; 04721 04722 /* Base subselect interface class */ 04723 class select_subselect :public select_result_interceptor 04724 { 04725 protected: 04726 Item_subselect *item; 04727 public: 04728 select_subselect(Item_subselect *item); 04729 bool send_data(List<Item> &items)=0; 04730 bool send_eof() { return 0; }; 04731 }; 04732 04733 /* Single value subselect interface class */ 04734 class select_singlerow_subselect :public select_subselect 04735 { 04736 public: 04737 select_singlerow_subselect(Item_subselect *item_arg) 04738 :select_subselect(item_arg) 04739 {} 04740 bool send_data(List<Item> &items); 04741 }; 04742 04743 /* used in independent ALL/ANY optimisation */ 04744 class select_max_min_finder_subselect :public select_subselect 04745 { 04746 Item_cache *cache; 04747 bool (select_max_min_finder_subselect::*op)(); 04748 bool fmax; 04754 bool ignore_nulls; 04755 public: 04756 select_max_min_finder_subselect(Item_subselect *item_arg, bool mx, 04757 bool ignore_nulls) 04758 :select_subselect(item_arg), cache(0), fmax(mx), ignore_nulls(ignore_nulls) 04759 {} 04760 void cleanup(); 04761 bool send_data(List<Item> &items); 04762 private: 04763 bool cmp_real(); 04764 bool cmp_int(); 04765 bool cmp_decimal(); 04766 bool cmp_str(); 04767 }; 04768 04769 /* EXISTS subselect interface class */ 04770 class select_exists_subselect :public select_subselect 04771 { 04772 public: 04773 select_exists_subselect(Item_subselect *item_arg) 04774 :select_subselect(item_arg){} 04775 bool send_data(List<Item> &items); 04776 }; 04777 04778 04779 /* Structs used when sorting */ 04780 04781 typedef struct st_sort_field { 04782 Field *field; /* Field to sort */ 04783 Item *item; /* Item if not sorting fields */ 04784 uint length; /* Length of sort field */ 04785 uint suffix_length; /* Length suffix (0-4) */ 04786 Item_result result_type; /* Type of item */ 04787 bool reverse; /* if descending sort */ 04788 bool need_strxnfrm; /* If we have to use strxnfrm() */ 04789 } SORT_FIELD; 04790 04791 04792 typedef struct st_sort_buffer { 04793 uint index; /* 0 or 1 */ 04794 uint sort_orders; 04795 uint change_pos; /* If sort-fields changed */ 04796 char **buff; 04797 SORT_FIELD *sortorder; 04798 } SORT_BUFFER; 04799 04800 /* Structure for db & table in sql_yacc */ 04801 04802 class Table_ident :public Sql_alloc 04803 { 04804 public: 04805 LEX_STRING db; 04806 LEX_STRING table; 04807 SELECT_LEX_UNIT *sel; 04808 inline Table_ident(THD *thd, LEX_STRING db_arg, LEX_STRING table_arg, 04809 bool force) 04810 :table(table_arg), sel((SELECT_LEX_UNIT *)0) 04811 { 04812 if (!force && (thd->client_capabilities & CLIENT_NO_SCHEMA)) 04813 db.str=0; 04814 else 04815 db= db_arg; 04816 } 04817 inline Table_ident(LEX_STRING table_arg) 04818 :table(table_arg), sel((SELECT_LEX_UNIT *)0) 04819 { 04820 db.str=0; 04821 } 04822 /* 04823 This constructor is used only for the case when we create a derived 04824 table. A derived table has no name and doesn't belong to any database. 04825 Later, if there was an alias specified for the table, it will be set 04826 by add_table_to_list. 04827 */ 04828 inline Table_ident(SELECT_LEX_UNIT *s) : sel(s) 04829 { 04830 /* We must have a table name here as this is used with add_table_to_list */ 04831 db.str= empty_c_string; /* a subject to casedn_str */ 04832 db.length= 0; 04833 table.str= internal_table_name; 04834 table.length=1; 04835 } 04836 bool is_derived_table() const { return MY_TEST(sel); } 04837 inline void change_db(char *db_name) 04838 { 04839 db.str= db_name; db.length= (uint) strlen(db_name); 04840 } 04841 }; 04842 04843 // this is needed for user_vars hash 04844 class user_var_entry 04845 { 04846 static const size_t extra_size= sizeof(double); 04847 char *m_ptr; // Value 04848 ulong m_length; // Value length 04849 Item_result m_type; // Value type 04850 04851 void reset_value() 04852 { m_ptr= NULL; m_length= 0; } 04853 void set_value(char *value, ulong length) 04854 { m_ptr= value; m_length= length; } 04855 04863 char *internal_buffer_ptr() const 04864 { return (char *) this + ALIGN_SIZE(sizeof(user_var_entry)); } 04865 04870 char *name_ptr() const 04871 { return internal_buffer_ptr() + extra_size; } 04872 04878 bool realloc(uint length); 04879 04885 bool alloced() 04886 { return m_ptr && m_ptr != internal_buffer_ptr(); } 04887 04891 void free_value() 04892 { 04893 if (alloced()) 04894 my_free(m_ptr); 04895 } 04896 04901 void copy_name(const Simple_cstring &name) 04902 { 04903 name.strcpy(name_ptr()); 04904 entry_name= Name_string(name_ptr(), name.length()); 04905 } 04906 04911 void init(const Simple_cstring &name) 04912 { 04913 copy_name(name); 04914 reset_value(); 04915 update_query_id= 0; 04916 collation.set(NULL, DERIVATION_IMPLICIT, 0); 04917 unsigned_flag= 0; 04918 /* 04919 If we are here, we were called from a SET or a query which sets a 04920 variable. Imagine it is this: 04921 INSERT INTO t SELECT @a:=10, @a:=@a+1. 04922 Then when we have a Item_func_get_user_var (because of the @a+1) so we 04923 think we have to write the value of @a to the binlog. But before that, 04924 we have a Item_func_set_user_var to create @a (@a:=10), in this we mark 04925 the variable as "already logged" (line below) so that it won't be logged 04926 by Item_func_get_user_var (because that's not necessary). 04927 */ 04928 used_query_id= current_thd->query_id; 04929 set_type(STRING_RESULT); 04930 } 04931 04941 bool store(void *from, uint length, Item_result type); 04942 04943 public: 04944 user_var_entry() {} /* Remove gcc warning */ 04945 04946 Simple_cstring entry_name; // Variable name 04947 DTCollation collation; // Collation with attributes 04948 query_id_t update_query_id, used_query_id; 04949 bool unsigned_flag; // true if unsigned, false if signed 04950 04964 bool store(void *from, uint length, Item_result type, 04965 const CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); 04970 void set_type(Item_result type) { m_type= type; } 04976 void set_null_value(Item_result type) 04977 { 04978 free_value(); 04979 reset_value(); 04980 set_type(type); 04981 } 04982 04990 static user_var_entry *create(const Name_string &name) 04991 { 04992 user_var_entry *entry; 04993 size_t size= ALIGN_SIZE(sizeof(user_var_entry)) + 04994 (name.length() + 1) + extra_size; 04995 if (!(entry= (user_var_entry*) my_malloc(size, MYF(MY_WME | 04996 ME_FATALERROR)))) 04997 return NULL; 04998 entry->init(name); 04999 return entry; 05000 } 05001 05006 void destroy() 05007 { 05008 free_value(); // Free the external value buffer 05009 my_free(this); // Free the instance itself 05010 } 05011 05012 /* Routines to access the value and its type */ 05013 const char *ptr() const { return m_ptr; } 05014 ulong length() const { return m_length; } 05015 Item_result type() const { return m_type; } 05016 /* Item-alike routines to access the value */ 05017 double val_real(my_bool *null_value); 05018 longlong val_int(my_bool *null_value) const; 05019 String *val_str(my_bool *null_value, String *str, uint decimals); 05020 my_decimal *val_decimal(my_bool *null_value, my_decimal *result); 05021 }; 05022 05023 /* 05024 Unique -- class for unique (removing of duplicates). 05025 Puts all values to the TREE. If the tree becomes too big, 05026 it's dumped to the file. User can request sorted values, or 05027 just iterate through them. In the last case tree merging is performed in 05028 memory simultaneously with iteration, so it should be ~2-3x faster. 05029 */ 05030 05031 class Unique :public Sql_alloc 05032 { 05033 DYNAMIC_ARRAY file_ptrs; 05034 ulong max_elements; 05035 ulonglong max_in_memory_size; 05036 IO_CACHE file; 05037 TREE tree; 05038 uchar *record_pointers; 05039 bool flush(); 05040 uint size; 05041 05042 public: 05043 ulong elements; 05044 Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg, 05045 uint size_arg, ulonglong max_in_memory_size_arg); 05046 ~Unique(); 05047 ulong elements_in_tree() { return tree.elements_in_tree; } 05048 inline bool unique_add(void *ptr) 05049 { 05050 DBUG_ENTER("unique_add"); 05051 DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements)); 05052 if (tree.elements_in_tree > max_elements && flush()) 05053 DBUG_RETURN(1); 05054 DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); 05055 } 05056 05057 bool get(TABLE *table); 05058 static double get_use_cost(uint *buffer, uint nkeys, uint key_size, 05059 ulonglong max_in_memory_size); 05060 05061 // Returns the number of bytes needed in imerge_cost_buf. 05062 inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size, 05063 ulonglong max_in_memory_size) 05064 { 05065 register ulonglong max_elems_in_tree= 05066 (max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size)); 05067 return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); 05068 } 05069 05070 void reset(); 05071 bool walk(tree_walk_action action, void *walk_action_arg); 05072 05073 uint get_size() const { return size; } 05074 ulonglong get_max_in_memory_size() const { return max_in_memory_size; } 05075 05076 friend int unique_write_to_file(uchar* key, element_count count, Unique *unique); 05077 friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique); 05078 }; 05079 05080 05081 class multi_delete :public select_result_interceptor 05082 { 05083 TABLE_LIST *delete_tables, *table_being_deleted; 05084 Unique **tempfiles; 05085 ha_rows deleted, found; 05086 uint num_of_tables; 05087 int error; 05088 bool do_delete; 05089 /* True if at least one table we delete from is transactional */ 05090 bool transactional_tables; 05091 /* True if at least one table we delete from is not transactional */ 05092 bool normal_tables; 05093 bool delete_while_scanning; 05094 /* 05095 error handling (rollback and binlogging) can happen in send_eof() 05096 so that afterward send_error() needs to find out that. 05097 */ 05098 bool error_handled; 05099 05100 public: 05101 multi_delete(TABLE_LIST *dt, uint num_of_tables); 05102 ~multi_delete(); 05103 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 05104 bool send_data(List<Item> &items); 05105 bool initialize_tables (JOIN *join); 05106 void send_error(uint errcode,const char *err); 05107 int do_deletes(); 05108 int do_table_deletes(TABLE *table, bool ignore); 05109 bool send_eof(); 05110 inline ha_rows num_deleted() 05111 { 05112 return deleted; 05113 } 05114 virtual void abort_result_set(); 05115 }; 05116 05117 05122 class multi_update :public select_result_interceptor 05123 { 05124 TABLE_LIST *all_tables; /* query/update command tables */ 05125 TABLE_LIST *leaves; /* list of leves of join table tree */ 05126 TABLE_LIST *update_tables, *table_being_updated; 05127 TABLE **tmp_tables, *main_table, *table_to_update; 05128 TMP_TABLE_PARAM *tmp_table_param; 05129 ha_rows updated, found; 05130 List <Item> *fields, *values; 05131 List <Item> **fields_for_table, **values_for_table; 05132 uint table_count; 05133 /* 05134 List of tables referenced in the CHECK OPTION condition of 05135 the updated view excluding the updated table. 05136 */ 05137 List <TABLE> unupdated_check_opt_tables; 05138 Copy_field *copy_field; 05139 enum enum_duplicates handle_duplicates; 05140 bool do_update, trans_safe; 05141 /* True if the update operation has made a change in a transactional table */ 05142 bool transactional_tables; 05143 bool ignore; 05144 /* 05145 error handling (rollback and binlogging) can happen in send_eof() 05146 so that afterward send_error() needs to find out that. 05147 */ 05148 bool error_handled; 05149 05164 COPY_INFO **update_operations; 05165 05166 public: 05167 multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list, 05168 List<Item> *fields, List<Item> *values, 05169 enum_duplicates handle_duplicates, bool ignore); 05170 ~multi_update(); 05171 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 05172 bool send_data(List<Item> &items); 05173 bool initialize_tables (JOIN *join); 05174 void send_error(uint errcode,const char *err); 05175 int do_updates(); 05176 bool send_eof(); 05177 inline ha_rows num_found() 05178 { 05179 return found; 05180 } 05181 inline ha_rows num_updated() 05182 { 05183 return updated; 05184 } 05185 virtual void abort_result_set(); 05186 }; 05187 05188 class my_var : public Sql_alloc { 05189 public: 05190 LEX_STRING s; 05191 #ifndef DBUG_OFF 05192 /* 05193 Routine to which this Item_splocal belongs. Used for checking if correct 05194 runtime context is used for variable handling. 05195 */ 05196 sp_head *sp; 05197 #endif 05198 bool local; 05199 uint offset; 05200 enum_field_types type; 05201 my_var (LEX_STRING& j, bool i, uint o, enum_field_types t) 05202 :s(j), local(i), offset(o), type(t) 05203 {} 05204 ~my_var() {} 05205 }; 05206 05207 class select_dumpvar :public select_result_interceptor { 05208 ha_rows row_count; 05209 public: 05210 List<my_var> var_list; 05211 select_dumpvar() { var_list.empty(); row_count= 0;} 05212 ~select_dumpvar() {} 05213 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 05214 bool send_data(List<Item> &items); 05215 bool send_eof(); 05216 virtual bool check_simple_select() const; 05217 void cleanup(); 05218 }; 05219 05220 /* Bits in sql_command_flags */ 05221 05222 #define CF_CHANGES_DATA (1U << 0) 05223 /* The 2nd bit is unused -- it used to be CF_HAS_ROW_COUNT. */ 05224 #define CF_STATUS_COMMAND (1U << 2) 05225 #define CF_SHOW_TABLE_COMMAND (1U << 3) 05226 #define CF_WRITE_LOGS_COMMAND (1U << 4) 05227 05240 #define CF_REEXECUTION_FRAGILE (1U << 5) 05241 05252 #define CF_IMPLICIT_COMMIT_BEGIN (1U << 6) 05253 05263 #define CF_IMPLICIT_COMMIT_END (1U << 7) 05264 05270 #define CF_AUTO_COMMIT_TRANS (CF_IMPLICIT_COMMIT_BEGIN | CF_IMPLICIT_COMMIT_END) 05271 05280 #define CF_DIAGNOSTIC_STMT (1U << 8) 05281 05286 #define CF_CAN_GENERATE_ROW_EVENTS (1U << 9) 05287 05292 #define CF_PREOPEN_TMP_TABLES (1U << 10) 05293 05298 #define CF_HA_CLOSE (1U << 11) 05299 05303 #define CF_CAN_BE_EXPLAINED (1U << 12) 05304 05306 #define CF_OPTIMIZER_TRACE (1U << 14) 05307 05312 #define CF_DISALLOW_IN_RO_TRANS (1U << 15) 05313 05314 /* Bits in server_command_flags */ 05315 05323 #define CF_SKIP_QUERY_ID (1U << 0) 05324 05331 #define CF_SKIP_QUESTIONS (1U << 1) 05332 05333 void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); 05334 05335 void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, 05336 STATUS_VAR *dec_var); 05337 05338 /* Inline functions */ 05339 05340 inline bool add_item_to_list(THD *thd, Item *item) 05341 { 05342 return thd->lex->current_select->add_item_to_list(thd, item); 05343 } 05344 05345 inline bool add_value_to_list(THD *thd, Item *value) 05346 { 05347 return thd->lex->value_list.push_back(value); 05348 } 05349 05350 inline bool add_order_to_list(THD *thd, Item *item, bool asc) 05351 { 05352 return thd->lex->current_select->add_order_to_list(thd, item, asc); 05353 } 05354 05355 inline bool add_gorder_to_list(THD *thd, Item *item, bool asc) 05356 { 05357 return thd->lex->current_select->add_gorder_to_list(thd, item, asc); 05358 } 05359 05360 inline bool add_group_to_list(THD *thd, Item *item, bool asc) 05361 { 05362 return thd->lex->current_select->add_group_to_list(thd, item, asc); 05363 } 05364 05365 #endif /* MYSQL_SERVER */ 05366 05367 #endif /* SQL_CLASS_INCLUDED */