Commit 5d58a49f authored by monty@tik.mysql.fi's avatar monty@tik.mysql.fi

Merge work.mysql.com:/home/bk/mysql-4.0

into tik.mysql.fi:/home/my/mysql-4.0
parents 38d3bf51 539541c5
...@@ -90,6 +90,6 @@ t1 CREATE TABLE `t1` ( ...@@ -90,6 +90,6 @@ t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0', `a` int(11) NOT NULL default '0',
PRIMARY KEY (`a`) PRIMARY KEY (`a`)
) TYPE=MyISAM ) TYPE=MyISAM
Open_tables_in_test Comment Database Table In_use Name_locked
Open_tables_in_test Comment Database Table In_use Name_locked
t1 cached=1, in_use=0 test t1 0 0
...@@ -37,17 +37,19 @@ extern ulong myisam_recover_options; ...@@ -37,17 +37,19 @@ extern ulong myisam_recover_options;
class ha_myisam: public handler class ha_myisam: public handler
{ {
MI_INFO *file; MI_INFO *file;
uint int_option_flag,enable_activate_all_index; uint int_option_flag;
char *data_file_name, *index_file_name; char *data_file_name, *index_file_name;
bool enable_activate_all_index;
int repair(THD *thd, MI_CHECK &param, bool optimize); int repair(THD *thd, MI_CHECK &param, bool optimize);
public: public:
ha_myisam(TABLE *table): handler(table), file(0),enable_activate_all_index(1), ha_myisam(TABLE *table): handler(table), file(0),
int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME | int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
HA_LONGLONG_KEYS | HA_NULL_KEY | HA_LONGLONG_KEYS | HA_NULL_KEY |
HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY) HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY),
enable_activate_all_index(1)
{} {}
~ha_myisam() {} ~ha_myisam() {}
const char *table_type() const { return "MyISAM"; } const char *table_type() const { return "MyISAM"; }
......
...@@ -374,7 +374,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, ...@@ -374,7 +374,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
/* sql_list.c */ /* sql_list.c */
int mysqld_show_dbs(THD *thd,const char *wild); int mysqld_show_dbs(THD *thd,const char *wild);
int mysqld_show_open_tables(THD *thd,const char *db,const char *wild); int mysqld_show_open_tables(THD *thd,const char *wild);
int mysqld_show_tables(THD *thd,const char *db,const char *wild); int mysqld_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild); int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild, int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild,
...@@ -451,8 +451,7 @@ bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables); ...@@ -451,8 +451,7 @@ bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
void copy_field_from_tmp_record(Field *field,int offset); void copy_field_from_tmp_record(Field *field,int offset);
int fill_record(List<Item> &fields,List<Item> &values); int fill_record(List<Item> &fields,List<Item> &values);
int fill_record(Field **field,List<Item> &values); int fill_record(Field **field,List<Item> &values);
int list_open_tables(THD *thd,List<char> *tables, const char *db, OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild);
const char *wild);
/* sql_calc.cc */ /* sql_calc.cc */
bool eval_const_cond(COND *cond); bool eval_const_cond(COND *cond);
......
...@@ -109,75 +109,71 @@ static void check_unused(void) ...@@ -109,75 +109,71 @@ static void check_unused(void)
#define check_unused() #define check_unused()
#endif #endif
int list_open_tables(THD *thd,List<char> *tables, const char *db, OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
const char *wild)
{ {
int result = 0; int result = 0;
uint col_access=thd->col_access; uint col_access=thd->col_access;
OPEN_TABLE_LIST **start_list, *open_list;
TABLE_LIST table_list; TABLE_LIST table_list;
char name[NAME_LEN*2];
DBUG_ENTER("list_open_tables"); DBUG_ENTER("list_open_tables");
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
bzero((char*) &table_list,sizeof(table_list)); 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); TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
continue; if ((!entry->real_name))
if (wild && wild[0] && wild_compare(entry->real_name,wild)) continue; // Shouldn't happen
continue; if (wild)
if (db && !(col_access & TABLE_ACLS))
{ {
table_list.db= (char*) db; strxmov(name,entry->table_cache_key,".",entry->real_name,NullS);
table_list.real_name= entry->real_name;/*real name*/ if (wild_compare(name,wild))
table_list.grant.privilege=col_access; continue;
if (check_grant(thd,TABLE_ACLS,&table_list,1))
continue;
} }
/* need to check if he have't already listed it */
List_iterator<char> it(*tables); /* Check if user has SELECT privilege for any column in the table */
char *table_name; table_list.db= (char*) entry->table_cache_key;
int check = 0; table_list.real_name= entry->real_name;
while (check == 0 && (table_name=it++)) 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)) if (!strcmp(table->table,entry->real_name) &&
check++; !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; continue;
if (!(*start_list = (OPEN_TABLE_LIST *)
if (tables->push_back(thd->strdup(entry->real_name))) sql_alloc(sizeof(OPEN_TABLE_LIST)+entry->key_length)))
{ {
result = -1; open_list=0; // Out of memory
break; 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)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(result); DBUG_RETURN(open_list);
}
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);
} }
...@@ -257,7 +253,7 @@ send_fields(THD *thd,List<Item> &list,uint flag) ...@@ -257,7 +253,7 @@ send_fields(THD *thd,List<Item> &list,uint flag)
if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */ break; /* purecov: inspected */
} }
send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1); send_eof(&thd->net);
return 0; return 0;
err: err:
send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
...@@ -405,47 +401,6 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, ...@@ -405,47 +401,6 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
DBUG_RETURN(result); DBUG_RETURN(result);
} }
/* 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);
}
/* Put all tables used by thread in free list */ /* Put all tables used by thread in free list */
...@@ -469,40 +424,9 @@ void close_thread_tables(THD *thd, bool locked) ...@@ -469,40 +424,9 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables)); DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
for (table=thd->open_tables ; table ; table=next) while (thd->open_tables)
{ found_old_table|=close_thread_table(thd, &thd->open_tables);
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;
/* Free tables to hold down open files */ /* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables) while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
...@@ -518,6 +442,48 @@ void close_thread_tables(THD *thd, bool locked) ...@@ -518,6 +442,48 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_VOID_RETURN; 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 */ /* Close and delete temporary tables */
void close_temporary(TABLE *table,bool delete_table) void close_temporary(TABLE *table,bool delete_table)
......
...@@ -47,7 +47,7 @@ static void mysql_init_query(THD *thd); ...@@ -47,7 +47,7 @@ static void mysql_init_query(THD *thd);
static void remove_escape(char *name); static void remove_escape(char *name);
static void refresh_status(void); static void refresh_status(void);
static bool append_file_to_dir(char **filename_ptr, char *table_name); static bool append_file_to_dir(char **filename_ptr, char *table_name);
static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables); static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables);
const char *any_db="*any*"; // Special symbol for check_access const char *any_db="*any*"; // Special symbol for check_access
...@@ -663,7 +663,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) ...@@ -663,7 +663,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
int error = 0; int error = 0;
DBUG_ENTER("mysql_table_dump"); DBUG_ENTER("mysql_table_dump");
db = (db && db[0]) ? db : thd->db; db = (db && db[0]) ? db : thd->db;
if (!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST)))) if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(1); // out of memory DBUG_RETURN(1); // out of memory
table_list->db = db; table_list->db = db;
table_list->real_name = table_list->name = tbl_name; table_list->real_name = table_list->name = tbl_name;
...@@ -780,7 +780,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -780,7 +780,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
slow_command = TRUE; slow_command = TRUE;
uint db_len = *(uchar*)packet; uint db_len = *(uchar*)packet;
uint tbl_len = *(uchar*)(packet + db_len + 1); uint tbl_len = *(uchar*)(packet + db_len + 1);
char* db = sql_alloc(db_len + tbl_len + 2); char* db = thd->alloc(db_len + tbl_len + 2);
memcpy(db, packet + 1, db_len); memcpy(db, packet + 1, db_len);
char* tbl_name = db + db_len; char* tbl_name = db + db_len;
*tbl_name++ = 0; *tbl_name++ = 0;
...@@ -973,7 +973,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -973,7 +973,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char buff[200]; char buff[200];
ulong uptime = (ulong) (thd->start_time - start_time); ulong uptime = (ulong) (thd->start_time - start_time);
sprintf((char*) buff, sprintf((char*) buff,
"Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %d Queries per second avg: %.3f", "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f",
uptime, uptime,
(int) thread_count,thd->query_id,long_query_count, (int) thread_count,thd->query_id,long_query_count,
opened_tables,refresh_version, cached_tables(), opened_tables,refresh_version, cached_tables(),
...@@ -1819,7 +1819,6 @@ mysql_execute_command(void) ...@@ -1819,7 +1819,6 @@ mysql_execute_command(void)
} }
#endif #endif
case SQLCOM_SHOW_TABLES: case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_OPEN_TABLES:
/* FALL THROUGH */ /* FALL THROUGH */
#ifdef DONT_ALLOW_SHOW_COMMANDS #ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
...@@ -1841,10 +1840,7 @@ mysql_execute_command(void) ...@@ -1841,10 +1840,7 @@ mysql_execute_command(void)
if (check_access(thd,SELECT_ACL,db,&thd->col_access)) if (check_access(thd,SELECT_ACL,db,&thd->col_access))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
/* grant is checked in mysqld_show_tables */ /* grant is checked in mysqld_show_tables */
if (lex->sql_command == SQLCOM_SHOW_OPEN_TABLES) if (select_lex->options & SELECT_DESCRIBE)
res= mysqld_show_open_tables(thd, db,
(lex->wild ? lex->wild->ptr() : NullS));
else if (select_lex->options & SELECT_DESCRIBE)
res= mysqld_extend_show_tables(thd,db, res= mysqld_extend_show_tables(thd,db,
(lex->wild ? lex->wild->ptr() : NullS)); (lex->wild ? lex->wild->ptr() : NullS));
else else
...@@ -1853,6 +1849,9 @@ mysql_execute_command(void) ...@@ -1853,6 +1849,9 @@ mysql_execute_command(void)
break; break;
} }
#endif #endif
case SQLCOM_SHOW_OPEN_TABLES:
res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS));
break;
case SQLCOM_SHOW_FIELDS: case SQLCOM_SHOW_FIELDS:
#ifdef DONT_ALLOW_SHOW_COMMANDS #ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
...@@ -2451,7 +2450,7 @@ void ...@@ -2451,7 +2450,7 @@ void
mysql_new_select(LEX *lex) mysql_new_select(LEX *lex)
{ {
uint select_no=lex->select->select_number; uint select_no=lex->select->select_number;
SELECT_LEX *select_lex = (SELECT_LEX *)sql_calloc(sizeof(SELECT_LEX)); SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
lex->select->next=select_lex; lex->select->next=select_lex;
lex->select=select_lex; lex->select->select_number = ++select_no; lex->select=select_lex; lex->select->select_number = ++select_no;
lex->select->item_list = lex->select_lex.item_list; lex->select->item_list = lex->select_lex.item_list;
......
...@@ -95,21 +95,17 @@ mysqld_show_dbs(THD *thd,const char *wild) ...@@ -95,21 +95,17 @@ mysqld_show_dbs(THD *thd,const char *wild)
** List all open tables in a database ** List all open tables in a database
***************************************************************************/ ***************************************************************************/
int mysqld_show_open_tables(THD *thd,const char *db,const char *wild) int mysqld_show_open_tables(THD *thd,const char *wild)
{ {
Item_string *field=new Item_string("",0);
List<Item> field_list; List<Item> field_list;
char *end,*table_name; OPEN_TABLE_LIST *open_list;
List<char> tables; CONVERT *convert=thd->convert_set;
DBUG_ENTER("mysqld_show_open_tables"); DBUG_ENTER("mysqld_show_open_tables");
field->name=(char*) thd->alloc(20+(uint) strlen(db)+(wild ? (uint) strlen(wild)+4:0)); field_list.push_back(new Item_empty_string("Database",NAME_LEN));
end=strxmov(field->name,"Open_tables_in_",db,NullS); field_list.push_back(new Item_empty_string("Table",NAME_LEN));
if (wild && wild[0]) field_list.push_back(new Item_int("In_use",0, 4));
strxmov(end," (",wild,")",NullS); field_list.push_back(new Item_int("Name_locked",0, 4));
field->max_length=NAME_LEN;
field_list.push_back(field);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1)) if (send_fields(thd,field_list,1))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -117,12 +113,13 @@ int mysqld_show_open_tables(THD *thd,const char *db,const char *wild) ...@@ -117,12 +113,13 @@ int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
if (!(list_open_tables(thd,&tables,db,wild)) && thd->fatal_error) if (!(list_open_tables(thd,&tables,db,wild)) && thd->fatal_error)
DBUG_RETURN(-1); DBUG_RETURN(-1);
List_iterator<char> it(tables); for ( ; open_list ; open_list=open_list->next)
while ((table_name=it++))
{ {
thd->packet.length(0); thd->packet.length(0);
net_store_data(&thd->packet,table_name); net_store_data(&thd->packet,convert, open_list->db);
net_store_data(&thd->packet,query_table_status(thd,db,table_name)); net_store_data(&thd->packet,convert, open_list->table);
net_store_data(&thd->packet,open_list->in_use);
net_store_data(&thd->packet,open_list->locked);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment