#include "mysql_priv.h"#include "sql_select.h"#include "sp_head.h"#include "sp.h"#include "sql_trigger.h"#include <m_ctype.h>#include <my_dir.h>#include <hash.h>Include dependency graph for sql_base.cc:

Go to the source code of this file.
Defines | |
| #define | check_unused() |
| #define | WRONG_GRANT (Field*) -1 |
Functions | |
| static int | open_unireg_entry (THD *thd, TABLE *entry, TABLE_LIST *table_list, const char *alias, char *cache_key, uint cache_key_length, MEM_ROOT *mem_root, uint flags) |
| static void | free_cache_entry (TABLE *entry) |
| static void | mysql_rm_tmp_tables (void) |
| static bool | open_new_frm (THD *thd, TABLE_SHARE *share, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc, MEM_ROOT *mem_root) |
| static void | close_old_data_files (THD *thd, TABLE *table, bool abort_locks, bool send_refresh) |
| static bool | reopen_table (TABLE *table) |
| static bool | has_two_write_locked_tables_with_auto_increment (TABLE_LIST *tables) |
| byte * | table_cache_key (const byte *record, uint *length, my_bool not_used __attribute__((unused))) |
| bool | table_cache_init (void) |
| void | table_cache_free (void) |
| uint | cached_open_tables (void) |
| uint | create_table_def_key (THD *thd, char *key, TABLE_LIST *table_list, bool tmp_table) |
| byte * | table_def_key (const byte *record, uint *length, my_bool not_used __attribute__((unused))) |
| static void | table_def_free_entry (TABLE_SHARE *share) |
| bool | table_def_init (void) |
| void | table_def_free (void) |
| uint | cached_table_definitions (void) |
| TABLE_SHARE * | get_table_share (THD *thd, TABLE_LIST *table_list, char *key, uint key_length, uint db_flags, int *error) |
| static TABLE_SHARE * | get_table_share_with_create (THD *thd, TABLE_LIST *table_list, char *key, uint key_length, uint db_flags, int *error) |
| void | release_table_share (TABLE_SHARE *share, enum release_type type) |
| TABLE_SHARE * | get_cached_table_share (const char *db, const char *table_name) |
| static void | close_handle_and_leave_table_as_lock (TABLE *table) |
| OPEN_TABLE_LIST * | list_open_tables (THD *thd, const char *db, const char *wild) |
| void | intern_close_table (TABLE *table) |
| void | free_io_cache (TABLE *table) |
| bool | close_cached_tables (THD *thd, bool if_wait_for_refresh, TABLE_LIST *tables, bool have_lock) |
| static void | mark_used_tables_as_free_for_reuse (THD *thd, TABLE *table) |
| void | close_thread_tables (THD *thd, bool lock_in_use, bool skip_derived) |
| bool | close_thread_table (THD *thd, TABLE **table_ptr) |
| static uint | tmpkeyval (THD *thd, TABLE *table) |
| void | close_temporary_tables (THD *thd) |
| TABLE_LIST * | find_table_in_list (TABLE_LIST *table, st_table_list *TABLE_LIST::*link, const char *db_name, const char *table_name) |
| TABLE_LIST * | unique_table (THD *thd, TABLE_LIST *table, TABLE_LIST *table_list) |
| void | update_non_unique_table_error (TABLE_LIST *update, const char *operation, TABLE_LIST *duplicate) |
| TABLE * | find_temporary_table (THD *thd, const char *db, const char *table_name) |
| TABLE * | find_temporary_table (THD *thd, TABLE_LIST *table_list) |
| bool | close_temporary_table (THD *thd, TABLE_LIST *table_list) |
| void | close_temporary_table (THD *thd, TABLE *table, bool free_share, bool delete_table) |
| void | close_temporary (TABLE *table, bool free_share, bool delete_table) |
| bool | rename_temporary_table (THD *thd, TABLE *table, const char *db, const char *table_name) |
| static void | relink_unused (TABLE *table) |
| TABLE * | unlink_open_table (THD *thd, TABLE *list, TABLE *find) |
| void | wait_for_condition (THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond) |
| bool | reopen_name_locked_table (THD *thd, TABLE_LIST *table_list) |
| TABLE * | open_table (THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, bool *refresh, uint flags) |
| TABLE * | find_locked_table (THD *thd, const char *db, const char *table_name) |
| bool | close_data_tables (THD *thd, const char *db, const char *table_name) |
| bool | reopen_tables (THD *thd, bool get_locks, bool in_refresh) |
| bool | table_is_used (TABLE *table, bool wait_for_name_lock) |
| bool | wait_for_tables (THD *thd) |
| TABLE * | drop_locked_tables (THD *thd, const char *db, const char *table_name) |
| void | abort_locked_tables (THD *thd, const char *db, const char *table_name) |
| void | assign_new_table_id (TABLE_SHARE *share) |
| int | open_tables (THD *thd, TABLE_LIST **start, uint *counter, uint flags) |
| static bool | check_lock_and_start_stmt (THD *thd, TABLE *table, thr_lock_type lock_type) |
| TABLE * | open_ltable (THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) |
| int | simple_open_n_lock_tables (THD *thd, TABLE_LIST *tables) |
| bool | open_and_lock_tables (THD *thd, TABLE_LIST *tables) |
| bool | open_normal_and_derived_tables (THD *thd, TABLE_LIST *tables, uint flags) |
| static void | mark_real_tables_as_free_for_reuse (TABLE_LIST *table) |
| int | lock_tables (THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) |
| void | close_tables_for_reopen (THD *thd, TABLE_LIST **tables) |
| TABLE * | open_temporary_table (THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list) |
| bool | rm_temporary_table (handlerton *base, char *path) |
| static void | update_field_dependencies (THD *thd, Field *field, TABLE *table) |
| static Field * | find_field_in_view (THD *thd, TABLE_LIST *table_list, const char *name, uint length, const char *item_name, Item **ref, bool register_tree_change) |
| static Field * | find_field_in_natural_join (THD *thd, TABLE_LIST *table_ref, const char *name, uint length, Item **ref, bool register_tree_change, TABLE_LIST **actual_table) |
| Field * | find_field_in_table (THD *thd, TABLE *table, const char *name, uint length, bool allow_rowid, uint *cached_field_index_ptr) |
| Field * | find_field_in_table_ref (THD *thd, TABLE_LIST *table_list, const char *name, uint length, const char *item_name, const char *db_name, const char *table_name, Item **ref, bool check_privileges, bool allow_rowid, uint *cached_field_index_ptr, bool register_tree_change, TABLE_LIST **actual_table) |
| Field * | find_field_in_table_sef (TABLE *table, const char *name) |
| Field * | find_field_in_tables (THD *thd, Item_ident *item, TABLE_LIST *first_table, TABLE_LIST *last_table, Item **ref, find_item_error_report_type report_error, bool check_privileges, bool register_tree_change) |
| Item ** | find_item_in_list (Item *find, List< Item > &items, uint *counter, find_item_error_report_type report_error, bool *unaliased) |
| static bool | test_if_string_in_list (const char *find, List< String > *str_list) |
| static bool | set_new_item_local_context (THD *thd, Item_ident *item, TABLE_LIST *table_ref) |
| static bool | mark_common_columns (THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, List< String > *using_fields, uint *found_using_fields) |
| static bool | store_natural_using_join_columns (THD *thd, TABLE_LIST *natural_using_join, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, List< String > *using_fields, uint found_using_fields) |
| static bool | store_top_level_join_columns (THD *thd, TABLE_LIST *table_ref, TABLE_LIST *left_neighbor, TABLE_LIST *right_neighbor) |
| static bool | setup_natural_join_row_types (THD *thd, List< TABLE_LIST > *from_clause, Name_resolution_context *context) |
| int | setup_wild (THD *thd, TABLE_LIST *tables, List< Item > &fields, List< Item > *sum_func_list, uint wild_num) |
| bool | setup_fields (THD *thd, Item **ref_pointer_array, List< Item > &fields, enum_mark_columns mark_used_columns, List< Item > *sum_func_list, bool allow_sum_func) |
| TABLE_LIST ** | make_leaves_list (TABLE_LIST **list, TABLE_LIST *tables) |
| bool | setup_tables (THD *thd, Name_resolution_context *context, List< TABLE_LIST > *from_clause, TABLE_LIST *tables, TABLE_LIST **leaves, bool select_insert) |
| bool | setup_tables_and_check_access (THD *thd, Name_resolution_context *context, List< TABLE_LIST > *from_clause, TABLE_LIST *tables, TABLE_LIST **leaves, bool select_insert, ulong want_access) |
| bool | get_key_map_from_key_list (key_map *map, TABLE *table, List< String > *index_list) |
| bool | insert_fields (THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator< Item > *it, bool any_privileges) |
| int | setup_conds (THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds) |
| static bool | fill_record (THD *thd, List< Item > &fields, List< Item > &values, bool ignore_errors) |
| bool | fill_record_n_invoke_before_triggers (THD *thd, List< Item > &fields, List< Item > &values, bool ignore_errors, Table_triggers_list *triggers, enum trg_event_type event) |
| bool | fill_record (THD *thd, Field **ptr, List< Item > &values, bool ignore_errors) |
| bool | fill_record_n_invoke_before_triggers (THD *thd, Field **ptr, List< Item > &values, bool ignore_errors, Table_triggers_list *triggers, enum trg_event_type event) |
| void | remove_db_from_cache (const char *db) |
| void | flush_tables () |
| bool | remove_table_from_cache (THD *thd, const char *db, const char *table_name, uint flags) |
| int | setup_ftfuncs (SELECT_LEX *select_lex) |
| int | init_ftfuncs (THD *thd, SELECT_LEX *select_lex, bool no_order) |
| bool | is_equal (const LEX_STRING *a, const LEX_STRING *b) |
| int | abort_and_upgrade_lock (ALTER_PARTITION_PARAM_TYPE *lpt) |
| void | close_open_tables_and_downgrade (ALTER_PARTITION_PARAM_TYPE *lpt) |
| void | mysql_wait_completed_table (ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table) |
Variables | |
| TABLE * | unused_tables |
| HASH | open_cache |
| static HASH | table_def_cache |
| static TABLE_SHARE * | oldest_unused_share |
| static TABLE_SHARE | end_of_unused_share |
| static pthread_mutex_t | LOCK_table_share |
| static bool | table_def_inited = 0 |
| Field * | not_found_field = (Field*) 0x1 |
| Field * | view_ref_found = (Field*) 0x2 |
| Item ** | not_found_item = (Item**) 0x1 |
| #define check_unused | ( | ) |
Definition at line 147 of file sql_base.cc.
Referenced by close_thread_tables(), free_cache_entry(), open_table(), relink_unused(), and reopen_name_locked_table().
| #define WRONG_GRANT (Field*) -1 |
Definition at line 3588 of file sql_base.cc.
Referenced by find_field_in_table_ref(), and find_field_in_tables().
| int abort_and_upgrade_lock | ( | ALTER_PARTITION_PARAM_TYPE * | lpt | ) |
Definition at line 6387 of file sql_base.cc.
References DBUG_ENTER, DBUG_RETURN, flags, LOCK_open, mysql_lock_abort(), pthread_mutex_lock, pthread_mutex_unlock, remove_table_from_cache(), TRUE, and VOID.
06388 { 06389 uint flags= RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG; 06390 DBUG_ENTER("abort_and_upgrade_locks"); 06391 06392 lpt->old_lock_type= lpt->table->reginfo.lock_type; 06393 VOID(pthread_mutex_lock(&LOCK_open)); 06394 mysql_lock_abort(lpt->thd, lpt->table, TRUE); 06395 VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags)); 06396 VOID(pthread_mutex_unlock(&LOCK_open)); 06397 DBUG_RETURN(0); 06398 }
Here is the call graph for this function:

