Commit 5fdf0327 authored by tim@cane.mysql.fi's avatar tim@cane.mysql.fi

Added SHOW OPEN TABLES. Thanks to Antony T Curtis <antony@abacus.co.uk>

for the code.
parent f11d5c83
...@@ -19889,7 +19889,7 @@ commands to examine and kill threads. ...@@ -19889,7 +19889,7 @@ commands to examine and kill threads.
@example @example
SHOW DATABASES [LIKE wild] SHOW DATABASES [LIKE wild]
or SHOW TABLES [FROM db_name] [LIKE wild] or SHOW [OPEN] TABLES [FROM db_name] [LIKE wild]
or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild] or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
or SHOW INDEX FROM tbl_name [FROM db_name] or SHOW INDEX FROM tbl_name [FROM db_name]
or SHOW TABLE STATUS [FROM db_name] [LIKE wild] or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
...@@ -19945,6 +19945,10 @@ get this list using the @code{mysqlshow db_name} command. ...@@ -19945,6 +19945,10 @@ get this list using the @code{mysqlshow db_name} command.
will not show up in the output from @code{SHOW TABLES} or @code{mysqlshow will not show up in the output from @code{SHOW TABLES} or @code{mysqlshow
db_name}. db_name}.
@code{SHOW OPEN TABLES} lists the tables that are currently open in
the table cache. @xref{Table cache}. The @code{Comment} field tells
how many times the table is @code{cached} and @code{in_use}.
@code{SHOW COLUMNS} lists the columns in a given table. If the column @code{SHOW COLUMNS} lists the columns in a given table. If the column
types are different than you expect them to be based on a @code{CREATE types are different than you expect them to be based on a @code{CREATE
TABLE} statement, note that @strong{MySQL} sometimes changes column TABLE} statement, note that @strong{MySQL} sometimes changes column
...@@ -472,7 +472,7 @@ int main(int argc,char **argv) ...@@ -472,7 +472,7 @@ int main(int argc,char **argv)
int error; int error;
MY_INIT(argv[0]); MY_INIT(argv[0]);
start_value=2610463L; best_t1=8358376L; best_t2=860646L; best_type=2; /* mode=4111 add=8 func_type: 0 */ start_value=5206280L; best_t1=590774L; best_t2=5977654L; best_type=1; /* mode=6229 add=2 func_type: 0 */
if (get_options(argc,(char **) argv)) if (get_options(argc,(char **) argv))
exit(1); exit(1);
......
...@@ -223,6 +223,7 @@ static SYMBOL symbols[] = { ...@@ -223,6 +223,7 @@ static SYMBOL symbols[] = {
{ "NOT", SYM(NOT),0,0}, { "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0}, { "NULL", SYM(NULL_SYM),0,0},
{ "ON", SYM(ON),0,0}, { "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0}, { "OPTIMIZE", SYM(OPTIMIZE),0,0},
{ "OPTION", SYM(OPTION),0,0}, { "OPTION", SYM(OPTION),0,0},
{ "OPTIONALLY", SYM(OPTIONALLY),0,0}, { "OPTIONALLY", SYM(OPTIONALLY),0,0},
......
...@@ -354,6 +354,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, ...@@ -354,6 +354,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_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);
...@@ -418,6 +419,8 @@ bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables); ...@@ -418,6 +419,8 @@ 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> *files, const char *db,const char *wild);
char* query_table_status(THD *thd,const char *db,const char *table_name);
/* sql_calc.cc */ /* sql_calc.cc */
bool eval_const_cond(COND *cond); bool eval_const_cond(COND *cond);
......
...@@ -112,6 +112,74 @@ static void check_unused(void) ...@@ -112,6 +112,74 @@ 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,const char *wild)
{
int result = 0;
uint col_access=thd->col_access;
TABLE_LIST table_list;
DBUG_ENTER("list_open_tables");
VOID(pthread_mutex_lock(&LOCK_open));
bzero((char*) &table_list,sizeof(table_list));
for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
{
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))
{
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))
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++))
{
if (!strcmp(table_name,entry->real_name))
check++;
}
if (check)
continue;
if (tables->push_back(thd->strdup(entry->real_name)))
{
result = -1;
}
}
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);
}
/****************************************************************************** /******************************************************************************
......
...@@ -52,7 +52,8 @@ enum enum_sql_command { ...@@ -52,7 +52,8 @@ enum enum_sql_command {
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE, SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
SQLCOM_SHOW_OPEN_TABLES
}; };
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
......
...@@ -1488,6 +1488,8 @@ mysql_execute_command(void) ...@@ -1488,6 +1488,8 @@ mysql_execute_command(void)
} }
#endif #endif
case SQLCOM_SHOW_TABLES: case SQLCOM_SHOW_TABLES:
/* FALL THROUGH */
case SQLCOM_SHOW_OPEN_TABLES:
#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 */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -1508,8 +1510,11 @@ mysql_execute_command(void) ...@@ -1508,8 +1510,11 @@ 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->options & SELECT_DESCRIBE) if (lex->sql_command == SQLCOM_SHOW_OPEN_TABLES)
res= mysqld_extend_show_tables(thd,db, res= mysqld_show_open_tables(thd,db,
(lex->wild ? lex->wild->ptr() : NullS));
else if (lex->options & SELECT_DESCRIBE)
res= mysqld_extend_show_tables(thd,db,
(lex->wild ? lex->wild->ptr() : NullS)); (lex->wild ? lex->wild->ptr() : NullS));
else else
res= mysqld_show_tables(thd,db, res= mysqld_show_tables(thd,db,
......
...@@ -86,6 +86,47 @@ mysqld_show_dbs(THD *thd,const char *wild) ...@@ -86,6 +86,47 @@ mysqld_show_dbs(THD *thd,const char *wild)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/***************************************************************************
** List all open tables in a database
***************************************************************************/
int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
{
Item_string *field=new Item_string("",0);
List<Item> field_list;
char *end,*table_name;
List<char> tables;
DBUG_ENTER("mysqld_show_open_tables");
field->name=(char*) thd->alloc(20+(uint) strlen(db)+(wild ? (uint) strlen(wild)+4:0));
end=strxmov(field->name,"Open_tables_in_",db,NullS);
if (wild && wild[0])
strxmov(end," (",wild,")",NullS);
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))
DBUG_RETURN(1);
if (list_open_tables(thd,&tables,db,wild))
DBUG_RETURN(-1);
List_iterator<char> it(tables);
while ((table_name=it++))
{
thd->packet.length(0);
net_store_data(&thd->packet,table_name);
net_store_data(&thd->packet,query_table_status(thd,db,table_name));
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
DBUG_RETURN(0);
}
/*************************************************************************** /***************************************************************************
** List all tables in a database (fast version) ** List all tables in a database (fast version)
** A table is a .frm file in the current databasedir ** A table is a .frm file in the current databasedir
...@@ -161,9 +202,9 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -161,9 +202,9 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
} }
else else
{ {
// Return only .frm files which isn't temp files. // Return only .frm files which aren't temp files.
if (my_strcasecmp(ext=fn_ext(file->name),reg_ext) || if (my_strcasecmp(ext=fn_ext(file->name),reg_ext) ||
is_prefix(file->name,tmp_file_prefix)) // Mysql temp table is_prefix(file->name,tmp_file_prefix))
continue; continue;
*ext=0; *ext=0;
if (wild && wild[0] && wild_compare(file->name,wild)) if (wild && wild[0] && wild_compare(file->name,wild))
......
...@@ -216,6 +216,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -216,6 +216,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NULL_SYM %token NULL_SYM
%token NUM %token NUM
%token ON %token ON
%token OPEN_SYM
%token OPTION %token OPTION
%token OPTIONALLY %token OPTIONALLY
%token OR %token OR
...@@ -2151,6 +2152,11 @@ show_param: ...@@ -2151,6 +2152,11 @@ show_param:
Lex->options|= SELECT_DESCRIBE; Lex->options|= SELECT_DESCRIBE;
Lex->db= $3; Lex->db= $3;
} }
| OPEN_SYM TABLES opt_db wild
{ Lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
Lex->db= $3;
Lex->options=0;
}
| COLUMNS FROM table_ident opt_db wild | COLUMNS FROM table_ident opt_db wild
{ {
Lex->sql_command= SQLCOM_SHOW_FIELDS; Lex->sql_command= SQLCOM_SHOW_FIELDS;
...@@ -2513,6 +2519,7 @@ keyword: ...@@ -2513,6 +2519,7 @@ keyword:
| NATIONAL_SYM {} | NATIONAL_SYM {}
| NCHAR_SYM {} | NCHAR_SYM {}
| NO_SYM {} | NO_SYM {}
| OPEN_SYM {}
| PACK_KEYS_SYM {} | PACK_KEYS_SYM {}
| PASSWORD {} | PASSWORD {}
| PROCESS {} | PROCESS {}
......
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