My Project
sql_class.h
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines