00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* Classes in mysql */ 00019 00020 #ifdef USE_PRAGMA_INTERFACE 00021 #pragma interface /* gcc class implementation */ 00022 #endif 00023 00024 #include "log.h" 00025 #include "rpl_rli.h" 00026 #include "rpl_tblmap.h" 00027 00028 class Query_log_event; 00029 class Load_log_event; 00030 class Slave_log_event; 00031 class sp_rcontext; 00032 class sp_cache; 00033 class Rows_log_event; 00034 00035 enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; 00036 enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; 00037 enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE }; 00038 enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, 00039 DELAY_KEY_WRITE_ALL }; 00040 enum enum_check_fields 00041 { CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, CHECK_FIELD_ERROR_FOR_NULL }; 00042 enum enum_mark_columns 00043 { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE}; 00044 00045 extern char internal_table_name[2]; 00046 extern char empty_c_string[1]; 00047 extern const char **errmesg; 00048 00049 #define TC_LOG_PAGE_SIZE 8192 00050 #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE) 00051 00052 #define TC_HEURISTIC_RECOVER_COMMIT 1 00053 #define TC_HEURISTIC_RECOVER_ROLLBACK 2 00054 extern uint tc_heuristic_recover; 00055 00056 typedef struct st_user_var_events 00057 { 00058 user_var_entry *user_var_event; 00059 char *value; 00060 ulong length; 00061 Item_result type; 00062 uint charset_number; 00063 } BINLOG_USER_VAR_EVENT; 00064 00065 #define RP_LOCK_LOG_IS_ALREADY_LOCKED 1 00066 #define RP_FORCE_ROTATE 2 00067 00068 typedef struct st_copy_info { 00069 ha_rows records; 00070 ha_rows deleted; 00071 ha_rows updated; 00072 ha_rows copied; 00073 ha_rows error_count; 00074 enum enum_duplicates handle_duplicates; 00075 int escape_char, last_errno; 00076 bool ignore; 00077 /* for INSERT ... UPDATE */ 00078 List<Item> *update_fields; 00079 List<Item> *update_values; 00080 /* for VIEW ... WITH CHECK OPTION */ 00081 TABLE_LIST *view; 00082 } COPY_INFO; 00083 00084 00085 class key_part_spec :public Sql_alloc { 00086 public: 00087 const char *field_name; 00088 uint length; 00089 key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {} 00090 bool operator==(const key_part_spec& other) const; 00091 }; 00092 00093 00094 class Alter_drop :public Sql_alloc { 00095 public: 00096 enum drop_type {KEY, COLUMN }; 00097 const char *name; 00098 enum drop_type type; 00099 Alter_drop(enum drop_type par_type,const char *par_name) 00100 :name(par_name), type(par_type) {} 00101 }; 00102 00103 00104 class Alter_column :public Sql_alloc { 00105 public: 00106 const char *name; 00107 Item *def; 00108 Alter_column(const char *par_name,Item *literal) 00109 :name(par_name), def(literal) {} 00110 }; 00111 00112 00113 class Key :public Sql_alloc { 00114 public: 00115 enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; 00116 enum Keytype type; 00117 KEY_CREATE_INFO key_create_info; 00118 List<key_part_spec> columns; 00119 const char *name; 00120 bool generated; 00121 00122 Key(enum Keytype type_par, const char *name_arg, 00123 KEY_CREATE_INFO *key_info_arg, 00124 bool generated_arg, List<key_part_spec> &cols) 00125 :type(type_par), key_create_info(*key_info_arg), columns(cols), 00126 name(name_arg), generated(generated_arg) 00127 {} 00128 ~Key() {} 00129 /* Equality comparison of keys (ignoring name) */ 00130 friend bool foreign_key_prefix(Key *a, Key *b); 00131 }; 00132 00133 class Table_ident; 00134 00135 class foreign_key: public Key { 00136 public: 00137 enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, 00138 FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; 00139 enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, 00140 FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; 00141 00142 Table_ident *ref_table; 00143 List<key_part_spec> ref_columns; 00144 uint delete_opt, update_opt, match_opt; 00145 foreign_key(const char *name_arg, List<key_part_spec> &cols, 00146 Table_ident *table, List<key_part_spec> &ref_cols, 00147 uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) 00148 :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), 00149 ref_table(table), ref_columns(cols), 00150 delete_opt(delete_opt_arg), update_opt(update_opt_arg), 00151 match_opt(match_opt_arg) 00152 {} 00153 }; 00154 00155 typedef struct st_mysql_lock 00156 { 00157 TABLE **table; 00158 uint table_count,lock_count; 00159 THR_LOCK_DATA **locks; 00160 } MYSQL_LOCK; 00161 00162 00163 class LEX_COLUMN : public Sql_alloc 00164 { 00165 public: 00166 String column; 00167 uint rights; 00168 LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} 00169 }; 00170 00171 #include "sql_lex.h" /* Must be here */ 00172 00173 class delayed_insert; 00174 class select_result; 00175 class Time_zone; 00176 00177 #define THD_SENTRY_MAGIC 0xfeedd1ff 00178 #define THD_SENTRY_GONE 0xdeadbeef 00179 00180 #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) 00181 00182 struct system_variables 00183 { 00184 ulonglong myisam_max_extra_sort_file_size; 00185 ulonglong myisam_max_sort_file_size; 00186 ha_rows select_limit; 00187 ha_rows max_join_size; 00188 ulong auto_increment_increment, auto_increment_offset; 00189 ulong bulk_insert_buff_size; 00190 ulong join_buff_size; 00191 ulong long_query_time; 00192 ulong max_allowed_packet; 00193 ulong max_error_count; 00194 ulong max_heap_table_size; 00195 ulong max_length_for_sort_data; 00196 ulong max_sort_length; 00197 ulong max_tmp_tables; 00198 ulong max_insert_delayed_threads; 00199 ulong multi_range_count; 00200 ulong myisam_repair_threads; 00201 ulong myisam_sort_buff_size; 00202 ulong myisam_stats_method; 00203 ulong net_buffer_length; 00204 ulong net_interactive_timeout; 00205 ulong net_read_timeout; 00206 ulong net_retry_count; 00207 ulong net_wait_timeout; 00208 ulong net_write_timeout; 00209 ulong optimizer_prune_level; 00210 ulong optimizer_search_depth; 00211 ulong preload_buff_size; 00212 ulong query_cache_type; 00213 ulong read_buff_size; 00214 ulong read_rnd_buff_size; 00215 ulong div_precincrement; 00216 ulong sortbuff_size; 00217 handlerton *table_type; 00218 ulong tmp_table_size; 00219 ulong tx_isolation; 00220 ulong completion_type; 00221 /* Determines which non-standard SQL behaviour should be enabled */ 00222 ulong sql_mode; 00223 ulong max_sp_recursion_depth; 00224 /* check of key presence in updatable view */ 00225 ulong updatable_views_with_limit; 00226 ulong default_week_format; 00227 ulong max_seeks_for_key; 00228 ulong range_alloc_block_size; 00229 ulong query_alloc_block_size; 00230 ulong query_prealloc_size; 00231 ulong trans_alloc_block_size; 00232 ulong trans_prealloc_size; 00233 ulong log_warnings; 00234 ulong group_concat_max_len; 00235 /* 00236 In slave thread we need to know in behalf of which 00237 thread the query is being run to replicate temp tables properly 00238 */ 00239 ulong pseudo_thread_id; 00240 00241 my_bool low_priority_updates; 00242 my_bool new_mode; 00243 my_bool query_cache_wlock_invalidate; 00244 my_bool engine_condition_pushdown; 00245 my_bool innodb_table_locks; 00246 my_bool innodb_support_xa; 00247 my_bool ndb_force_send; 00248 my_bool ndb_use_copying_alter_table; 00249 my_bool ndb_use_exact_count; 00250 my_bool ndb_use_transactions; 00251 my_bool ndb_index_stat_enable; 00252 ulong ndb_autoincrement_prefetch_sz; 00253 ulong ndb_index_stat_cache_entries; 00254 ulong ndb_index_stat_update_freq; 00255 ulong binlog_format; // binlog format for this thd (see enum_binlog_format) 00256 00257 my_bool old_alter_table; 00258 my_bool old_passwords; 00259 00260 /* Only charset part of these variables is sensible */ 00261 CHARSET_INFO *character_set_filesystem; 00262 CHARSET_INFO *character_set_client; 00263 CHARSET_INFO *character_set_results; 00264 00265 /* Both charset and collation parts of these variables are important */ 00266 CHARSET_INFO *collation_server; 00267 CHARSET_INFO *collation_database; 00268 CHARSET_INFO *collation_connection; 00269 00270 /* Locale Support */ 00271 MY_LOCALE *lc_time_names; 00272 00273 Time_zone *time_zone; 00274 00275 /* DATE, DATETIME and TIME formats */ 00276 DATE_TIME_FORMAT *date_format; 00277 DATE_TIME_FORMAT *datetime_format; 00278 DATE_TIME_FORMAT *time_format; 00279 my_bool sysdate_is_now; 00280 }; 00281 00282 00283 /* per thread status variables */ 00284 00285 typedef struct system_status_var 00286 { 00287 ulong bytes_received; 00288 ulong bytes_sent; 00289 ulong com_other; 00290 ulong com_stat[(uint) SQLCOM_END]; 00291 ulong created_tmp_disk_tables; 00292 ulong created_tmp_tables; 00293 ulong ha_commit_count; 00294 ulong ha_delete_count; 00295 ulong ha_read_first_count; 00296 ulong ha_read_last_count; 00297 ulong ha_read_key_count; 00298 ulong ha_read_next_count; 00299 ulong ha_read_prev_count; 00300 ulong ha_read_rnd_count; 00301 ulong ha_read_rnd_next_count; 00302 ulong ha_rollback_count; 00303 ulong ha_update_count; 00304 ulong ha_write_count; 00305 ulong ha_prepare_count; 00306 ulong ha_discover_count; 00307 ulong ha_savepoint_count; 00308 ulong ha_savepoint_rollback_count; 00309 00310 /* KEY_CACHE parts. These are copies of the original */ 00311 ulong key_blocks_changed; 00312 ulong key_blocks_used; 00313 ulong key_cache_r_requests; 00314 ulong key_cache_read; 00315 ulong key_cache_w_requests; 00316 ulong key_cache_write; 00317 /* END OF KEY_CACHE parts */ 00318 00319 ulong net_big_packet_count; 00320 ulong opened_tables; 00321 ulong opened_shares; 00322 ulong select_full_join_count; 00323 ulong select_full_range_join_count; 00324 ulong select_range_count; 00325 ulong select_range_check_count; 00326 ulong select_scan_count; 00327 ulong long_query_count; 00328 ulong filesort_merge_passes; 00329 ulong filesort_range_count; 00330 ulong filesort_rows; 00331 ulong filesort_scan_count; 00332 /* Prepared statements and binary protocol */ 00333 ulong com_stmt_prepare; 00334 ulong com_stmt_execute; 00335 ulong com_stmt_send_long_data; 00336 ulong com_stmt_fetch; 00337 ulong com_stmt_reset; 00338 ulong com_stmt_close; 00339 00340 double last_query_cost; 00341 } STATUS_VAR; 00342 00343 /* 00344 This is used for 'show status'. It must be updated to the last ulong 00345 variable in system_status_var 00346 */ 00347 00348 #define last_system_status_var com_stmt_close 00349 00350 #ifdef MYSQL_SERVER 00351 00352 void free_tmp_table(THD *thd, TABLE *entry); 00353 00354 00355 /* The following macro is to make init of Query_arena simpler */ 00356 #ifndef DBUG_OFF 00357 #define INIT_ARENA_DBUG_INFO is_backup_arena= 0 00358 #else 00359 #define INIT_ARENA_DBUG_INFO 00360 #endif 00361 00362 class Query_arena 00363 { 00364 public: 00365 /* 00366 List of items created in the parser for this query. Every item puts 00367 itself to the list on creation (see Item::Item() for details)) 00368 */ 00369 Item *free_list; 00370 MEM_ROOT *mem_root; // Pointer to current memroot 00371 #ifndef DBUG_OFF 00372 bool is_backup_arena; /* True if this arena is used for backup. */ 00373 #endif 00374 enum enum_state 00375 { 00376 INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2, 00377 CONVENTIONAL_EXECUTION= 3, EXECUTED= 4, ERROR= -1 00378 }; 00379 00380 enum_state state; 00381 00382 /* We build without RTTI, so dynamic_cast can't be used. */ 00383 enum Type 00384 { 00385 STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE 00386 }; 00387 00388 Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) : 00389 free_list(0), mem_root(mem_root_arg), state(state_arg) 00390 { INIT_ARENA_DBUG_INFO; } 00391 /* 00392 This constructor is used only when Query_arena is created as 00393 backup storage for another instance of Query_arena. 00394 */ 00395 Query_arena() { INIT_ARENA_DBUG_INFO; } 00396 00397 virtual Type type() const; 00398 virtual ~Query_arena() {}; 00399 00400 inline bool is_stmt_prepare() const { return state == INITIALIZED; } 00401 inline bool is_first_sp_execute() const 00402 { return state == INITIALIZED_FOR_SP; } 00403 inline bool is_stmt_prepare_or_first_sp_execute() const 00404 { return (int)state < (int)PREPARED; } 00405 inline bool is_first_stmt_execute() const { return state == PREPARED; } 00406 inline bool is_stmt_execute() const 00407 { return state == PREPARED || state == EXECUTED; } 00408 inline bool is_conventional() const 00409 { return state == CONVENTIONAL_EXECUTION; } 00410 00411 inline gptr alloc(unsigned int size) { return alloc_root(mem_root,size); } 00412 inline gptr calloc(unsigned int size) 00413 { 00414 gptr ptr; 00415 if ((ptr=alloc_root(mem_root,size))) 00416 bzero((char*) ptr,size); 00417 return ptr; 00418 } 00419 inline char *strdup(const char *str) 00420 { return strdup_root(mem_root,str); } 00421 inline char *strmake(const char *str, uint size) 00422 { return strmake_root(mem_root,str,size); } 00423 inline char *memdup(const char *str, uint size) 00424 { return memdup_root(mem_root,str,size); } 00425 inline char *memdup_w_gap(const char *str, uint size, uint gap) 00426 { 00427 gptr ptr; 00428 if ((ptr=alloc_root(mem_root,size+gap))) 00429 memcpy(ptr,str,size); 00430 return ptr; 00431 } 00432 00433 void set_query_arena(Query_arena *set); 00434 00435 void free_items(); 00436 /* Close the active state associated with execution of this statement */ 00437 virtual void cleanup_stmt(); 00438 }; 00439 00440 00441 class Server_side_cursor; 00442 00443 /* 00444 State of a single command executed against this connection. 00445 One connection can contain a lot of simultaneously running statements, 00446 some of which could be: 00447 - prepared, that is, contain placeholders, 00448 - opened as cursors. We maintain 1 to 1 relationship between 00449 statement and cursor - if user wants to create another cursor for his 00450 query, we create another statement for it. 00451 To perform some action with statement we reset THD part to the state of 00452 that statement, do the action, and then save back modified state from THD 00453 to the statement. It will be changed in near future, and Statement will 00454 be used explicitly. 00455 */ 00456 00457 class Statement: public ilink, public Query_arena 00458 { 00459 Statement(const Statement &rhs); /* not implemented: */ 00460 Statement &operator=(const Statement &rhs); /* non-copyable */ 00461 public: 00462 /* FIXME: these must be protected */ 00463 MEM_ROOT main_mem_root; 00464 LEX main_lex; 00465 00466 /* 00467 Uniquely identifies each statement object in thread scope; change during 00468 statement lifetime. FIXME: must be const 00469 */ 00470 ulong id; 00471 00472 /* 00473 MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to 00474 handler of fields used is set 00475 MARK_COLUMNS_READ: Means a bit in read set is set to inform handler 00476 that the field is to be read. If field list contains 00477 duplicates, then thd->dup_field is set to point 00478 to the last found duplicate. 00479 MARK_COLUMNS_WRITE: Means a bit is set in write set to inform handler 00480 that it needs to update this field in write_row 00481 and update_row. 00482 */ 00483 enum enum_mark_columns mark_used_columns; 00484 00485 LEX_STRING name; /* name for named prepared statements */ 00486 LEX *lex; // parse tree descriptor 00487 /* 00488 Points to the query associated with this statement. It's const, but 00489 we need to declare it char * because all table handlers are written 00490 in C and need to point to it. 00491 00492 Note that (A) if we set query = NULL, we must at the same time set 00493 query_length = 0, and protect the whole operation with the 00494 LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a 00495 non-NULL value if its previous value is NULL. We do not need to protect 00496 operation (B) with any mutex. To avoid crashes in races, if we do not 00497 know that thd->query cannot change at the moment, one should print 00498 thd->query like this: 00499 (1) reserve the LOCK_thread_count mutex; 00500 (2) check if thd->query is NULL; 00501 (3) if not NULL, then print at most thd->query_length characters from 00502 it. We will see the query_length field as either 0, or the right value 00503 for it. 00504 Assuming that the write and read of an n-bit memory field in an n-bit 00505 computer is atomic, we can avoid races in the above way. 00506 This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB 00507 STATUS. 00508 */ 00509 char *query; 00510 uint32 query_length; // current query length 00511 Server_side_cursor *cursor; 00512 00513 public: 00514 00515 /* This constructor is called for backup statements */ 00516 Statement() { clear_alloc_root(&main_mem_root); } 00517 00518 Statement(enum enum_state state_arg, ulong id_arg, 00519 ulong alloc_block_size, ulong prealloc_size); 00520 virtual ~Statement(); 00521 00522 /* Assign execution context (note: not all members) of given stmt to self */ 00523 void set_statement(Statement *stmt); 00524 void set_n_backup_statement(Statement *stmt, Statement *backup); 00525 void restore_backup_statement(Statement *stmt, Statement *backup); 00526 /* return class type */ 00527 virtual Type type() const; 00528 }; 00529 00530 00531 /* 00532 Container for all statements created/used in a connection. 00533 Statements in Statement_map have unique Statement::id (guaranteed by id 00534 assignment in Statement::Statement) 00535 Non-empty statement names are unique too: attempt to insert a new statement 00536 with duplicate name causes older statement to be deleted 00537 00538 Statements are auto-deleted when they are removed from the map and when the 00539 map is deleted. 00540 */ 00541 00542 class Statement_map 00543 { 00544 public: 00545 Statement_map(); 00546 00547 int insert(THD *thd, Statement *statement); 00548 00549 Statement *find_by_name(LEX_STRING *name) 00550 { 00551 Statement *stmt; 00552 stmt= (Statement*)hash_search(&names_hash, (byte*)name->str, 00553 name->length); 00554 return stmt; 00555 } 00556 00557 Statement *find(ulong id) 00558 { 00559 if (last_found_statement == 0 || id != last_found_statement->id) 00560 { 00561 Statement *stmt; 00562 stmt= (Statement *) hash_search(&st_hash, (byte *) &id, sizeof(id)); 00563 if (stmt && stmt->name.str) 00564 return NULL; 00565 last_found_statement= stmt; 00566 } 00567 return last_found_statement; 00568 } 00569 /* 00570 Close all cursors of this connection that use tables of a storage 00571 engine that has transaction-specific state and therefore can not 00572 survive COMMIT or ROLLBACK. Currently all but MyISAM cursors are closed. 00573 */ 00574 void close_transient_cursors(); 00575 void erase(Statement *statement); 00576 /* Erase all statements (calls Statement destructor) */ 00577 void reset(); 00578 ~Statement_map(); 00579 private: 00580 HASH st_hash; 00581 HASH names_hash; 00582 I_List<Statement> transient_cursor_list; 00583 Statement *last_found_statement; 00584 }; 00585 00586 struct st_savepoint { 00587 struct st_savepoint *prev; 00588 char *name; 00589 uint length, nht; 00590 }; 00591 00592 enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED}; 00593 extern const char *xa_state_names[]; 00594 00595 typedef struct st_xid_state { 00596 /* For now, this is only used to catch duplicated external xids */ 00597 XID xid; // transaction identifier 00598 enum xa_states xa_state; // used by external XA only 00599 bool in_thd; 00600 } XID_STATE; 00601 00602 extern pthread_mutex_t LOCK_xid_cache; 00603 extern HASH xid_cache; 00604 bool xid_cache_init(void); 00605 void xid_cache_free(void); 00606 XID_STATE *xid_cache_search(XID *xid); 00607 bool xid_cache_insert(XID *xid, enum xa_states xa_state); 00608 bool xid_cache_insert(XID_STATE *xid_state); 00609 void xid_cache_delete(XID_STATE *xid_state); 00610 00611 00612 class Security_context { 00613 public: 00614 Security_context() {} /* Remove gcc warning */ 00615 /* 00616 host - host of the client 00617 user - user of the client, set to NULL until the user has been read from 00618 the connection 00619 priv_user - The user privilege we are using. May be "" for anonymous user. 00620 ip - client IP 00621 */ 00622 char *host, *user, *priv_user, *ip; 00623 /* The host privilege we are using */ 00624 char priv_host[MAX_HOSTNAME]; 00625 /* points to host if host is available, otherwise points to ip */ 00626 const char *host_or_ip; 00627 ulong master_access; /* Global privileges from mysql.user */ 00628 ulong db_access; /* Privileges for current db */ 00629 00630 void init(); 00631 void destroy(); 00632 void skip_grants(); 00633 inline char *priv_host_name() 00634 { 00635 return (*priv_host ? priv_host : (char *)"%"); 00636 } 00637 00638 bool set_user(char *user_arg); 00639 }; 00640 00641 00642 /* 00643 A registry for item tree transformations performed during 00644 query optimization. We register only those changes which require 00645 a rollback to re-execute a prepared statement or stored procedure 00646 yet another time. 00647 */ 00648 00649 struct Item_change_record; 00650 typedef I_List<Item_change_record> Item_change_list; 00651 00652 00653 /* 00654 Type of prelocked mode. 00655 See comment for THD::prelocked_mode for complete description. 00656 */ 00657 00658 enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1, 00659 PRELOCKED_UNDER_LOCK_TABLES= 2}; 00660 00661 00662 /* 00663 Class that holds information about tables which were opened and locked 00664 by the thread. It is also used to save/restore this information in 00665 push_open_tables_state()/pop_open_tables_state(). 00666 */ 00667 00668 class Open_tables_state 00669 { 00670 public: 00671 /* 00672 open_tables - list of regular tables in use by this thread 00673 temporary_tables - list of temp tables in use by this thread 00674 handler_tables - list of tables that were opened with HANDLER OPEN 00675 and are still in use by this thread 00676 */ 00677 TABLE *open_tables, *temporary_tables, *handler_tables, *derived_tables; 00678 /* 00679 During a MySQL session, one can lock tables in two modes: automatic 00680 or manual. In automatic mode all necessary tables are locked just before 00681 statement execution, and all acquired locks are stored in 'lock' 00682 member. Unlocking takes place automatically as well, when the 00683 statement ends. 00684 Manual mode comes into play when a user issues a 'LOCK TABLES' 00685 statement. In this mode the user can only use the locked tables. 00686 Trying to use any other tables will give an error. The locked tables are 00687 stored in 'locked_tables' member. Manual locking is described in 00688 the 'LOCK_TABLES' chapter of the MySQL manual. 00689 See also lock_tables() for details. 00690 */ 00691 MYSQL_LOCK *lock; 00692 /* 00693 Tables that were locked with explicit or implicit LOCK TABLES. 00694 (Implicit LOCK TABLES happens when we are prelocking tables for 00695 execution of statement which uses stored routines. See description 00696 THD::prelocked_mode for more info.) 00697 */ 00698 MYSQL_LOCK *locked_tables; 00699 00700 /* 00701 CREATE-SELECT keeps an extra lock for the table being 00702 created. This field is used to keep the extra lock available for 00703 lower level routines, which would otherwise miss that lock. 00704 */ 00705 MYSQL_LOCK *extra_lock; 00706 00707 /* 00708 prelocked_mode_type enum and prelocked_mode member are used for 00709 indicating whenever "prelocked mode" is on, and what type of 00710 "prelocked mode" is it. 00711 00712 Prelocked mode is used for execution of queries which explicitly 00713 or implicitly (via views or triggers) use functions, thus may need 00714 some additional tables (mentioned in query table list) for their 00715 execution. 00716 00717 First open_tables() call for such query will analyse all functions 00718 used by it and add all additional tables to table its list. It will 00719 also mark this query as requiring prelocking. After that lock_tables() 00720 will issue implicit LOCK TABLES for the whole table list and change 00721 thd::prelocked_mode to non-0. All queries called in functions invoked 00722 by the main query will use prelocked tables. Non-0 prelocked_mode 00723 will also surpress mentioned analysys in those queries thus saving 00724 cycles. Prelocked mode will be turned off once close_thread_tables() 00725 for the main query will be called. 00726 00727 Note: Since not all "tables" present in table list are really locked 00728 thd::prelocked_mode does not imply thd::locked_tables. 00729 */ 00730 prelocked_mode_type prelocked_mode; 00731 ulong version; 00732 uint current_tablenr; 00733 00734 enum enum_flags { 00735 BACKUPS_AVAIL = (1U << 0) /* There are backups available */ 00736 }; 00737 00738 /* 00739 Flags with information about the open tables state. 00740 */ 00741 uint state_flags; 00742 00743 /* 00744 This constructor serves for creation of Open_tables_state instances 00745 which are used as backup storage. 00746 */ 00747 Open_tables_state() : state_flags(0U) { } 00748 00749 Open_tables_state(ulong version_arg); 00750 00751 void set_open_tables_state(Open_tables_state *state) 00752 { 00753 *this= *state; 00754 } 00755 00756 void reset_open_tables_state() 00757 { 00758 open_tables= temporary_tables= handler_tables= derived_tables= 0; 00759 extra_lock= lock= locked_tables= 0; 00760 prelocked_mode= NON_PRELOCKED; 00761 state_flags= 0U; 00762 } 00763 }; 00764 00765 00766 /* class to save context when executing a function or trigger */ 00767 00768 /* Defines used for Sub_statement_state::in_sub_stmt */ 00769 00770 #define SUB_STMT_TRIGGER 1 00771 #define SUB_STMT_FUNCTION 2 00772 00773 class Sub_statement_state 00774 { 00775 public: 00776 ulonglong options; 00777 ulonglong first_successful_insert_id_in_prev_stmt; 00778 ulonglong first_successful_insert_id_in_cur_stmt, insert_id_for_cur_row; 00779 Discrete_interval auto_inc_interval_for_cur_row; 00780 ulonglong limit_found_rows; 00781 ha_rows cuted_fields, sent_row_count, examined_row_count; 00782 ulong client_capabilities; 00783 uint in_sub_stmt; 00784 bool enable_slow_log; 00785 bool last_insert_id_used; 00786 my_bool no_send_ok; 00787 SAVEPOINT *savepoints; 00788 }; 00789 00790 00791 /* Flags for the THD::system_thread variable */ 00792 enum enum_thread_type 00793 { 00794 NON_SYSTEM_THREAD= 0, 00795 SYSTEM_THREAD_DELAYED_INSERT= 1, 00796 SYSTEM_THREAD_SLAVE_IO= 2, 00797 SYSTEM_THREAD_SLAVE_SQL= 4, 00798 SYSTEM_THREAD_NDBCLUSTER_BINLOG= 8, 00799 SYSTEM_THREAD_EVENT_SCHEDULER= 16, 00800 SYSTEM_THREAD_EVENT_WORKER= 32 00801 }; 00802 00803 00804 /* 00805 For each client connection we create a separate thread with THD serving as 00806 a thread/connection descriptor 00807 */ 00808 00809 class THD :public Statement, 00810 public Open_tables_state 00811 { 00812 public: 00813 /* Used to execute base64 coded binlog events in MySQL server */ 00814 RELAY_LOG_INFO* rli_fake; 00815 00816 /* 00817 Constant for THD::where initialization in the beginning of every query. 00818 00819 It's needed because we do not save/restore THD::where normally during 00820 primary (non subselect) query execution. 00821 */ 00822 static const char * const DEFAULT_WHERE; 00823 00824 #ifdef EMBEDDED_LIBRARY 00825 struct st_mysql *mysql; 00826 unsigned long client_stmt_id; 00827 unsigned long client_param_count; 00828 struct st_mysql_bind *client_params; 00829 char *extra_data; 00830 ulong extra_length; 00831 struct st_mysql_data *cur_data; 00832 struct st_mysql_data *first_data; 00833 struct st_mysql_data **data_tail; 00834 void clear_data_list(); 00835 struct st_mysql_data *alloc_new_dataset(); 00836 #endif 00837 NET net; // client connection descriptor 00838 MEM_ROOT warn_root; // For warnings and errors 00839 Protocol *protocol; // Current protocol 00840 Protocol_simple protocol_simple; // Normal protocol 00841 Protocol_prep protocol_prep; // Binary protocol 00842 HASH user_vars; // hash for user variables 00843 String packet; // dynamic buffer for network I/O 00844 String convert_buffer; // buffer for charset conversions 00845 struct sockaddr_in remote; // client socket address 00846 struct rand_struct rand; // used for authentication 00847 struct system_variables variables; // Changeable local variables 00848 struct system_status_var status_var; // Per thread statistic vars 00849 struct system_status_var *initial_status_var; /* used by show status */ 00850 THR_LOCK_INFO lock_info; // Locking info of this thread 00851 THR_LOCK_OWNER main_lock_id; // To use for conventional queries 00852 THR_LOCK_OWNER *lock_id; // If not main_lock_id, points to 00853 // the lock_id of a cursor. 00854 pthread_mutex_t LOCK_delete; // Locked before thd is deleted 00855 /* all prepared statements and cursors of this connection */ 00856 Statement_map stmt_map; 00857 /* 00858 A pointer to the stack frame of handle_one_connection(), 00859 which is called first in the thread for handling a client 00860 */ 00861 char *thread_stack; 00862 00863 /* 00864 db - currently selected database 00865 catalog - currently selected catalog 00866 WARNING: some members of THD (currently 'db', 'catalog' and 'query') are 00867 set and alloced by the slave SQL thread (for the THD of that thread); that 00868 thread is (and must remain, for now) the only responsible for freeing these 00869 3 members. If you add members here, and you add code to set them in 00870 replication, don't forget to free_them_and_set_them_to_0 in replication 00871 properly. For details see the 'err:' label of the handle_slave_sql() 00872 in sql/slave.cc. 00873 */ 00874 char *db, *catalog; 00875 Security_context main_security_ctx; 00876 Security_context *security_ctx; 00877 00878 /* remote (peer) port */ 00879 uint16 peer_port; 00880 /* 00881 Points to info-string that we show in SHOW PROCESSLIST 00882 You are supposed to update thd->proc_info only if you have coded 00883 a time-consuming piece that MySQL can get stuck in for a long time. 00884 */ 00885 const char *proc_info; 00886 00887 ulong client_capabilities; /* What the client supports */ 00888 ulong max_client_packet_length; 00889 00890 HASH handler_tables_hash; 00891 /* 00892 One thread can hold up to one named user-level lock. This variable 00893 points to a lock object if the lock is present. See item_func.cc and 00894 chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK. 00895 */ 00896 User_level_lock *ull; 00897 #ifndef DBUG_OFF 00898 uint dbug_sentry; // watch out for memory corruption 00899 #endif 00900 struct st_my_thread_var *mysys_var; 00901 /* 00902 Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from 00903 first byte of the packet in do_command() 00904 */ 00905 enum enum_server_command command; 00906 uint32 server_id; 00907 uint32 file_id; // for LOAD DATA INFILE 00908 /* 00909 Used in error messages to tell user in what part of MySQL we found an 00910 error. E. g. when where= "having clause", if fix_fields() fails, user 00911 will know that the error was in having clause. 00912 */ 00913 const char *where; 00914 time_t start_time,time_after_lock,user_time; 00915 time_t connect_time,thr_create_time; // track down slow pthread_create 00916 thr_lock_type update_lock_default; 00917 delayed_insert *di; 00918 00919 /* <> 0 if we are inside of trigger or stored function. */ 00920 uint in_sub_stmt; 00921 00922 /* container for handler's private per-connection data */ 00923 void *ha_data[MAX_HA]; 00924 00925 #ifndef MYSQL_CLIENT 00926 int binlog_setup_trx_data(); 00927 00928 #ifdef HAVE_ROW_BASED_REPLICATION 00929 00930 /* 00931 Public interface to write RBR events to the binlog 00932 */ 00933 int binlog_write_table_map(TABLE *table, bool is_transactional); 00934 int binlog_write_row(TABLE* table, bool is_transactional, 00935 MY_BITMAP const* cols, my_size_t colcnt, 00936 const byte *buf); 00937 int binlog_delete_row(TABLE* table, bool is_transactional, 00938 MY_BITMAP const* cols, my_size_t colcnt, 00939 const byte *buf); 00940 int binlog_update_row(TABLE* table, bool is_transactional, 00941 MY_BITMAP const* cols, my_size_t colcnt, 00942 const byte *old_data, const byte *new_data); 00943 00944 void set_server_id(uint32 sid) { server_id = sid; } 00945 00946 /* 00947 Member functions to handle pending event for row-level logging. 00948 */ 00949 template <class RowsEventT> Rows_log_event* 00950 binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, 00951 MY_BITMAP const* cols, 00952 my_size_t colcnt, 00953 my_size_t needed, 00954 bool is_transactional, 00955 RowsEventT* hint); 00956 Rows_log_event* binlog_get_pending_rows_event() const; 00957 void binlog_set_pending_rows_event(Rows_log_event* ev); 00958 00959 my_size_t max_row_length_blob(TABLE* table, const byte *data) const; 00960 my_size_t max_row_length(TABLE* table, const byte *data) const 00961 { 00962 TABLE_SHARE *table_s= table->s; 00963 my_size_t length= table_s->reclength + 2 * table_s->fields; 00964 if (table_s->blob_fields == 0) 00965 return length; 00966 00967 return (length+max_row_length_blob(table,data)); 00968 } 00969 00970 my_size_t pack_row(TABLE* table, MY_BITMAP const* cols, byte *row_data, 00971 const byte *data) const; 00972 00973 int binlog_flush_pending_rows_event(bool stmt_end); 00974 void binlog_delete_pending_rows_event(); 00975 00976 private: 00977 uint binlog_table_maps; // Number of table maps currently in the binlog 00978 public: 00979 uint get_binlog_table_maps() const { 00980 return binlog_table_maps; 00981 } 00982 #endif /* HAVE_ROW_BASED_REPLICATION */ 00983 #endif /* MYSQL_CLIENT */ 00984 00985 #ifndef MYSQL_CLIENT 00986 public: 00987 enum enum_binlog_query_type { 00988 /* 00989 The query can be logged row-based or statement-based 00990 */ 00991 ROW_QUERY_TYPE, 00992 00993 /* 00994 The query has to be logged statement-based 00995 */ 00996 STMT_QUERY_TYPE, 00997 00998 /* 00999 The query represents a change to a table in the "mysql" 01000 database and is currently mapped to ROW_QUERY_TYPE. 01001 */ 01002 MYSQL_QUERY_TYPE, 01003 QUERY_TYPE_COUNT 01004 }; 01005 01006 int binlog_query(enum_binlog_query_type qtype, 01007 char const *query, ulong query_len, 01008 bool is_trans, bool suppress_use); 01009 #endif 01010 01011 public: 01012 01013 struct st_transactions { 01014 SAVEPOINT *savepoints; 01015 THD_TRANS all; // Trans since BEGIN WORK 01016 THD_TRANS stmt; // Trans for current statement 01017 bool on; // see ha_enable_transaction() 01018 XID xid; // transaction identifier 01019 enum xa_states xa_state; // used by external XA only 01020 XID_STATE xid_state; 01021 #ifdef HAVE_ROW_BASED_REPLICATION 01022 Rows_log_event *m_pending_rows_event; 01023 #endif 01024 01025 /* 01026 Tables changed in transaction (that must be invalidated in query cache). 01027 List contain only transactional tables, that not invalidated in query 01028 cache (instead of full list of changed in transaction tables). 01029 */ 01030 CHANGED_TABLE_LIST* changed_tables; 01031 MEM_ROOT mem_root; // Transaction-life memory allocation pool 01032 void cleanup() 01033 { 01034 changed_tables= 0; 01035 savepoints= 0; 01036 #ifdef USING_TRANSACTIONS 01037 free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); 01038 #endif 01039 } 01040 st_transactions() 01041 { 01042 #ifdef USING_TRANSACTIONS 01043 bzero((char*)this, sizeof(*this)); 01044 xid_state.xid.null(); 01045 init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); 01046 #else 01047 xid_state.xa_state= XA_NOTR; 01048 #endif 01049 } 01050 } transaction; 01051 Field *dup_field; 01052 #ifndef __WIN__ 01053 sigset_t signals,block_signals; 01054 #endif 01055 #ifdef SIGNAL_WITH_VIO_CLOSE 01056 Vio* active_vio; 01057 #endif 01058 /* 01059 This is to track items changed during execution of a prepared 01060 statement/stored procedure. It's created by 01061 register_item_tree_change() in memory root of THD, and freed in 01062 rollback_item_tree_changes(). For conventional execution it's always 01063 empty. 01064 */ 01065 Item_change_list change_list; 01066 01067 /* 01068 A permanent memory area of the statement. For conventional 01069 execution, the parsed tree and execution runtime reside in the same 01070 memory root. In this case stmt_arena points to THD. In case of 01071 a prepared statement or a stored procedure statement, thd->mem_root 01072 conventionally points to runtime memory, and thd->stmt_arena 01073 points to the memory of the PS/SP, where the parsed tree of the 01074 statement resides. Whenever you need to perform a permanent 01075 transformation of a parsed tree, you should allocate new memory in 01076 stmt_arena, to allow correct re-execution of PS/SP. 01077 Note: in the parser, stmt_arena == thd, even for PS/SP. 01078 */ 01079 Query_arena *stmt_arena; 01080 /* Tells if LAST_INSERT_ID(#) was called for the current statement */ 01081 bool arg_of_last_insert_id_function; 01082 /* 01083 ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for 01084 insertion into an auto_increment column". 01085 */ 01086 /* 01087 This is the first autogenerated insert id which was *successfully* 01088 inserted by the previous statement (exactly, if the previous statement 01089 didn't successfully insert an autogenerated insert id, then it's the one 01090 of the statement before, etc). 01091 It can also be set by SET LAST_INSERT_ID=# or SELECT LAST_INSERT_ID(#). 01092 It is returned by LAST_INSERT_ID(). 01093 */ 01094 ulonglong first_successful_insert_id_in_prev_stmt; 01095 /* 01096 Variant of the above, used for storing in statement-based binlog. The 01097 difference is that the one above can change as the execution of a stored 01098 function progresses, while the one below is set once and then does not 01099 change (which is the value which statement-based binlog needs). 01100 */ 01101 ulonglong first_successful_insert_id_in_prev_stmt_for_binlog; 01102 /* 01103 This is the first autogenerated insert id which was *successfully* 01104 inserted by the current statement. It is maintained only to set 01105 first_successful_insert_id_in_prev_stmt when statement ends. 01106 */ 01107 ulonglong first_successful_insert_id_in_cur_stmt; 01108 /* 01109 We follow this logic: 01110 - when stmt starts, first_successful_insert_id_in_prev_stmt contains the 01111 first insert id successfully inserted by the previous stmt. 01112 - as stmt makes progress, handler::insert_id_for_cur_row changes; every 01113 time get_auto_increment() is called, auto_inc_intervals_for_binlog is 01114 augmented with the reserved interval (if statement-based binlogging). 01115 - at first successful insertion of an autogenerated value, 01116 first_successful_insert_id_in_cur_stmt is set to 01117 handler::insert_id_for_cur_row. 01118 - when stmt goes to binlog, auto_inc_intervals_for_binlog is 01119 binlogged if non-empty. 01120 - when stmt ends, first_successful_insert_id_in_prev_stmt is set to 01121 first_successful_insert_id_in_cur_stmt. 01122 */ 01123 /* 01124 stmt_depends_on_first_successful_insert_id_in_prev_stmt is set when 01125 LAST_INSERT_ID() is used by a statement. 01126 If it is set, first_successful_insert_id_in_prev_stmt_for_binlog will be 01127 stored in the statement-based binlog. 01128 This variable is CUMULATIVE along the execution of a stored function or 01129 trigger: if one substatement sets it to 1 it will stay 1 until the 01130 function/trigger ends, thus making sure that 01131 first_successful_insert_id_in_prev_stmt_for_binlog does not change anymore 01132 and is propagated to the caller for binlogging. 01133 */ 01134 bool stmt_depends_on_first_successful_insert_id_in_prev_stmt; 01135 /* 01136 List of auto_increment intervals reserved by the thread so far, for 01137 storage in the statement-based binlog. 01138 Note that its minimum is not first_successful_insert_id_in_cur_stmt: 01139 assuming a table with an autoinc column, and this happens: 01140 INSERT INTO ... VALUES(3); 01141 SET INSERT_ID=3; INSERT IGNORE ... VALUES (NULL); 01142 then the latter INSERT will insert no rows 01143 (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3" 01144 in the binlog is still needed; the list's minimum will contain 3. 01145 */ 01146 Discrete_intervals_list auto_inc_intervals_in_cur_stmt_for_binlog; 01147 /* Used by replication and SET INSERT_ID */ 01148 Discrete_intervals_list auto_inc_intervals_forced; 01149 /* 01150 There is BUG#19630 where statement-based replication of stored 01151 functions/triggers with two auto_increment columns breaks. 01152 We however ensure that it works when there is 0 or 1 auto_increment 01153 column; our rules are 01154 a) on master, while executing a top statement involving substatements, 01155 first top- or sub- statement to generate auto_increment values wins the 01156 exclusive right to see its values be written to binlog (the write 01157 will be done by the statement or its caller), and the losers won't see 01158 their values be written to binlog. 01159 b) on slave, while replicating a top statement involving substatements, 01160 first top- or sub- statement to need to read auto_increment values from 01161 the master's binlog wins the exclusive right to read them (so the losers 01162 won't read their values from binlog but instead generate on their own). 01163 a) implies that we mustn't backup/restore 01164 auto_inc_intervals_in_cur_stmt_for_binlog. 01165 b) implies that we mustn't backup/restore auto_inc_intervals_forced. 01166 01167 If there are more than 1 auto_increment columns, then intervals for 01168 different columns may mix into the 01169 auto_inc_intervals_in_cur_stmt_for_binlog list, which is logically wrong, 01170 but there is no point in preventing this mixing by preventing intervals 01171 from the secondly inserted column to come into the list, as such 01172 prevention would be wrong too. 01173 What will happen in the case of 01174 INSERT INTO t1 (auto_inc) VALUES(NULL); 01175 where t1 has a trigger which inserts into an auto_inc column of t2, is 01176 that in binlog we'll store the interval of t1 and the interval of t2 (when 01177 we store intervals, soon), then in slave, t1 will use both intervals, t2 01178 will use none; if t1 inserts the same number of rows as on master, 01179 normally the 2nd interval will not be used by t1, which is fine. t2's 01180 values will be wrong if t2's internal auto_increment counter is different 01181 from what it was on master (which is likely). In 5.1, in mixed binlogging 01182 mode, row-based binlogging is used for such cases where two 01183 auto_increment columns are inserted. 01184 */ 01185 inline void record_first_successful_insert_id_in_cur_stmt(ulonglong id) 01186 { 01187 if (first_successful_insert_id_in_cur_stmt == 0) 01188 first_successful_insert_id_in_cur_stmt= id; 01189 } 01190 inline ulonglong read_first_successful_insert_id_in_prev_stmt(void) 01191 { 01192 if (!stmt_depends_on_first_successful_insert_id_in_prev_stmt) 01193 { 01194 /* It's the first time we read it */ 01195 first_successful_insert_id_in_prev_stmt_for_binlog= 01196 first_successful_insert_id_in_prev_stmt; 01197 stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1; 01198 } 01199 return first_successful_insert_id_in_prev_stmt; 01200 } 01201 /* 01202 Used by Intvar_log_event::exec_event() and by "SET INSERT_ID=#" 01203 (mysqlbinlog). We'll soon add a variant which can take many intervals in 01204 argument. 01205 */ 01206 inline void force_one_auto_inc_interval(ulonglong next_id) 01207 { 01208 auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID 01209 auto_inc_intervals_forced.append(next_id, ULONGLONG_MAX, 0); 01210 } 01211 01212 ulonglong limit_found_rows; 01213 ulonglong options; /* Bitmap of states */ 01214 longlong row_count_func; /* For the ROW_COUNT() function */ 01215 ha_rows cuted_fields, 01216 sent_row_count, examined_row_count; 01217 /* 01218 The set of those tables whose fields are referenced in all subqueries 01219 of the query. 01220 TODO: possibly this it is incorrect to have used tables in THD because 01221 with more than one subquery, it is not clear what does the field mean. 01222 */ 01223 table_map used_tables; 01224 USER_CONN *user_connect; 01225 CHARSET_INFO *db_charset; 01226 /* 01227 FIXME: this, and some other variables like 'count_cuted_fields' 01228 maybe should be statement/cursor local, that is, moved to Statement 01229 class. With current implementation warnings produced in each prepared 01230 statement/cursor settle here. 01231 */ 01232 List <MYSQL_ERROR> warn_list; 01233 uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; 01234 uint total_warn_count; 01235 /* 01236 Id of current query. Statement can be reused to execute several queries 01237 query_id is global in context of the whole MySQL server. 01238 ID is automatically generated from mutex-protected counter. 01239 It's used in handler code for various purposes: to check which columns 01240 from table are necessary for this select, to check if it's necessary to 01241 update auto-updatable fields (like auto_increment and timestamp). 01242 */ 01243 query_id_t query_id, warn_id; 01244 ulong thread_id, col_access; 01245 01246 #ifdef ERROR_INJECT_SUPPORT 01247 ulong error_inject_value; 01248 #endif 01249 /* Statement id is thread-wide. This counter is used to generate ids */ 01250 ulong statement_id_counter; 01251 ulong rand_saved_seed1, rand_saved_seed2; 01252 ulong row_count; // Row counter, mainly for errors and warnings 01253 long dbug_thread_id; 01254 pthread_t real_id; 01255 uint tmp_table, global_read_lock; 01256 uint server_status,open_options; 01257 enum enum_thread_type system_thread; 01258 uint db_length; 01259 uint select_number; //number of select (used for EXPLAIN) 01260 /* variables.transaction_isolation is reset to this after each commit */ 01261 enum_tx_isolation session_tx_isolation; 01262 enum_check_fields count_cuted_fields; 01263 01264 DYNAMIC_ARRAY user_var_events; /* For user variables replication */ 01265 MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ 01266 01267 enum killed_state { NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED }; 01268 killed_state volatile killed; 01269 01270 /* scramble - random string sent to client on handshake */ 01271 char scramble[SCRAMBLE_LENGTH+1]; 01272 01273 bool slave_thread, one_shot_set; 01274 /* tells if current statement should binlog row-based(1) or stmt-based(0) */ 01275 bool current_stmt_binlog_row_based; 01276 bool locked, some_tables_deleted; 01277 bool last_cuted_field; 01278 bool no_errors, password, is_fatal_error; 01279 bool query_start_used, rand_used, time_zone_used; 01280 /* for IS NULL => = last_insert_id() fix in remove_eq_conds() */ 01281 bool substitute_null_with_insert_id; 01282 bool in_lock_tables; 01283 bool query_error, bootstrap, cleanup_done; 01284 bool tmp_table_used; 01285 bool charset_is_system_charset, charset_is_collation_connection; 01286 bool charset_is_character_set_filesystem; 01287 bool enable_slow_log; /* enable slow log for current statement */ 01288 bool no_trans_update, abort_on_warning; 01289 bool got_warning; /* Set on call to push_warning() */ 01290 bool no_warnings_for_error; /* no warnings on call to my_error() */ 01291 /* set during loop of derived table processing */ 01292 bool derived_tables_processing; 01293 my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ 01294 01295 sp_rcontext *spcont; // SP runtime context 01296 sp_cache *sp_proc_cache; 01297 sp_cache *sp_func_cache; 01298 01299 /* 01300 If we do a purge of binary logs, log index info of the threads 01301 that are currently reading it needs to be adjusted. To do that 01302 each thread that is using LOG_INFO needs to adjust the pointer to it 01303 */ 01304 LOG_INFO* current_linfo; 01305 NET* slave_net; // network connection from slave -> m. 01306 /* Used by the sys_var class to store temporary values */ 01307 union 01308 { 01309 my_bool my_bool_value; 01310 long long_value; 01311 ulong ulong_value; 01312 ulonglong ulonglong_value; 01313 } sys_var_tmp; 01314 01315 struct { 01316 /* 01317 If true, mysql_bin_log::write(Log_event) call will not write events to 01318 binlog, and maintain 2 below variables instead (use 01319 mysql_bin_log.start_union_events to turn this on) 01320 */ 01321 bool do_union; 01322 /* 01323 If TRUE, at least one mysql_bin_log::write(Log_event) call has been 01324 made after last mysql_bin_log.start_union_events() call. 01325 */ 01326 bool unioned_events; 01327 /* 01328 If TRUE, at least one mysql_bin_log::write(Log_event e), where 01329 e.cache_stmt == TRUE call has been made after last 01330 mysql_bin_log.start_union_events() call. 01331 */ 01332 bool unioned_events_trans; 01333 01334 /* 01335 'queries' (actually SP statements) that run under inside this binlog 01336 union have thd->query_id >= first_query_id. 01337 */ 01338 query_id_t first_query_id; 01339 } binlog_evt_union; 01340 #ifdef WITH_PARTITION_STORAGE_ENGINE 01341 partition_info *work_part_info; 01342 #endif 01343 01344 THD(); 01345 ~THD(); 01346 01347 void init(void); 01348 /* 01349 Initialize memory roots necessary for query processing and (!) 01350 pre-allocate memory for it. We can't do that in THD constructor because 01351 there are use cases (acl_init, delayed inserts, watcher threads, 01352 killing mysqld) where it's vital to not allocate excessive and not used 01353 memory. Note, that we still don't return error from init_for_queries(): 01354 if preallocation fails, we should notice that at the first call to 01355 alloc_root. 01356 */ 01357 void init_for_queries(); 01358 void change_user(void); 01359 void cleanup(void); 01360 void cleanup_after_query(); 01361 bool store_globals(); 01362 #ifdef SIGNAL_WITH_VIO_CLOSE 01363 inline void set_active_vio(Vio* vio) 01364 { 01365 pthread_mutex_lock(&LOCK_delete); 01366 active_vio = vio; 01367 pthread_mutex_unlock(&LOCK_delete); 01368 } 01369 inline void clear_active_vio() 01370 { 01371 pthread_mutex_lock(&LOCK_delete); 01372 active_vio = 0; 01373 pthread_mutex_unlock(&LOCK_delete); 01374 } 01375 void close_active_vio(); 01376 #endif 01377 void awake(THD::killed_state state_to_set); 01378 /* 01379 For enter_cond() / exit_cond() to work the mutex must be got before 01380 enter_cond(); this mutex is then released by exit_cond(). 01381 Usage must be: lock mutex; enter_cond(); your code; exit_cond(). 01382 */ 01383 inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, 01384 const char* msg) 01385 { 01386 const char* old_msg = proc_info; 01387 safe_mutex_assert_owner(mutex); 01388 mysys_var->current_mutex = mutex; 01389 mysys_var->current_cond = cond; 01390 proc_info = msg; 01391 return old_msg; 01392 } 01393 inline void exit_cond(const char* old_msg) 01394 { 01395 /* 01396 Putting the mutex unlock in exit_cond() ensures that 01397 mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is 01398 locked (if that would not be the case, you'll get a deadlock if someone 01399 does a THD::awake() on you). 01400 */ 01401 pthread_mutex_unlock(mysys_var->current_mutex); 01402 pthread_mutex_lock(&mysys_var->mutex); 01403 mysys_var->current_mutex = 0; 01404 mysys_var->current_cond = 0; 01405 proc_info = old_msg; 01406 pthread_mutex_unlock(&mysys_var->mutex); 01407 } 01408 inline time_t query_start() { query_start_used=1; return start_time; } 01409 inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else time_after_lock=time(&start_time); } 01410 inline void end_time() { time(&start_time); } 01411 inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; } 01412 inline void lock_time() { time(&time_after_lock); } 01413 inline ulonglong found_rows(void) 01414 { 01415 return limit_found_rows; 01416 } 01417 inline bool active_transaction() 01418 { 01419 #ifdef USING_TRANSACTIONS 01420 return server_status & SERVER_STATUS_IN_TRANS; 01421 #else 01422 return 0; 01423 #endif 01424 } 01425 inline bool fill_derived_tables() 01426 { 01427 return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure(); 01428 } 01429 inline bool fill_information_schema_tables() 01430 { 01431 return !stmt_arena->is_stmt_prepare(); 01432 } 01433 inline gptr trans_alloc(unsigned int size) 01434 { 01435 return alloc_root(&transaction.mem_root,size); 01436 } 01437 01438 bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, 01439 const char *from, uint from_length, 01440 CHARSET_INFO *from_cs); 01441 01442 bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs); 01443 01444 void add_changed_table(TABLE *table); 01445 void add_changed_table(const char *key, long key_length); 01446 CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); 01447 int send_explain_fields(select_result *result); 01448 #ifndef EMBEDDED_LIBRARY 01449 inline void clear_error() 01450 { 01451 net.last_error[0]= 0; 01452 net.last_errno= 0; 01453 net.report_error= 0; 01454 query_error= 0; 01455 } 01456 inline bool vio_ok() const { return net.vio != 0; } 01457 #else 01458 void clear_error(); 01459 inline bool vio_ok() const { return true; } 01460 #endif 01461 inline void fatal_error() 01462 { 01463 is_fatal_error= 1; 01464 net.report_error= 1; 01465 DBUG_PRINT("error",("Fatal error set")); 01466 } 01467 inline CHARSET_INFO *charset() { return variables.character_set_client; } 01468 void update_charset(); 01469 01470 inline Query_arena *activate_stmt_arena_if_needed(Query_arena *backup) 01471 { 01472 /* 01473 Use the persistent arena if we are in a prepared statement or a stored 01474 procedure statement and we have not already changed to use this arena. 01475 */ 01476 if (!stmt_arena->is_conventional() && mem_root != stmt_arena->mem_root) 01477 { 01478 set_n_backup_active_arena(stmt_arena, backup); 01479 return stmt_arena; 01480 } 01481 return 0; 01482 } 01483 01484 void change_item_tree(Item **place, Item *new_value) 01485 { 01486 /* TODO: check for OOM condition here */ 01487 if (!stmt_arena->is_conventional()) 01488 nocheck_register_item_tree_change(place, *place, mem_root); 01489 *place= new_value; 01490 } 01491 void nocheck_register_item_tree_change(Item **place, Item *old_value, 01492 MEM_ROOT *runtime_memroot); 01493 void rollback_item_tree_changes(); 01494 01495 /* 01496 Cleanup statement parse state (parse tree, lex) and execution 01497 state after execution of a non-prepared SQL statement. 01498 */ 01499 void end_statement(); 01500 inline int killed_errno() const 01501 { 01502 return killed != KILL_BAD_DATA ? killed : 0; 01503 } 01504 inline void send_kill_message() const 01505 { 01506 int err= killed_errno(); 01507 if (err) 01508 my_message(err, ER(err), MYF(0)); 01509 } 01510 /* return TRUE if we will abort query if we make a warning now */ 01511 inline bool really_abort_on_warning() 01512 { 01513 return (abort_on_warning && 01514 (!no_trans_update || 01515 (variables.sql_mode & MODE_STRICT_ALL_TABLES))); 01516 } 01517 void set_status_var_init(); 01518 bool is_context_analysis_only() 01519 { return stmt_arena->is_stmt_prepare() || lex->view_prepare_mode; } 01520 void reset_n_backup_open_tables_state(Open_tables_state *backup); 01521 void restore_backup_open_tables_state(Open_tables_state *backup); 01522 void reset_sub_statement_state(Sub_statement_state *backup, uint new_state); 01523 void restore_sub_statement_state(Sub_statement_state *backup); 01524 void set_n_backup_active_arena(Query_arena *set, Query_arena *backup); 01525 void restore_active_arena(Query_arena *set, Query_arena *backup); 01526 inline void set_current_stmt_binlog_row_based_if_mixed() 01527 { 01528 #ifdef HAVE_ROW_BASED_REPLICATION 01529 /* 01530 If in a stored/function trigger, the caller should already have done the 01531 change. We test in_sub_stmt to prevent introducing bugs where people 01532 wouldn't ensure that, and would switch to row-based mode in the middle 01533 of executing a stored function/trigger (which is too late, see also 01534 reset_current_stmt_binlog_row_based()); this condition will make their 01535 tests fail and so force them to propagate the 01536 lex->binlog_row_based_if_mixed upwards to the caller. 01537 */ 01538 if ((variables.binlog_format == BINLOG_FORMAT_MIXED) && 01539 (in_sub_stmt == 0)) 01540 current_stmt_binlog_row_based= TRUE; 01541 #endif 01542 } 01543 inline void set_current_stmt_binlog_row_based() 01544 { 01545 #ifdef HAVE_ROW_BASED_REPLICATION 01546 current_stmt_binlog_row_based= TRUE; 01547 #endif 01548 } 01549 inline void clear_current_stmt_binlog_row_based() 01550 { 01551 #ifdef HAVE_ROW_BASED_REPLICATION 01552 current_stmt_binlog_row_based= FALSE; 01553 #endif 01554 } 01555 inline void reset_current_stmt_binlog_row_based() 01556 { 01557 #ifdef HAVE_ROW_BASED_REPLICATION 01558 /* 01559 If there are temporary tables, don't reset back to 01560 statement-based. Indeed it could be that: 01561 CREATE TEMPORARY TABLE t SELECT UUID(); # row-based 01562 # and row-based does not store updates to temp tables 01563 # in the binlog. 01564 INSERT INTO u SELECT * FROM t; # stmt-based 01565 and then the INSERT will fail as data inserted into t was not logged. 01566 So we continue with row-based until the temp table is dropped. 01567 If we are in a stored function or trigger, we mustn't reset in the 01568 middle of its execution (as the binary logging way of a stored function 01569 or trigger is decided when it starts executing, depending for example on 01570 the caller (for a stored function: if caller is SELECT or 01571 INSERT/UPDATE/DELETE...). 01572 */ 01573 if ((temporary_tables == NULL) && (in_sub_stmt == 0)) 01574 { 01575 current_stmt_binlog_row_based= 01576 test(variables.binlog_format == BINLOG_FORMAT_ROW); 01577 } 01578 #else 01579 current_stmt_binlog_row_based= FALSE; 01580 #endif 01581 } 01582 01583 /* 01584 Initialize the current database from a NULL-terminated string with length 01585 If we run out of memory, we free the current database and return TRUE. 01586 This way the user will notice the error as there will be no current 01587 database selected (in addition to the error message set by malloc). 01588 */ 01589 bool set_db(const char *new_db, uint new_db_len) 01590 { 01591 /* Do not reallocate memory if current chunk is big enough. */ 01592 if (db && new_db && db_length >= new_db_len) 01593 memcpy(db, new_db, new_db_len+1); 01594 else 01595 { 01596 x_free(db); 01597 db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL; 01598 } 01599 db_length= db ? new_db_len : 0; 01600 return new_db && !db; 01601 } 01602 void reset_db(char *new_db, uint new_db_len) 01603 { 01604 db= new_db; 01605 db_length= new_db_len; 01606 } 01607 /* 01608 Copy the current database to the argument. Use the current arena to 01609 allocate memory for a deep copy: current database may be freed after 01610 a statement is parsed but before it's executed. 01611 */ 01612 bool copy_db_to(char **p_db, uint *p_db_length) 01613 { 01614 if (db == NULL) 01615 { 01616 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); 01617 return TRUE; 01618 } 01619 *p_db= strmake(db, db_length); 01620 if (p_db_length) 01621 *p_db_length= db_length; 01622 return FALSE; 01623 } 01624 }; 01625 01626 01627 #define tmp_disable_binlog(A) \ 01628 {ulonglong tmp_disable_binlog__save_options= (A)->options; \ 01629 (A)->options&= ~OPTION_BIN_LOG 01630 01631 #define reenable_binlog(A) (A)->options= tmp_disable_binlog__save_options;} 01632 01633 01634 /* 01635 Used to hold information about file and file structure in exchainge 01636 via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) 01637 XXX: We never call destructor for objects of this class. 01638 */ 01639 01640 class sql_exchange :public Sql_alloc 01641 { 01642 public: 01643 char *file_name; 01644 String *field_term,*enclosed,*line_term,*line_start,*escaped; 01645 bool opt_enclosed; 01646 bool dumpfile; 01647 ulong skip_lines; 01648 sql_exchange(char *name,bool dumpfile_flag); 01649 }; 01650 01651 #include "log_event.h" 01652 01653 /* 01654 This is used to get result from a select 01655 */ 01656 01657 class JOIN; 01658 01659 class select_result :public Sql_alloc { 01660 protected: 01661 THD *thd; 01662 SELECT_LEX_UNIT *unit; 01663 public: 01664 select_result(); 01665 virtual ~select_result() {}; 01666 virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u) 01667 { 01668 unit= u; 01669 return 0; 01670 } 01671 virtual int prepare2(void) { return 0; } 01672 /* 01673 Because of peculiarities of prepared statements protocol 01674 we need to know number of columns in the result set (if 01675 there is a result set) apart from sending columns metadata. 01676 */ 01677 virtual uint field_count(List<Item> &fields) const 01678 { return fields.elements; } 01679 virtual bool send_fields(List<Item> &list, uint flags)=0; 01680 virtual bool send_data(List<Item> &items)=0; 01681 virtual bool initialize_tables (JOIN *join=0) { return 0; } 01682 virtual void send_error(uint errcode,const char *err); 01683 virtual bool send_eof()=0; 01684 virtual bool simple_select() { return 0; } 01685 virtual void abort() {} 01686 /* 01687 Cleanup instance of this class for next execution of a prepared 01688 statement/stored procedure. 01689 */ 01690 virtual void cleanup(); 01691 void set_thd(THD *thd_arg) { thd= thd_arg; } 01692 #ifdef EMBEDDED_LIBRARY 01693 virtual void begin_dataset() {} 01694 #else 01695 void begin_dataset() {} 01696 #endif 01697 }; 01698 01699 01700 /* 01701 Base class for select_result descendands which intercept and 01702 transform result set rows. As the rows are not sent to the client, 01703 sending of result set metadata should be suppressed as well. 01704 */ 01705 01706 class select_result_interceptor: public select_result 01707 { 01708 public: 01709 select_result_interceptor() {} /* Remove gcc warning */ 01710 uint field_count(List<Item> &fields) const { return 0; } 01711 bool send_fields(List<Item> &fields, uint flag) { return FALSE; } 01712 }; 01713 01714 01715 class select_send :public select_result { 01716 int status; 01717 public: 01718 select_send() :status(0) {} 01719 bool send_fields(List<Item> &list, uint flags); 01720 bool send_data(List<Item> &items); 01721 bool send_eof(); 01722 bool simple_select() { return 1; } 01723 void abort(); 01724 }; 01725 01726 01727 class select_to_file :public select_result_interceptor { 01728 protected: 01729 sql_exchange *exchange; 01730 File file; 01731 IO_CACHE cache; 01732 ha_rows row_count; 01733 char path[FN_REFLEN]; 01734 01735 public: 01736 select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) 01737 { path[0]=0; } 01738 ~select_to_file(); 01739 void send_error(uint errcode,const char *err); 01740 bool send_eof(); 01741 void cleanup(); 01742 }; 01743 01744 01745 class select_export :public select_to_file { 01746 uint field_term_length; 01747 int field_sep_char,escape_char,line_sep_char; 01748 bool fixed_row_size; 01749 public: 01750 select_export(sql_exchange *ex) :select_to_file(ex) {} 01751 ~select_export(); 01752 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 01753 bool send_data(List<Item> &items); 01754 }; 01755 01756 01757 class select_dump :public select_to_file { 01758 public: 01759 select_dump(sql_exchange *ex) :select_to_file(ex) {} 01760 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 01761 bool send_data(List<Item> &items); 01762 }; 01763 01764 01765 class select_insert :public select_result_interceptor { 01766 public: 01767 TABLE_LIST *table_list; 01768 TABLE *table; 01769 List<Item> *fields; 01770 ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not 01771 COPY_INFO info; 01772 bool insert_into_view; 01773 01774 select_insert(TABLE_LIST *table_list_par, 01775 TABLE *table_par, List<Item> *fields_par, 01776 List<Item> *update_fields, List<Item> *update_values, 01777 enum_duplicates duplic, bool ignore); 01778 ~select_insert(); 01779 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 01780 int prepare2(void); 01781 bool send_data(List<Item> &items); 01782 virtual void store_values(List<Item> &values); 01783 virtual bool can_rollback_data() { return 0; } 01784 void send_error(uint errcode,const char *err); 01785 bool send_eof(); 01786 /* not implemented: select_insert is never re-used in prepared statements */ 01787 void cleanup(); 01788 }; 01789 01790 01791 class select_create: public select_insert { 01792 ORDER *group; 01793 TABLE_LIST *create_table; 01794 List<create_field> *extra_fields; 01795 List<Key> *keys; 01796 HA_CREATE_INFO *create_info; 01797 Field **field; 01798 public: 01799 select_create (TABLE_LIST *table, 01800 HA_CREATE_INFO *create_info_par, 01801 List<create_field> &fields_par, 01802 List<Key> &keys_par, 01803 List<Item> &select_fields,enum_duplicates duplic, bool ignore) 01804 :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), 01805 create_table(table), extra_fields(&fields_par),keys(&keys_par), 01806 create_info(create_info_par) 01807 {} 01808 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 01809 01810 void binlog_show_create_table(TABLE **tables, uint count); 01811 void store_values(List<Item> &values); 01812 void send_error(uint errcode,const char *err); 01813 bool send_eof(); 01814 void abort(); 01815 virtual bool can_rollback_data() { return 1; } 01816 01817 // Needed for access from local class MY_HOOKS in prepare(), since thd is proteted. 01818 const THD *get_thd(void) { return thd; } 01819 const HA_CREATE_INFO *get_create_info() { return create_info; }; 01820 }; 01821 01822 #include <myisam.h> 01823 01824 /* 01825 Param to create temporary tables when doing SELECT:s 01826 NOTE 01827 This structure is copied using memcpy as a part of JOIN. 01828 */ 01829 01830 class TMP_TABLE_PARAM :public Sql_alloc 01831 { 01832 private: 01833 /* Prevent use of these (not safe because of lists and copy_field) */ 01834 TMP_TABLE_PARAM(const TMP_TABLE_PARAM &); 01835 void operator=(TMP_TABLE_PARAM &); 01836 01837 public: 01838 List<Item> copy_funcs; 01839 List<Item> save_copy_funcs; 01840 Copy_field *copy_field, *copy_field_end; 01841 Copy_field *save_copy_field, *save_copy_field_end; 01842 byte *group_buff; 01843 Item **items_to_copy; /* Fields in tmp table */ 01844 MI_COLUMNDEF *recinfo,*start_recinfo; 01845 KEY *keyinfo; 01846 ha_rows end_write_records; 01847 uint field_count,sum_func_count,func_count; 01848 uint hidden_field_count; 01849 uint group_parts,group_length,group_null_parts; 01850 uint quick_group; 01851 bool using_indirect_summary_function; 01852 /* If >0 convert all blob fields to varchar(convert_blob_length) */ 01853 uint convert_blob_length; 01854 CHARSET_INFO *table_charset; 01855 bool schema_table; 01856 /* 01857 True if GROUP BY and its aggregate functions are already computed 01858 by a table access method (e.g. by loose index scan). In this case 01859 query execution should not perform aggregation and should treat 01860 aggregate functions as normal functions. 01861 */ 01862 bool precomputed_group_by; 01863 bool force_copy_fields; 01864 01865 TMP_TABLE_PARAM() 01866 :copy_field(0), group_parts(0), 01867 group_length(0), group_null_parts(0), convert_blob_length(0), 01868 schema_table(0), precomputed_group_by(0), force_copy_fields(0) 01869 {} 01870 ~TMP_TABLE_PARAM() 01871 { 01872 cleanup(); 01873 } 01874 void init(void); 01875 inline void cleanup(void) 01876 { 01877 if (copy_field) /* Fix for Intel compiler */ 01878 { 01879 delete [] copy_field; 01880 save_copy_field= copy_field= 0; 01881 } 01882 } 01883 }; 01884 01885 class select_union :public select_result_interceptor 01886 { 01887 TMP_TABLE_PARAM tmp_table_param; 01888 public: 01889 TABLE *table; 01890 01891 select_union() :table(0) {} 01892 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 01893 bool send_data(List<Item> &items); 01894 bool send_eof(); 01895 bool flush(); 01896 01897 bool create_result_table(THD *thd, List<Item> *column_types, 01898 bool is_distinct, ulonglong options, 01899 const char *alias); 01900 }; 01901 01902 /* Base subselect interface class */ 01903 class select_subselect :public select_result_interceptor 01904 { 01905 protected: 01906 Item_subselect *item; 01907 public: 01908 select_subselect(Item_subselect *item); 01909 bool send_data(List<Item> &items)=0; 01910 bool send_eof() { return 0; }; 01911 }; 01912 01913 /* Single value subselect interface class */ 01914 class select_singlerow_subselect :public select_subselect 01915 { 01916 public: 01917 select_singlerow_subselect(Item_subselect *item):select_subselect(item){} 01918 bool send_data(List<Item> &items); 01919 }; 01920 01921 /* used in independent ALL/ANY optimisation */ 01922 class select_max_min_finder_subselect :public select_subselect 01923 { 01924 Item_cache *cache; 01925 bool (select_max_min_finder_subselect::*op)(); 01926 bool fmax; 01927 public: 01928 select_max_min_finder_subselect(Item_subselect *item, bool mx) 01929 :select_subselect(item), cache(0), fmax(mx) 01930 {} 01931 void cleanup(); 01932 bool send_data(List<Item> &items); 01933 bool cmp_real(); 01934 bool cmp_int(); 01935 bool cmp_decimal(); 01936 bool cmp_str(); 01937 }; 01938 01939 /* EXISTS subselect interface class */ 01940 class select_exists_subselect :public select_subselect 01941 { 01942 public: 01943 select_exists_subselect(Item_subselect *item):select_subselect(item){} 01944 bool send_data(List<Item> &items); 01945 }; 01946 01947 /* Structs used when sorting */ 01948 01949 typedef struct st_sort_field { 01950 Field *field; /* Field to sort */ 01951 Item *item; /* Item if not sorting fields */ 01952 uint length; /* Length of sort field */ 01953 uint suffix_length; /* Length suffix (0-4) */ 01954 Item_result result_type; /* Type of item */ 01955 bool reverse; /* if descending sort */ 01956 bool need_strxnfrm; /* If we have to use strxnfrm() */ 01957 } SORT_FIELD; 01958 01959 01960 typedef struct st_sort_buffer { 01961 uint index; /* 0 or 1 */ 01962 uint sort_orders; 01963 uint change_pos; /* If sort-fields changed */ 01964 char **buff; 01965 SORT_FIELD *sortorder; 01966 } SORT_BUFFER; 01967 01968 /* Structure for db & table in sql_yacc */ 01969 01970 class Table_ident :public Sql_alloc 01971 { 01972 public: 01973 LEX_STRING db; 01974 LEX_STRING table; 01975 SELECT_LEX_UNIT *sel; 01976 inline Table_ident(THD *thd, LEX_STRING db_arg, LEX_STRING table_arg, 01977 bool force) 01978 :table(table_arg), sel((SELECT_LEX_UNIT *)0) 01979 { 01980 if (!force && (thd->client_capabilities & CLIENT_NO_SCHEMA)) 01981 db.str=0; 01982 else 01983 db= db_arg; 01984 } 01985 inline Table_ident(LEX_STRING table_arg) 01986 :table(table_arg), sel((SELECT_LEX_UNIT *)0) 01987 { 01988 db.str=0; 01989 } 01990 /* 01991 This constructor is used only for the case when we create a derived 01992 table. A derived table has no name and doesn't belong to any database. 01993 Later, if there was an alias specified for the table, it will be set 01994 by add_table_to_list. 01995 */ 01996 inline Table_ident(SELECT_LEX_UNIT *s) : sel(s) 01997 { 01998 /* We must have a table name here as this is used with add_table_to_list */ 01999 db.str= empty_c_string; /* a subject to casedn_str */ 02000 db.length= 0; 02001 table.str= internal_table_name; 02002 table.length=1; 02003 } 02004 bool is_derived_table() const { return test(sel); } 02005 inline void change_db(char *db_name) 02006 { 02007 db.str= db_name; db.length= (uint) strlen(db_name); 02008 } 02009 }; 02010 02011 // this is needed for user_vars hash 02012 class user_var_entry 02013 { 02014 public: 02015 user_var_entry() {} /* Remove gcc warning */ 02016 LEX_STRING name; 02017 char *value; 02018 ulong length; 02019 query_id_t update_query_id, used_query_id; 02020 Item_result type; 02021 bool unsigned_flag; 02022 02023 double val_real(my_bool *null_value); 02024 longlong val_int(my_bool *null_value); 02025 String *val_str(my_bool *null_value, String *str, uint decimals); 02026 my_decimal *val_decimal(my_bool *null_value, my_decimal *result); 02027 DTCollation collation; 02028 }; 02029 02030 /* 02031 Unique -- class for unique (removing of duplicates). 02032 Puts all values to the TREE. If the tree becomes too big, 02033 it's dumped to the file. User can request sorted values, or 02034 just iterate through them. In the last case tree merging is performed in 02035 memory simultaneously with iteration, so it should be ~2-3x faster. 02036 */ 02037 02038 class Unique :public Sql_alloc 02039 { 02040 DYNAMIC_ARRAY file_ptrs; 02041 ulong max_elements, max_in_memory_size; 02042 IO_CACHE file; 02043 TREE tree; 02044 byte *record_pointers; 02045 bool flush(); 02046 uint size; 02047 02048 public: 02049 ulong elements; 02050 Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg, 02051 uint size_arg, ulong max_in_memory_size_arg); 02052 ~Unique(); 02053 ulong elements_in_tree() { return tree.elements_in_tree; } 02054 inline bool unique_add(void *ptr) 02055 { 02056 DBUG_ENTER("unique_add"); 02057 DBUG_PRINT("info", ("tree %u - %u", tree.elements_in_tree, max_elements)); 02058 if (tree.elements_in_tree > max_elements && flush()) 02059 DBUG_RETURN(1); 02060 DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); 02061 } 02062 02063 bool get(TABLE *table); 02064 static double get_use_cost(uint *buffer, uint nkeys, uint key_size, 02065 ulong max_in_memory_size); 02066 inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size, 02067 ulong max_in_memory_size) 02068 { 02069 register ulong max_elems_in_tree= 02070 (1 + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size)); 02071 return sizeof(uint)*(1 + nkeys/max_elems_in_tree); 02072 } 02073 02074 void reset(); 02075 bool walk(tree_walk_action action, void *walk_action_arg); 02076 02077 friend int unique_write_to_file(gptr key, element_count count, Unique *unique); 02078 friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique); 02079 }; 02080 02081 02082 class multi_delete :public select_result_interceptor 02083 { 02084 TABLE_LIST *delete_tables, *table_being_deleted; 02085 Unique **tempfiles; 02086 ha_rows deleted, found; 02087 uint num_of_tables; 02088 int error; 02089 bool do_delete; 02090 /* True if at least one table we delete from is transactional */ 02091 bool transactional_tables; 02092 /* True if at least one table we delete from is not transactional */ 02093 bool normal_tables; 02094 bool delete_while_scanning; 02095 02096 public: 02097 multi_delete(TABLE_LIST *dt, uint num_of_tables); 02098 ~multi_delete(); 02099 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 02100 bool send_data(List<Item> &items); 02101 bool initialize_tables (JOIN *join); 02102 void send_error(uint errcode,const char *err); 02103 int do_deletes(); 02104 bool send_eof(); 02105 }; 02106 02107 02108 class multi_update :public select_result_interceptor 02109 { 02110 TABLE_LIST *all_tables; /* query/update command tables */ 02111 TABLE_LIST *leaves; /* list of leves of join table tree */ 02112 TABLE_LIST *update_tables, *table_being_updated; 02113 TABLE **tmp_tables, *main_table, *table_to_update; 02114 TMP_TABLE_PARAM *tmp_table_param; 02115 ha_rows updated, found; 02116 List <Item> *fields, *values; 02117 List <Item> **fields_for_table, **values_for_table; 02118 uint table_count; 02119 Copy_field *copy_field; 02120 enum enum_duplicates handle_duplicates; 02121 bool do_update, trans_safe; 02122 /* True if the update operation has made a change in a transactional table */ 02123 bool transactional_tables; 02124 bool ignore; 02125 02126 public: 02127 multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list, 02128 List<Item> *fields, List<Item> *values, 02129 enum_duplicates handle_duplicates, bool ignore); 02130 ~multi_update(); 02131 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 02132 bool send_data(List<Item> &items); 02133 bool initialize_tables (JOIN *join); 02134 void send_error(uint errcode,const char *err); 02135 int do_updates (bool from_send_error); 02136 bool send_eof(); 02137 }; 02138 02139 class my_var : public Sql_alloc { 02140 public: 02141 LEX_STRING s; 02142 #ifndef DBUG_OFF 02143 /* 02144 Routine to which this Item_splocal belongs. Used for checking if correct 02145 runtime context is used for variable handling. 02146 */ 02147 sp_head *sp; 02148 #endif 02149 bool local; 02150 uint offset; 02151 enum_field_types type; 02152 my_var (LEX_STRING& j, bool i, uint o, enum_field_types t) 02153 :s(j), local(i), offset(o), type(t) 02154 {} 02155 ~my_var() {} 02156 }; 02157 02158 class select_dumpvar :public select_result_interceptor { 02159 ha_rows row_count; 02160 public: 02161 List<my_var> var_list; 02162 List<Item_func_set_user_var> vars; 02163 List<Item_splocal> local_vars; 02164 select_dumpvar(void) { var_list.empty(); local_vars.empty(); vars.empty(); row_count=0;} 02165 ~select_dumpvar() {} 02166 int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 02167 bool send_data(List<Item> &items); 02168 bool send_eof(); 02169 void cleanup(); 02170 }; 02171 02172 /* Bits in sql_command_flags */ 02173 02174 #define CF_CHANGES_DATA 1 02175 #define CF_HAS_ROW_COUNT 2 02176 #define CF_STATUS_COMMAND 4 02177 #define CF_SHOW_TABLE_COMMAND 8 02178 02179 /* Functions in sql_class.cc */ 02180 02181 void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); 02182 void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, 02183 STATUS_VAR *dec_var); 02184 #endif /* MYSQL_SERVER */
1.4.7