| void abort_locked_tables | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) |
Definition at line 2531 of file sql_base.cc.
References st_table_share::db, mysql_lock_abort(), st_table::next, st_table::s, LEX_STRING::str, strcmp(), st_table_share::table_name, and TRUE.
Referenced by mysql_rm_table_part2().
02532 { 02533 TABLE *table; 02534 for (table= thd->open_tables; table ; table= table->next) 02535 { 02536 if (!strcmp(table->s->table_name.str, table_name) && 02537 !strcmp(table->s->db.str, db)) 02538 { 02539 mysql_lock_abort(thd,table, TRUE); 02540 break; 02541 } 02542 } 02543 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void assign_new_table_id | ( | TABLE_SHARE * | share | ) |
Definition at line 2574 of file sql_base.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, LOCK_open, NULL, safe_mutex_assert_owner, st_table_share::table_map_id, and unlikely.
Referenced by get_table_share().
02575 { 02576 static ulong last_table_id= ~0UL; 02577 02578 DBUG_ENTER("assign_new_table_id"); 02579 02580 /* Preconditions */ 02581 DBUG_ASSERT(share != NULL); 02582 safe_mutex_assert_owner(&LOCK_open); 02583 02584 ulong tid= ++last_table_id; /* get next id */ 02585 /* 02586 There is one reserved number that cannot be used. Remember to 02587 change this when 6-byte global table id's are introduced. 02588 */ 02589 if (unlikely(tid == ~0UL)) 02590 tid= ++last_table_id; 02591 share->table_map_id= tid; 02592 DBUG_PRINT("info", ("table_id=%lu", tid)); 02593 02594 /* Post conditions */ 02595 DBUG_ASSERT(share->table_map_id != ~0UL); 02596 02597 DBUG_VOID_RETURN; 02598 }
Here is the caller graph for this function:

| uint cached_open_tables | ( | void | ) |
Definition at line 85 of file sql_base.cc.
References open_cache, and st_hash::records.
Referenced by dispatch_command(), mysql_print_status(), and show_open_tables().
00086 { 00087 return open_cache.records; 00088 }
Here is the caller graph for this function:

| uint cached_table_definitions | ( | void | ) |
Definition at line 247 of file sql_base.cc.
References st_hash::records, and table_def_cache.
Referenced by show_table_definitions().
00248 { 00249 return table_def_cache.records; 00250 }
Here is the caller graph for this function:

| static bool check_lock_and_start_stmt | ( | THD * | thd, | |
| TABLE * | table, | |||
| thr_lock_type | lock_type | |||
| ) | [static] |
Definition at line 3046 of file sql_base.cc.
References st_table::alias, DBUG_ENTER, DBUG_RETURN, ER_TABLE_NOT_LOCKED_FOR_WRITE, error, st_table::file, st_reginfo::lock_type, my_error(), MYF, handler::print_error(), st_table::reginfo, handler::start_stmt(), and TL_WRITE_ALLOW_READ.
Referenced by lock_tables(), and open_ltable().
03048 { 03049 int error; 03050 DBUG_ENTER("check_lock_and_start_stmt"); 03051 03052 if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && 03053 (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) 03054 { 03055 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias); 03056 DBUG_RETURN(1); 03057 } 03058 if ((error=table->file->start_stmt(thd, lock_type))) 03059 { 03060 table->file->print_error(error,MYF(0)); 03061 DBUG_RETURN(1); 03062 } 03063 DBUG_RETURN(0); 03064 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool close_cached_tables | ( | THD * | thd, | |
| bool | if_wait_for_refresh, | |||
| TABLE_LIST * | tables, | |||
| bool | have_lock | |||
| ) |
Definition at line 818 of file sql_base.cc.
References close_old_data_files(), COND_refresh, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, hash_delete(), hash_element(), kill_delayed_threads(), LOCK_open, st_table_share::mutex, mysql_ha_flush(), st_table_share::next, st_table_list::next_local, oldest_unused_share, open_cache, pthread_mutex_lock, st_hash::records, refresh_version, remove_table_from_cache(), reopen_tables(), table_def_cache, TRUE, unused_tables, and VOID.
Referenced by reload_acl_and_cache(), and table_cache_free().
00820 { 00821 bool result=0; 00822 DBUG_ENTER("close_cached_tables"); 00823 DBUG_ASSERT(thd || (!if_wait_for_refresh && !tables)); 00824 00825 if (!have_lock) 00826 VOID(pthread_mutex_lock(&LOCK_open)); 00827 if (!tables) 00828 { 00829 refresh_version++; // Force close of open tables 00830 while (unused_tables) 00831 { 00832 #ifdef EXTRA_DEBUG 00833 if (hash_delete(&open_cache,(byte*) unused_tables)) 00834 printf("Warning: Couldn't delete open table from hash\n"); 00835 #else 00836 VOID(hash_delete(&open_cache,(byte*) unused_tables)); 00837 #endif 00838 } 00839 /* Free table shares */ 00840 while (oldest_unused_share->next) 00841 { 00842 pthread_mutex_lock(&oldest_unused_share->mutex); 00843 VOID(hash_delete(&table_def_cache, (byte*) oldest_unused_share)); 00844 } 00845 } 00846 else 00847 { 00848 bool found=0; 00849 for (TABLE_LIST *table= tables; table; table= table->next_local) 00850 { 00851 if ((!table->table || !table->table->s->log_table) && 00852 remove_table_from_cache(thd, table->db, table->table_name, 00853 RTFC_OWNED_BY_THD_FLAG)) 00854 found=1; 00855 } 00856 if (!found) 00857 if_wait_for_refresh=0; // Nothing to wait for 00858 } 00859 #ifndef EMBEDDED_LIBRARY 00860 if (!tables) 00861 kill_delayed_threads(); 00862 #endif 00863 if (if_wait_for_refresh) 00864 { 00865 /* 00866 If there is any table that has a lower refresh_version, wait until 00867 this is closed (or this thread is killed) before returning 00868 */ 00869 thd->mysys_var->current_mutex= &LOCK_open; 00870 thd->mysys_var->current_cond= &COND_refresh; 00871 thd->proc_info="Flushing tables"; 00872 00873 close_old_data_files(thd,thd->open_tables,1,1); 00874 mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL, 00875 TRUE); 00876 bool found=1; 00877 /* Wait until all threads has closed all the tables we had locked */ 00878 DBUG_PRINT("info", 00879 ("Waiting for other threads to close their open tables")); 00880 while (found && ! thd->killed) 00881 { 00882 found=0; 00883 for (uint idx=0 ; idx < open_cache.records ; idx++) 00884 { 00885 TABLE *table=(TABLE*) hash_element(&open_cache,idx); 00886 if (!table->s->log_table && 00887 ((table->s->version) < refresh_version && table->db_stat)) 00888 { 00889 found=1; 00890 DBUG_PRINT("signal", ("Waiting for COND_refresh")); 00891 pthread_cond_wait(&COND_refresh,&LOCK_open); 00892 break; 00893 } 00894 } 00895 } 00896 /* 00897 No other thread has the locked tables open; reopen them and get the 00898 old locks. This should always succeed (unless some external process 00899 has removed the tables) 00900 */ 00901 thd->in_lock_tables=1; 00902 result=reopen_tables(thd,1,1); 00903 thd->in_lock_tables=0; 00904 /* Set version for table */ 00905 for (TABLE *table=thd->open_tables; table ; table= table->next) 00906 table->s->version= refresh_version; 00907 } 00908 if (!have_lock) 00909 VOID(pthread_mutex_unlock(&LOCK_open)); 00910 if (if_wait_for_refresh) 00911 { 00912 pthread_mutex_lock(&thd->mysys_var->mutex); 00913 thd->mysys_var->current_mutex= 0; 00914 thd->mysys_var->current_cond= 0; 00915 thd->proc_info=0; 00916 pthread_mutex_unlock(&thd->mysys_var->mutex); 00917 } 00918 DBUG_RETURN(result); 00919 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool close_data_tables | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) |
Definition at line 2234 of file sql_base.cc.
References close_handle_and_leave_table_as_lock(), st_table_share::db, DBUG_ENTER, DBUG_RETURN, mysql_lock_remove(), st_table::next, st_table::s, LEX_STRING::str, strcmp(), and st_table_share::table_name.
02235 { 02236 TABLE *table; 02237 DBUG_ENTER("close_data_tables"); 02238 02239 for (table=thd->open_tables; table ; table=table->next) 02240 { 02241 if (!strcmp(table->s->table_name.str, table_name) && 02242 !strcmp(table->s->db.str, db)) 02243 { 02244 mysql_lock_remove(thd, thd->locked_tables,table); 02245 close_handle_and_leave_table_as_lock(table); 02246 } 02247 } 02248 DBUG_RETURN(0); // For the future 02249 }
Here is the call graph for this function:

| static void close_handle_and_leave_table_as_lock | ( | TABLE * | table | ) | [static] |
Definition at line 634 of file sql_base.cc.
References bzero, handler::close(), st_table::db_stat, DBUG_ENTER, DBUG_VOID_RETURN, st_table::file, INTERNAL_TMP_TABLE, LEX_STRING::length, st_table::mem_root, multi_alloc_root(), NULL, RELEASE_NORMAL, release_table_share(), st_table::s, LEX_STRING::str, and st_table_share::table_cache_key.
Referenced by close_data_tables(), and close_old_data_files().
00635 { 00636 TABLE_SHARE *share, *old_share= table->s; 00637 char *key_buff; 00638 MEM_ROOT *mem_root= &table->mem_root; 00639 DBUG_ENTER("close_handle_and_leave_table_as_lock"); 00640 00641 /* 00642 Make a local copy of the table share and free the current one. 00643 This has to be done to ensure that the table share is removed from 00644 the table defintion cache as soon as the last instance is removed 00645 */ 00646 if (multi_alloc_root(mem_root, 00647 &share, sizeof(*share), 00648 &key_buff, old_share->table_cache_key.length, 00649 NULL)) 00650 { 00651 bzero((char*) share, sizeof(*share)); 00652 share->set_table_cache_key(key_buff, old_share->table_cache_key.str, 00653 old_share->table_cache_key.length); 00654 share->tmp_table= INTERNAL_TMP_TABLE; // for intern_close_table() 00655 } 00656 00657 table->file->close(); 00658 table->db_stat= 0; // Mark file closed 00659 release_table_share(table->s, RELEASE_NORMAL); 00660 table->s= share; 00661 00662 DBUG_VOID_RETURN; 00663 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void close_old_data_files | ( | THD * | thd, | |
| TABLE * | table, | |||
| bool | abort_locks, | |||
| bool | send_refresh | |||
| ) | [static] |
Definition at line 2333 of file sql_base.cc.
References close_handle_and_leave_table_as_lock(), st_table::db_stat, DBUG_ENTER, st_table::locked_by_flush, st_table_share::log_table, mysql_lock_abort(), mysql_lock_remove(), st_table::next, refresh_version, st_table::s, TRUE, and st_table_share::version.
Referenced by close_cached_tables(), open_table(), and wait_for_tables().
02335 { 02336 bool found= send_refresh; 02337 DBUG_ENTER("close_old_data_files"); 02338 02339 for (; table ; table=table->next) 02340 { 02341 /* 02342 Reopen marked for flush. But close log tables. They are flushed only 02343 explicitly on FLUSH LOGS 02344 */ 02345 if (table->s->version != refresh_version && !table->s->log_table) 02346 { 02347 found=1; 02348 if (table->db_stat) 02349 { 02350 if (abort_locks) 02351 { 02352 mysql_lock_abort(thd,table, TRUE); // Close waiting threads 02353 mysql_lock_remove(thd, thd->locked_tables,table); 02354 table->locked_by_flush=1; // Will be reopened with locks 02355 } 02356 close_handle_and_leave_table_as_lock(table); 02357 } 02358 } 02359 } 02360 if (found) 02361 broadcast_refresh(); 02362 DBUG_VOID_RETURN; 02363 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void close_open_tables_and_downgrade | ( | ALTER_PARTITION_PARAM_TYPE * | lpt | ) |
Definition at line 6415 of file sql_base.cc.
References LOCK_open, mysql_lock_downgrade_write(), pthread_mutex_lock, pthread_mutex_unlock, remove_table_from_cache(), and VOID.
06416 { 06417 VOID(pthread_mutex_lock(&LOCK_open)); 06418 remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, 06419 RTFC_WAIT_OTHER_THREAD_FLAG); 06420 VOID(pthread_mutex_unlock(&LOCK_open)); 06421 mysql_lock_downgrade_write(lpt->thd, lpt->table, lpt->old_lock_type); 06422 }
Here is the call graph for this function:

| void close_tables_for_reopen | ( | THD * | thd, | |
| TABLE_LIST ** | tables | |||
| ) |
Definition at line 3452 of file sql_base.cc.
References close_thread_tables(), mark_used_tables_as_free_for_reuse(), st_table_list::next_global, and sp_remove_not_own_routines().
Referenced by get_all_tables(), mysql_test_update(), mysql_update(), open_and_lock_tables(), and simple_open_n_lock_tables().
03453 { 03454 /* 03455 If table list consists only from tables from prelocking set, table list 03456 for new attempt should be empty, so we have to update list's root pointer. 03457 */ 03458 if (thd->lex->first_not_own_table() == *tables) 03459 *tables= 0; 03460 thd->lex->chop_off_not_own_tables(); 03461 sp_remove_not_own_routines(thd->lex); 03462 for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global) 03463 tmp->table= 0; 03464 mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables); 03465 close_thread_tables(thd); 03466 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1571 of file sql_base.cc.
References closefrm(), st_table_share::db_type, DBUG_ENTER, DBUG_VOID_RETURN, free_io_cache(), free_table_share(), my_free, MYF, st_table_share::path, rm_temporary_table(), st_table::s, and LEX_STRING::str.
Referenced by close_temporary_table(), and close_temporary_tables().
01572 { 01573 handlerton *table_type= table->s->db_type; 01574 DBUG_ENTER("close_temporary"); 01575 01576 free_io_cache(table); 01577 closefrm(table, 0); 01578 if (delete_table) 01579 rm_temporary_table(table_type, table->s->path.str); 01580 if (free_share) 01581 { 01582 free_table_share(table->s); 01583 my_free((char*) table,MYF(0)); 01584 } 01585 DBUG_VOID_RETURN; 01586 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1531 of file sql_base.cc.
References close_temporary(), DBUG_ASSERT, st_table::next, st_table::prev, and slave_open_temp_tables.
01533 { 01534 if (table->prev) 01535 { 01536 table->prev->next= table->next; 01537 if (table->prev->next) 01538 table->next->prev= table->prev; 01539 } 01540 else 01541 { 01542 /* removing the item from the list */ 01543 DBUG_ASSERT(table == thd->temporary_tables); 01544 /* 01545 slave must reset its temporary list pointer to zero to exclude 01546 passing non-zero value to end_slave via rli->save_temporary_tables 01547 when no temp tables opened, see an invariant below. 01548 */ 01549 thd->temporary_tables= table->next; 01550 if (thd->temporary_tables) 01551 table->next->prev= 0; 01552 } 01553 if (thd->slave_thread) 01554 { 01555 /* natural invariant of temporary_tables */ 01556 DBUG_ASSERT(slave_open_temp_tables || !thd->temporary_tables); 01557 slave_open_temp_tables--; 01558 } 01559 close_temporary(table, free_share, delete_table); 01560 }
Here is the call graph for this function:

| bool close_temporary_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1517 of file sql_base.cc.
References find_temporary_table().
Referenced by mysql_rm_table_part2(), and mysql_truncate().
01518 { 01519 TABLE *table; 01520 01521 if (!(table= find_temporary_table(thd, table_list))) 01522 return 1; 01523 close_temporary_table(thd, table, 1, 1); 01524 return 0; 01525 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void close_temporary_tables | ( | THD * | thd | ) |
Definition at line 1177 of file sql_base.cc.
References append_identifier(), buf, close_temporary(), FALSE, MYSQL_LOG::is_open(), String::length(), LINT_INIT, memcpy, mysql_bin_log, st_table::next, NULL, OPTION_QUOTE_SHOW_CREATE, String::ptr(), String::q_append(), strlen(), system_charset_info, tmpkeyval(), and MYSQL_BIN_LOG::write().
01178 { 01179 TABLE *table; 01180 if (!thd->temporary_tables) 01181 return; 01182 01183 if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based) 01184 { 01185 TABLE *next; 01186 for (table= thd->temporary_tables; table; table= next) 01187 { 01188 next=table->next; 01189 close_temporary(table, 1, 1); 01190 } 01191 thd->temporary_tables= 0; 01192 return; 01193 } 01194 01195 TABLE *next, 01196 *prev_table /* TODO: 5.1 maintaines prev link in temporary_tables 01197 double-linked list so we could fix it. But it is not necessary 01198 at this time when the list is being destroyed */; 01199 bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */ 01200 // Better add "if exists", in case a RESET MASTER has been done 01201 const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS "; 01202 uint stub_len= sizeof(stub) - 1; 01203 char buf[256]; 01204 memcpy(buf, stub, stub_len); 01205 String s_query= String(buf, sizeof(buf), system_charset_info); 01206 bool found_user_tables= false; 01207 LINT_INIT(next); 01208 01209 /* 01210 insertion sort of temp tables by pseudo_thread_id to build ordered list 01211 of sublists of equal pseudo_thread_id 01212 */ 01213 01214 for (prev_table= thd->temporary_tables, table= prev_table->next; 01215 table; 01216 prev_table= table, table= table->next) 01217 { 01218 TABLE *prev_sorted /* same as for prev_table */, *sorted; 01219 if (is_user_table(table)) 01220 { 01221 if (!found_user_tables) 01222 found_user_tables= true; 01223 for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table; 01224 prev_sorted= sorted, sorted= sorted->next) 01225 { 01226 if (!is_user_table(sorted) || 01227 tmpkeyval(thd, sorted) > tmpkeyval(thd, table)) 01228 { 01229 /* move into the sorted part of the list from the unsorted */ 01230 prev_table->next= table->next; 01231 table->next= sorted; 01232 if (prev_sorted) 01233 { 01234 prev_sorted->next= table; 01235 } 01236 else 01237 { 01238 thd->temporary_tables= table; 01239 } 01240 table= prev_table; 01241 break; 01242 } 01243 } 01244 } 01245 } 01246 01247 /* We always quote db,table names though it is slight overkill */ 01248 if (found_user_tables && 01249 !(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE))) 01250 { 01251 thd->options |= OPTION_QUOTE_SHOW_CREATE; 01252 } 01253 01254 /* scan sorted tmps to generate sequence of DROP */ 01255 for (table= thd->temporary_tables; table; table= next) 01256 { 01257 if (is_user_table(table)) 01258 { 01259 /* Set pseudo_thread_id to be that of the processed table */ 01260 thd->variables.pseudo_thread_id= tmpkeyval(thd, table); 01261 /* Loop forward through all tables within the sublist of 01262 common pseudo_thread_id to create single DROP query */ 01263 for (s_query.length(stub_len); 01264 table && is_user_table(table) && 01265 tmpkeyval(thd, table) == thd->variables.pseudo_thread_id; 01266 table= next) 01267 { 01268 /* 01269 We are going to add 4 ` around the db/table names and possible more 01270 due to special characters in the names 01271 */ 01272 append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str)); 01273 s_query.q_append('.'); 01274 append_identifier(thd, &s_query, table->s->table_name.str, 01275 strlen(table->s->table_name.str)); 01276 s_query.q_append(','); 01277 next= table->next; 01278 close_temporary(table, 1, 1); 01279 } 01280 thd->clear_error(); 01281 CHARSET_INFO *cs_save= thd->variables.character_set_client; 01282 thd->variables.character_set_client= system_charset_info; 01283 Query_log_event qinfo(thd, s_query.ptr(), 01284 s_query.length() - 1 /* to remove trailing ',' */, 01285 0, FALSE); 01286 thd->variables.character_set_client= cs_save; 01287 /* 01288 Imagine the thread had created a temp table, then was doing a SELECT, and 01289 the SELECT was killed. Then it's not clever to mark the statement above as 01290 "killed", because it's not really a statement updating data, and there 01291 are 99.99% chances it will succeed on slave. 01292 If a real update (one updating a persistent table) was killed on the 01293 master, then this real update will be logged with error_code=killed, 01294 rightfully causing the slave to stop. 01295 */ 01296 qinfo.error_code= 0; 01297 mysql_bin_log.write(&qinfo); 01298 } 01299 else 01300 { 01301 next= table->next; 01302 close_temporary(table, 1, 1); 01303 } 01304 } 01305 if (!was_quote_show) 01306 thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */ 01307 thd->temporary_tables=0; 01308 }
Here is the call graph for this function:

Definition at line 1126 of file sql_base.cc.
References st_table::db_stat, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, handler::extra(), st_table::file, flush_version, st_table_share::flush_version, HA_EXTRA_FLUSH, handler::ha_reset(), hash_delete(), st_table::in_use, handler::inited, st_table::key_read, st_table::next, handler::NONE, open_cache, st_table::prev, refresh_version, st_table::s, unused_tables, st_table_share::version, and VOID.
Referenced by close_thread_tables(), mysql_ha_close(), and mysql_ha_flush_table().
01127 { 01128 bool found_old_table= 0; 01129 TABLE *table= *table_ptr; 01130 DBUG_ENTER("close_thread_table"); 01131 DBUG_ASSERT(table->key_read == 0); 01132 DBUG_ASSERT(table->file->inited == handler::NONE); 01133 01134 *table_ptr=table->next; 01135 if (table->s->version != refresh_version || 01136 thd->version != refresh_version || !table->db_stat) 01137 { 01138 VOID(hash_delete(&open_cache,(byte*) table)); 01139 found_old_table=1; 01140 } 01141 else 01142 { 01143 if (table->s->flush_version != flush_version) 01144 { 01145 table->s->flush_version= flush_version; 01146 table->file->extra(HA_EXTRA_FLUSH); 01147 } 01148 // Free memory and reset for next loop 01149 table->file->ha_reset(); 01150 table->in_use=0; 01151 if (unused_tables) 01152 { 01153 table->next=unused_tables; /* Link in last */ 01154 table->prev=unused_tables->prev; 01155 unused_tables->prev=table; 01156 table->prev->next=table; 01157 } 01158 else 01159 unused_tables=table->next=table->prev=table; 01160 } 01161 DBUG_RETURN(found_old_table); 01162 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 982 of file sql_base.cc.
References broadcast_refresh(), bzero, check_unused, close_thread_table(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, free_tmp_table(), ha_commit_stmt, hash_delete(), LOCK_open, mark_used_tables_as_free_for_reuse(), mysql_unlock_tables(), st_table::next, open_cache, OPTION_TABLE_LOCK, pthread_mutex_lock, pthread_mutex_unlock, st_hash::records, table_cache_size, TRUE, unused_tables, and VOID.
00983 { 00984 bool found_old_table; 00985 prelocked_mode_type prelocked_mode= thd->prelocked_mode; 00986 DBUG_ENTER("close_thread_tables"); 00987 00988 /* 00989 We are assuming here that thd->derived_tables contains ONLY derived 00990 tables for this substatement. i.e. instead of approach which uses 00991 query_id matching for determining which of the derived tables belong 00992 to this substatement we rely on the ability of substatements to 00993 save/restore thd->derived_tables during their execution. 00994 00995 TODO: Probably even better approach is to simply associate list of 00996 derived tables with (sub-)statement instead of thread and destroy 00997 them at the end of its execution. 00998 */ 00999 if (thd->derived_tables && !skip_derived) 01000 { 01001 TABLE *table, *next; 01002 /* 01003 Close all derived tables generated in queries like 01004 SELECT * FROM (SELECT * FROM t1) 01005 */ 01006 for (table= thd->derived_tables ; table ; table= next) 01007 { 01008 next= table->next; 01009 free_tmp_table(thd, table); 01010 } 01011 thd->derived_tables= 0; 01012 } 01013 01014 if (prelocked_mode) 01015 { 01016 /* 01017 Mark all temporary tables used by this substatement as free for reuse. 01018 */ 01019 mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables); 01020 } 01021 01022 if (thd->locked_tables || prelocked_mode) 01023 { 01024 /* 01025 Let us commit transaction for statement. Since in 5.0 we only have 01026 one statement transaction and don't allow several nested statement 01027 transactions this call will do nothing if we are inside of stored 01028 function or trigger (i.e. statement transaction is already active and 01029 does not belong to statement for which we do close_thread_tables()). 01030 TODO: This should be fixed in later releases. 01031 */ 01032 ha_commit_stmt(thd); 01033 01034 /* Ensure we are calling ha_reset() for all used tables */ 01035 mark_used_tables_as_free_for_reuse(thd, thd->open_tables); 01036 01037 /* We are under simple LOCK TABLES so should not do anything else. */ 01038 if (!prelocked_mode || !thd->lex->requires_prelocking()) 01039 DBUG_VOID_RETURN; 01040 01041 /* 01042 We are in prelocked mode, so we have to leave it now with doing 01043 implicit UNLOCK TABLES if need. 01044 */ 01045 DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED")); 01046 thd->prelocked_mode= NON_PRELOCKED; 01047 01048 if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES) 01049 DBUG_VOID_RETURN; 01050 01051 thd->lock= thd->locked_tables; 01052 thd->locked_tables= 0; 01053 /* Fallthrough */ 01054 } 01055 01056 if (thd->lock) 01057 { 01058 /* 01059 For RBR we flush the pending event just before we unlock all the 01060 tables. This means that we are at the end of a topmost 01061 statement, so we ensure that the STMT_END_F flag is set on the 01062 pending event. For statements that are *inside* stored 01063 functions, the pending event will not be flushed: that will be 01064 handled either before writing a query log event (inside 01065 binlog_query()) or when preparing a pending event. 01066 */ 01067 #ifdef HAVE_ROW_BASED_REPLICATION 01068 thd->binlog_flush_pending_rows_event(TRUE); 01069 #endif /*HAVE_ROW_BASED_REPLICATION*/ 01070 mysql_unlock_tables(thd, thd->lock); 01071 thd->lock=0; 01072 } 01073 /* 01074 assume handlers auto-commit (if some doesn't - transaction handling 01075 in MySQL should be redesigned to support it; it's a big change, 01076 and it's not worth it - better to commit explicitly only writing 01077 transactions, read-only ones should better take care of themselves. 01078 saves some work in 2pc too) 01079 see also sql_parse.cc - dispatch_command() 01080 */ 01081 if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)) 01082 bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt)); 01083 if (!thd->active_transaction()) 01084 thd->transaction.xid_state.xid.null(); 01085 01086 /* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */ 01087 if (!lock_in_use) 01088 VOID(pthread_mutex_lock(&LOCK_open)); 01089 01090 DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables)); 01091 01092 found_old_table= 0; 01093 while (thd->open_tables) 01094 found_old_table|= close_thread_table(thd, &thd->open_tables); 01095 thd->some_tables_deleted=0; 01096 01097 /* Free tables to hold down open files */ 01098 while (open_cache.records > table_cache_size && unused_tables) 01099 VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ 01100 check_unused(); 01101 if (found_old_table) 01102 { 01103 /* Tell threads waiting for refresh that something has happened */ 01104 broadcast_refresh(); 01105 } 01106 if (!lock_in_use) 01107 VOID(pthread_mutex_unlock(&LOCK_open)); 01108 /* VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */ 01109 01110 if (prelocked_mode == PRELOCKED) 01111 { 01112 /* 01113 If we are here then we are leaving normal prelocked mode, so it is 01114 good idea to turn off OPTION_TABLE_LOCK flag. 01115 */ 01116 DBUG_ASSERT(thd->lex->requires_prelocking()); 01117 thd->options&= ~(ulong) (OPTION_TABLE_LOCK); 01118 } 01119 01120 DBUG_VOID_RETURN; 01121 }
Here is the call graph for this function:

| uint create_table_def_key | ( | THD * | thd, | |
| char * | key, | |||
| TABLE_LIST * | table_list, | |||
| bool | tmp_table | |||
| ) |
Definition at line 176 of file sql_base.cc.
References st_table_list::db, int4store, key_length, strmov(), and st_table_list::table_name.
Referenced by find_temporary_table(), get_cached_table_share(), lock_table_name(), open_table(), open_temporary_table(), prepare_for_repair(), and rename_temporary_table().
00178 { 00179 uint key_length= (uint) (strmov(strmov(key, table_list->db)+1, 00180 table_list->table_name)-key)+1; 00181 if (tmp_table) 00182 { 00183 int4store(key + key_length, thd->server_id); 00184 int4store(key + key_length + 4, thd->variables.pseudo_thread_id); 00185 key_length+= TMP_TABLE_KEY_EXTRA; 00186 } 00187 return key_length; 00188 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* drop_locked_tables | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) |
Definition at line 2478 of file sql_base.cc.
References broadcast_refresh(), handler::close(), st_table_share::db, st_table::db_stat, DBUG_ENTER, DBUG_RETURN, st_table::file, hash_delete(), my_free, MYF, mysql_lock_remove(), st_table::next, open_cache, st_table::s, LEX_STRING::str, strcmp(), st_table_share::table_name, and VOID.
Referenced by mysql_rm_table_part2().
02479 { 02480 TABLE *table,*next,**prev, *found= 0; 02481 prev= &thd->open_tables; 02482 DBUG_ENTER("drop_locked_tables"); 02483 02484 for (table= thd->open_tables; table ; table=next) 02485 { 02486 next=table->next; 02487 if (!strcmp(table->s->table_name.str, table_name) && 02488 !strcmp(table->s->db.str, db)) 02489 { 02490 mysql_lock_remove(thd, thd->locked_tables,table); 02491 if (!found) 02492 { 02493 found= table; 02494 /* Close engine table, but keep object around as a name lock */ 02495 if (table->db_stat) 02496 { 02497 table->db_stat= 0; 02498 table->file->close(); 02499 } 02500 } 02501 else 02502 { 02503 /* We already have a name lock, remove copy */ 02504 VOID(hash_delete(&open_cache,(byte*) table)); 02505 } 02506 } 02507 else 02508 { 02509 *prev=table; 02510 prev= &table->next; 02511 } 02512 } 02513 *prev=0; 02514 if (found) 02515 broadcast_refresh(); 02516 if (thd->locked_tables && thd->locked_tables->table_count == 0) 02517 { 02518 my_free((gptr) thd->locked_tables,MYF(0)); 02519 thd->locked_tables=0; 02520 } 02521 DBUG_RETURN(found); 02522 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5968 of file sql_base.cc.
References st_table::auto_increment_field_not_null, DBUG_ENTER, DBUG_RETURN, st_table::next_number_field, Field::table, TRUE, and value.
05969 { 05970 List_iterator_fast<Item> v(values); 05971 Item *value; 05972 DBUG_ENTER("fill_record"); 05973 05974 Field *field; 05975 while ((field = *ptr++)) 05976 { 05977 value=v++; 05978 TABLE *table= field->table; 05979 if (field == table->next_number_field) 05980 table->auto_increment_field_not_null= TRUE; 05981 if (value->save_in_field(field, 0) == -1) 05982 DBUG_RETURN(TRUE); 05983 } 05984 DBUG_RETURN(thd->net.report_error); 05985 }
| static bool fill_record | ( | THD * | thd, | |
| List< Item > & | fields, | |||
| List< Item > & | values, | |||
| bool | ignore_errors | |||
| ) | [static] |
Definition at line 5887 of file sql_base.cc.
References st_table::auto_increment_field_not_null, DBUG_ENTER, DBUG_RETURN, ER, ER_NONUPDATEABLE_COLUMN, ER_UNKNOWN_ERROR, f, Item_field::field, Item::filed_for_view_update(), my_error(), my_message(), MYF, Item::name, st_table::next_number_field, Field::table, TRUE, and value.
Referenced by fill_record_n_invoke_before_triggers().
05889 { 05890 List_iterator_fast<Item> f(fields),v(values); 05891 Item *value, *fld; 05892 Item_field *field; 05893 DBUG_ENTER("fill_record"); 05894 05895 while ((fld= f++)) 05896 { 05897 if (!(field= fld->filed_for_view_update())) 05898 { 05899 my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name); 05900 DBUG_RETURN(TRUE); 05901 } 05902 value=v++; 05903 Field *rfield= field->field; 05904 TABLE *table= rfield->table; 05905 if (rfield == table->next_number_field) 05906 table->auto_increment_field_not_null= TRUE; 05907 if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) 05908 { 05909 my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); 05910 DBUG_RETURN(TRUE); 05911 } 05912 } 05913 DBUG_RETURN(thd->net.report_error); 05914 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool fill_record_n_invoke_before_triggers | ( | THD * | thd, | |
| Field ** | ptr, | |||
| List< Item > & | values, | |||
| bool | ignore_errors, | |||
| Table_triggers_list * | triggers, | |||
| enum trg_event_type | event | |||
| ) |
Definition at line 6012 of file sql_base.cc.
References fill_record(), Table_triggers_list::process_triggers(), TRG_ACTION_BEFORE, and TRUE.
06016 { 06017 return (fill_record(thd, ptr, values, ignore_errors) || 06018 triggers && triggers->process_triggers(thd, event, 06019 TRG_ACTION_BEFORE, TRUE)); 06020 }
Here is the call graph for this function:

| bool fill_record_n_invoke_before_triggers | ( | THD * | thd, | |
| List< Item > & | fields, | |||
| List< Item > & | values, | |||
| bool | ignore_errors, | |||
| Table_triggers_list * | triggers, | |||
| enum trg_event_type | event | |||
| ) |
Definition at line 5941 of file sql_base.cc.
References fill_record(), Table_triggers_list::process_triggers(), TRG_ACTION_BEFORE, and TRUE.
Referenced by mysql_insert(), read_fixed_length(), read_sep_field(), and write_record().
05945 { 05946 return (fill_record(thd, fields, values, ignore_errors) || 05947 triggers && triggers->process_triggers(thd, event, 05948 TRG_ACTION_BEFORE, TRUE)); 05949 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static Field* find_field_in_natural_join | ( | THD * | thd, | |
| TABLE_LIST * | table_ref, | |||
| const char * | name, | |||
| uint | length, | |||
| Item ** | ref, | |||
| bool | register_tree_change, | |||
| TABLE_LIST ** | actual_table | |||
| ) | [static] |
Definition at line 3748 of file sql_base.cc.
References backup, Natural_join_column::create_item(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table_list::is_natural_join, Field_translator::item, st_table_list::join_columns, LINT_INIT, my_strcasecmp, Natural_join_column::name(), NULL, st_table_list::schema_table_reformed, system_charset_info, Field::table, st_table_list::table, Natural_join_column::table_field, Natural_join_column::table_ref, update_field_dependencies(), Natural_join_column::view_field, and view_ref_found.
Referenced by find_field_in_table_ref().
03751 { 03752 List_iterator_fast<Natural_join_column> 03753 field_it(*(table_ref->join_columns)); 03754 Natural_join_column *nj_col; 03755 Field *found_field; 03756 Query_arena *arena, backup; 03757 DBUG_ENTER("find_field_in_natural_join"); 03758 DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx", 03759 name, (ulong) ref)); 03760 DBUG_ASSERT(table_ref->is_natural_join && table_ref->join_columns); 03761 DBUG_ASSERT(*actual_table == NULL); 03762 03763 LINT_INIT(arena); 03764 LINT_INIT(found_field); 03765 03766 for (;;) 03767 { 03768 if (!(nj_col= field_it++)) 03769 DBUG_RETURN(NULL); 03770 03771 if (!my_strcasecmp(system_charset_info, nj_col->name(), name)) 03772 break; 03773 } 03774 03775 if (nj_col->view_field) 03776 { 03777 Item *item; 03778 if (register_tree_change) 03779 arena= thd->activate_stmt_arena_if_needed(&backup); 03780 /* 03781 create_item() may, or may not create a new Item, depending on the 03782 column reference. See create_view_field() for details. 03783 */ 03784 item= nj_col->create_item(thd); 03785 if (register_tree_change && arena) 03786 thd->restore_active_arena(arena, &backup); 03787 03788 if (!item) 03789 DBUG_RETURN(NULL); 03790 DBUG_ASSERT(nj_col->table_field == NULL); 03791 if (nj_col->table_ref->schema_table_reformed) 03792 { 03793 /* 03794 Translation table items are always Item_fields and fixed 03795 already('mysql_schema_table' function). So we can return 03796 ->field. It is used only for 'show & where' commands. 03797 */ 03798 DBUG_RETURN(((Item_field*) (nj_col->view_field->item))->field); 03799 } 03800 if (register_tree_change) 03801 thd->change_item_tree(ref, item); 03802 else 03803 *ref= item; 03804 found_field= (Field*) view_ref_found; 03805 } 03806 else 03807 { 03808 /* This is a base table. */ 03809 DBUG_ASSERT(nj_col->view_field == NULL); 03810 DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->table); 03811 found_field= nj_col->table_field; 03812 update_field_dependencies(thd, found_field, nj_col->table_ref->table); 03813 } 03814 03815 *actual_table= nj_col->table_ref; 03816 03817 DBUG_RETURN(found_field); 03818 }
Here is the call graph for this function:

Here is the caller graph for this function:

| Field* find_field_in_table | ( | THD * | thd, | |
| TABLE * | table, | |||
| const char * | name, | |||
| uint | length, | |||
| bool | allow_rowid, | |||
| uint * | cached_field_index_ptr | |||
| ) |
Definition at line 3840 of file sql_base.cc.
References st_table::alias, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table_share::field, st_table::field, Field::field_name, hash_search(), my_strcasecmp, st_table_share::name_hash, st_hash::records, st_table_share::rowid_field_offset, st_table::s, system_charset_info, and update_field_dependencies().
Referenced by find_field_in_table_ref(), find_field_in_tables(), and Item_trigger_field::setup_field().
03842 { 03843 Field **field_ptr, *field; 03844 uint cached_field_index= *cached_field_index_ptr; 03845 DBUG_ENTER("find_field_in_table"); 03846 DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name)); 03847 03848 /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */ 03849 if (cached_field_index < table->s->fields && 03850 !my_strcasecmp(system_charset_info, 03851 table->field[cached_field_index]->field_name, name)) 03852 field_ptr= table->field + cached_field_index; 03853 else if (table->s->name_hash.records) 03854 { 03855 field_ptr= (Field**) hash_search(&table->s->name_hash, (byte*) name, 03856 length); 03857 if (field_ptr) 03858 { 03859 /* 03860 field_ptr points to field in TABLE_SHARE. Convert it to the matching 03861 field in table 03862 */ 03863 field_ptr= (table->field + (field_ptr - table->s->field)); 03864 } 03865 } 03866 else 03867 { 03868 if (!(field_ptr= table->field)) 03869 DBUG_RETURN((Field *)0); 03870 for (; *field_ptr; ++field_ptr) 03871 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name)) 03872 break; 03873 } 03874 03875 if (field_ptr && *field_ptr) 03876 { 03877 *cached_field_index_ptr= field_ptr - table->field; 03878 field= *field_ptr; 03879 } 03880 else 03881 { 03882 if (!allow_rowid || 03883 my_strcasecmp(system_charset_info, name, "_rowid") || 03884 table->s->rowid_field_offset == 0) 03885 DBUG_RETURN((Field*) 0); 03886 field= table->field[table->s->rowid_field_offset-1]; 03887 } 03888 03889 update_field_dependencies(thd, field, table); 03890 03891 DBUG_RETURN(field); 03892 }
Here is the call graph for this function:

Here is the caller graph for this function:

| Field* find_field_in_table_ref | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| const char * | name, | |||
| uint | length, | |||
| const char * | item_name, | |||
| const char * | db_name, | |||
| const char * | table_name, | |||
| Item ** | ref, | |||
| bool | check_privileges, | |||
| bool | allow_rowid, | |||
| uint * | cached_field_index_ptr, | |||
| bool | register_tree_change, | |||
| TABLE_LIST ** | actual_table | |||
| ) |
Definition at line 3938 of file sql_base.cc.
References st_table_list::alias, bitmap_set_bit(), check_column_grant_in_table_ref(), st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, Field::field_index, Item::FIELD_ITEM, st_table_list::field_translation, find_field_in_natural_join(), find_field_in_table(), find_field_in_view(), st_nested_join::join_list, MARK_COLUMNS_NONE, MARK_COLUMNS_READ, my_strcasecmp, st_table_list::nested_join, NULL, st_table::read_set, Item::register_field_in_read_map(), strcmp(), Field::table, st_table_list::table, table_alias_charset, Item::type(), view_ref_found, Item::walk(), st_table::write_set, and WRONG_GRANT.
Referenced by find_field_in_tables(), and mysql_table_grant().
03945 { 03946 Field *fld; 03947 DBUG_ENTER("find_field_in_table_ref"); 03948 DBUG_PRINT("enter", 03949 ("table: '%s' field name: '%s' item name: '%s' ref 0x%lx", 03950 table_list->alias, name, item_name, (ulong) ref)); 03951 03952 /* 03953 Check that the table and database that qualify the current field name 03954 are the same as the table reference we are going to search for the field. 03955 03956 Exclude from the test below nested joins because the columns in a 03957 nested join generally originate from different tables. Nested joins 03958 also have no table name, except when a nested join is a merge view 03959 or an information schema table. 03960 03961 We include explicitly table references with a 'field_translation' table, 03962 because if there are views over natural joins we don't want to search 03963 inside the view, but we want to search directly in the view columns 03964 which are represented as a 'field_translation'. 03965 03966 TODO: Ensure that table_name, db_name and tables->db always points to 03967 something ! 03968 */ 03969 if (/* Exclude nested joins. */ 03970 (!table_list->nested_join || 03971 /* Include merge views and information schema tables. */ 03972 table_list->field_translation) && 03973 /* 03974 Test if the field qualifiers match the table reference we plan 03975 to search. 03976 */ 03977 table_name && table_name[0] && 03978 (my_strcasecmp(table_alias_charset, table_list->alias, table_name) || 03979 (db_name && db_name[0] && table_list->db && table_list->db[0] && 03980 strcmp(db_name, table_list->db)))) 03981 DBUG_RETURN(0); 03982 03983 *actual_table= NULL; 03984 03985 if (table_list->field_translation) 03986 { 03987 /* 'table_list' is a view or an information schema table. */ 03988 if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref, 03989 register_tree_change))) 03990 *actual_table= table_list; 03991 } 03992 else if (!table_list->nested_join) 03993 { 03994 /* 'table_list' is a stored table. */ 03995 DBUG_ASSERT(table_list->table); 03996 if ((fld= find_field_in_table(thd, table_list->table, name, length, 03997 allow_rowid, 03998 cached_field_index_ptr))) 03999 *actual_table= table_list; 04000 } 04001 else 04002 { 04003 /* 04004 'table_list' is a NATURAL/USING join, or an operand of such join that 04005 is a nested join itself. 04006 04007 If the field name we search for is qualified, then search for the field 04008 in the table references used by NATURAL/USING the join. 04009 */ 04010 if (table_name && table_name[0]) 04011 { 04012 List_iterator<TABLE_LIST> it(table_list->nested_join->join_list); 04013 TABLE_LIST *table; 04014 while ((table= it++)) 04015 { 04016 if ((fld= find_field_in_table_ref(thd, table, name, length, item_name, 04017 db_name, table_name, ref, 04018 check_privileges, allow_rowid, 04019 cached_field_index_ptr, 04020 register_tree_change, actual_table))) 04021 DBUG_RETURN(fld); 04022 } 04023 DBUG_RETURN(0); 04024 } 04025 /* 04026 Non-qualified field, search directly in the result columns of the 04027 natural join. The condition of the outer IF is true for the top-most 04028 natural join, thus if the field is not qualified, we will search 04029 directly the top-most NATURAL/USING join. 04030 */ 04031 fld= find_field_in_natural_join(thd, table_list, name, length, ref, 04032 register_tree_change, actual_table); 04033 } 04034 04035 if (fld) 04036 { 04037 #ifndef NO_EMBEDDED_ACCESS_CHECKS 04038 /* Check if there are sufficient access rights to the found field. */ 04039 if (check_privileges && 04040 check_column_grant_in_table_ref(thd, *actual_table, name, length)) 04041 fld= WRONG_GRANT; 04042 else 04043 #endif 04044 if (thd->mark_used_columns != MARK_COLUMNS_NONE) 04045 { 04046 /* 04047 Get rw_set correct for this field so that the handler 04048 knows that this field is involved in the query and gets 04049 retrieved/updated 04050 */ 04051 Field *field_to_set= NULL; 04052 if (fld == view_ref_found) 04053 { 04054 Item *it= (*ref)->real_item(); 04055 if (it->type() == Item::FIELD_ITEM) 04056 field_to_set= ((Item_field*)it)->field; 04057 else 04058 { 04059 if (thd->mark_used_columns == MARK_COLUMNS_READ) 04060 it->walk(&Item::register_field_in_read_map, 1, (byte *) 0); 04061 } 04062 } 04063 else 04064 field_to_set= fld; 04065 if (field_to_set) 04066 { 04067 TABLE *table= field_to_set->table; 04068 if (thd->mark_used_columns == MARK_COLUMNS_READ) 04069 bitmap_set_bit(table->read_set, field_to_set->field_index); 04070 else 04071 bitmap_set_bit(table->write_set, field_to_set->field_index); 04072 } 04073 } 04074 } 04075 DBUG_RETURN(fld); 04076 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4094 of file sql_base.cc.
References st_table_share::field, st_table::field, hash_search(), my_strcasecmp, st_table_share::name_hash, st_hash::records, st_table::s, strlen(), and system_charset_info.
04095 { 04096 Field **field_ptr; 04097 if (table->s->name_hash.records) 04098 { 04099 field_ptr= (Field**)hash_search(&table->s->name_hash,(byte*) name, 04100 strlen(name)); 04101 if (field_ptr) 04102 { 04103 /* 04104 field_ptr points to field in TABLE_SHARE. Convert it to the matching 04105 field in table 04106 */ 04107 field_ptr= (table->field + (field_ptr - table->s->field)); 04108 } 04109 } 04110 else 04111 { 04112 if (!(field_ptr= table->field)) 04113 return (Field *)0; 04114 for (; *field_ptr; ++field_ptr) 04115 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name)) 04116 break; 04117 } 04118 if (field_ptr) 04119 return *field_ptr; 04120 else 04121 return (Field *)0; 04122 }
Here is the call graph for this function:

| Field* find_field_in_tables | ( | THD * | thd, | |
| Item_ident * | item, | |||
| TABLE_LIST * | first_table, | |||
| TABLE_LIST * | last_table, | |||
| Item ** | ref, | |||
| find_item_error_report_type | report_error, | |||
| bool | check_privileges, | |||
| bool | register_tree_change | |||
| ) |
Definition at line 4160 of file sql_base.cc.
References st_table_list::cacheable_table, Item_ident::cached_field_index, Item_ident::cached_table, db, Item_ident::db_name, DBUG_ASSERT, ER_BAD_FIELD_ERROR, ER_NON_UNIQ_ERROR, ER_UNKNOWN_TABLE, Item_ident::field_name, files_charset_info, find_field_in_table(), find_field_in_table_ref(), Item_ident::full_name(), lower_case_table_names, mark_select_range_as_dependent(), my_casedn_str, my_error(), MYF, Item::name, name, NAME_LEN, st_table_list::next_local, st_table_list::next_name_resolution_table, not_found_field, NULL, NullS, st_table_list::select_lex, strlen(), strmake(), strxnmov(), st_table_list::table, Item_ident::table_name, TRUE, st_table_list::view, and WRONG_GRANT.
Referenced by db_show_routine_status(), find_order_in_list(), Item_ref::fix_fields(), Item_field::fix_fields(), Item_field::fix_outer_field(), and init_fields().
04164 { 04165 Field *found=0; 04166 const char *db= item->db_name; 04167 const char *table_name= item->table_name; 04168 const char *name= item->field_name; 04169 uint length=(uint) strlen(name); 04170 char name_buff[NAME_LEN+1]; 04171 TABLE_LIST *cur_table= first_table; 04172 TABLE_LIST *actual_table; 04173 bool allow_rowid; 04174 04175 if (!table_name || !table_name[0]) 04176 { 04177 table_name= 0; // For easier test 04178 db= 0; 04179 } 04180 04181 allow_rowid= table_name || (cur_table && !cur_table->next_local); 04182 04183 if (item->cached_table) 04184 { 04185 /* 04186 This shortcut is used by prepared statements. We assume that 04187 TABLE_LIST *first_table is not changed during query execution (which 04188 is true for all queries except RENAME but luckily RENAME doesn't 04189 use fields...) so we can rely on reusing pointer to its member. 04190 With this optimization we also miss case when addition of one more 04191 field makes some prepared query ambiguous and so erroneous, but we 04192 accept this trade off. 04193 */ 04194 TABLE_LIST *table_ref= item->cached_table; 04195 /* 04196 The condition (table_ref->view == NULL) ensures that we will call 04197 find_field_in_table even in the case of information schema tables 04198 when table_ref->field_translation != NULL. 04199 */ 04200 if (table_ref->table && !table_ref->view) 04201 found= find_field_in_table(thd, table_ref->table, name, length, 04202 TRUE, &(item->cached_field_index)); 04203 else 04204 found= find_field_in_table_ref(thd, table_ref, name, length, item->name, 04205 NULL, NULL, ref, check_privileges, 04206 TRUE, &(item->cached_field_index), 04207 register_tree_change, 04208 &actual_table); 04209 if (found) 04210 { 04211 if (found == WRONG_GRANT) 04212 return (Field*) 0; 04213 { 04214 SELECT_LEX *current_sel= thd->lex->current_select; 04215 SELECT_LEX *last_select= table_ref->select_lex; 04216 /* 04217 If the field was an outer referencee, mark all selects using this 04218 sub query as dependent on the outer query 04219 */ 04220 if (current_sel != last_select) 04221 mark_select_range_as_dependent(thd, last_select, current_sel, 04222 found, *ref, item); 04223 } 04224 return found; 04225 } 04226 } 04227 04228 if (db && lower_case_table_names) 04229 { 04230 /* 04231 convert database to lower case for comparison. 04232 We can't do this in Item_field as this would change the 04233 'name' of the item which may be used in the select list 04234 */ 04235 strmake(name_buff, db, sizeof(name_buff)-1); 04236 my_casedn_str(files_charset_info, name_buff); 04237 db= name_buff; 04238 } 04239 04240 if (last_table) 04241 last_table= last_table->next_name_resolution_table; 04242 04243 for (; cur_table != last_table ; 04244 cur_table= cur_table->next_name_resolution_table) 04245 { 04246 Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length, 04247 item->name, db, table_name, ref, 04248 check_privileges, allow_rowid, 04249 &(item->cached_field_index), 04250 register_tree_change, 04251 &actual_table); 04252 if (cur_field) 04253 { 04254 if (cur_field == WRONG_GRANT) 04255 return (Field*) 0; 04256 04257 /* 04258 Store the original table of the field, which may be different from 04259 cur_table in the case of NATURAL/USING join. 04260 */ 04261 item->cached_table= (!actual_table->cacheable_table || found) ? 04262 0 : actual_table; 04263 04264 DBUG_ASSERT(thd->where); 04265 /* 04266 If we found a fully qualified field we return it directly as it can't 04267 have duplicates. 04268 */ 04269 if (db) 04270 return cur_field; 04271 04272 if (found) 04273 { 04274 if (report_error == REPORT_ALL_ERRORS || 04275 report_error == IGNORE_EXCEPT_NON_UNIQUE) 04276 my_error(ER_NON_UNIQ_ERROR, MYF(0), 04277 table_name ? item->full_name() : name, thd->where); 04278 return (Field*) 0; 04279 } 04280 found= cur_field; 04281 } 04282 } 04283 04284 if (found) 04285 return found; 04286 04287 /* 04288 If the field was qualified and there were no tables to search, issue 04289 an error that an unknown table was given. The situation is detected 04290 as follows: if there were no tables we wouldn't go through the loop 04291 and cur_table wouldn't be updated by the loop increment part, so it 04292 will be equal to the first table. 04293 */ 04294 if (table_name && (cur_table == first_table) && 04295 (report_error == REPORT_ALL_ERRORS || 04296 report_error == REPORT_EXCEPT_NON_UNIQUE)) 04297 { 04298 char buff[NAME_LEN*2+1]; 04299 if (db && db[0]) 04300 { 04301 strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); 04302 table_name=buff; 04303 } 04304 my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where); 04305 } 04306 else 04307 { 04308 if (report_error == REPORT_ALL_ERRORS || 04309 report_error == REPORT_EXCEPT_NON_UNIQUE) 04310 my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where); 04311 else 04312 found= not_found_field; 04313 } 04314 return found; 04315 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static Field* find_field_in_view | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| const char * | name, | |||
| uint | length, | |||
| const char * | item_name, | |||
| Item ** | ref, | |||
| bool | register_tree_change | |||
| ) | [static] |
Definition at line 3661 of file sql_base.cc.
References st_table_list::alias, backup, Field_iterator_view::create_item(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, Field_iterator_view::end_of_fields(), LINT_INIT, my_strcasecmp, Field_iterator_view::name(), Field_iterator_view::next(), Item::real_item(), st_table_list::schema_table_reformed, Field_iterator_view::set(), Item::set_name(), system_charset_info, st_table_list::view, and view_ref_found.
Referenced by find_field_in_table_ref().
03665 { 03666 DBUG_ENTER("find_field_in_view"); 03667 DBUG_PRINT("enter", 03668 ("view: '%s', field name: '%s', item name: '%s', ref 0x%lx", 03669 table_list->alias, name, item_name, (ulong) ref)); 03670 Field_iterator_view field_it; 03671 field_it.set(table_list); 03672 Query_arena *arena, backup; 03673 LINT_INIT(arena); 03674 03675 DBUG_ASSERT(table_list->schema_table_reformed || 03676 (ref != 0 && table_list->view != 0)); 03677 for (; !field_it.end_of_fields(); field_it.next()) 03678 { 03679 if (!my_strcasecmp(system_charset_info, field_it.name(), name)) 03680 { 03681 // in PS use own arena or data will be freed after prepare 03682 if (register_tree_change) 03683 arena= thd->activate_stmt_arena_if_needed(&backup); 03684 /* 03685 create_item() may, or may not create a new Item, depending on 03686 the column reference. See create_view_field() for details. 03687 */ 03688 Item *item= field_it.create_item(thd); 03689 if (register_tree_change && arena) 03690 thd->restore_active_arena(arena, &backup); 03691 03692 if (!item) 03693 DBUG_RETURN(0); 03694 /* 03695 *ref != NULL means that *ref contains the item that we need to 03696 replace. If the item was aliased by the user, set the alias to 03697 the replacing item. 03698 We need to set alias on both ref itself and on ref real item. 03699 */ 03700 if (*ref && !(*ref)->is_autogenerated_name) 03701 { 03702 item->set_name((*ref)->name, (*ref)->name_length, 03703 system_charset_info); 03704 item->real_item()->set_name((*ref)->name, (*ref)->name_length, 03705 system_charset_info); 03706 } 03707 if (register_tree_change) 03708 thd->change_item_tree(ref, item); 03709 else 03710 *ref= item; 03711 DBUG_RETURN((Field*) view_ref_found); 03712 } 03713 } 03714 DBUG_RETURN(0); 03715 }
Here is the call graph for this function:

Here is the caller graph for this function:

| Item** find_item_in_list | ( | Item * | find, | |
| List< Item > & | items, | |||
| uint * | counter, | |||
| find_item_error_report_type | report_error, | |||
| bool * | unaliased | |||
| ) |
Definition at line 4353 of file sql_base.cc.
References current_thd, ER_BAD_FIELD_ERROR, ER_NON_UNIQ_ERROR, FALSE, Item::FIELD_ITEM, find(), LINT_INIT, my_error(), my_strcasecmp, MYF, charset_info_st::name, not_found_item, List_iterator< T >::ref(), Item::REF_ITEM, strcmp(), system_charset_info, and TRUE.
Referenced by find_order_in_list(), Item_field::fix_fields(), resolve_ref_in_select_and_group(), and setup_new_fields().
04355 { 04356 List_iterator<Item> li(items); 04357 Item **found=0, **found_unaliased= 0, *item; 04358 const char *db_name=0; 04359 const char *field_name=0; 04360 const char *table_name=0; 04361 bool found_unaliased_non_uniq= 0; 04362 uint unaliased_counter; 04363 04364 LINT_INIT(unaliased_counter); // Dependent on found_unaliased 04365 04366 *unaliased= FALSE; 04367 04368 if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM) 04369 { 04370 field_name= ((Item_ident*) find)->field_name; 04371 table_name= ((Item_ident*) find)->table_name; 04372 db_name= ((Item_ident*) find)->db_name; 04373 } 04374 04375 for (uint i= 0; (item=li++); i++) 04376 { 04377 if (field_name && item->real_item()->type() == Item::FIELD_ITEM) 04378 { 04379 Item_ident *item_field= (Item_ident*) item; 04380 04381 /* 04382 In case of group_concat() with ORDER BY condition in the QUERY 04383 item_field can be field of temporary table without item name 04384 (if this field created from expression argument of group_concat()), 04385 => we have to check presence of name before compare 04386 */ 04387 if (!item_field->name) 04388 continue; 04389 04390 if (table_name) 04391 { 04392 /* 04393 If table name is specified we should find field 'field_name' in 04394 table 'table_name'. According to SQL-standard we should ignore 04395 aliases in this case. 04396 04397 Since we should NOT prefer fields from the select list over 04398 other fields from the tables participating in this select in 04399 case of ambiguity we have to do extra check outside this function. 04400 04401 We use strcmp for table names and database names as these may be 04402 case sensitive. In cases where they are not case sensitive, they 04403 are always in lower case. 04404 04405 item_field->field_name and item_field->table_name can be 0x0 if 04406 item is not fix_field()'ed yet. 04407 */ 04408 if (item_field->field_name && item_field->table_name && 04409 !my_strcasecmp(system_charset_info, item_field->field_name, 04410 field_name) && 04411 !strcmp(item_field->table_name, table_name) && 04412 (!db_name || (item_field->db_name && 04413 !strcmp(item_field->db_name, db_name)))) 04414 { 04415 if (found_unaliased) 04416 { 04417 if ((*found_unaliased)->eq(item, 0)) 04418 continue; 04419 /* 04420 Two matching fields in select list. 04421 We already can bail out because we are searching through 04422 unaliased names only and will have duplicate error anyway. 04423 */ 04424 if (report_error != IGNORE_ERRORS) 04425 my_error(ER_NON_UNIQ_ERROR, MYF(0), 04426 find->full_name(), current_thd->where); 04427 return (Item**) 0; 04428 } 04429 found_unaliased= li.ref(); 04430 unaliased_counter= i; 04431 if (db_name) 04432 break; // Perfect match 04433 } 04434 } 04435 else if (!my_strcasecmp(system_charset_info, item_field->name, 04436 field_name)) 04437 { 04438 /* 04439 If table name was not given we should scan through aliases 04440 (or non-aliased fields) first. We are also checking unaliased 04441 name of the field in then next else-if, to be able to find 04442 instantly field (hidden by alias) if no suitable alias (or 04443 non-aliased field) was found. 04444 */ 04445 if (found) 04446 { 04447 if ((*found)->eq(item, 0)) 04448 continue; // Same field twice 04449 if (report_error != IGNORE_ERRORS) 04450 my_error(ER_NON_UNIQ_ERROR, MYF(0), 04451 find->full_name(), current_thd->where); 04452 return (Item**) 0; 04453 } 04454 found= li.ref(); 04455 *counter= i; 04456 } 04457 else if (!my_strcasecmp(system_charset_info, item_field->field_name, 04458 field_name)) 04459 { 04460 /* 04461 We will use un-aliased field or react on such ambiguities only if 04462 we won't be able to find aliased field. 04463 Again if we have ambiguity with field outside of select list 04464 we should prefer fields from select list. 04465 */ 04466 if (found_unaliased) 04467 { 04468 if ((*found_unaliased)->eq(item, 0)) 04469 continue; // Same field twice 04470 found_unaliased_non_uniq= 1; 04471 } 04472 else 04473 { 04474 found_unaliased= li.ref(); 04475 unaliased_counter= i; 04476 } 04477 } 04478 } 04479 else if (!table_name && (find->eq(item,0) || 04480 find->name && item->name && 04481 !my_strcasecmp(system_charset_info, 04482 item->name,find->name))) 04483 { 04484 found= li.ref(); 04485 *counter= i; 04486 break; 04487 } 04488 } 04489 if (!found) 04490 { 04491 if (found_unaliased_non_uniq) 04492 { 04493 if (report_error != IGNORE_ERRORS) 04494 my_error(ER_NON_UNIQ_ERROR, MYF(0), 04495 find->full_name(), current_thd->where); 04496 return (Item **) 0; 04497 } 04498 if (found_unaliased) 04499 { 04500 found= found_unaliased; 04501 *counter= unaliased_counter; 04502 *unaliased= TRUE; 04503 } 04504 } 04505 if (found) 04506 return found; 04507 if (report_error != REPORT_EXCEPT_NOT_FOUND) 04508 { 04509 if (report_error == REPORT_ALL_ERRORS) 04510 my_error(ER_BAD_FIELD_ERROR, MYF(0), 04511 find->full_name(), current_thd->where); 04512 return (Item **) 0; 04513 } 04514 else 04515 return (Item **) not_found_item; 04516 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* find_locked_table | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) |
Definition at line 2112 of file sql_base.cc.
References key, key_length, MAX_DBKEY_LENGTH, memcmp(), and strmov().
Referenced by mysql_insert().
02113 { 02114 char key[MAX_DBKEY_LENGTH]; 02115 uint key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; 02116 02117 for (TABLE *table=thd->open_tables; table ; table=table->next) 02118 { 02119 if (table->s->table_cache_key.length == key_length && 02120 !memcmp(table->s->table_cache_key.str, key, key_length)) 02121 return table; 02122 } 02123 return(0); 02124 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE_LIST* find_table_in_list | ( | TABLE_LIST * | table, | |
| st_table_list *TABLE_LIST::* | link, | |||
| const char * | db_name, | |||
| const char * | table_name | |||
| ) |
Definition at line 1329 of file sql_base.cc.
References st_table_list::db, NO_TMP_TABLE, st_table::s, strcmp(), st_table_list::table, st_table_list::table_name, and st_table_share::tmp_table.
01333 { 01334 for (; table; table= table->*link ) 01335 { 01336 if ((table->table == 0 || table->table->s->tmp_table == NO_TMP_TABLE) && 01337 strcmp(table->db, db_name) == 0 && 01338 strcmp(table->table_name, table_name) == 0) 01339 break; 01340 } 01341 return table; 01342 }
Here is the call graph for this function:

| TABLE* find_temporary_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1493 of file sql_base.cc.
References create_table_def_key(), st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, key, key_length, LEX_STRING::length, MAX_DBKEY_LENGTH, memcmp(), st_table::next, st_table::s, LEX_STRING::str, st_table_share::table_cache_key, and st_table_list::table_name.
01494 { 01495 char key[MAX_DBKEY_LENGTH]; 01496 uint key_length; 01497 TABLE *table; 01498 DBUG_ENTER("find_temporary_table"); 01499 DBUG_PRINT("enter", ("table: '%s'.'%s'", 01500 table_list->db, table_list->table_name)); 01501 01502 key_length= create_table_def_key(thd, key, table_list, 1); 01503 for (table=thd->temporary_tables ; table ; table= table->next) 01504 { 01505 if (table->s->table_cache_key.length == key_length && 01506 !memcmp(table->s->table_cache_key.str, key, key_length)) 01507 DBUG_RETURN(table); 01508 } 01509 DBUG_RETURN(0); // Not a temporary table 01510 }
Here is the call graph for this function:

| TABLE* find_temporary_table | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) |
Definition at line 1483 of file sql_base.cc.
References st_table_list::db, and st_table_list::table_name.
Referenced by close_temporary_table(), mysql_alter_table(), mysql_create_like_table(), mysql_create_or_drop_trigger(), mysql_create_table_internal(), mysql_truncate(), and some_non_temp_table_to_be_updated().
01484 { 01485 TABLE_LIST table_list; 01486 01487 table_list.db= (char*) db; 01488 table_list.table_name= (char*) table_name; 01489 return find_temporary_table(thd, &table_list); 01490 }
Here is the caller graph for this function:

| void flush_tables | ( | ) |
Definition at line 6104 of file sql_base.cc.
References hash_delete(), LOCK_open, open_cache, pthread_mutex_lock, pthread_mutex_unlock, and unused_tables.
Referenced by handle_manager().
06105 { 06106 (void) pthread_mutex_lock(&LOCK_open); 06107 while (unused_tables) 06108 hash_delete(&open_cache,(byte*) unused_tables); 06109 (void) pthread_mutex_unlock(&LOCK_open); 06110 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void free_cache_entry | ( | TABLE * | entry | ) | [static] |
Definition at line 776 of file sql_base.cc.
References check_unused, DBUG_ENTER, DBUG_VOID_RETURN, st_table::in_use, intern_close_table(), my_free, MYF, st_table::next, st_table::prev, and unused_tables.
Referenced by table_cache_init().
00777 { 00778 DBUG_ENTER("free_cache_entry"); 00779 00780 intern_close_table(table); 00781 if (!table->in_use) 00782 { 00783 table->next->prev=table->prev; /* remove from used chain */ 00784 table->prev->next=table->next; 00785 if (table == unused_tables) 00786 { 00787 unused_tables=unused_tables->next; 00788 if (table == unused_tables) 00789 unused_tables=0; 00790 } 00791 check_unused(); // consisty check 00792 } 00793 my_free((gptr) table,MYF(0)); 00794 DBUG_VOID_RETURN; 00795 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void free_io_cache | ( | TABLE * | table | ) |
Definition at line 799 of file sql_base.cc.
References close_cached_file(), DBUG_ENTER, DBUG_VOID_RETURN, st_filesort_info::io_cache, my_free, MYF, and st_table::sort.
Referenced by JOIN::cleanup(), close_temporary(), copy_data_between_tables(), free_tmp_table(), get_schema_tables_result(), handler::ha_reset(), intern_close_table(), JOIN::reinit(), and remove_duplicates().
00800 { 00801 DBUG_ENTER("free_io_cache"); 00802 if (table->sort.io_cache) 00803 { 00804 close_cached_file(table->sort.io_cache); 00805 my_free((gptr) table->sort.io_cache,MYF(0)); 00806 table->sort.io_cache=0; 00807 } 00808 DBUG_VOID_RETURN; 00809 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE_SHARE* get_cached_table_share | ( | const char * | db, | |
| const char * | table_name | |||
| ) |
Definition at line 605 of file sql_base.cc.
References create_table_def_key(), st_table_list::db, hash_search(), key, key_length, LOCK_open, NAME_LEN, safe_mutex_assert_owner, table_def_cache, and st_table_list::table_name.
Referenced by mysql_create_table_internal(), mysql_drop_view(), and mysql_rm_table_part2().
00606 { 00607 char key[NAME_LEN*2+2]; 00608 TABLE_LIST table_list; 00609 uint key_length; 00610 safe_mutex_assert_owner(&LOCK_open); 00611 00612 table_list.db= (char*) db; 00613 table_list.table_name= (char*) table_name; 00614 key_length= create_table_def_key((THD*) 0, key, &table_list, 0); 00615 return (TABLE_SHARE*) hash_search(&table_def_cache,(byte*) key, key_length); 00616 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5522 of file sql_base.cc.
References st_table_list::alias, ER_KEY_DOES_NOT_EXITS, find_type(), st_table_share::keynames, map, my_error(), MYF, name, pos(), st_table::pos_in_table_list, st_table::s, and st_typelib::type_names.
Referenced by ha_myisam::assign_to_keycache(), ha_myisam::preload_keys(), and setup_tables().
05524 { 05525 List_iterator_fast<String> it(*index_list); 05526 String *name; 05527 uint pos; 05528 05529 map->clear_all(); 05530 while ((name=it++)) 05531 { 05532 if (table->s->keynames.type_names == 0 || 05533 (pos= find_type(&table->s->keynames, name->ptr(), 05534 name->length(), 1)) <= 05535 0) 05536 { 05537 my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), name->c_ptr(), 05538 table->pos_in_table_list->alias); 05539 map->set_all(); 05540 return 1; 05541 } 05542 map->set_bit(pos-1); 05543 } 05544 return 0; 05545 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE_SHARE* get_table_share | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| char * | key, | |||
| uint | key_length, | |||
| uint | db_flags, | |||
| int * | error | |||
| ) |
Definition at line 278 of file sql_base.cc.
References alloc_table_share(), assign_new_table_id(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, free_table_share(), hash_delete(), hash_search(), LOCK_open, LOCK_table_share, st_table_share::mutex, my_hash_insert(), st_table_share::next, oldest_unused_share, open_table_def(), open_table_error(), OPEN_VIEW, pthread_mutex_lock, pthread_mutex_unlock, st_hash::records, table_def_cache, table_def_size, and VOID.
Referenced by get_table_share_with_create(), and prepare_for_repair().
00280 { 00281 TABLE_SHARE *share; 00282 DBUG_ENTER("get_table_share"); 00283 00284 *error= 0; 00285 00286 /* Read table definition from cache */ 00287 if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(byte*) key, 00288 key_length))) 00289 goto found; 00290 00291 if (!(share= alloc_table_share(table_list, key, key_length))) 00292 { 00293 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00294 pthread_mutex_unlock(&LOCK_open); 00295 #endif 00296 DBUG_RETURN(0); 00297 } 00298 00299 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00300 // We need a write lock to be able to add a new entry 00301 pthread_mutex_unlock(&LOCK_open); 00302 pthread_mutex_lock(&LOCK_open); 00303 /* Check that another thread didn't insert the same table in between */ 00304 if ((old_share= hash_search(&table_def_cache, (byte*) key, key_length))) 00305 { 00306 (void) pthread_mutex_lock(&share->mutex); 00307 free_table_share(share); 00308 share= old_share; 00309 goto found; 00310 } 00311 #endif 00312 00313 /* 00314 Lock mutex to be able to read table definition from file without 00315 conflicts 00316 */ 00317 (void) pthread_mutex_lock(&share->mutex); 00318 00319 /* 00320 We assign a new table id under the protection of the LOCK_open and 00321 the share's own mutex. We do this insted of creating a new mutex 00322 and using it for the sole purpose of serializing accesses to a 00323 static variable, we assign the table id here. We assign it to the 00324 share before inserting it into the table_def_cache to be really 00325 sure that it cannot be read from the cache without having a table 00326 id assigned. 00327 00328 CAVEAT. This means that the table cannot be used for 00329 binlogging/replication purposes, unless get_table_share() has been 00330 called directly or indirectly. 00331 */ 00332 assign_new_table_id(share); 00333 00334 if (my_hash_insert(&table_def_cache, (byte*) share)) 00335 { 00336 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00337 pthread_mutex_unlock(&LOCK_open); 00338 (void) pthread_mutex_unlock(&share->mutex); 00339 #endif 00340 free_table_share(share); 00341 DBUG_RETURN(0); // return error 00342 } 00343 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00344 pthread_mutex_unlock(&LOCK_open); 00345 #endif 00346 if (open_table_def(thd, share, db_flags)) 00347 { 00348 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00349 /* 00350 No such table or wrong table definition file 00351 Lock first the table cache and then the mutex. 00352 This will ensure that no other thread is using the share 00353 structure. 00354 */ 00355 (void) pthread_mutex_unlock(&share->mutex); 00356 (void) pthread_mutex_lock(&LOCK_open); 00357 (void) pthread_mutex_lock(&share->mutex); 00358 #endif 00359 *error= share->error; 00360 (void) hash_delete(&table_def_cache, (byte*) share); 00361 DBUG_RETURN(0); 00362 } 00363 share->ref_count++; // Mark in use 00364 DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", 00365 (ulong) share, share->ref_count)); 00366 (void) pthread_mutex_unlock(&share->mutex); 00367 DBUG_RETURN(share); 00368 00369 found: 00370 /* 00371 We found an existing table definition. Return it if we didn't get 00372 an error when reading the table definition from file. 00373 */ 00374 00375 /* We must do a lock to ensure that the structure is initialized */ 00376 (void) pthread_mutex_lock(&share->mutex); 00377 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00378 pthread_mutex_unlock(&LOCK_open); 00379 #endif 00380 if (share->error) 00381 { 00382 /* Table definition contained an error */ 00383 open_table_error(share, share->error, share->open_errno, share->errarg); 00384 (void) pthread_mutex_unlock(&share->mutex); 00385 DBUG_RETURN(0); 00386 } 00387 if (share->is_view && !(db_flags & OPEN_VIEW)) 00388 { 00389 open_table_error(share, 1, ENOENT, 0); 00390 (void) pthread_mutex_unlock(&share->mutex); 00391 DBUG_RETURN(0); 00392 } 00393 00394 if (!share->ref_count++ && share->prev) 00395 { 00396 /* 00397 Share was not used before and it was in the old_unused_share list 00398 Unlink share from this list 00399 */ 00400 DBUG_PRINT("info", ("Unlinking from not used list")); 00401 pthread_mutex_lock(&LOCK_table_share); 00402 *share->prev= share->next; 00403 share->next->prev= share->prev; 00404 share->next= 0; 00405 share->prev= 0; 00406 pthread_mutex_unlock(&LOCK_table_share); 00407 } 00408 (void) pthread_mutex_unlock(&share->mutex); 00409 00410 /* Free cache if too big */ 00411 while (table_def_cache.records > table_def_size && 00412 oldest_unused_share->next) 00413 { 00414 pthread_mutex_lock(&oldest_unused_share->mutex); 00415 VOID(hash_delete(&table_def_cache, (byte*) oldest_unused_share)); 00416 } 00417 00418 DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", 00419 (ulong) share, share->ref_count)); 00420 DBUG_RETURN(share); 00421 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static TABLE_SHARE* get_table_share_with_create | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| char * | key, | |||
| uint | key_length, | |||
| uint | db_flags, | |||
| int * | error | |||
| ) | [static] |
Definition at line 431 of file sql_base.cc.
References st_table_list::belong_to_view, st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_NO_SUCH_TABLE, ER_UNKNOWN_ERROR, ER_VIEW_INVALID, get_table_share(), ha_create_table_from_engine(), my_error(), my_printf_error(), MYF, mysql_reset_errors(), LEX_STRING::str, st_table_list::table_name, st_table_list::view_db, and st_table_list::view_name.
Referenced by open_unireg_entry().
00434 { 00435 TABLE_SHARE *share; 00436 int tmp; 00437 DBUG_ENTER("get_table_share_with_create"); 00438 00439 if ((share= get_table_share(thd, table_list, key, key_length, 00440 db_flags, error)) || 00441 thd->net.last_errno != ER_NO_SUCH_TABLE) 00442 DBUG_RETURN(share); 00443 00444 /* Table didn't exist. Check if some engine can provide it */ 00445 if ((tmp= ha_create_table_from_engine(thd, table_list->db, 00446 table_list->table_name)) < 0) 00447 { 00448 /* 00449 No such table in any engine. 00450 Hide "Table doesn't exist" errors if table belong to view 00451 */ 00452 if (table_list->belong_to_view) 00453 { 00454 TABLE_LIST *view= table_list->belong_to_view; 00455 thd->clear_error(); 00456 my_error(ER_VIEW_INVALID, MYF(0), 00457 view->view_db.str, view->view_name.str); 00458 } 00459 DBUG_RETURN(0); 00460 } 00461 if (tmp) 00462 { 00463 /* Give right error message */ 00464 thd->clear_error(); 00465 DBUG_PRINT("error", ("Discovery of %s/%s failed", table_list->db, 00466 table_list->table_name)); 00467 my_printf_error(ER_UNKNOWN_ERROR, 00468 "Failed to open '%-.64s', error while " 00469 "unpacking from engine", 00470 MYF(0), table_list->table_name); 00471 DBUG_RETURN(0); 00472 } 00473 /* Table existed in engine. Let's open it */ 00474 mysql_reset_errors(thd, 1); // Clear warnings 00475 thd->clear_error(); // Clear error message 00476 DBUG_RETURN(get_table_share(thd, table_list, key, key_length, 00477 db_flags, error)); 00478 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool has_two_write_locked_tables_with_auto_increment | ( | TABLE_LIST * | tables | ) | [static] |
Definition at line 6530 of file sql_base.cc.
References DBUG_ASSERT, st_table_list::next_global, NULL, strcmp(), and TL_WRITE_ALLOW_WRITE.
Referenced by lock_tables().
06531 { 06532 char *first_table_name= NULL, *first_db; 06533 for (TABLE_LIST *table= tables; table; table= table->next_global) 06534 { 06535 /* we must do preliminary checks as table->table may be NULL */ 06536 if (!table->placeholder() && !table->schema_table && 06537 table->table->found_next_number_field && 06538 (table->lock_type >= TL_WRITE_ALLOW_WRITE)) 06539 { 06540 if (first_table_name == NULL) 06541 { 06542 first_table_name= table->table_name; 06543 first_db= table->db; 06544 DBUG_ASSERT(first_db); 06545 } 06546 else if (strcmp(first_db, table->db) || 06547 strcmp(first_table_name, table->table_name)) 06548 return 1; 06549 } 06550 } 06551 return 0; 06552 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int init_ftfuncs | ( | THD * | thd, | |
| SELECT_LEX * | select_lex, | |||
| bool | no_order | |||
| ) |
Definition at line 6281 of file sql_base.cc.
References DBUG_PRINT, and Item_func_match::init_search().
Referenced by mysql_delete().
06282 { 06283 if (select_lex->ftfunc_list->elements) 06284 { 06285 List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)); 06286 Item_func_match *ifm; 06287 DBUG_PRINT("info",("Performing FULLTEXT search")); 06288 thd->proc_info="FULLTEXT initialization"; 06289 06290 while ((ifm=li++)) 06291 ifm->init_search(no_order); 06292 } 06293 return 0; 06294 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool insert_fields | ( | THD * | thd, | |
| Name_resolution_context * | context, | |||
| const char * | db_name, | |||
| const char * | table_name, | |||
| List_iterator< Item > * | it, | |||
| bool | any_privileges | |||
| ) |
Definition at line 5567 of file sql_base.cc.
References List_iterator< T >::after(), bitmap_set_bit(), check_grant_all_columns(), Field_iterator_table_ref::create_item(), Field_iterator_table_ref::db_name(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, Field_iterator_table_ref::end_of_fields(), ER, ER_BAD_TABLE_ERROR, ER_COLUMNACCESS_DENIED_ERROR, ER_NO_TABLES_USED, FALSE, Field_iterator_table_ref::field(), Field::field_index, Item::FIELD_ITEM, st_table_share::fields, files_charset_info, Name_resolution_context::first_name_resolution_table, get_column_grant(), Field_iterator_table_ref::get_natural_column_ref(), Field_iterator_table_ref::grant(), st_table::grant, Bitmap< 64 >::intersect(), lower_case_table_names, st_table::map, Bitmap< 64 >::merge(), st_table::merge_keys, my_casedn_str, my_error(), my_message(), my_strcasecmp, MYF, NAME_LEN, Field_iterator_table_ref::next(), NULL, Field::part_of_key, st_grant_info::privilege, st_table::read_set, List_iterator< T >::replace(), st_table::s, SELECT_ACL, Field_iterator_table_ref::set(), strcmp(), strmake(), st_table_list::table, Field::table, table_alias_charset, Natural_join_column::table_field, Name_resolution_context::table_list, Field_iterator_table_ref::table_name(), Natural_join_column::table_ref, TRUE, st_table::used_fields, st_table::used_keys, and VIEW_ANY_ACL.
Referenced by mysql_ha_read(), and setup_wild().
05570 { 05571 Field_iterator_table_ref field_iterator; 05572 bool found; 05573 char name_buff[NAME_LEN+1]; 05574 DBUG_ENTER("insert_fields"); 05575 DBUG_PRINT("arena", ("stmt arena: 0x%lx", (ulong)thd->stmt_arena)); 05576 05577 if (db_name && lower_case_table_names) 05578 { 05579 /* 05580 convert database to lower case for comparison 05581 We can't do this in Item_field as this would change the 05582 'name' of the item which may be used in the select list 05583 */ 05584 strmake(name_buff, db_name, sizeof(name_buff)-1); 05585 my_casedn_str(files_charset_info, name_buff); 05586 db_name= name_buff; 05587 } 05588 05589 found= FALSE; 05590 05591 /* 05592 If table names are qualified, then loop over all tables used in the query, 05593 else treat natural joins as leaves and do not iterate over their underlying 05594 tables. 05595 */ 05596 for (TABLE_LIST *tables= (table_name ? context->table_list : 05597 context->first_name_resolution_table); 05598 tables; 05599 tables= (table_name ? tables->next_local : 05600 tables->next_name_resolution_table) 05601 ) 05602 { 05603 Field *field; 05604 TABLE *table= tables->table; 05605 05606 DBUG_ASSERT(tables->is_leaf_for_name_resolution()); 05607 05608 if (table_name && my_strcasecmp(table_alias_charset, table_name, 05609 tables->alias) || 05610 (db_name && strcmp(tables->db,db_name))) 05611 continue; 05612 05613 #ifndef NO_EMBEDDED_ACCESS_CHECKS 05614 /* Ensure that we have access rights to all fields to be inserted. */ 05615 if (!((table && (table->grant.privilege & SELECT_ACL) || 05616 tables->view && (tables->grant.privilege & SELECT_ACL))) && 05617 !any_privileges) 05618 { 05619 field_iterator.set(tables); 05620 if (check_grant_all_columns(thd, SELECT_ACL, field_iterator.grant(), 05621 field_iterator.db_name(), 05622 field_iterator.table_name(), 05623 &field_iterator)) 05624 DBUG_RETURN(TRUE); 05625 } 05626 #endif 05627 05628 /* 05629 Update the tables used in the query based on the referenced fields. For 05630 views and natural joins this update is performed inside the loop below. 05631 */ 05632 if (table) 05633 thd->used_tables|= table->map; 05634 05635 /* 05636 Initialize a generic field iterator for the current table reference. 05637 Notice that it is guaranteed that this iterator will iterate over the 05638 fields of a single table reference, because 'tables' is a leaf (for 05639 name resolution purposes). 05640 */ 05641 field_iterator.set(tables); 05642 05643 for (; !field_iterator.end_of_fields(); field_iterator.next()) 05644 { 05645 Item *item; 05646 05647 if (!(item= field_iterator.create_item(thd))) 05648 DBUG_RETURN(TRUE); 05649 05650 if (!found) 05651 { 05652 found= TRUE; 05653 it->replace(item); /* Replace '*' with the first found item. */ 05654 } 05655 else 05656 it->after(item); /* Add 'item' to the SELECT list. */ 05657 05658 #ifndef NO_EMBEDDED_ACCESS_CHECKS 05659 /* 05660 Set privilege information for the fields of newly created views. 05661 We have that (any_priviliges == TRUE) if and only if we are creating 05662 a view. In the time of view creation we can't use the MERGE algorithm, 05663 therefore if 'tables' is itself a view, it is represented by a 05664 temporary table. Thus in this case we can be sure that 'item' is an 05665 Item_field. 05666 */ 05667 if (any_privileges) 05668 { 05669 DBUG_ASSERT(tables->field_translation == NULL && table || 05670 tables->is_natural_join); 05671 DBUG_ASSERT(item->type() == Item::FIELD_ITEM); 05672 Item_field *fld= (Item_field*) item; 05673 const char *field_table_name= field_iterator.table_name(); 05674 05675 if (!tables->schema_table && 05676 !(fld->have_privileges= 05677 (get_column_grant(thd, field_iterator.grant(), 05678 field_iterator.db_name(), 05679 field_table_name, fld->field_name) & 05680 VIEW_ANY_ACL))) 05681 { 05682 my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), "ANY", 05683 thd->security_ctx->priv_user, 05684 thd->security_ctx->host_or_ip, 05685 fld->field_name, field_table_name); 05686 DBUG_RETURN(TRUE); 05687 } 05688 } 05689 #endif 05690 05691 if ((field= field_iterator.field())) 05692 { 05693 /* Mark fields as used to allow storage engine to optimze access */ 05694 bitmap_set_bit(field->table->read_set, field->field_index); 05695 if (table) 05696 { 05697 table->used_keys.intersect(field->part_of_key); 05698 table->merge_keys.merge(field->part_of_key); 05699 } 05700 if (tables->is_natural_join) 05701 { 05702 TABLE *field_table; 05703 /* 05704 In this case we are sure that the column ref will not be created 05705 because it was already created and stored with the natural join. 05706 */ 05707 Natural_join_column *nj_col; 05708 if (!(nj_col= field_iterator.get_natural_column_ref())) 05709 DBUG_RETURN(TRUE); 05710 DBUG_ASSERT(nj_col->table_field); 05711 field_table= nj_col->table_ref->table; 05712 if (field_table) 05713 { 05714 thd->used_tables|= field_table->map; 05715 field_table->used_keys.intersect(field->part_of_key); 05716 field_table->merge_keys.merge(field->part_of_key); 05717 field_table->used_fields++; 05718 } 05719 } 05720 } 05721 else 05722 thd->used_tables|= item->used_tables(); 05723 } 05724 /* 05725 In case of stored tables, all fields are considered as used, 05726 while in the case of views, the fields considered as used are the 05727 ones marked in setup_tables during fix_fields of view columns. 05728 For NATURAL joins, used_tables is updated in the IF above. 05729 */ 05730 if (table) 05731 table->used_fields= table->s->fields; 05732 } 05733 if (found) 05734 DBUG_RETURN(FALSE); 05735 05736 /* 05737 TODO: in the case when we skipped all columns because there was a 05738 qualified '*', and all columns were coalesced, we have to give a more 05739 meaningful message than ER_BAD_TABLE_ERROR. 05740 */ 05741 if (!table_name) 05742 my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); 05743 else 05744 my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name); 05745 05746 DBUG_RETURN(TRUE); 05747 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void intern_close_table | ( | TABLE * | table | ) |
Definition at line 754 of file sql_base.cc.
References closefrm(), DBUG_ENTER, DBUG_VOID_RETURN, st_table::file, free_io_cache(), st_table::triggers, and VOID.
Referenced by free_cache_entry(), and reopen_name_locked_table().
00755 { // Free all structures 00756 DBUG_ENTER("intern_close_table"); 00757 00758 free_io_cache(table); 00759 delete table->triggers; 00760 if (table->file) // Not true if name lock 00761 VOID(closefrm(table, 1)); // close file 00762 DBUG_VOID_RETURN; 00763 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool is_equal | ( | const LEX_STRING * | a, | |
| const LEX_STRING * | b | |||
| ) |
Definition at line 6361 of file sql_base.cc.
References LEX_STRING::length, and LEX_STRING::str.
Referenced by add_table_for_trigger(), Table_triggers_list::check_n_load(), mysql_register_view(), mysql_rename_view(), open_new_frm(), and row_sel_sec_rec_is_for_clust_rec().
Here is the caller graph for this function:

| OPEN_TABLE_LIST* list_open_tables | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | wild | |||
| ) |
Definition at line 685 of file sql_base.cc.
References bzero, check_table_access(), st_table_share::db, DBUG_ENTER, EXTRA_ACL, hash_element(), LOCK_open, my_strcasecmp, st_open_table_list::next, open_cache, pthread_mutex_lock, st_hash::records, SELECT_ACL, sql_alloc(), LEX_STRING::str, strcmp(), system_charset_info, st_table_share::table_name, VOID, and wild_compare().
Referenced by fill_open_tables().
00686 { 00687 int result = 0; 00688 OPEN_TABLE_LIST **start_list, *open_list; 00689 TABLE_LIST table_list; 00690 DBUG_ENTER("list_open_tables"); 00691 00692 VOID(pthread_mutex_lock(&LOCK_open)); 00693 bzero((char*) &table_list,sizeof(table_list)); 00694 start_list= &open_list; 00695 open_list=0; 00696 00697 for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++) 00698 { 00699 OPEN_TABLE_LIST *table; 00700 TABLE *entry=(TABLE*) hash_element(&open_cache,idx); 00701 TABLE_SHARE *share= entry->s; 00702 00703 if (db && my_strcasecmp(system_charset_info, db, share->db.str)) 00704 continue; 00705 if (wild && wild_compare(share->table_name.str, wild, 0)) 00706 continue; 00707 00708 /* Check if user has SELECT privilege for any column in the table */ 00709 table_list.db= share->db.str; 00710 table_list.table_name= share->table_name.str; 00711 table_list.grant.privilege=0; 00712 00713 if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1)) 00714 continue; 00715 /* need to check if we haven't already listed it */ 00716 for (table= open_list ; table ; table=table->next) 00717 { 00718 if (!strcmp(table->table, share->table_name.str) && 00719 !strcmp(table->db, share->db.str)) 00720 { 00721 if (entry->in_use) 00722 table->in_use++; 00723 if (entry->locked_by_name) 00724 table->locked++; 00725 break; 00726 } 00727 } 00728 if (table) 00729 continue; 00730 if (!(*start_list = (OPEN_TABLE_LIST *) 00731 sql_alloc(sizeof(**start_list)+share->table_cache_key.length))) 00732 { 00733 open_list=0; // Out of memory 00734 break; 00735 } 00736 strmov((*start_list)->table= 00737 strmov(((*start_list)->db= (char*) ((*start_list)+1)), 00738 share->db.str)+1, 00739 share->table_name.str); 00740 (*start_list)->in_use= entry->in_use ? 1 : 0; 00741 (*start_list)->locked= entry->locked_by_name ? 1 : 0; 00742 start_list= &(*start_list)->next; 00743 *start_list=0; 00744 } 00745 VOID(pthread_mutex_unlock(&LOCK_open)); 00746 DBUG_RETURN(open_list); 00747 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int lock_tables | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| uint | count, | |||
| bool * | need_reopen | |||
| ) |
Definition at line 3294 of file sql_base.cc.
References check_lock_and_start_stmt(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, FALSE, ha_rollback_stmt, has_two_write_locked_tables_with_auto_increment(), HAVE_ROW_BASED_REPLICATION, st_table_list::lock_type, mark_real_tables_as_free_for_reuse(), mysql_lock_tables(), mysql_unlock_tables(), st_table_list::next_global, OPTION_TABLE_LOCK, st_table_list::placeholder(), st_table::query_id, st_table_list::schema_table, SQLCOM_LOCK_TABLES, start(), st_table_list::table, and TRUE.
03295 { 03296 TABLE_LIST *table; 03297 03298 DBUG_ENTER("lock_tables"); 03299 /* 03300 We can't meet statement requiring prelocking if we already 03301 in prelocked mode. 03302 */ 03303 DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking()); 03304 03305 *need_reopen= FALSE; 03306 03307 #ifdef HAVE_ROW_BASED_REPLICATION 03308 /* 03309 CREATE ... SELECT UUID() locks no tables, we have to test here. 03310 */ 03311 if (thd->lex->binlog_row_based_if_mixed) 03312 thd->set_current_stmt_binlog_row_based_if_mixed(); 03313 #endif /*HAVE_ROW_BASED_REPLICATION*/ 03314 03315 if (!tables && !thd->lex->requires_prelocking()) 03316 DBUG_RETURN(0); 03317 03318 /* 03319 We need this extra check for thd->prelocked_mode because we want to avoid 03320 attempts to lock tables in substatements. Checking for thd->locked_tables 03321 is not enough in some situations. For example for SP containing 03322 "drop table t3; create temporary t3 ..; insert into t3 ...;" 03323 thd->locked_tables may be 0 after drop tables, and without this extra 03324 check insert will try to lock temporary table t3, that will lead 03325 to memory leak... 03326 */ 03327 if (!thd->locked_tables && !thd->prelocked_mode) 03328 { 03329 DBUG_ASSERT(thd->lock == 0); // You must lock everything at once 03330 TABLE **start,**ptr; 03331 03332 if (!(ptr=start=(TABLE**) thd->alloc(sizeof(TABLE*)*count))) 03333 DBUG_RETURN(-1); 03334 for (table= tables; table; table= table->next_global) 03335 { 03336 if (!table->placeholder() && !table->schema_table) 03337 *(ptr++)= table->table; 03338 } 03339 03340 /* We have to emulate LOCK TABLES if we are statement needs prelocking. */ 03341 if (thd->lex->requires_prelocking()) 03342 { 03343 thd->in_lock_tables=1; 03344 thd->options|= OPTION_TABLE_LOCK; 03345 #ifdef HAVE_ROW_BASED_REPLICATION 03346 /* 03347 If we have >= 2 different tables to update with auto_inc columns, 03348 statement-based binlogging won't work. We can solve this problem in 03349 mixed mode by switching to row-based binlogging: 03350 */ 03351 if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED && 03352 has_two_write_locked_tables_with_auto_increment(tables)) 03353 { 03354 thd->lex->binlog_row_based_if_mixed= TRUE; 03355 thd->set_current_stmt_binlog_row_based_if_mixed(); 03356 } 03357 #endif 03358 } 03359 03360 if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), 03361 MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, 03362 need_reopen))) 03363 { 03364 if (thd->lex->requires_prelocking()) 03365 { 03366 thd->options&= ~(ulong) (OPTION_TABLE_LOCK); 03367 thd->in_lock_tables=0; 03368 } 03369 DBUG_RETURN(-1); 03370 } 03371 if (thd->lex->requires_prelocking() && 03372 thd->lex->sql_command != SQLCOM_LOCK_TABLES) 03373 { 03374 TABLE_LIST *first_not_own= thd->lex->first_not_own_table(); 03375 /* 03376 We just have done implicit LOCK TABLES, and now we have 03377 to emulate first open_and_lock_tables() after it. 03378 03379 Note that "LOCK TABLES" can also be marked as requiring prelocking 03380 (e.g. if one locks view which uses functions). We should not emulate 03381 such open_and_lock_tables() in this case. We also should not set 03382 THD::prelocked_mode or first close_thread_tables() call will do 03383 "UNLOCK TABLES". 03384 */ 03385 thd->locked_tables= thd->lock; 03386 thd->lock= 0; 03387 thd->in_lock_tables=0; 03388 03389 for (table= tables; table != first_not_own; table= table->next_global) 03390 { 03391 if (!table->placeholder() && !table->schema_table) 03392 { 03393 table->table->query_id= thd->query_id; 03394 if (check_lock_and_start_stmt(thd, table->table, table->lock_type)) 03395 { 03396 ha_rollback_stmt(thd); 03397 mysql_unlock_tables(thd, thd->locked_tables); 03398 thd->locked_tables= 0; 03399 thd->options&= ~(ulong) (OPTION_TABLE_LOCK); 03400 DBUG_RETURN(-1); 03401 } 03402 } 03403 } 03404 /* 03405 Let us mark all tables which don't belong to the statement itself, 03406 and was marked as occupied during open_tables() as free for reuse. 03407 */ 03408 mark_real_tables_as_free_for_reuse(first_not_own); 03409 DBUG_PRINT("info",("prelocked_mode= PRELOCKED")); 03410 thd->prelocked_mode= PRELOCKED; 03411 } 03412 } 03413 else 03414 { 03415 TABLE_LIST *first_not_own= thd->lex->first_not_own_table(); 03416 for (table= tables; table != first_not_own; table= table->next_global) 03417 { 03418 if (!table->placeholder() && !table->schema_table && 03419 check_lock_and_start_stmt(thd, table->table, table->lock_type)) 03420 { 03421 ha_rollback_stmt(thd); 03422 DBUG_RETURN(-1); 03423 } 03424 } 03425 /* 03426 If we are under explicit LOCK TABLES and our statement requires 03427 prelocking, we should mark all "additional" tables as free for use 03428 and enter prelocked mode. 03429 */ 03430 if (thd->lex->requires_prelocking()) 03431 { 03432 mark_real_tables_as_free_for_reuse(first_not_own); 03433 DBUG_PRINT("info", ("thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES")); 03434 thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES; 03435 } 03436 } 03437 DBUG_RETURN(0); 03438 }
Here is the call graph for this function:

| TABLE_LIST** make_leaves_list | ( | TABLE_LIST ** | list, | |
| TABLE_LIST * | tables | |||
| ) |
Definition at line 5320 of file sql_base.cc.
References DBUG_ASSERT, list(), st_table_list::next_local, and VIEW_ALGORITHM_MERGE.
Referenced by setup_tables().
05321 { 05322 for (TABLE_LIST *table= tables; table; table= table->next_local) 05323 { 05324 if (table->merge_underlying_list) 05325 { 05326 DBUG_ASSERT(table->view && 05327 table->effective_algorithm == VIEW_ALGORITHM_MERGE); 05328 list= make_leaves_list(list, table->merge_underlying_list); 05329 } 05330 else 05331 { 05332 *list= table; 05333 list= &table->next_leaf; 05334 } 05335 } 05336 return list; 05337 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool mark_common_columns | ( | THD * | thd, | |
| TABLE_LIST * | table_ref_1, | |||
| TABLE_LIST * | table_ref_2, | |||
| List< String > * | using_fields, | |||
| uint * | found_using_fields | |||
| ) | [static] |
Definition at line 4618 of file sql_base.cc.
References add_join_on(), st_table_list::alias, backup, bitmap_set_bit(), Natural_join_column::create_item(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, Field_iterator_table_ref::end_of_fields(), ER_NON_UNIQ_ERROR, err, FALSE, Natural_join_column::field(), Field::field_index, Item::FIELD_ITEM, Field_iterator_table_ref::get_or_create_column_ref(), Bitmap< 64 >::intersect(), Natural_join_column::is_common, st_table_list::is_join_columns_complete, st_table_list::is_natural_join, JOIN_TYPE_RIGHT, Bitmap< 64 >::merge(), st_table::merge_keys, my_error(), my_strcasecmp, MYF, Natural_join_column::name(), st_table_list::nested_join, Field_iterator_table_ref::next(), NULL, st_table_list::outer_join, Field::part_of_key, st_table::read_set, Item::REF_ITEM, Field_iterator_table_ref::set(), set_new_item_local_context(), system_charset_info, st_table_list::table, Natural_join_column::table_ref, test_if_string_in_list(), TRUE, Item::type(), and st_table::used_keys.
Referenced by store_top_level_join_columns().
04620 { 04621 Field_iterator_table_ref it_1, it_2; 04622 Natural_join_column *nj_col_1, *nj_col_2; 04623 Query_arena *arena, backup; 04624 bool result= TRUE; 04625 bool first_outer_loop= TRUE; 04626 /* 04627 Leaf table references to which new natural join columns are added 04628 if the leaves are != NULL. 04629 */ 04630 TABLE_LIST *leaf_1= (table_ref_1->nested_join && 04631 !table_ref_1->is_natural_join) ? 04632 NULL : table_ref_1; 04633 TABLE_LIST *leaf_2= (table_ref_2->nested_join && 04634 !table_ref_2->is_natural_join) ? 04635 NULL : table_ref_2; 04636 04637 DBUG_ENTER("mark_common_columns"); 04638 DBUG_PRINT("info", ("operand_1: %s operand_2: %s", 04639 table_ref_1->alias, table_ref_2->alias)); 04640 04641 *found_using_fields= 0; 04642 arena= thd->activate_stmt_arena_if_needed(&backup); 04643 04644 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) 04645 { 04646 bool found= FALSE; 04647 const char *field_name_1; 04648 if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1))) 04649 goto err; 04650 field_name_1= nj_col_1->name(); 04651 04652 /* 04653 Find a field with the same name in table_ref_2. 04654 04655 Note that for the second loop, it_2.set() will iterate over 04656 table_ref_2->join_columns and not generate any new elements or 04657 lists. 04658 */ 04659 nj_col_2= NULL; 04660 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) 04661 { 04662 Natural_join_column *cur_nj_col_2; 04663 const char *cur_field_name_2; 04664 if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2))) 04665 goto err; 04666 cur_field_name_2= cur_nj_col_2->name(); 04667 04668 /* 04669 Compare the two columns and check for duplicate common fields. 04670 A common field is duplicate either if it was already found in 04671 table_ref_2 (then found == TRUE), or if a field in table_ref_2 04672 was already matched by some previous field in table_ref_1 04673 (then cur_nj_col_2->is_common == TRUE). 04674 */ 04675 if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2)) 04676 { 04677 if (found || cur_nj_col_2->is_common) 04678 { 04679 my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where); 04680 goto err; 04681 } 04682 nj_col_2= cur_nj_col_2; 04683 found= TRUE; 04684 } 04685 } 04686 if (first_outer_loop && leaf_2) 04687 { 04688 /* 04689 Make sure that the next inner loop "knows" that all columns 04690 are materialized already. 04691 */ 04692 leaf_2->is_join_columns_complete= TRUE; 04693 first_outer_loop= FALSE; 04694 } 04695 if (!found) 04696 continue; // No matching field 04697 04698 /* 04699 field_1 and field_2 have the same names. Check if they are in the USING 04700 clause (if present), mark them as common fields, and add a new 04701 equi-join condition to the ON clause. 04702 */ 04703 if (nj_col_2 && 04704 (!using_fields || 04705 test_if_string_in_list(field_name_1, using_fields))) 04706 { 04707 Item *item_1= nj_col_1->create_item(thd); 04708 Item *item_2= nj_col_2->create_item(thd); 04709 Field *field_1= nj_col_1->field(); 04710 Field *field_2= nj_col_2->field(); 04711 Item_ident *item_ident_1, *item_ident_2; 04712 Item_func_eq *eq_cond; 04713 04714 if (!item_1 || !item_2) 04715 goto err; // out of memory 04716 04717 /* 04718 The following assert checks that the two created items are of 04719 type Item_ident. 04720 */ 04721 DBUG_ASSERT(!thd->lex->current_select->no_wrap_view_item); 04722 /* 04723 In the case of no_wrap_view_item == 0, the created items must be 04724 of sub-classes of Item_ident. 04725 */ 04726 DBUG_ASSERT(item_1->type() == Item::FIELD_ITEM || 04727 item_1->type() == Item::REF_ITEM); 04728 DBUG_ASSERT(item_2->type() == Item::FIELD_ITEM || 04729 item_2->type() == Item::REF_ITEM); 04730 04731 /* 04732 We need to cast item_1,2 to Item_ident, because we need to hook name 04733 resolution contexts specific to each item. 04734 */ 04735 item_ident_1= (Item_ident*) item_1; 04736 item_ident_2= (Item_ident*) item_2; 04737 /* 04738 Create and hook special name resolution contexts to each item in the 04739 new join condition . We need this to both speed-up subsequent name 04740 resolution of these items, and to enable proper name resolution of 04741 the items during the execute phase of PS. 04742 */ 04743 if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) || 04744 set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref)) 04745 goto err; 04746 04747 if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2))) 04748 goto err; /* Out of memory. */ 04749 04750 /* 04751 Add the new equi-join condition to the ON clause. Notice that 04752 fix_fields() is applied to all ON conditions in setup_conds() 04753 so we don't do it here. 04754 */ 04755 add_join_on((table_ref_1->outer_join & JOIN_TYPE_RIGHT ? 04756 table_ref_1 : table_ref_2), 04757 eq_cond); 04758 04759 nj_col_1->is_common= nj_col_2->is_common= TRUE; 04760 04761 if (field_1) 04762 { 04763 TABLE *table_1= nj_col_1->table_ref->table; 04764 /* Mark field_1 used for table cache. */ 04765 bitmap_set_bit(table_1->read_set, field_1->field_index); 04766 table_1->used_keys.intersect(field_1->part_of_key); 04767 table_1->merge_keys.merge(field_1->part_of_key); 04768 } 04769 if (field_2) 04770 { 04771 TABLE *table_2= nj_col_2->table_ref->table; 04772 /* Mark field_2 used for table cache. */ 04773 bitmap_set_bit(table_2->read_set, field_2->field_index); 04774 table_2->used_keys.intersect(field_2->part_of_key); 04775 table_2->merge_keys.merge(field_2->part_of_key); 04776 } 04777 04778 if (using_fields != NULL) 04779 ++(*found_using_fields); 04780 } 04781 } 04782 if (leaf_1) 04783 leaf_1->is_join_columns_complete= TRUE; 04784 04785 /* 04786 Everything is OK. 04787 Notice that at this point there may be some column names in the USING 04788 clause that are not among the common columns. This is an SQL error and 04789 we check for this error in store_natural_using_join_columns() when 04790 (found_using_fields < length(join_using_fields)). 04791 */ 04792 result= FALSE; 04793 04794 err: 04795 if (arena) 04796 thd->restore_active_arena(arena, &backup); 04797 DBUG_RETURN(result); 04798 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void mark_real_tables_as_free_for_reuse | ( | TABLE_LIST * | table | ) | [static] |
Definition at line 3258 of file sql_base.cc.
References st_table_list::next_global, st_table_list::placeholder(), st_table::query_id, st_table_list::schema_table, and st_table_list::table.
Referenced by lock_tables().
03259 { 03260 for (; table; table= table->next_global) 03261 if (!table->placeholder() && !table->schema_table) 03262 table->table->query_id= 0; 03263 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void mark_used_tables_as_free_for_reuse | ( | THD * | thd, | |
| TABLE * | table | |||
| ) | [static] |
Definition at line 945 of file sql_base.cc.
References st_table::file, handler::ha_reset(), st_table::next, and st_table::query_id.
Referenced by close_tables_for_reopen(), and close_thread_tables().
00946 { 00947 for (; table ; table= table->next) 00948 { 00949 if (table->query_id == thd->query_id) 00950 { 00951 table->query_id= 0; 00952 table->file->ha_reset(); 00953 } 00954 } 00955 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void mysql_rm_tmp_tables | ( | void | ) | [static] |
Definition at line 6023 of file sql_base.cc.
References bcmp, DBUG_ENTER, st_my_dir::dir_entry, FN_LIBCHAR, FN_REFLEN, st_my_tmpdir::list, st_my_tmpdir::max, my_delete(), my_dir(), MY_DONT_SORT, MY_WME, MYF, mysql_tmpdir_list, fileinfo::name, st_my_dir::number_off_files, tmp_file_prefix, tmp_file_prefix_length, and VOID.
Referenced by table_cache_init().
06024 { 06025 uint i, idx; 06026 char filePath[FN_REFLEN], *tmpdir; 06027 MY_DIR *dirp; 06028 FILEINFO *file; 06029 DBUG_ENTER("mysql_rm_tmp_tables"); 06030 06031 for (i=0; i<=mysql_tmpdir_list.max; i++) 06032 { 06033 tmpdir=mysql_tmpdir_list.list[i]; 06034 /* See if the directory exists */ 06035 if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT)))) 06036 continue; 06037 06038 /* Remove all SQLxxx tables from directory */ 06039 06040 for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++) 06041 { 06042 file=dirp->dir_entry+idx; 06043 06044 /* skiping . and .. */ 06045 if (file->name[0] == '.' && (!file->name[1] || 06046 (file->name[1] == '.' && !file->name[2]))) 06047 continue; 06048 06049 if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) 06050 { 06051 sprintf(filePath,"%s%c%s",tmpdir,FN_LIBCHAR,file->name); 06052 VOID(my_delete(filePath,MYF(MY_WME))); 06053 } 06054 } 06055 my_dirend(dirp); 06056 } 06057 DBUG_VOID_RETURN; 06058 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void mysql_wait_completed_table | ( | ALTER_PARTITION_PARAM_TYPE * | lpt, | |
| TABLE * | my_table | |||
| ) |
Definition at line 6448 of file sql_base.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, FALSE, hash_first(), hash_next(), st_table::in_use, key, key_length, KILL_CONNECTION, LOCK_open, MAX_DBKEY_LENGTH, mysql_lock_abort(), mysql_lock_abort_for_thread(), open_cache, pthread_mutex_lock, pthread_mutex_unlock, relink_unused(), st_table::s, strmov(), st_table_share::version, and VOID.
06449 { 06450 char key[MAX_DBKEY_LENGTH]; 06451 uint key_length; 06452 TABLE *table; 06453 DBUG_ENTER("mysql_wait_completed_table"); 06454 06455 key_length=(uint) (strmov(strmov(key,lpt->db)+1,lpt->table_name)-key)+1; 06456 VOID(pthread_mutex_lock(&LOCK_open)); 06457 HASH_SEARCH_STATE state; 06458 for (table= (TABLE*) hash_first(&open_cache,(byte*) key,key_length, 06459 &state) ; 06460 table; 06461 table= (TABLE*) hash_next(&open_cache,(byte*) key,key_length, 06462 &state)) 06463 { 06464 THD *in_use= table->in_use; 06465 table->s->version= 0L; 06466 if (!in_use) 06467 { 06468 relink_unused(table); 06469 } 06470 else 06471 { 06472 /* Kill delayed insert threads */ 06473 if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && 06474 ! in_use->killed) 06475 { 06476 in_use->killed= THD::KILL_CONNECTION; 06477 pthread_mutex_lock(&in_use->mysys_var->mutex); 06478 if (in_use->mysys_var->current_cond) 06479 { 06480 pthread_mutex_lock(in_use->mysys_var->current_mutex); 06481 pthread_cond_broadcast(in_use->mysys_var->current_cond); 06482 pthread_mutex_unlock(in_use->mysys_var->current_mutex); 06483 } 06484 pthread_mutex_unlock(&in_use->mysys_var->mutex); 06485 } 06486 /* 06487 Now we must abort all tables locks used by this thread 06488 as the thread may be waiting to get a lock for another table 06489 */ 06490 for (TABLE *thd_table= in_use->open_tables; 06491 thd_table ; 06492 thd_table= thd_table->next) 06493 { 06494 if (thd_table->db_stat) // If table is open 06495 mysql_lock_abort_for_thread(lpt->thd, thd_table); 06496 } 06497 } 06498 } 06499 /* 06500 We start by removing all unused objects from the cache and marking 06501 those in use for removal after completion. Now we also need to abort 06502 all that are locked and are not progressing due to being locked 06503 by our lock. We don't upgrade our lock here. 06504 */ 06505 mysql_lock_abort(lpt->thd, my_table, FALSE); 06506 VOID(pthread_mutex_unlock(&LOCK_open)); 06507 DBUG_VOID_RETURN; 06508 }
Here is the call graph for this function:

| bool open_and_lock_tables | ( | THD * | thd, | |
| TABLE_LIST * | tables | |||
| ) |
Definition at line 3189 of file sql_base.cc.
References close_tables_for_reopen(), DBUG_ENTER, DBUG_RETURN, lock_tables, mysql_derived_filling(), mysql_derived_prepare(), mysql_handle_derived(), open_tables(), and TRUE.
Referenced by execute_sqlcom_select(), mysql_admin_table(), mysql_delete(), mysql_execute_command(), mysql_insert(), mysql_load(), mysql_table_grant(), mysql_test_delete(), mysql_test_do_fields(), mysql_test_select(), mysql_test_set_fields(), mysqld_help(), sp_lex_keeper::reset_lex_and_exec_core(), and select_like_stmt_test_with_open_n_lock().
03190 { 03191 uint counter; 03192 bool need_reopen; 03193 DBUG_ENTER("open_and_lock_tables"); 03194 03195 for ( ; ; ) 03196 { 03197 if (open_tables(thd, &tables, &counter, 0)) 03198 DBUG_RETURN(-1); 03199 if (!lock_tables(thd, tables, counter, &need_reopen)) 03200 break; 03201 if (!need_reopen) 03202 DBUG_RETURN(-1); 03203 close_tables_for_reopen(thd, &tables); 03204 } 03205 if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || 03206 (thd->fill_derived_tables() && 03207 mysql_handle_derived(thd->lex, &mysql_derived_filling))) 03208 DBUG_RETURN(TRUE); /* purecov: inspected */ 03209 DBUG_RETURN(0); 03210 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* open_ltable | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| thr_lock_type | lock_type | |||
| ) |
Definition at line 3090 of file sql_base.cc.
References check_lock_and_start_stmt(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, FRMTYPE_TABLE, st_table_list::grant, st_table::grant, st_reginfo::lock_type, st_table_list::lock_type, mysql_lock_tables(), open_table(), st_table::reginfo, st_table_list::required_type, st_table_list::table, TL_UNLOCK, TL_WRITE, and TL_WRITE_ALLOW_READ.
Referenced by change_password(), db_show_routine_status(), handle_delayed_insert(), mysql_admin_table(), mysql_alter_table(), mysql_checksum_table(), mysql_create_like_table(), mysql_discard_or_import_tablespace(), mysql_install_plugin(), mysql_table_dump(), mysql_uninstall_plugin(), and open_proc_table_for_update().
03091 { 03092 TABLE *table; 03093 bool refresh; 03094 DBUG_ENTER("open_ltable"); 03095 03096 thd->proc_info="Opening table"; 03097 thd->current_tablenr= 0; 03098 /* open_ltable can be used only for BASIC TABLEs */ 03099 table_list->required_type= FRMTYPE_TABLE; 03100 while (!(table= open_table(thd, table_list, thd->mem_root, &refresh, 0)) && 03101 refresh) 03102 ; 03103 03104 if (table) 03105 { 03106 #if defined( __WIN__) 03107 /* Win32 can't drop a file that is open */ 03108 if (lock_type == TL_WRITE_ALLOW_READ) 03109 { 03110 lock_type= TL_WRITE; 03111 } 03112 #endif /* __WIN__ */ 03113 table_list->lock_type= lock_type; 03114 table_list->table= table; 03115 table->grant= table_list->grant; 03116 if (thd->locked_tables) 03117 { 03118 if (check_lock_and_start_stmt(thd, table, lock_type)) 03119 table= 0; 03120 } 03121 else 03122 { 03123 DBUG_ASSERT(thd->lock == 0); // You must lock everything at once 03124 if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK) 03125 if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1, 0, 03126 &refresh))) 03127 table= 0; 03128 } 03129 } 03130 thd->proc_info=0; 03131 DBUG_RETURN(table); 03132 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool open_new_frm | ( | THD * | thd, | |
| TABLE_SHARE * | share, | |||
| const char * | alias, | |||
| uint | db_stat, | |||
| uint | prgflag, | |||
| uint | ha_open_flags, | |||
| TABLE * | outparam, | |||
| TABLE_LIST * | table_desc, | |||
| MEM_ROOT * | mem_root | |||
| ) | [static] |
Definition at line 6317 of file sql_base.cc.
References bzero, st_table_share::db, DBUG_ENTER, DBUG_RETURN, ER_FRM_UNKNOWN_TYPE, ER_WRONG_OBJECT, err, FN_REFLEN, FRMTYPE_TABLE, is_equal(), LEX_STRING::length, my_error(), MYF, mysql_make_view(), st_table_share::normalized_path, NullS, OPEN_VIEW_NO_PARSE, parser, st_table_share::path, path, reg_ext, st_table_list::required_type, sql_parse_prepare(), LEX_STRING::str, strxmov(), st_table_share::table_name, and view_type.
Referenced by open_unireg_entry().
06321 { 06322 LEX_STRING pathstr; 06323 File_parser *parser; 06324 char path[FN_REFLEN]; 06325 DBUG_ENTER("open_new_frm"); 06326 06327 /* Create path with extension */ 06328 pathstr.length= (uint) (strxmov(path, share->normalized_path.str, reg_ext, 06329 NullS)- path); 06330 pathstr.str= path; 06331 06332 if ((parser= sql_parse_prepare(&pathstr, mem_root, 1))) 06333 { 06334 if (is_equal(&view_type, parser->type())) 06335 { 06336 if (table_desc == 0 || table_desc->required_type == FRMTYPE_TABLE) 06337 { 06338 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, 06339 "BASE TABLE"); 06340 goto err; 06341 } 06342 if (mysql_make_view(thd, parser, table_desc, 06343 (prgflag & OPEN_VIEW_NO_PARSE))) 06344 goto err; 06345 } 06346 else 06347 { 06348 /* only VIEWs are supported now */ 06349 my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path, parser->type()->str); 06350 goto err; 06351 } 06352 DBUG_RETURN(0); 06353 } 06354 06355 err: 06356 bzero(outparam, sizeof(TABLE)); // do not run repair 06357 DBUG_RETURN(1); 06358 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool open_normal_and_derived_tables | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| uint | flags | |||
| ) |
Definition at line 3233 of file sql_base.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, mysql_derived_prepare(), mysql_handle_derived(), open_tables(), and TRUE.
Referenced by get_all_tables(), mysql_test_insert(), mysqld_list_fields(), and mysqld_show_create().
03234 { 03235 uint counter; 03236 DBUG_ENTER("open_normal_and_derived_tables"); 03237 DBUG_ASSERT(!thd->fill_derived_tables()); 03238 if (open_tables(thd, &tables, &counter, flags) || 03239 mysql_handle_derived(thd->lex, &mysql_derived_prepare)) 03240 DBUG_RETURN(TRUE); /* purecov: inspected */ 03241 DBUG_RETURN(0); 03242 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* open_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| MEM_ROOT * | mem_root, | |||
| bool * | refresh, | |||
| uint | flags | |||
| ) |
Definition at line 1809 of file sql_base.cc.
References st_table_list::alias, build_table_filename(), check_stack_overrun(), check_unused, close_old_data_files(), COND_refresh, create_table_def_key(), st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_CANT_REOPEN_TABLE, ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, ER_TABLE_NOT_LOCKED, error, FN_REFLEN, FRMTYPE_VIEW, hash_delete(), hash_first(), hash_next(), st_table::in_use, int(), key, key_length, LOCK_open, st_table_list::lock_type, MAX_DBKEY_LENGTH, memcmp(), memcpy, my_error(), my_free, my_hash_insert(), my_malloc(), my_realloc(), my_strcasecmp, MY_WME, MYF, mysql_frm_type(), mysql_ha_flush(), st_table::next, NO_TMP_TABLE, NULL, open_cache, open_unireg_entry(), OPEN_VIEW_NO_PARSE, path, st_table::prev, pthread_mutex_lock, pthread_mutex_unlock, st_table::query_id, st_hash::records, refresh_version, reg1, reg_ext, st_table_list::skip_temporary, STACK_MIN_SIZE_FOR_OPEN, STATUS_NO_RECORD, strcmp(), strlen(), system_charset_info, table_alias_charset, table_cache_size, st_table_list::table_name, TL_READ, TL_WRITE_ALLOW_WRITE, TRUE, unused_tables, st_table_list::updatable, st_table_list::view, VOID, and wait_for_condition().
Referenced by ha_myisammrg::append_create_info(), create_table_from_items(), fill_defined_view_parts(), open_ltable(), open_proc_table_for_read(), ha_myisammrg::store_lock(), and ha_myisammrg::update_create_info().
01811 { 01812 reg1 TABLE *table; 01813 char key[MAX_DBKEY_LENGTH]; 01814 uint key_length; 01815 char *alias= table_list->alias; 01816 HASH_SEARCH_STATE state; 01817 DBUG_ENTER("open_table"); 01818 01819 /* find a unused table in the open table cache */ 01820 if (refresh) 01821 *refresh=0; 01822 01823 /* an open table operation needs a lot of the stack space */ 01824 if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (char *)&alias)) 01825 DBUG_RETURN(0); 01826 01827 if (thd->killed) 01828 DBUG_RETURN(0); 01829 01830 key_length= (create_table_def_key(thd, key, table_list, 1) - 01831 TMP_TABLE_KEY_EXTRA); 01832 01833 if (!table_list->skip_temporary) 01834 { 01835 for (table= thd->temporary_tables; table ; table=table->next) 01836 { 01837 if (table->s->table_cache_key.length == key_length + 01838 TMP_TABLE_KEY_EXTRA && 01839 !memcmp(table->s->table_cache_key.str, key, 01840 key_length + TMP_TABLE_KEY_EXTRA)) 01841 { 01842 if (table->query_id == thd->query_id || 01843 thd->prelocked_mode && table->query_id) 01844 { 01845 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); 01846 DBUG_RETURN(0); 01847 } 01848 table->query_id= thd->query_id; 01849 table->clear_query_id= 1; 01850 thd->tmp_table_used= 1; 01851 DBUG_PRINT("info",("Using temporary table")); 01852 goto reset; 01853 } 01854 } 01855 } 01856 01857 if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) && 01858 (thd->locked_tables || thd->prelocked_mode)) 01859 { // Using table locks 01860 TABLE *best_table= 0; 01861 int best_distance= INT_MIN; 01862 bool check_if_used= thd->prelocked_mode && 01863 ((int) table_list->lock_type >= 01864 (int) TL_WRITE_ALLOW_WRITE); 01865 for (table=thd->open_tables; table ; table=table->next) 01866 { 01867 if (table->s->table_cache_key.length == key_length && 01868 !memcmp(table->s->table_cache_key.str, key, key_length)) 01869 { 01870 if (check_if_used && table->query_id && 01871 table->query_id != thd->query_id) 01872 { 01873 /* 01874 If we are in stored function or trigger we should ensure that 01875 we won't change table that is already used by calling statement. 01876 So if we are opening table for writing, we should check that it 01877 is not already open by some calling stamement. 01878 */ 01879 my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0), 01880 table->s->table_name.str); 01881 DBUG_RETURN(0); 01882 } 01883 if (!my_strcasecmp(system_charset_info, table->alias, alias) && 01884 table->query_id != thd->query_id && /* skip tables already used */ 01885 !(thd->prelocked_mode && table->query_id)) 01886 { 01887 int distance= ((int) table->reginfo.lock_type - 01888 (int) table_list->lock_type); 01889 /* 01890 Find a table that either has the exact lock type requested, 01891 or has the best suitable lock. In case there is no locked 01892 table that has an equal or higher lock than requested, 01893 we us the closest matching lock to be able to produce an error 01894 message about wrong lock mode on the table. The best_table 01895 is changed if bd < 0 <= d or bd < d < 0 or 0 <= d < bd. 01896 01897 distance < 0 - No suitable lock found 01898 distance > 0 - we have lock mode higher then we require 01899 distance == 0 - we have lock mode exactly which we need 01900 */ 01901 if (best_distance < 0 && distance > best_distance || 01902 distance >= 0 && distance < best_distance) 01903 { 01904 best_distance= distance; 01905 best_table= table; 01906 if (best_distance == 0 && !check_if_used) 01907 { 01908 /* 01909 If we have found perfect match and we don't need to check that 01910 table is not used by one of calling statements (assuming that 01911 we are inside of function or trigger) we can finish iterating 01912 through open tables list. 01913 */ 01914 break; 01915 } 01916 } 01917 } 01918 } 01919 } 01920 if (best_table) 01921 { 01922 table= best_table; 01923 table->query_id= thd->query_id; 01924 DBUG_PRINT("info",("Using locked table")); 01925 goto reset; 01926 } 01927 /* 01928 is it view? 01929 (it is work around to allow to open view with locked tables, 01930 real fix will be made after definition cache will be made) 01931 */ 01932 { 01933 char path[FN_REFLEN]; 01934 enum legacy_db_type not_used; 01935 build_table_filename(path, sizeof(path) - 1, 01936 table_list->db, table_list->table_name, reg_ext, 0); 01937 if (mysql_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) 01938 { 01939 /* 01940 Will not be used (because it's VIEW) but has to be passed. 01941 Also we will not free it (because it is a stack variable). 01942 */ 01943 TABLE tab; 01944 table= &tab; 01945 VOID(pthread_mutex_lock(&LOCK_open)); 01946 if (!open_unireg_entry(thd, table, table_list, alias, 01947 key, key_length, mem_root, 0)) 01948 { 01949 DBUG_ASSERT(table_list->view != 0); 01950 VOID(pthread_mutex_unlock(&LOCK_open)); 01951 DBUG_RETURN(0); // VIEW 01952 } 01953 VOID(pthread_mutex_unlock(&LOCK_open)); 01954 } 01955 } 01956 my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); 01957 DBUG_RETURN(0); 01958 } 01959 01960 VOID(pthread_mutex_lock(&LOCK_open)); 01961 01962 if (!thd->open_tables) 01963 thd->version=refresh_version; 01964 else if ((thd->version != refresh_version) && 01965 ! (flags & MYSQL_LOCK_IGNORE_FLUSH)) 01966 { 01967 /* Someone did a refresh while thread was opening tables */ 01968 if (refresh) 01969 *refresh=1; 01970 VOID(pthread_mutex_unlock(&LOCK_open)); 01971 DBUG_RETURN(0); 01972 } 01973 01974 /* close handler tables which are marked for flush */ 01975 if (thd->handler_tables) 01976 mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); 01977 01978 for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, 01979 &state); 01980 table && table->in_use ; 01981 table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, 01982 &state)) 01983 { 01984 /* 01985 Here we flush tables marked for flush. However we never flush log 01986 tables here. They are flushed only on FLUSH LOGS. 01987 */ 01988 if (table->s->version != refresh_version && !table->s->log_table) 01989 { 01990 DBUG_PRINT("note", 01991 ("Found table '%s.%s' with different refresh version", 01992 table_list->db, table_list->table_name)); 01993 01994 if (flags & MYSQL_LOCK_IGNORE_FLUSH) 01995 { 01996 /* Force close at once after usage */ 01997 thd->version= table->s->version; 01998 continue; 01999 } 02000 02001 /* 02002 There is a refresh in progress for this table 02003 Wait until the table is freed or the thread is killed. 02004 */ 02005 close_old_data_files(thd,thd->open_tables,0,0); 02006 if (table->in_use != thd) 02007 wait_for_condition(thd, &LOCK_open, &COND_refresh); 02008 else 02009 { 02010 VOID(pthread_mutex_unlock(&LOCK_open)); 02011 } 02012 if (refresh) 02013 *refresh=1; 02014 DBUG_RETURN(0); 02015 } 02016 } 02017 if (table) 02018 { 02019 if (table == unused_tables) 02020 { // First unused 02021 unused_tables=unused_tables->next; // Remove from link 02022 if (table == unused_tables) 02023 unused_tables=0; 02024 } 02025 table->prev->next=table->next; /* Remove from unused list */ 02026 table->next->prev=table->prev; 02027 table->in_use= thd; 02028 } 02029 else 02030 { 02031 int error; 02032 /* Free cache if too big */ 02033 while (open_cache.records > table_cache_size && unused_tables) 02034 VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ 02035 02036 /* make a new table */ 02037 if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME)))) 02038 { 02039 VOID(pthread_mutex_unlock(&LOCK_open)); 02040 DBUG_RETURN(NULL); 02041 } 02042 02043 error= open_unireg_entry(thd, table, table_list, alias, key, key_length, 02044 mem_root, (flags & OPEN_VIEW_NO_PARSE)); 02045 if (error > 0) 02046 { 02047 my_free((gptr)table, MYF(0)); 02048 VOID(pthread_mutex_unlock(&LOCK_open)); 02049 DBUG_RETURN(NULL); 02050 } 02051 if (table_list->view || error < 0) 02052 { 02053 /* 02054 VIEW not really opened, only frm were read. 02055 Set 1 as a flag here 02056 */ 02057 if (error < 0) 02058 table_list->view= (st_lex*)1; 02059 02060 my_free((gptr)table, MYF(0)); 02061 VOID(pthread_mutex_unlock(&LOCK_open)); 02062 DBUG_RETURN(0); // VIEW 02063 } 02064 DBUG_PRINT("info", ("inserting table %p into the cache", table)); 02065 VOID(my_hash_insert(&open_cache,(byte*) table)); 02066 } 02067 02068 check_unused(); // Debugging call 02069 02070 VOID(pthread_mutex_unlock(&LOCK_open)); 02071 if (refresh) 02072 { 02073 table->next=thd->open_tables; /* Link into simple list */ 02074 thd->open_tables=table; 02075 } 02076 table->reginfo.lock_type=TL_READ; /* Assume read */ 02077 02078 reset: 02079 DBUG_ASSERT(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE); 02080 02081 if (thd->lex->need_correct_ident()) 02082 table->alias_name_used= my_strcasecmp(table_alias_charset, 02083 table->s->table_name.str, alias); 02084 /* Fix alias if table name changes */ 02085 if (strcmp(table->alias, alias)) 02086 { 02087 uint length=(uint) strlen(alias)+1; 02088 table->alias= (char*) my_realloc((char*) table->alias, length, 02089 MYF(MY_WME)); 02090 memcpy((char*) table->alias, alias, length); 02091 } 02092 /* These variables are also set in reopen_table() */ 02093 table->tablenr=thd->current_tablenr++; 02094 table->used_fields=0; 02095 table->const_table=0; 02096 table->null_row= table->maybe_null= table->force_index= 0; 02097 table->status=STATUS_NO_RECORD; 02098 table->keys_in_use_for_query= table->s->keys_in_use; 02099 table->insert_values= 0; 02100 table->used_keys= table->s->keys_for_keyread; 02101 table->fulltext_searched= 0; 02102 table->file->ft_handler= 0; 02103 if (table->timestamp_field) 02104 table->timestamp_field_type= table->timestamp_field->get_auto_set_type(); 02105 table_list->updatable= 1; // It is not derived table nor non-updatable VIEW 02106 table->clear_column_bitmaps(); 02107 DBUG_ASSERT(table->key_read == 0); 02108 DBUG_RETURN(table); 02109 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int open_tables | ( | THD * | thd, | |
| TABLE_LIST ** | start, | |||
| uint * | counter, | |||
| uint | flags | |||
| ) |
Definition at line 2830 of file sql_base.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_table_list::derived, err, init_alloc_root(), mysql_schema_table(), st_table_list::next_global, st_table_list::schema_table, sp_cache_routines_and_add_tables(), sp_get_prelocking_info(), start(), and st_table_list::view.
Referenced by mysql_ha_open(), mysql_multi_update_prepare(), mysql_test_update(), mysql_update(), open_and_lock_tables(), open_normal_and_derived_tables(), and simple_open_n_lock_tables().
02831 { 02832 TABLE_LIST *tables; 02833 bool refresh; 02834 int result=0; 02835 MEM_ROOT new_frm_mem; 02836 /* Also used for indicating that prelocking is need */ 02837 TABLE_LIST **query_tables_last_own; 02838 DBUG_ENTER("open_tables"); 02839 /* 02840 temporary mem_root for new .frm parsing. 02841 TODO: variables for size 02842 */ 02843 init_alloc_root(&new_frm_mem, 8024, 8024); 02844 02845 thd->current_tablenr= 0; 02846 restart: 02847 *counter= 0; 02848 query_tables_last_own= 0; 02849 thd->proc_info="Opening tables"; 02850 02851 /* 02852 If we are not already executing prelocked statement and don't have 02853 statement for which table list for prelocking is already built, let 02854 us cache routines and try to build such table list. 02855 02856 */ 02857 02858 if (!thd->prelocked_mode && !thd->lex->requires_prelocking() && 02859 thd->lex->sroutines_list.elements) 02860 { 02861 bool first_no_prelocking, need_prelocking; 02862 TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last; 02863 02864 DBUG_ASSERT(thd->lex->query_tables == *start); 02865 sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking); 02866 02867 if (sp_cache_routines_and_add_tables(thd, thd->lex, first_no_prelocking)) 02868 { 02869 /* 02870 Serious error during reading stored routines from mysql.proc table. 02871 Something's wrong with the table or its contents, and an error has 02872 been emitted; we must abort. 02873 */ 02874 result= -1; 02875 goto err; 02876 } 02877 else if (need_prelocking) 02878 { 02879 query_tables_last_own= save_query_tables_last; 02880 *start= thd->lex->query_tables; 02881 } 02882 } 02883 02884 for (tables= *start; tables ;tables= tables->next_global) 02885 { 02886 /* 02887 Ignore placeholders for derived tables. After derived tables 02888 processing, link to created temporary table will be put here. 02889 If this is derived table for view then we still want to process 02890 routines used by this view. 02891 */ 02892 if (tables->derived) 02893 { 02894 if (tables->view) 02895 goto process_view_routines; 02896 continue; 02897 } 02898 if (tables->schema_table) 02899 { 02900 if (!mysql_schema_table(thd, thd->lex, tables)) 02901 continue; 02902 DBUG_RETURN(-1); 02903 } 02904 (*counter)++; 02905 02906 if (!tables->table && 02907 !(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags))) 02908 { 02909 free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC)); 02910 02911 if (tables->view) 02912 { 02913 /* VIEW placeholder */ 02914 (*counter)--; 02915 02916 /* 02917 tables->next_global list consists of two parts: 02918 1) Query tables and underlying tables of views. 02919 2) Tables used by all stored routines that this statement invokes on 02920 execution. 02921 We need to know where the bound between these two parts is. If we've 02922 just opened a view, which was the last table in part #1, and it 02923 has added its base tables after itself, adjust the boundary pointer 02924 accordingly. 02925 */ 02926 if (query_tables_last_own == &(tables->next_global) && 02927 tables->view->query_tables) 02928 query_tables_last_own= tables->view->query_tables_last; 02929 /* 02930 Let us free memory used by 'sroutines' hash here since we never 02931 call destructor for this LEX. 02932 */ 02933 hash_free(&tables->view->sroutines); 02934 goto process_view_routines; 02935 } 02936 02937 if (refresh) // Refresh in progress 02938 { 02939 /* 02940 We have met name-locked or old version of table. Now we have 02941 to close all tables which are not up to date. We also have to 02942 throw away set of prelocked tables (and thus close tables from 02943 this set that were open by now) since it possible that one of 02944 tables which determined its content was changed. 02945 02946 Instead of implementing complex/non-robust logic mentioned 02947 above we simply close and then reopen all tables. 02948 02949 In order to prepare for recalculation of set of prelocked tables 02950 we pretend that we have finished calculation which we were doing 02951 currently. 02952 */ 02953 if (query_tables_last_own) 02954 thd->lex->mark_as_requiring_prelocking(query_tables_last_own); 02955 close_tables_for_reopen(thd, start); 02956 goto restart; 02957 } 02958 result= -1; // Fatal error 02959 break; 02960 } 02961 else 02962 { 02963 /* 02964 If we are not already in prelocked mode and extended table list is not 02965 yet built and we have trigger for table being opened then we should 02966 cache all routines used by its triggers and add their tables to 02967 prelocking list. 02968 If we lock table for reading we won't update it so there is no need to 02969 process its triggers since they never will be activated. 02970 */ 02971 if (!thd->prelocked_mode && !thd->lex->requires_prelocking() && 02972 tables->table->triggers && 02973 tables->lock_type >= TL_WRITE_ALLOW_WRITE) 02974 { 02975 if (!query_tables_last_own) 02976 query_tables_last_own= thd->lex->query_tables_last; 02977 if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex, 02978 tables)) 02979 { 02980 /* 02981 Serious error during reading stored routines from mysql.proc table. 02982 Something's wrong with the table or its contents, and an error has 02983 been emitted; we must abort. 02984 */ 02985 result= -1; 02986 goto err; 02987 } 02988 } 02989 free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC)); 02990 } 02991 02992 if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables) 02993 tables->table->reginfo.lock_type=tables->lock_type; 02994 tables->table->grant= tables->grant; 02995 02996 process_view_routines: 02997 /* 02998 Again we may need cache all routines used by this view and add 02999 tables used by them to table list. 03000 */ 03001 if (tables->view && !thd->prelocked_mode && 03002 !thd->lex->requires_prelocking() && 03003 tables->view->sroutines_list.elements) 03004 { 03005 /* We have at least one table in TL here. */ 03006 if (!query_tables_last_own) 03007 query_tables_last_own= thd->lex->query_tables_last; 03008 if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables)) 03009 { 03010 /* 03011 Serious error during reading stored routines from mysql.proc table. 03012 Something's wrong with the table or its contents, and an error has 03013 been emitted; we must abort. 03014 */ 03015 result= -1; 03016 goto err; 03017 } 03018 } 03019 } 03020 03021 err: 03022 thd->proc_info=0; 03023 free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block 03024 03025 if (query_tables_last_own) 03026 thd->lex->mark_as_requiring_prelocking(query_tables_last_own); 03027 03028 DBUG_RETURN(result); 03029 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* open_temporary_table | ( | THD * | thd, | |
| const char * | path, | |||
| const char * | db, | |||
| const char * | table_name, | |||
| bool | link_in_list | |||
| ) |
Definition at line 3489 of file sql_base.cc.
References COMPUTE_TYPES, create_table_def_key(), st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, EXTRA_RECORD, FALSE, free_table_share(), HA_GET_INDEX, HA_OPEN_KEYFILE, ha_open_options, HA_OPEN_RNDFILE, init_tmp_table_share(), key_length, MAX_DBKEY_LENGTH, memcpy, my_free, my_malloc(), MY_WME, MYF, open_table_def(), open_table_from_share(), READ_KEYINFO, slave_open_temp_tables, strend(), strlen(), strmov(), st_table_list::table_name, TL_WRITE, TMP_TABLE, and TRANSACTIONAL_TMP_TABLE.
Referenced by mysql_create_like_table(), mysql_create_table_internal(), and mysql_truncate().
03491 { 03492 TABLE *tmp_table; 03493 TABLE_SHARE *share; 03494 char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path; 03495 uint key_length; 03496 TABLE_LIST table_list; 03497 DBUG_ENTER("open_temporary_table"); 03498 DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", 03499 db, table_name, path)); 03500 03501 table_list.db= (char*) db; 03502 table_list.table_name= (char*) table_name; 03503 /* Create the cache_key for temporary tables */ 03504 key_length= create_table_def_key(thd, cache_key, &table_list, 1); 03505 03506 if (!(tmp_table= (TABLE*) my_malloc(sizeof(*tmp_table) + sizeof(*share) + 03507 strlen(path)+1 + key_length, 03508 MYF(MY_WME)))) 03509 DBUG_RETURN(0); /* purecov: inspected */ 03510 03511 share= (TABLE_SHARE*) (tmp_table+1); 03512 tmp_path= (char*) (share+1); 03513 saved_cache_key= strmov(tmp_path, path)+1; 03514 memcpy(saved_cache_key, cache_key, key_length); 03515 03516 init_tmp_table_share(share, saved_cache_key, key_length, 03517 strend(saved_cache_key)+1, tmp_path); 03518 03519 if (open_table_def(thd, share, 0) || 03520 open_table_from_share(thd, share, table_name, 03521 (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | 03522 HA_GET_INDEX), 03523 READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, 03524 ha_open_options, 03525 tmp_table, FALSE)) 03526 { 03527 /* No need to lock share->mutex as this is not needed for tmp tables */ 03528 free_table_share(share); 03529 my_free((char*) tmp_table,MYF(0)); 03530 DBUG_RETURN(0); 03531 } 03532 03533 tmp_table->reginfo.lock_type= TL_WRITE; // Simulate locked 03534 share->tmp_table= (tmp_table->file->has_transactions() ? 03535 TRANSACTIONAL_TMP_TABLE : TMP_TABLE); 03536 03537 if (link_in_list) 03538 { 03539 /* growing temp list at the head */ 03540 tmp_table->next= thd->temporary_tables; 03541 if (tmp_table->next) 03542 tmp_table->next->prev= tmp_table; 03543 thd->temporary_tables= tmp_table; 03544 thd->temporary_tables->prev= 0; 03545 if (thd->slave_thread) 03546 slave_open_temp_tables++; 03547 } 03548 DBUG_RETURN(tmp_table); 03549 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int open_unireg_entry | ( | THD * | thd, | |
| TABLE * | entry, | |||
| TABLE_LIST * | table_list, | |||
| const char * | alias, | |||
| char * | cache_key, | |||
| uint | cache_key_length, | |||
| MEM_ROOT * | mem_root, | |||
| uint | flags | |||
| ) | [static] |
Definition at line 2624 of file sql_base.cc.
References Table_triggers_list::check_n_load(), closefrm(), COMPUTE_TYPES, st_table_share::db, st_table_list::db, DBUG_ENTER, DBUG_RETURN, ER_NOT_KEYFILE, err, error, EXTRA_RECORD, FALSE, get_table_share_with_create(), ha_create_table_from_engine(), HA_GET_INDEX, HA_OPEN_FOR_REPAIR, HA_OPEN_KEYFILE, ha_open_options, HA_OPEN_RNDFILE, HA_TRY_READ_ONLY, int(), MYSQL_LOG::is_open(), st_table_share::is_view, LEX_STRING::length, LOCK_open, lock_table_name(), my_errno, my_error(), my_free, my_malloc(), MY_WME, MYF, mysql_bin_log, mysql_reset_errors(), NullS, open_new_frm(), open_table_from_share(), OPEN_VIEW, OPEN_VIEW_NO_PARSE, pthread_mutex_lock, pthread_mutex_unlock, READ_KEYINFO, st_table_share::ref_count, RELEASE_NORMAL, release_table_share(), RELEASE_WAIT_FOR_DROP, safe_mutex_assert_owner, sql_print_error(), LEX_STRING::str, strmov(), strxmov(), st_table_share::table_name, st_table_list::table_name, TRUE, unlikely, unlock_table_name(), st_table_share::version, and wait_for_locked_table_names().
Referenced by open_table(), reopen_name_locked_table(), and reopen_table().
02628 { 02629 int error; 02630 TABLE_SHARE *share; 02631 uint discover_retry_count= 0; 02632 DBUG_ENTER("open_unireg_entry"); 02633 02634 safe_mutex_assert_owner(&LOCK_open); 02635 02636 retry: 02637 if (!(share= get_table_share_with_create(thd, table_list, cache_key, 02638 cache_key_length, 02639 OPEN_VIEW, &error))) 02640 DBUG_RETURN(1); 02641 02642 if (share->is_view) 02643 { 02644 /* Open view */ 02645 error= (int) open_new_frm(thd, share, alias, 02646 (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | 02647 HA_GET_INDEX | HA_TRY_READ_ONLY), 02648 READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | 02649 (flags & OPEN_VIEW_NO_PARSE), 02650 thd->open_options, entry, table_list, 02651 mem_root); 02652 if (error) 02653 goto err; 02654 /* TODO: Don't free this */ 02655 release_table_share(share, RELEASE_NORMAL); 02656 DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0); 02657 } 02658 02659 while ((error= open_table_from_share(thd, share, alias, 02660 (uint) (HA_OPEN_KEYFILE | 02661 HA_OPEN_RNDFILE | 02662 HA_GET_INDEX | 02663 HA_TRY_READ_ONLY), 02664 (READ_KEYINFO | COMPUTE_TYPES | 02665 EXTRA_RECORD), 02666 thd->open_options, entry, FALSE))) 02667 { 02668 if (error == 7) // Table def changed 02669 { 02670 share->version= 0; // Mark share as old 02671 if (discover_retry_count++) // Retry once 02672 goto err; 02673 02674 /* 02675 TODO: 02676 Here we should wait until all threads has released the table. 02677 For now we do one retry. This may cause a deadlock if there 02678 is other threads waiting for other tables used by this thread. 02679 02680 Proper fix would be to if the second retry failed: 02681 - Mark that table def changed 02682 - Return from open table 02683 - Close all tables used by this thread 02684 - Start waiting that the share is released 02685 - Retry by opening all tables again 02686 */ 02687 if (ha_create_table_from_engine(thd, table_list->db, 02688 table_list->table_name)) 02689 goto err; 02690 /* 02691 TO BE FIXED 02692 To avoid deadlock, only wait for release if no one else is 02693 using the share. 02694 */ 02695 if (share->ref_count != 1) 02696 goto err; 02697 /* Free share and wait until it's released by all threads */ 02698 release_table_share(share, RELEASE_WAIT_FOR_DROP); 02699 if (!thd->killed) 02700 { 02701 mysql_reset_errors(thd, 1); // Clear warnings 02702 thd->clear_error(); // Clear error message 02703 goto retry; 02704 } 02705 DBUG_RETURN(1); 02706 } 02707 if (!entry->s || !entry->s->crashed) 02708 goto err; 02709 // Code below is for repairing a crashed file 02710 if ((error= lock_table_name(thd, table_list, TRUE))) 02711 { 02712 if (error < 0) 02713 goto err; 02714 if (wait_for_locked_table_names(thd, table_list)) 02715 { 02716 unlock_table_name(thd, table_list); 02717 goto err; 02718 } 02719 } 02720 pthread_mutex_unlock(&LOCK_open); 02721 thd->clear_error(); // Clear error message 02722 error= 0; 02723 if (open_table_from_share(thd, share, alias, 02724 (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | 02725 HA_GET_INDEX | 02726 HA_TRY_READ_ONLY), 02727 READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, 02728 ha_open_options | HA_OPEN_FOR_REPAIR, 02729 entry, FALSE) || ! entry->file || 02730 (entry->file->is_crashed() && entry->file->check_and_repair(thd))) 02731 { 02732 /* Give right error message */ 02733 thd->clear_error(); 02734 my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno); 02735 sql_print_error("Couldn't repair table: %s.%s", share->db.str, 02736 share->table_name.str); 02737 if (entry->file) 02738 closefrm(entry, 0); 02739 error=1; 02740 } 02741 else 02742 thd->clear_error(); // Clear error message 02743 pthread_mutex_lock(&LOCK_open); 02744 unlock_table_name(thd, table_list); 02745 02746 if (error) 02747 goto err; 02748 break; 02749 } 02750 02751 if (Table_triggers_list::check_n_load(thd, share->db.str, 02752 share->table_name.str, entry, 0)) 02753 { 02754 closefrm(entry, 0); 02755 goto err; 02756 } 02757 02758 /* 02759 If we are here, there was no fatal error (but error may be still 02760 unitialized). 02761 */ 02762 if (unlikely(entry->file->implicit_emptied)) 02763 { 02764 entry->file->implicit_emptied= 0; 02765 if (mysql_bin_log.is_open()) 02766 { 02767 char *query, *end; 02768 uint query_buf_size= 20 + share->db.length + share->table_name.length +1; 02769 if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME)))) 02770 { 02771 /* this DELETE FROM is needed even with row-based binlogging */ 02772 end = strxmov(strmov(query, "DELETE FROM `"), 02773 share->db.str,"`.`",share->table_name.str,"`", NullS); 02774 thd->binlog_query(THD::STMT_QUERY_TYPE, 02775 query, (ulong)(end-query), FALSE, FALSE); 02776 my_free(query, MYF(0)); 02777 } 02778 else 02779 { 02780 /* 02781 As replication is maybe going to be corrupted, we need to warn the 02782 DBA on top of warning the client (which will automatically be done 02783 because of MYF(MY_WME) in my_malloc() above). 02784 */ 02785 sql_print_error("When opening HEAP table, could not allocate memory " 02786 "to write 'DELETE FROM `%s`.`%s`' to the binary log", 02787 table_list->db, table_list->table_name); 02788 delete entry->triggers; 02789 closefrm(entry, 0); 02790 goto err; 02791 } 02792 } 02793 } 02794 DBUG_RETURN(0); 02795 02796 err: 02797 release_table_share(share, RELEASE_NORMAL); 02798 DBUG_RETURN(1); 02799 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void release_table_share | ( | TABLE_SHARE * | share, | |
| enum release_type | type | |||
| ) |
Definition at line 502 of file sql_base.cc.
References st_table_share::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, end_of_unused_share, free_table_share(), hash_delete(), hash_replace(), hash_search(), key, key_length, LOCK_open, LOCK_table_share, st_table_share::next, st_table_share::prev, pthread_mutex_lock, pthread_mutex_unlock, st_hash::records, refresh_version, RELEASE_WAIT_FOR_DROP, safe_mutex_assert_owner, LEX_STRING::str, table_def_cache, and table_def_size.
Referenced by close_handle_and_leave_table_as_lock(), closefrm(), mysql_drop_view(), open_unireg_entry(), and prepare_for_repair().
00503 { 00504 bool to_be_deleted= 0; 00505 DBUG_ENTER("release_table_share"); 00506 DBUG_PRINT("enter", 00507 ("share: 0x%lx table: %s.%s ref_count: %u version: %lu", 00508 (ulong) share, share->db.str, share->table_name.str, 00509 share->ref_count, share->version)); 00510 00511 safe_mutex_assert_owner(&LOCK_open); 00512 00513 pthread_mutex_lock(&share->mutex); 00514 if (!--share->ref_count) 00515 { 00516 if (share->version != refresh_version) 00517 to_be_deleted=1; 00518 else 00519 { 00520 /* Link share last in used_table_share list */ 00521 DBUG_PRINT("info",("moving share to unused list")); 00522 00523 DBUG_ASSERT(share->next == 0); 00524 pthread_mutex_lock(&LOCK_table_share); 00525 share->prev= end_of_unused_share.prev; 00526 *end_of_unused_share.prev= share; 00527 end_of_unused_share.prev= &share->next; 00528 share->next= &end_of_unused_share; 00529 pthread_mutex_unlock(&LOCK_table_share); 00530 00531 to_be_deleted= (table_def_cache.records > table_def_size); 00532 } 00533 } 00534 00535 if (to_be_deleted) 00536 { 00537 DBUG_PRINT("info", ("Deleting share")); 00538 hash_delete(&table_def_cache, (byte*) share); 00539 DBUG_VOID_RETURN; 00540 } 00541 pthread_mutex_unlock(&share->mutex); 00542 DBUG_VOID_RETURN; 00543 00544 00545 #ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 00546 if (to_be_deleted) 00547 { 00548 /* 00549 We must try again with new locks as we must get LOCK_open 00550 before share->mutex 00551 */ 00552 pthread_mutex_unlock(&share->mutex); 00553 pthread_mutex_lock(&LOCK_open); 00554 pthread_mutex_lock(&share->mutex); 00555 if (!share->ref_count) 00556 { // No one is using this now 00557 TABLE_SHARE *name_lock; 00558 if (share->replace_with_name_lock && (name_lock=get_name_lock(share))) 00559 { 00560 /* 00561 This code is execured when someone does FLUSH TABLES while on has 00562 locked tables. 00563 */ 00564 (void) hash_search(&def_cache,(byte*) key,key_length); 00565 hash_replace(&def_cache, def_cache.current_record,(byte*) name_lock); 00566 } 00567 else 00568 { 00569 /* Remove table definition */ 00570 hash_delete(&def_cache,(byte*) share); 00571 } 00572 pthread_mutex_unlock(&LOCK_open); 00573 free_table_share(share); 00574 } 00575 else 00576 { 00577 pthread_mutex_unlock(&LOCK_open); 00578 if (type == RELEASE_WAIT_FOR_DROP) 00579 wait_for_table(share, "Waiting for close"); 00580 else 00581 pthread_mutex_unlock(&share->mutex); 00582 } 00583 } 00584 else if (type == RELEASE_WAIT_FOR_DROP) 00585 wait_for_table(share, "Waiting for close"); 00586 else 00587 pthread_mutex_unlock(&share->mutex); 00588 #endif 00589 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void relink_unused | ( | TABLE * | table | ) | [static] |
Definition at line 1619 of file sql_base.cc.
References check_unused, st_table::next, st_table::prev, and unused_tables.
Referenced by mysql_wait_completed_table(), remove_db_from_cache(), and remove_table_from_cache().
01620 { 01621 if (table != unused_tables) 01622 { 01623 table->prev->next=table->next; /* Remove from unused list */ 01624 table->next->prev=table->prev; 01625 table->next=unused_tables; /* Link in unused tables */ 01626 table->prev=unused_tables->prev; 01627 unused_tables->prev->next=table; 01628 unused_tables->prev=table; 01629 unused_tables=table; 01630 check_unused(); 01631 } 01632 }
Here is the caller graph for this function:

| void remove_db_from_cache | ( | const char * | db | ) |
Definition at line 6079 of file sql_base.cc.
References hash_element(), open_cache, st_hash::records, relink_unused(), and strcmp().
Referenced by mysql_rm_db().
06080 { 06081 for (uint idx=0 ; idx < open_cache.records ; idx++) 06082 { 06083 TABLE *table=(TABLE*) hash_element(&open_cache,idx); 06084 if (!strcmp(table->s->db.str, db)) 06085 { 06086 table->s->version= 0L; /* Free when thread is ready */ 06087 if (!table->in_use) 06088 relink_unused(table); 06089 } 06090 } 06091 while (unused_tables && !unused_tables->s->version) 06092 VOID(hash_delete(&open_cache,(byte*) unused_tables)); 06093 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6128 of file sql_base.cc.
References broadcast_refresh(), COND_refresh, st_table::db_stat, DBUG_ENTER, DBUG_PRINT, dropping_tables, hash_delete(), hash_first(), hash_next(), hash_search(), st_table::in_use, key, key_length, KILL_CONNECTION, likely, LOCK_open, MAX_DBKEY_LENGTH, st_table_share::mutex, mysql_lock_abort_for_thread(), open_cache, pthread_mutex_lock, pthread_mutex_unlock, st_table_share::ref_count, relink_unused(), st_table::s, set_timespec, strmov(), table_def_cache, unused_tables, st_table_share::version, and VOID.
Referenced by abort_and_upgrade_lock(), close_cached_tables(), close_open_tables_and_downgrade(), lock_table_name(), mysql_admin_table(), mysql_rm_table_part2(), and wait_while_table_is_used().
06130 { 06131 char key[MAX_DBKEY_LENGTH]; 06132 uint key_length; 06133 TABLE *table; 06134 TABLE_SHARE *share; 06135 bool result= 0, signalled= 0; 06136 DBUG_ENTER("remove_table_from_cache"); 06137 DBUG_PRINT("enter", ("Table: '%s.%s' flags: %u", db, table_name, flags)); 06138 06139 key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; 06140 for (;;) 06141 { 06142 HASH_SEARCH_STATE state; 06143 result= signalled= 0; 06144 06145 for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, 06146 &state); 06147 table; 06148 table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, 06149 &state)) 06150 { 06151 THD *in_use; 06152 06153 table->s->version=0L; /* Free when thread is ready */ 06154 if (!(in_use=table->in_use)) 06155 { 06156 DBUG_PRINT("info",("Table was not in use")); 06157 relink_unused(table); 06158 } 06159 else if (in_use != thd) 06160 { 06161 DBUG_PRINT("info", ("Table was in use by other thread")); 06162 in_use->some_tables_deleted=1; 06163 if (table->db_stat) 06164 { 06165 DBUG_PRINT("info", ("Found another active instance of the table")); 06166 result=1; 06167 } 06168 /* Kill delayed insert threads */ 06169 if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && 06170 ! in_use->killed) 06171 { 06172 in_use->killed= THD::KILL_CONNECTION; 06173 pthread_mutex_lock(&in_use->mysys_var->mutex); 06174 if (in_use->mysys_var->current_cond) 06175 { 06176 pthread_mutex_lock(in_use->mysys_var->current_mutex); 06177 signalled= 1; 06178 pthread_cond_broadcast(in_use->mysys_var->current_cond); 06179 pthread_mutex_unlock(in_use->mysys_var->current_mutex); 06180 } 06181 pthread_mutex_unlock(&in_use->mysys_var->mutex); 06182 } 06183 /* 06184 Now we must abort all tables locks used by this thread 06185 as the thread may be waiting to get a lock for another table 06186 */ 06187 for (TABLE *thd_table= in_use->open_tables; 06188 thd_table ; 06189 thd_table= thd_table->next) 06190 { 06191 if (thd_table->db_stat) // If table is open 06192 signalled|= mysql_lock_abort_for_thread(thd, thd_table); 06193 } 06194 } 06195 else 06196 { 06197 DBUG_PRINT("info", ("Table was in use by current thread. db_stat: %u", 06198 table->db_stat)); 06199 result= result || (flags & RTFC_OWNED_BY_THD_FLAG); 06200 } 06201 } 06202 while (unused_tables && !unused_tables->s->version) 06203 VOID(hash_delete(&open_cache,(byte*) unused_tables)); 06204 06205 DBUG_PRINT("info", ("Removing table from table_def_cache")); 06206 /* Remove table from table definition cache if it's not in use */ 06207 if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(byte*) key, 06208 key_length))) 06209 { 06210 DBUG_PRINT("info", ("share version: %lu ref_count: %u", 06211 share->version, share->ref_count)); 06212 share->version= 0; // Mark for delete 06213 if (share->ref_count == 0) 06214 { 06215 pthread_mutex_lock(&share->mutex); 06216 VOID(hash_delete(&table_def_cache, (byte*) share)); 06217 } 06218 } 06219 06220 if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG)) 06221 { 06222 /* 06223 Signal any thread waiting for tables to be freed to 06224 reopen their tables 06225 */ 06226 broadcast_refresh(); 06227 DBUG_PRINT("info", ("Waiting for refresh signal")); 06228 if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed) 06229 { 06230 dropping_tables++; 06231 if (likely(signalled)) 06232 (void) pthread_cond_wait(&COND_refresh, &LOCK_open); 06233 else 06234 { 06235 struct timespec abstime; 06236 /* 06237 It can happen that another thread has opened the 06238 table but has not yet locked any table at all. Since 06239 it can be locked waiting for a table that our thread 06240 has done LOCK TABLE x WRITE on previously, we need to 06241 ensure that the thread actually hears our signal 06242 before we go to sleep. Thus we wait for a short time 06243 and then we retry another loop in the 06244 remove_table_from_cache routine. 06245 */ 06246 set_timespec(abstime, 10); 06247 pthread_cond_timedwait(&COND_refresh, &LOCK_open, &abstime); 06248 } 06249 dropping_tables--; 06250 continue; 06251 } 06252 } 06253 break; 06254 } 06255 DBUG_RETURN(result); 06256 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1597 of file sql_base.cc.
References alloc_root(), create_table_def_key(), st_table_list::db, DBUG_ENTER, DBUG_RETURN, key, key_length, MAX_DBKEY_LENGTH, st_table_share::mem_root, st_table::s, st_table_share::set_table_cache_key(), and st_table_list::table_name.
01599 { 01600 char *key; 01601 uint key_length; 01602 TABLE_SHARE *share= table->s; 01603 TABLE_LIST table_list; 01604 DBUG_ENTER("rename_temporary_table"); 01605 01606 if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH))) 01607 DBUG_RETURN(1); /* purecov: inspected */ 01608 01609 table_list.db= (char*) db; 01610 table_list.table_name= (char*) table_name; 01611 key_length= create_table_def_key(thd, key, &table_list, 1); 01612 share->set_table_cache_key(key, key_length); 01613 DBUG_RETURN(0); 01614 }
Here is the call graph for this function:

| bool reopen_name_locked_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1733 of file sql_base.cc.
References check_unused, st_table::const_table, DBUG_ENTER, DBUG_RETURN, FALSE, st_table_share::flush_version, st_table::force_index, st_table::in_use, intern_close_table(), st_table_share::keys_for_keyread, st_table_share::keys_in_use, st_table::keys_in_use_for_query, LEX_STRING::length, LOCK_open, st_table::maybe_null, st_table::next, st_table::null_row, open_unireg_entry(), st_table::s, safe_mutex_assert_owner, st_table::status, STATUS_NO_RECORD, LEX_STRING::str, st_table_list::table, st_table_share::table_cache_key, st_table_list::table_name, st_table::tablenr, TRUE, st_table::used_fields, st_table::used_keys, and st_table_share::version.
Referenced by mysql_create_or_drop_trigger(), prepare_for_repair(), and prepare_for_restore().
01734 { 01735 TABLE *table= table_list->table; 01736 TABLE_SHARE *share; 01737 char *table_name= table_list->table_name; 01738 TABLE orig_table; 01739 DBUG_ENTER("reopen_name_locked_table"); 01740 01741 safe_mutex_assert_owner(&LOCK_open); 01742 01743 if (thd->killed || !table) 01744 DBUG_RETURN(TRUE); 01745 01746 orig_table= *table; 01747 01748 if (open_unireg_entry(thd, table, table_list, table_name, 01749 table->s->table_cache_key.str, 01750 table->s->table_cache_key.length, thd->mem_root, 0)) 01751 { 01752 intern_close_table(table); 01753 /* 01754 If there was an error during opening of table (for example if it 01755 does not exist) '*table' object can be wiped out. To be able 01756 properly release name-lock in this case we should restore this 01757 object to its original state. 01758 */ 01759 *table= orig_table; 01760 DBUG_RETURN(TRUE); 01761 } 01762 01763 share= table->s; 01764 share->version=0; 01765 share->flush_version=0; 01766 table->in_use = thd; 01767 check_unused(); 01768 table->next = thd->open_tables; 01769 thd->open_tables = table; 01770 table->tablenr=thd->current_tablenr++; 01771 table->used_fields=0; 01772 table->const_table=0; 01773 table->null_row= table->maybe_null= table->force_index= 0; 01774 table->status=STATUS_NO_RECORD; 01775 table->keys_in_use_for_query= share->keys_in_use; 01776 table->used_keys= share->keys_for_keyread; 01777 DBUG_RETURN(FALSE); 01778 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2143 of file sql_base.cc.
References st_table::alias, st_table_list::belong_to_view, broadcast_refresh(), handler::change_table_ptr(), closefrm(), st_table::const_table, st_table_share::db, st_table_list::db, st_table::db_stat, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_table::default_column_bitmaps(), error, st_key_part_info::field, st_table::field, st_table::file, st_table::grant, st_table::in_use, st_filesort_info::io_cache, key, st_table::key_info, st_key::key_part, st_table_share::keys, st_table_share::keys_for_keyread, st_table_share::keys_in_use, st_table::keys_in_use_for_query, LEX_STRING::length, st_reginfo::lock_type, st_table::maybe_null, st_table::next, st_table_list::next_local, st_table::null_row, open_unireg_entry(), st_table::prev, st_table_share::ref_count, st_table::reginfo, st_table::s, Table_triggers_list::set_table(), st_table::sort, sql_print_error(), st_table::status, LEX_STRING::str, Field::table, st_table_list::table, st_table_share::table_cache_key, st_table_share::table_map_id, st_table_share::table_name, st_table_list::table_name, st_table::tablenr, st_table::triggers, st_key::usable_key_parts, st_table::used_fields, st_table::used_keys, VOID, and wait_for_locked_table_names().
Referenced by reopen_tables().
02144 { 02145 TABLE tmp; 02146 bool error= 1; 02147 Field **field; 02148 uint key,part; 02149 TABLE_LIST table_list; 02150 THD *thd= table->in_use; 02151 DBUG_ENTER("reopen_table"); 02152 02153 DBUG_ASSERT(table->s->ref_count == 0); 02154 DBUG_ASSERT(!table->sort.io_cache); 02155 02156 #ifdef EXTRA_DEBUG 02157 if (table->db_stat) 02158 sql_print_error("Table %s had a open data handler in reopen_table", 02159 table->alias); 02160 #endif 02161 table_list.db= table->s->db.str; 02162 table_list.table_name= table->s->table_name.str; 02163 table_list.table= table; 02164 table_list.belong_to_view= 0; 02165 table_list.next_local= 0; 02166 02167 if (wait_for_locked_table_names(thd, &table_list)) 02168 DBUG_RETURN(1); // Thread was killed 02169 02170 if (open_unireg_entry(thd, &tmp, &table_list, 02171 table->alias, 02172 table->s->table_cache_key.str, 02173 table->s->table_cache_key.length, 02174 thd->mem_root, 0)) 02175 goto end; 02176 02177 /* This list copies variables set by open_table */ 02178 tmp.tablenr= table->tablenr; 02179 tmp.used_fields= table->used_fields; 02180 tmp.const_table= table->const_table; 02181 tmp.null_row= table->null_row; 02182 tmp.maybe_null= table->maybe_null; 02183 tmp.status= table->status; 02184 tmp.keys_in_use_for_query= tmp.s->keys_in_use; 02185 tmp.used_keys= tmp.s->keys_for_keyread; 02186 02187 tmp.s->table_map_id= table->s->table_map_id; 02188 02189 /* Get state */ 02190 tmp.in_use= thd; 02191 tmp.reginfo.lock_type=table->reginfo.lock_type; 02192 tmp.grant= table->grant; 02193 02194 /* Replace table in open list */ 02195 tmp.next= table->next; 02196 tmp.prev= table->prev; 02197 02198 delete table->triggers; 02199 if (table->file) 02200 VOID(closefrm(table, 1)); // close file, free everything 02201 02202 *table= tmp; 02203 table->default_column_bitmaps(); 02204 table->file->change_table_ptr(table, table->s); 02205 02206 DBUG_ASSERT(table->alias != 0); 02207 for (field=table->field ; *field ; field++) 02208 { 02209 (*field)->table= (*field)->orig_table= table; 02210 (*field)->table_name= &table->alias; 02211 } 02212 for (key=0 ; key < table->s->keys ; key++) 02213 { 02214 for (part=0 ; part < table->key_info[key].usable_key_parts ; part++) 02215 table->key_info[key].key_part[part].field->table= table; 02216 } 02217 if (table->triggers) 02218 table->triggers->set_table(table); 02219 02220 broadcast_refresh(); 02221 error=0; 02222 02223 end: 02224 DBUG_RETURN(error); 02225 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2257 of file sql_base.cc.
References st_table::alias, broadcast_refresh(), st_table::db_stat, DBUG_ENTER, DBUG_RETURN, ER_CANT_REOPEN_TABLE, error, hash_delete(), lock, LOCK_open, st_table::locked_by_flush, my_afree, my_alloca, my_error(), MYF, mysql_lock_merge(), mysql_lock_tables(), st_table::next, open_cache, reopen_table(), st_table::s, safe_mutex_assert_owner, st_table_share::version, and VOID.
Referenced by close_cached_tables(), mysql_multi_update_prepare(), and wait_for_tables().
02258 { 02259 TABLE *table,*next,**prev; 02260 TABLE **tables,**tables_ptr; // For locks 02261 bool error=0, not_used; 02262 DBUG_ENTER("reopen_tables"); 02263 02264 if (!thd->open_tables) 02265 DBUG_RETURN(0); 02266 02267 safe_mutex_assert_owner(&LOCK_open); 02268 if (get_locks) 02269 { 02270 /* The ptr is checked later */ 02271 uint opens=0; 02272 for (table= thd->open_tables; table ; table=table->next) 02273 opens++; 02274 tables= (TABLE**) my_alloca(sizeof(TABLE*)*opens); 02275 } 02276 else 02277 tables= &thd->open_tables; 02278 tables_ptr =tables; 02279 02280 prev= &thd->open_tables; 02281 for (table=thd->open_tables; table ; table=next) 02282 { 02283 uint db_stat=table->db_stat; 02284 next=table->next; 02285 if (!tables || (!db_stat && reopen_table(table))) 02286 { 02287 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); 02288 VOID(hash_delete(&open_cache,(byte*) table)); 02289 error=1; 02290 } 02291 else 02292 { 02293 *prev= table; 02294 prev= &table->next; 02295 if (get_locks && !db_stat) 02296 *tables_ptr++= table; // need new lock on this 02297 if (in_refresh) 02298 { 02299 table->s->version=0; 02300 table->locked_by_flush=0; 02301 } 02302 } 02303 } 02304 if (tables != tables_ptr) // Should we get back old locks 02305 { 02306 MYSQL_LOCK *lock; 02307 /* We should always get these locks */ 02308 thd->some_tables_deleted=0; 02309 if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables), 02310 0, ¬_used))) 02311 { 02312 thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock); 02313 } 02314 else 02315 error=1; 02316 } 02317 if (get_locks && tables) 02318 { 02319 my_afree((gptr) tables); 02320 } 02321 broadcast_refresh(); 02322 *prev=0; 02323 DBUG_RETURN(error); 02324 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool rm_temporary_table | ( | handlerton * | base, | |
| char * | path | |||
| ) |
Definition at line 3552 of file sql_base.cc.
References current_thd, DBUG_ENTER, DBUG_RETURN, handler::delete_table(), error, get_new_handler(), my_delete(), my_errno, MYF, reg_ext, sql_print_warning(), strend(), and strmov().
Referenced by close_temporary(), mysql_create_like_table(), mysql_create_table_internal(), and mysql_truncate().
03553 { 03554 bool error=0; 03555 handler *file; 03556 char *ext; 03557 DBUG_ENTER("rm_temporary_table"); 03558 03559 strmov(ext= strend(path), reg_ext); 03560 if (my_delete(path,MYF(0))) 03561 error=1; /* purecov: inspected */ 03562 *ext= 0; // remove extension 03563 file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base); 03564 if (file && file->delete_table(path)) 03565 { 03566 error=1; 03567 sql_print_warning("Could not remove temporary table: '%s', error: %d", 03568 path, my_errno); 03569 } 03570 delete file; 03571 DBUG_RETURN(error); 03572 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool set_new_item_local_context | ( | THD * | thd, | |
| Item_ident * | item, | |||
| TABLE_LIST * | table_ref | |||
| ) | [static] |
Definition at line 4573 of file sql_base.cc.
References Item_ident::context, FALSE, Name_resolution_context::first_name_resolution_table, Name_resolution_context::init(), Name_resolution_context::last_name_resolution_table, and TRUE.
Referenced by mark_common_columns().
04574 { 04575 Name_resolution_context *context; 04576 if (!(context= new (thd->mem_root) Name_resolution_context)) 04577 return TRUE; 04578 context->init(); 04579 context->first_name_resolution_table= 04580 context->last_name_resolution_table= table_ref; 04581 item->context= context; 04582 return FALSE; 04583 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int setup_conds | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| TABLE_LIST * | leaves, | |||
| COND ** | conds | |||
| ) |
Definition at line 5768 of file sql_base.cc.
References backup, st_table_list::check_option, DBUG_ENTER, DBUG_PRINT, st_table_list::effective_with_check, st_table_list::embedding, FALSE, MARK_COLUMNS_READ, st_table_list::next_leaf, st_table_list::next_local, NULL, st_table_list::prepare_check_option(), st_table_list::prepare_where(), st_table_list::top_table(), and st_table_list::where.
Referenced by mysql_prepare_delete(), mysql_prepare_update(), and setup_without_group().
05770 { 05771 SELECT_LEX *select_lex= thd->lex->current_select; 05772 Query_arena *arena= thd->stmt_arena, backup; 05773 TABLE_LIST *table= NULL; // For HP compilers 05774 /* 05775 it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX 05776 which belong to LEX, i.e. most up SELECT) will be updated by 05777 INSERT/UPDATE/LOAD 05778 NOTE: using this condition helps to prevent call of prepare_check_option() 05779 from subquery of VIEW, because tables of subquery belongs to VIEW 05780 (see condition before prepare_check_option() call) 05781 */ 05782 bool it_is_update= (select_lex == &thd->lex->select_lex) && 05783 thd->lex->which_check_option_applicable(); 05784 DBUG_ENTER("setup_conds"); 05785 05786 if (select_lex->conds_processed_with_permanent_arena || 05787 arena->is_conventional()) 05788 arena= 0; // For easier test 05789 05790 thd->mark_used_columns= MARK_COLUMNS_READ; 05791 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 05792 select_lex->cond_count= 0; 05793 05794 for (table= tables; table; table= table->next_local) 05795 { 05796 if (table->prepare_where(thd, conds, FALSE)) 05797 goto err_no_arena; 05798 } 05799 05800 if (*conds) 05801 { 05802 thd->where="where clause"; 05803 if (!(*conds)->fixed && (*conds)->fix_fields(thd, conds) || 05804 (*conds)->check_cols(1)) 05805 goto err_no_arena; 05806 } 05807 05808 /* 05809 Apply fix_fields() to all ON clauses at all levels of nesting, 05810 including the ones inside view definitions. 05811 */ 05812 for (table= leaves; table; table= table->next_leaf) 05813 { 05814 TABLE_LIST *embedded; /* The table at the current level of nesting. */ 05815 TABLE_LIST *embedding= table; /* The parent nested table reference. */ 05816 do 05817 { 05818 embedded= embedding; 05819 if (embedded->on_expr) 05820 { 05821 /* Make a join an a expression */ 05822 thd->where="on clause"; 05823 if (!embedded->on_expr->fixed && 05824 embedded->on_expr->fix_fields(thd, &embedded->on_expr) || 05825 embedded->on_expr->check_cols(1)) 05826 goto err_no_arena; 05827 select_lex->cond_count++; 05828 } 05829 embedding= embedded->embedding; 05830 } 05831 while (embedding && 05832 embedding->nested_join->join_list.head() == embedded); 05833 05834 /* process CHECK OPTION */ 05835 if (it_is_update) 05836 { 05837 TABLE_LIST *view= table->top_table(); 05838 if (view->effective_with_check) 05839 { 05840 if (view->prepare_check_option(thd)) 05841 goto err_no_arena; 05842 thd->change_item_tree(&table->check_option, view->check_option); 05843 } 05844 } 05845 } 05846 05847 if (!thd->stmt_arena->is_conventional()) 05848 { 05849 /* 05850 We are in prepared statement preparation code => we should store 05851 WHERE clause changing for next executions. 05852 05853 We do this ON -> WHERE transformation only once per PS/SP statement. 05854 */ 05855 select_lex->where= *conds; 05856 select_lex->conds_processed_with_permanent_arena= 1; 05857 } 05858 DBUG_RETURN(test(thd->net.report_error)); 05859 05860 err_no_arena: 05861 DBUG_RETURN(1); 05862 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool setup_fields | ( | THD * | thd, | |
| Item ** | ref_pointer_array, | |||
| List< Item > & | fields, | |||
| enum_mark_columns | mark_used_columns, | |||
| List< Item > * | sum_func_list, | |||
| bool | allow_sum_func | |||
| ) |
Definition at line 5254 of file sql_base.cc.
References bzero, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, base_list::elements, List_iterator< T >::ref(), reg2, Item::SUM_FUNC_ITEM, test, and TRUE.
Referenced by check_insert_fields(), check_update_fields(), mysql_do(), mysql_insert(), mysql_load(), mysql_prepare_insert(), mysql_test_do_fields(), mysql_test_insert(), and JOIN::prepare().
05257 { 05258 reg2 Item *item; 05259 enum_mark_columns save_mark_used_columns= thd->mark_used_columns; 05260 nesting_map save_allow_sum_func= thd->lex->allow_sum_func; 05261 List_iterator<Item> it(fields); 05262 DBUG_ENTER("setup_fields"); 05263 05264 thd->mark_used_columns= mark_used_columns; 05265 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 05266 if (allow_sum_func) 05267 thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; 05268 thd->where= THD::DEFAULT_WHERE; 05269 05270 /* 05271 To prevent fail on forward lookup we fill it with zerows, 05272 then if we got pointer on zero after find_item_in_list we will know 05273 that it is forward lookup. 05274 05275 There is other way to solve problem: fill array with pointers to list, 05276 but it will be slower. 05277 05278 TODO: remove it when (if) we made one list for allfields and 05279 ref_pointer_array 05280 */ 05281 if (ref_pointer_array) 05282 bzero(ref_pointer_array, sizeof(Item *) * fields.elements); 05283 05284 Item **ref= ref_pointer_array; 05285 while ((item= it++)) 05286 { 05287 if (!item->fixed && item->fix_fields(thd, it.ref()) || 05288 (item= *(it.ref()))->check_cols(1)) 05289 { 05290 thd->lex->allow_sum_func= save_allow_sum_func; 05291 thd->mark_used_columns= save_mark_used_columns; 05292 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 05293 DBUG_RETURN(TRUE); /* purecov: inspected */ 05294 } 05295 if (ref) 05296 *(ref++)= item; 05297 if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && 05298 sum_func_list) 05299 item->split_sum_func(thd, ref_pointer_array, *sum_func_list); 05300 thd->used_tables|= item->used_tables(); 05301 } 05302 thd->lex->allow_sum_func= save_allow_sum_func; 05303 thd->mark_used_columns= save_mark_used_columns; 05304 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 05305 DBUG_RETURN(test(thd->net.report_error)); 05306 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int setup_ftfuncs | ( | SELECT_LEX * | select_lex | ) |
Definition at line 6259 of file sql_base.cc.
References Item_func_match::eq(), Item_func_match::fix_index(), and List_iterator< T >::rewind().
Referenced by mysql_prepare_delete(), mysql_prepare_update(), and JOIN::prepare().
06260 { 06261 List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)), 06262 lj(*(select_lex->ftfunc_list)); 06263 Item_func_match *ftf, *ftf2; 06264 06265 while ((ftf=li++)) 06266 { 06267 if (ftf->fix_index()) 06268 return 1; 06269 lj.rewind(); 06270 while ((ftf2=lj++) != ftf) 06271 { 06272 if (ftf->eq(ftf2,1) && !ftf2->master) 06273 ftf2->master=ftf; 06274 } 06275 } 06276 06277 return 0; 06278 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool setup_natural_join_row_types | ( | THD * | thd, | |
| List< TABLE_LIST > * | from_clause, | |||
| Name_resolution_context * | context | |||
| ) | [static] |
Definition at line 5125 of file sql_base.cc.
References base_list::elements, FALSE, st_table_list::first_leaf_for_name_resolution(), st_table_list::next_name_resolution_table, NULL, Name_resolution_context::select_lex, store_top_level_join_columns(), and TRUE.
05128 { 05129 thd->where= "from clause"; 05130 if (from_clause->elements == 0) 05131 return FALSE; /* We come here in the case of UNIONs. */ 05132 05133 List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause); 05134 TABLE_LIST *table_ref; /* Current table reference. */ 05135 /* Table reference to the left of the current. */ 05136 TABLE_LIST *left_neighbor; 05137 /* Table reference to the right of the current. */ 05138 TABLE_LIST *right_neighbor= NULL; 05139 05140 /* Note that tables in the list are in reversed order */ 05141 for (left_neighbor= table_ref_it++; left_neighbor ; ) 05142 { 05143 table_ref= left_neighbor; 05144 left_neighbor= table_ref_it++; 05145 /* For stored procedures do not redo work if already done. */ 05146 if (context->select_lex->first_execution) 05147 { 05148 if (store_top_level_join_columns(thd, table_ref, 05149 left_neighbor, right_neighbor)) 05150 return TRUE; 05151 if (left_neighbor) 05152 { 05153 TABLE_LIST *first_leaf_on_the_right; 05154 first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution(); 05155 left_neighbor->next_name_resolution_table= first_leaf_on_the_right; 05156 } 05157 } 05158 right_neighbor= table_ref; 05159 } 05160 05161 /* 05162 Store the top-most, left-most NATURAL/USING join, so that we start 05163 the search from that one instead of context->table_list. At this point 05164 right_neighbor points to the left-most top-level table reference in the 05165 FROM clause. 05166 */ 05167 DBUG_ASSERT(right_neighbor); 05168 context->first_name_resolution_table= 05169 right_neighbor->first_leaf_for_name_resolution(); 05170 05171 return FALSE; 05172 }
Here is the call graph for this function:

| bool setup_tables | ( | THD * | thd, | |
| Name_resolution_context * | context, | |||
| List< TABLE_LIST > * | from_clause, | |||
| TABLE_LIST * | tables, | |||
| TABLE_LIST ** | leaves, | |||
| bool | select_insert | |||
| ) |
Definition at line 5367 of file sql_base.cc.
References backup, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_table_list::effective_algorithm, ER_TOO_MANY_TABLES, Name_resolution_context::first_name_resolution_table, get_key_map_from_key_list(), st_table_list::ignore_index, make_leaves_list(), map, MAX_TABLES, st_table_list::merge_underlying_list, my_error(), MYF, st_table_list::next_leaf, st_table_list::next_local, st_table::pos_in_table_list, st_table_list::setup_underlying(), st_table_list::table, Name_resolution_context::table_list, st_table_list::top_table(), st_table_list::use_index, st_table_list::view, and VIEW_ALGORITHM_MERGE.
Referenced by db_show_routine_status(), mysqld_help(), and setup_tables_and_check_access().
05370 { 05371 uint tablenr= 0; 05372 DBUG_ENTER("setup_tables"); 05373 05374 context->table_list= context->first_name_resolution_table= tables; 05375 05376 /* 05377 this is used for INSERT ... SELECT. 05378 For select we setup tables except first (and its underlying tables) 05379 */ 05380 TABLE_LIST *first_select_table= (select_insert ? 05381 tables->next_local: 05382 0); 05383 if (!(*leaves)) 05384 make_leaves_list(leaves, tables); 05385 05386 TABLE_LIST *table_list; 05387 for (table_list= *leaves; 05388 table_list; 05389 table_list= table_list->next_leaf, tablenr++) 05390 { 05391 TABLE *table= table_list->table; 05392 table->pos_in_table_list= table_list; 05393 if (first_select_table && 05394 table_list->top_table() == first_select_table) 05395 { 05396 /* new counting for SELECT of INSERT ... SELECT command */ 05397 first_select_table= 0; 05398 tablenr= 0; 05399 } 05400 setup_table_map(table, table_list, tablenr); 05401 table->used_keys= table->s->keys_for_keyread; 05402 table->merge_keys.clear_all(); 05403 if (table_list->use_index) 05404 { 05405 key_map map; 05406 get_key_map_from_key_list(&map, table, table_list->use_index); 05407 if (map.is_set_all()) 05408 DBUG_RETURN(1); 05409 table->keys_in_use_for_query=map; 05410 } 05411 if (table_list->ignore_index) 05412 { 05413 key_map map; 05414 get_key_map_from_key_list(&map, table, table_list->ignore_index); 05415 if (map.is_set_all()) 05416 DBUG_RETURN(1); 05417 table->keys_in_use_for_query.subtract(map); 05418 } 05419 table->used_keys.intersect(table->keys_in_use_for_query); 05420 } 05421 if (tablenr > MAX_TABLES) 05422 { 05423 my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); 05424 DBUG_RETURN(1); 05425 } 05426 for (table_list= tables; 05427 table_list; 05428 table_list= table_list->next_local) 05429 { 05430 if (table_list->merge_underlying_list) 05431 { 05432 DBUG_ASSERT(table_list->view && 05433 table_list->effective_algorithm == VIEW_ALGORITHM_MERGE); 05434 Query_arena *arena= thd->stmt_arena, backup; 05435 bool res; 05436 if (arena->is_conventional()) 05437 arena= 0; // For easier test 05438 else 05439 thd->set_n_backup_active_arena(arena, &backup); 05440 res= table_list->setup_underlying(thd); 05441 if (arena) 05442 thd->restore_active_arena(arena, &backup); 05443 if (res) 05444 DBUG_RETURN(1); 05445 } 05446 } 05447 05448 /* Precompute and store the row types of NATURAL/USING joins. */ 05449 if (setup_natural_join_row_types(thd, from_clause, context)) 05450 DBUG_RETURN(1); 05451 05452 DBUG_RETURN(0); 05453 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool setup_tables_and_check_access | ( | THD * | thd, | |
| Name_resolution_context * | context, | |||
| List< TABLE_LIST > * | from_clause, | |||
| TABLE_LIST * | tables, | |||
| TABLE_LIST ** | leaves, | |||
| bool | select_insert, | |||
| ulong | want_access | |||
| ) |
Definition at line 5479 of file sql_base.cc.
References st_table_list::belong_to_view, check_single_table_access(), FALSE, st_table_list::hide_view_error(), st_table_list::next_leaf, NULL, setup_tables(), and TRUE.
Referenced by mysql_load(), mysql_multi_delete_prepare(), mysql_multi_update_prepare(), mysql_prepare_delete(), mysql_prepare_insert_check_table(), mysql_prepare_update(), and JOIN::prepare().
05486 { 05487 TABLE_LIST *leaves_tmp= NULL; 05488 05489 if (setup_tables(thd, context, from_clause, tables, 05490 &leaves_tmp, select_insert)) 05491 return TRUE; 05492 05493 *leaves= leaves_tmp; 05494 05495 for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf) 05496 { 05497 if (leaves_tmp->belong_to_view && 05498 check_single_table_access(thd, want_access, leaves_tmp)) 05499 { 05500 tables->hide_view_error(thd); 05501 return TRUE; 05502 } 05503 } 05504 return FALSE; 05505 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int setup_wild | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| List< Item > & | fields, | |||
| List< Item > * | sum_func_list, | |||
| uint | wild_num | |||
| ) |
Definition at line 5179 of file sql_base.cc.
References backup, DBUG_ENTER, DBUG_RETURN, base_list::elements, Item_subselect::EXISTS_SUBS, Item::FIELD_ITEM, insert_fields(), List_iterator< T >::replace(), Item_subselect::substype(), and Item::type().
Referenced by JOIN::prepare().
05182 { 05183 if (!wild_num) 05184 return(0); 05185 05186 Item *item; 05187 List_iterator<Item> it(fields); 05188 Query_arena *arena, backup; 05189 DBUG_ENTER("setup_wild"); 05190 05191 /* 05192 Don't use arena if we are not in prepared statements or stored procedures 05193 For PS/SP we have to use arena to remember the changes 05194 */ 05195 arena= thd->activate_stmt_arena_if_needed(&backup); 05196 05197 while (wild_num && (item= it++)) 05198 { 05199 if (item->type() == Item::FIELD_ITEM && 05200 ((Item_field*) item)->field_name && 05201 ((Item_field*) item)->field_name[0] == '*' && 05202 !((Item_field*) item)->field) 05203 { 05204 uint elem= fields.elements; 05205 bool any_privileges= ((Item_field *) item)->any_privileges; 05206 Item_subselect *subsel= thd->lex->current_select->master_unit()->item; 05207 if (subsel && 05208 subsel->substype() == Item_subselect::EXISTS_SUBS) 05209 { 05210 /* 05211 It is EXISTS(SELECT * ...) and we can replace * by any constant. 05212 05213 Item_int do not need fix_fields() because it is basic constant. 05214 */ 05215 it.replace(new Item_int("Not_used", (longlong) 1, 21)); 05216 } 05217 else if (insert_fields(thd, ((Item_field*) item)->context, 05218 ((Item_field*) item)->db_name, 05219 ((Item_field*) item)->table_name, &it, 05220 any_privileges)) 05221 { 05222 if (arena) 05223 thd->restore_active_arena(arena, &backup); 05224 DBUG_RETURN(-1); 05225 } 05226 if (sum_func_list) 05227 { 05228 /* 05229 sum_func_list is a list that has the fields list as a tail. 05230 Because of this we have to update the element count also for this 05231 list after expanding the '*' entry. 05232 */ 05233 sum_func_list->elements+= fields.elements - elem; 05234 } 05235 wild_num--; 05236 } 05237 } 05238 if (arena) 05239 { 05240 /* make * substituting permanent */ 05241 SELECT_LEX *select_lex= thd->lex->current_select; 05242 select_lex->with_wild= 0; 05243 select_lex->item_list= fields; 05244 05245 thd->restore_active_arena(arena, &backup); 05246 } 05247 DBUG_RETURN(0); 05248 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int simple_open_n_lock_tables | ( | THD * | thd, | |
| TABLE_LIST * | tables | |||
| ) |
Definition at line 3152 of file sql_base.cc.
References close_tables_for_reopen(), DBUG_ENTER, DBUG_RETURN, lock_tables, and open_tables().
Referenced by acl_reload(), Event_scheduler::check_system_tables(), grant_reload(), my_tz_find_with_opening_tz_tables(), my_tz_init(), mysql_execute_command(), mysql_grant(), mysql_routine_grant(), mysql_table_grant(), Events::open_event_table(), open_grant_tables(), Log_to_csv_event_handler::open_log_table(), and plugin_load().
03153 { 03154 uint counter; 03155 bool need_reopen; 03156 DBUG_ENTER("simple_open_n_lock_tables"); 03157 03158 for ( ; ; ) 03159 { 03160 if (open_tables(thd, &tables, &counter, 0)) 03161 DBUG_RETURN(-1); 03162 if (!lock_tables(thd, tables, counter, &need_reopen)) 03163 break; 03164 if (!need_reopen) 03165 DBUG_RETURN(-1); 03166 close_tables_for_reopen(thd, &tables); 03167 } 03168 DBUG_RETURN(0); 03169 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool store_natural_using_join_columns | ( | THD * | thd, | |
| TABLE_LIST * | natural_using_join, | |||
| TABLE_LIST * | table_ref_1, | |||
| TABLE_LIST * | table_ref_2, | |||
| List< String > * | using_fields, | |||
| uint | found_using_fields | |||
| ) | [static] |
Definition at line 4838 of file sql_base.cc.
References backup, String::c_ptr(), List< T >::concat(), current_thd, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, base_list::elements, Field_iterator_table_ref::end_of_fields(), ER_BAD_FIELD_ERROR, err, FALSE, Field_iterator_table_ref::get_natural_column_ref(), Natural_join_column::is_common, st_table_list::is_join_columns_complete, st_table_list::join_columns, my_error(), my_strcasecmp, MYF, Natural_join_column::name(), Field_iterator_table_ref::next(), List< T >::push_back(), Field_iterator_table_ref::set(), system_charset_info, and TRUE.
Referenced by store_top_level_join_columns().
04843 { 04844 Field_iterator_table_ref it_1, it_2; 04845 Natural_join_column *nj_col_1, *nj_col_2; 04846 Query_arena *arena, backup; 04847 bool result= TRUE; 04848 List<Natural_join_column> *non_join_columns; 04849 DBUG_ENTER("store_natural_using_join_columns"); 04850 04851 DBUG_ASSERT(!natural_using_join->join_columns); 04852 04853 arena= thd->activate_stmt_arena_if_needed(&backup); 04854 04855 if (!(non_join_columns= new List<Natural_join_column>) || 04856 !(natural_using_join->join_columns= new List<Natural_join_column>)) 04857 goto err; 04858 04859 /* Append the columns of the first join operand. */ 04860 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) 04861 { 04862 nj_col_1= it_1.get_natural_column_ref(); 04863 if (nj_col_1->is_common) 04864 { 04865 natural_using_join->join_columns->push_back(nj_col_1); 04866 /* Reset the common columns for the next call to mark_common_columns. */ 04867 nj_col_1->is_common= FALSE; 04868 } 04869 else 04870 non_join_columns->push_back(nj_col_1); 04871 } 04872 04873 /* 04874 Check that all columns in the USING clause are among the common 04875 columns. If this is not the case, report the first one that was 04876 not found in an error. 04877 */ 04878 if (using_fields && found_using_fields < using_fields->elements) 04879 { 04880 String *using_field_name; 04881 List_iterator_fast<String> using_fields_it(*using_fields); 04882 while ((using_field_name= using_fields_it++)) 04883 { 04884 const char *using_field_name_ptr= using_field_name->c_ptr(); 04885 List_iterator_fast<Natural_join_column> 04886 it(*(natural_using_join->join_columns)); 04887 Natural_join_column *common_field; 04888 04889 for (;;) 04890 { 04891 /* If reached the end of fields, and none was found, report error. */ 04892 if (!(common_field= it++)) 04893 { 04894 my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr, 04895 current_thd->where); 04896 goto err; 04897 } 04898 if (!my_strcasecmp(system_charset_info, 04899 common_field->name(), using_field_name_ptr)) 04900 break; // Found match 04901 } 04902 } 04903 } 04904 04905 /* Append the non-equi-join columns of the second join operand. */ 04906 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) 04907 { 04908 nj_col_2= it_2.get_natural_column_ref(); 04909 if (!nj_col_2->is_common) 04910 non_join_columns->push_back(nj_col_2); 04911 else 04912 { 04913 /* Reset the common columns for the next call to mark_common_columns. */ 04914 nj_col_2->is_common= FALSE; 04915 } 04916 } 04917 04918 if (non_join_columns->elements > 0) 04919 natural_using_join->join_columns->concat(non_join_columns); 04920 natural_using_join->is_join_columns_complete= TRUE; 04921 04922 result= FALSE; 04923 04924 err: 04925 if (arena) 04926 thd->restore_active_arena(arena, &backup); 04927 DBUG_RETURN(result); 04928 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool store_top_level_join_columns | ( | THD * | thd, | |
| TABLE_LIST * | table_ref, | |||
| TABLE_LIST * | left_neighbor, | |||
| TABLE_LIST * | right_neighbor | |||
| ) | [static] |
Definition at line 4962 of file sql_base.cc.
References backup, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, err, FALSE, st_table_list::first_leaf_for_name_resolution(), st_table_list::is_natural_join, st_nested_join::join_list, JOIN_TYPE_RIGHT, st_table_list::join_using_fields, st_table_list::last_leaf_for_name_resolution(), mark_common_columns(), st_table_list::natural_join, st_table_list::nested_join, st_table_list::next_name_resolution_table, NULL, st_table_list::on_expr, st_table_list::outer_join, store_natural_using_join_columns(), swap_variables, and TRUE.
Referenced by setup_natural_join_row_types().
04965 { 04966 Query_arena *arena, backup; 04967 bool result= TRUE; 04968 04969 DBUG_ENTER("store_top_level_join_columns"); 04970 04971 arena= thd->activate_stmt_arena_if_needed(&backup); 04972 04973 /* Call the procedure recursively for each nested table reference. */ 04974 if (table_ref->nested_join) 04975 { 04976 List_iterator_fast<TABLE_LIST> nested_it(table_ref->nested_join->join_list); 04977 TABLE_LIST *same_level_left_neighbor= nested_it++; 04978 TABLE_LIST *same_level_right_neighbor= NULL; 04979 /* Left/right-most neighbors, possibly at higher levels in the join tree. */ 04980 TABLE_LIST *real_left_neighbor, *real_right_neighbor; 04981 04982 while (same_level_left_neighbor) 04983 { 04984 TABLE_LIST *cur_table_ref= same_level_left_neighbor; 04985 same_level_left_neighbor= nested_it++; 04986 /* 04987 The order of RIGHT JOIN operands is reversed in 'join list' to 04988 transform it into a LEFT JOIN. However, in this procedure we need 04989 the join operands in their lexical order, so below we reverse the 04990 join operands. Notice that this happens only in the first loop, 04991 and not in the second one, as in the second loop 04992 same_level_left_neighbor == NULL. 04993 This is the correct behavior, because the second loop sets 04994 cur_table_ref reference correctly after the join operands are 04995 swapped in the first loop. 04996 */ 04997 if (same_level_left_neighbor && 04998 cur_table_ref->outer_join & JOIN_TYPE_RIGHT) 04999 { 05000 /* This can happen only for JOIN ... ON. */ 05001 DBUG_ASSERT(table_ref->nested_join->join_list.elements == 2); 05002 swap_variables(TABLE_LIST*, same_level_left_neighbor, cur_table_ref); 05003 } 05004 05005 /* 05006 Pick the parent's left and right neighbors if there are no immediate 05007 neighbors at the same level. 05008 */ 05009 real_left_neighbor= (same_level_left_neighbor) ? 05010 same_level_left_neighbor : left_neighbor; 05011 real_right_neighbor= (same_level_right_neighbor) ? 05012 same_level_right_neighbor : right_neighbor; 05013 05014 if (cur_table_ref->nested_join && 05015 store_top_level_join_columns(thd, cur_table_ref, 05016 real_left_neighbor, real_right_neighbor)) 05017 goto err; 05018 same_level_right_neighbor= cur_table_ref; 05019 } 05020 } 05021 05022 /* 05023 If this is a NATURAL/USING join, materialize its result columns and 05024 convert to a JOIN ... ON. 05025 */ 05026 if (table_ref->is_natural_join) 05027 { 05028 DBUG_ASSERT(table_ref->nested_join && 05029 table_ref->nested_join->join_list.elements == 2); 05030 List_iterator_fast<TABLE_LIST> operand_it(table_ref->nested_join->join_list); 05031 /* 05032 Notice that the order of join operands depends on whether table_ref 05033 represents a LEFT or a RIGHT join. In a RIGHT join, the operands are 05034 in inverted order. 05035 */ 05036 TABLE_LIST *table_ref_2= operand_it++; /* Second NATURAL join operand.*/ 05037 TABLE_LIST *table_ref_1= operand_it++; /* First NATURAL join operand. */ 05038 List<String> *using_fields= table_ref->join_using_fields; 05039 uint found_using_fields; 05040 05041 /* 05042 The two join operands were interchanged in the parser, change the order 05043 back for 'mark_common_columns'. 05044 */ 05045 if (table_ref_2->outer_join & JOIN_TYPE_RIGHT) 05046 swap_variables(TABLE_LIST*, table_ref_1, table_ref_2); 05047 if (mark_common_columns(thd, table_ref_1, table_ref_2, 05048 using_fields, &found_using_fields)) 05049 goto err; 05050 05051 /* 05052 Swap the join operands back, so that we pick the columns of the second 05053 one as the coalesced columns. In this way the coalesced columns are the 05054 same as of an equivalent LEFT JOIN. 05055 */ 05056 if (table_ref_1->outer_join & JOIN_TYPE_RIGHT) 05057 swap_variables(TABLE_LIST*, table_ref_1, table_ref_2); 05058 if (store_natural_using_join_columns(thd, table_ref, table_ref_1, 05059 table_ref_2, using_fields, 05060 found_using_fields)) 05061 goto err; 05062 05063 /* 05064 Change NATURAL JOIN to JOIN ... ON. We do this for both operands 05065 because either one of them or the other is the one with the 05066 natural join flag because RIGHT joins are transformed into LEFT, 05067 and the two tables may be reordered. 05068 */ 05069 table_ref_1->natural_join= table_ref_2->natural_join= NULL; 05070 05071 /* Add a TRUE condition to outer joins that have no common columns. */ 05072 if (table_ref_2->outer_join && 05073 !table_ref_1->on_expr && !table_ref_2->on_expr) 05074 table_ref_2->on_expr= new Item_int((longlong) 1,1); /* Always true. */ 05075 05076 /* Change this table reference to become a leaf for name resolution. */ 05077 if (left_neighbor) 05078 { 05079 TABLE_LIST *last_leaf_on_the_left; 05080 last_leaf_on_the_left= left_neighbor->last_leaf_for_name_resolution(); 05081 last_leaf_on_the_left->next_name_resolution_table= table_ref; 05082 } 05083 if (right_neighbor) 05084 { 05085 TABLE_LIST *first_leaf_on_the_right; 05086 first_leaf_on_the_right= right_neighbor->first_leaf_for_name_resolution(); 05087 table_ref->next_name_resolution_table= first_leaf_on_the_right; 05088 } 05089 else 05090 table_ref->next_name_resolution_table= NULL; 05091 } 05092 result= FALSE; /* All is OK.

