diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 231 |
1 files changed, 109 insertions, 122 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 624377b688e..9ba5277a92c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -34,8 +34,6 @@ HASH open_cache; /* Used by mysql_test */ static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, const char *name, const char *alias, bool locked); -static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, - const char *table_name, List_iterator<Item> *it); static void free_cache_entry(TABLE *entry); static void mysql_rm_tmp_tables(void); static key_map get_key_map_from_key_list(TABLE *table, @@ -111,75 +109,71 @@ static void check_unused(void) #define check_unused() #endif -int list_open_tables(THD *thd,List<char> *tables, const char *db, - const char *wild) +OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) { int result = 0; uint col_access=thd->col_access; + OPEN_TABLE_LIST **start_list, *open_list; TABLE_LIST table_list; + char name[NAME_LEN*2]; DBUG_ENTER("list_open_tables"); + VOID(pthread_mutex_lock(&LOCK_open)); bzero((char*) &table_list,sizeof(table_list)); + start_list= &open_list; + open_list=0; - for (uint idx=0 ; idx < open_cache.records; idx++) + for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++) { + OPEN_TABLE_LIST *table; TABLE *entry=(TABLE*) hash_element(&open_cache,idx); - if ((!entry->real_name) || strcmp(entry->table_cache_key,db)) - continue; - if (wild && wild[0] && wild_compare(entry->real_name,wild)) - continue; - if (db && !(col_access & TABLE_ACLS)) + + if ((!entry->real_name)) + continue; // Shouldn't happen + if (wild) { - table_list.db= (char*) db; - table_list.real_name= entry->real_name;/*real name*/ - table_list.grant.privilege=col_access; - if (check_grant(thd,TABLE_ACLS,&table_list,1,1)) - continue; + strxmov(name,entry->table_cache_key,".",entry->real_name,NullS); + if (wild_compare(name,wild)) + continue; } - /* need to check if he have't already listed it */ - List_iterator<char> it(*tables); - char *table_name; - int check = 0; - while (check == 0 && (table_name=it++)) + /* Check if user has SELECT privilege for any column in the table */ + table_list.db= (char*) entry->table_cache_key; + table_list.real_name= entry->real_name; + table_list.grant.privilege=0; + if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list)) + continue; + + /* need to check if we haven't already listed it */ + for (table= open_list ; table ; table=table->next) { - if (!strcmp(table_name,entry->real_name)) - check++; + if (!strcmp(table->table,entry->real_name) && + !strcmp(table->db,entry->table_cache_key)) + { + if (entry->in_use) + table->in_use++; + if (entry->locked_by_name) + table->locked++; + break; + } } - if (check) + if (table) continue; - - if (tables->push_back(thd->strdup(entry->real_name))) + if (!(*start_list = (OPEN_TABLE_LIST *) + sql_alloc(sizeof(OPEN_TABLE_LIST)+entry->key_length))) { - result = -1; + open_list=0; // Out of memory break; } + (*start_list)->table=(strmov((*start_list)->db=(char*) ((*start_list)+1), + entry->table_cache_key)+1, + entry->real_name); + (*start_list)->in_use= entry->in_use ? 1 : 0; + (*start_list)->locked= entry->locked_by_name ? 1 : 0; + start_list= &(*start_list)->next; } - VOID(pthread_mutex_unlock(&LOCK_open)); - DBUG_RETURN(result); -} - -char* -query_table_status(THD *thd,const char *db,const char *table_name) -{ - int cached = 0, in_use = 0; - char info[256]; - - for (uint idx=0 ; idx < open_cache.records; idx++) - { - TABLE *entry=(TABLE*) hash_element(&open_cache,idx); - if (strcmp(entry->table_cache_key,db) || - strcmp(entry->real_name,table_name)) - continue; - - cached++; - if (entry->in_use) - in_use++; - } - - sprintf(info, "cached=%d, in_use=%d", cached, in_use); - return thd->strdup(info); + DBUG_RETURN(open_list); } @@ -195,7 +189,7 @@ query_table_status(THD *thd,const char *db,const char *table_name) bool send_fields(THD *thd,List<Item> &list,uint flag) { - List_iterator<Item> it(list); + List_iterator_fast<Item> it(list); Item *item; char buff[80]; CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; @@ -259,7 +253,7 @@ send_fields(THD *thd,List<Item> &list,uint flag) if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) break; /* purecov: inspected */ } - send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1); + send_eof(&thd->net); return 0; err: send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ @@ -431,40 +425,9 @@ void close_thread_tables(THD *thd, bool locked) DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables)); - for (table=thd->open_tables ; table ; table=next) - { - next=table->next; - if (table->version != refresh_version || - thd->version != refresh_version || !table->db_stat) - { - VOID(hash_delete(&open_cache,(byte*) table)); - found_old_table=1; - } - else - { - if (table->flush_version != flush_version) - { - table->flush_version=flush_version; - table->file->extra(HA_EXTRA_FLUSH); - } - else - { - // Free memory and reset for next loop - table->file->extra(HA_EXTRA_RESET); - } - table->in_use=0; - if (unused_tables) - { - table->next=unused_tables; /* Link in last */ - table->prev=unused_tables->prev; - unused_tables->prev=table; - table->prev->next=table; - } - else - unused_tables=table->next=table->prev=table; - } - } - thd->open_tables=0; + while (thd->open_tables) + found_old_table|=close_thread_table(thd, &thd->open_tables); + /* Free tables to hold down open files */ while (open_cache.records > table_cache_size && unused_tables) VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ @@ -480,6 +443,48 @@ void close_thread_tables(THD *thd, bool locked) DBUG_VOID_RETURN; } +/* move one table to free list */ + +bool close_thread_table(THD *thd, TABLE **table_ptr) +{ + DBUG_ENTER("close_thread_table"); + + bool found_old_table=0; + TABLE *table=*table_ptr; + + *table_ptr=table->next; + if (table->version != refresh_version || + thd->version != refresh_version || !table->db_stat) + { + VOID(hash_delete(&open_cache,(byte*) table)); + found_old_table=1; + } + else + { + if (table->flush_version != flush_version) + { + table->flush_version=flush_version; + table->file->extra(HA_EXTRA_FLUSH); + } + else + { + // Free memory and reset for next loop + table->file->extra(HA_EXTRA_RESET); + } + table->in_use=0; + if (unused_tables) + { + table->next=unused_tables; /* Link in last */ + table->prev=unused_tables->prev; + unused_tables->prev=table; + table->prev->next=table; + } + else + unused_tables=table->next=table->prev=table; + } + DBUG_RETURN(found_old_table); +} + /* Close and delete temporary tables */ void close_temporary(TABLE *table,bool delete_table) @@ -689,7 +694,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) if (thd->killed) DBUG_RETURN(0); TABLE* table; - if(!(table = table_list->table)) + if (!(table = table_list->table)) DBUG_RETURN(0); char* db = thd->db ? thd->db : table_list->db; @@ -836,25 +841,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, !(table->table_cache_key=memdup_root(&table->mem_root,(char*) key, key_length))) { - MEM_ROOT* glob_alloc; - LINT_INIT(glob_alloc); - - if (errno == ENOENT && - (glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC))) - // Sasha: needed for replication - // remember the name of the non-existent table - // so we can try to download it from the master - { - int table_name_len = (uint) strlen(table_name); - int db_len = (uint) strlen(db); - thd->last_nx_db = alloc_root(glob_alloc,db_len + table_name_len + 2); - if(thd->last_nx_db) - { - thd->last_nx_table = thd->last_nx_db + db_len + 1; - memcpy(thd->last_nx_table, table_name, table_name_len + 1); - memcpy(thd->last_nx_db, db, db_len + 1); - } - } table->next=table->prev=table; free_cache_entry(table); VOID(pthread_mutex_unlock(&LOCK_open)); @@ -1337,7 +1323,7 @@ int open_tables(THD *thd,TABLE_LIST *start) { if (!tables->table && !(tables->table=open_table(thd, - tables->db ? tables->db : thd->db, + tables->db, tables->real_name, tables->name, &refresh))) { @@ -1394,7 +1380,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) DBUG_ENTER("open_ltable"); thd->proc_info="Opening table"; - while (!(table=open_table(thd,table_list->db ? table_list->db : thd->db, + while (!(table=open_table(thd,table_list->db, table_list->real_name,table_list->name, &refresh)) && refresh) ; if (table) @@ -1626,9 +1612,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) for (; tables ; tables=tables->next) { if (!strcmp(tables->name,table_name) && - (!db || - (tables->db && !strcmp(db,tables->db)) || - (!tables->db && !strcmp(db,thd->db)))) + (!db || !strcmp(db,tables->db))) { found_table=1; Field *find=find_field_in_table(thd,tables->table,name,length, @@ -1752,14 +1736,15 @@ find_item_in_list(Item *find,List<Item> &items) ****************************************************************************/ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, - bool set_query_id, List<Item> *sum_func_list) + bool set_query_id, List<Item> *sum_func_list, + bool allow_sum_func) { reg2 Item *item; List_iterator<Item> it(fields); DBUG_ENTER("setup_fields"); thd->set_query_id=set_query_id; - thd->allow_sum_func= test(sum_func_list); + thd->allow_sum_func= allow_sum_func; thd->where="field list"; while ((item=it++)) @@ -1775,7 +1760,8 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, { if (item->fix_fields(thd,tables)) DBUG_RETURN(-1); /* purecov: inspected */ - if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) + if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && + sum_func_list) item->split_sum_func(*sum_func_list); thd->used_tables|=item->used_tables(); } @@ -1830,7 +1816,7 @@ static key_map get_key_map_from_key_list(TABLE *table, List<String> *index_list) { key_map map=0; - List_iterator<String> it(*index_list); + List_iterator_fast<String> it(*index_list); String *name; uint pos; while ((name=it++)) @@ -1851,7 +1837,7 @@ static key_map get_key_map_from_key_list(TABLE *table, ** Returns pointer to last inserted field if ok ****************************************************************************/ -static bool +bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it) { @@ -1866,8 +1852,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, check_grant_all_columns(thd,SELECT_ACL,table) ) DBUG_RETURN(-1); if (!table_name || (!strcmp(table_name,tables->name) && - (!db_name || !tables->db || - !strcmp(tables->db,db_name)))) + (!db_name || !strcmp(tables->db,db_name)))) { Field **ptr=table->field,*field; thd->used_tables|=table->map; @@ -2010,7 +1995,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) int fill_record(List<Item> &fields,List<Item> &values) { - List_iterator<Item> f(fields),v(values); + List_iterator_fast<Item> f(fields),v(values); Item *value; Item_field *field; DBUG_ENTER("fill_record"); @@ -2028,7 +2013,7 @@ fill_record(List<Item> &fields,List<Item> &values) int fill_record(Field **ptr,List<Item> &values) { - List_iterator<Item> v(values); + List_iterator_fast<Item> v(values); Item *value; DBUG_ENTER("fill_record"); @@ -2091,7 +2076,8 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) create_info.db_type=DB_TYPE_DEFAULT; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, - fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR)); + fields, keys, drop, alter, (ORDER*)0, FALSE, + DUP_ERROR)); } @@ -2106,7 +2092,8 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) create_info.db_type=DB_TYPE_DEFAULT; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, - fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR)); + fields, keys, drop, alter, (ORDER*)0, FALSE, + DUP_ERROR)); } /***************************************************************************** |