diff options
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 508 |
1 files changed, 244 insertions, 264 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1f860fe23db..84da93a2131 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2012, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,11 +57,8 @@ #include <my_dir.h> #include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH #include "debug_sync.h" -#include "datadict.h" // dd_frm_type() #include "keycaches.h" -#define STR_OR_NIL(S) ((S) ? (S) : "<nil>") - #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" #endif @@ -122,6 +119,14 @@ append_algorithm(TABLE_LIST *table, String *buff); static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table); +typedef struct st_lookup_field_values +{ + LEX_STRING db_value, table_value; + bool wild_db_value, wild_table_value; +} LOOKUP_FIELD_VALUES; + +bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *); + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -160,7 +165,6 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, cs); switch (plugin_state(plugin)) { - /* case PLUGIN_IS_FREED: does not happen */ case PLUGIN_IS_DELETED: table->field[2]->store(STRING_WITH_LEN("DELETED"), cs); break; @@ -173,6 +177,9 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, case PLUGIN_IS_DISABLED: table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs); break; + case PLUGIN_IS_FREED: // filtered in fill_plugins, used in fill_all_plugins + table->field[2]->store(STRING_WITH_LEN("NOT INSTALLED"), cs); + break; default: DBUG_ASSERT(0); } @@ -270,6 +277,65 @@ int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond) } +int fill_all_plugins(THD *thd, TABLE_LIST *tables, COND *cond) +{ + DBUG_ENTER("fill_all_plugins"); + TABLE *table= tables->table; + LOOKUP_FIELD_VALUES lookup; + + if (get_lookup_field_values(thd, cond, tables, &lookup)) + DBUG_RETURN(0); + + if (lookup.db_value.str && !lookup.db_value.str[0]) + DBUG_RETURN(0); // empty string never matches a valid SONAME + + MY_DIR *dirp= my_dir(opt_plugin_dir, MY_THREAD_SPECIFIC); + if (!dirp) + { + my_error(ER_CANT_READ_DIR, MYF(0), opt_plugin_dir, my_errno); + DBUG_RETURN(1); + } + + if (!lookup.db_value.str) + plugin_dl_foreach(thd, 0, show_plugins, table); + + const char *wstr= lookup.db_value.str, *wend= wstr + lookup.db_value.length; + for (uint i=0; i < (uint) dirp->number_of_files; i++) + { + FILEINFO *file= dirp->dir_entry+i; + LEX_STRING dl= { file->name, strlen(file->name) }; + const char *dlend= dl.str + dl.length; + const size_t so_ext_len= sizeof(SO_EXT) - 1; + + if (strcasecmp(dlend - so_ext_len, SO_EXT)) + continue; + + if (lookup.db_value.str) + { + if (lookup.wild_db_value) + { + if (my_wildcmp(files_charset_info, dl.str, dlend, wstr, wend, + wild_prefix, wild_one, wild_many)) + continue; + } + else + { + if (my_strnncoll(files_charset_info, + (uchar*)dl.str, dl.length, + (uchar*)lookup.db_value.str, lookup.db_value.length)) + continue; + } + } + + plugin_dl_foreach(thd, &dl, show_plugins, table); + thd->clear_error(); + } + + my_dirend(dirp); + DBUG_RETURN(0); +} + + /*************************************************************************** ** List all Authors. ** If you can update it, you get to be in it :) @@ -689,6 +755,11 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; } +enum find_files_result { + FIND_FILES_OK, + FIND_FILES_OOM, + FIND_FILES_DIR +}; /* find_files() - find files in a given directory. @@ -697,11 +768,10 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) find_files() thd thread handler files put found files in this list - db database name to set in TABLE_LIST structure + db database name to search tables in + or NULL to search for databases path path to database wild filter for found files - dir read databases in path if TRUE, read .frm files in - database otherwise RETURN FIND_FILES_OK success @@ -710,65 +780,40 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) */ -find_files_result -find_files(THD *thd, List<LEX_STRING> *files, const char *db, - const char *path, const char *wild, bool dir) +static find_files_result +find_files(THD *thd, Dynamic_array<LEX_STRING*> *files, LEX_STRING *db, + const char *path, const LEX_STRING *wild) { - uint i; - char *ext; MY_DIR *dirp; - FILEINFO *file; - LEX_STRING *file_name= 0; - uint file_name_len; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - uint col_access=thd->col_access; -#endif - uint wild_length= 0; - TABLE_LIST table_list; + Discovered_table_list tl(thd, files, wild); DBUG_ENTER("find_files"); - if (wild) - { - if (!wild[0]) - wild= 0; - else - wild_length= strlen(wild); - } - - bzero((char*) &table_list,sizeof(table_list)); - - if (!(dirp = my_dir(path,MYF((dir ? MY_WANT_STAT : 0) | - MY_THREAD_SPECIFIC)))) + if (!(dirp = my_dir(path, MY_THREAD_SPECIFIC | (db ? 0 : MY_WANT_STAT)))) { if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); + my_error(ER_BAD_DB_ERROR, MYF(ME_BELL | ME_WAITTANG), db->str); else - my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno); + my_error(ER_CANT_READ_DIR, MYF(ME_BELL | ME_WAITTANG), path, my_errno); DBUG_RETURN(FIND_FILES_DIR); } - for (i=0 ; i < (uint) dirp->number_off_files ; i++) + if (!db) /* Return databases */ { - char uname[SAFE_NAME_LEN + 1]; /* Unencoded name */ - file=dirp->dir_entry+i; - if (dir) - { /* Return databases */ - if ((file->name[0] == '.' && - ((file->name[1] == '.' && file->name[2] == '\0') || - file->name[1] == '\0'))) - continue; /* . or .. */ + for (uint i=0; i < (uint) dirp->number_of_files; i++) + { + FILEINFO *file= dirp->dir_entry+i; #ifdef USE_SYMDIR char *ext; char buff[FN_REFLEN]; if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym")) { - /* Only show the sym file if it points to a directory */ - char *end; + /* Only show the sym file if it points to a directory */ + char *end; *ext=0; /* Remove extension */ - unpack_dirname(buff, file->name); - end= strend(buff); - if (end != buff && end[-1] == FN_LIBCHAR) - end[-1]= 0; // Remove end FN_LIBCHAR + unpack_dirname(buff, file->name); + end= strend(buff); + if (end != buff && end[-1] == FN_LIBCHAR) + end[-1]= 0; // Remove end FN_LIBCHAR if (!mysql_file_stat(key_file_misc, buff, file->mystat, MYF(0))) continue; } @@ -779,70 +824,25 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db, if (is_in_ignore_db_dirs_list(file->name)) continue; - file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); - if (wild) - { - if (lower_case_table_names) - { - if (my_wildcmp(files_charset_info, - uname, uname + file_name_len, - wild, wild + wild_length, - wild_prefix, wild_one, wild_many)) - continue; - } - else if (wild_compare(uname, wild, 0)) - continue; - } - } - else - { - // Return only .frm files which aren't temp files. - if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) || - is_prefix(file->name, tmp_file_prefix)) - continue; - *ext=0; - file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); - if (wild) - { - if (lower_case_table_names) - { - if (my_wildcmp(files_charset_info, - uname, uname + file_name_len, - wild, wild + wild_length, - wild_prefix, wild_one,wild_many)) - continue; - } - else if (wild_compare(uname, wild, 0)) - continue; - } - } -#ifndef NO_EMBEDDED_ACCESS_CHECKS - /* Don't show tables where we don't have any privileges */ - if (db && !(col_access & TABLE_ACLS)) - { - table_list.db= (char*) db; - table_list.db_length= strlen(db); - table_list.table_name= uname; - table_list.table_name_length= file_name_len; - table_list.grant.privilege=col_access; - if (check_grant(thd, TABLE_ACLS, &table_list, TRUE, 1, TRUE)) - continue; - } -#endif - if (!(file_name= - thd->make_lex_string(file_name, uname, file_name_len, TRUE)) || - files->push_back(file_name)) - { - my_dirend(dirp); - DBUG_RETURN(FIND_FILES_OOM); + if (tl.add_file(file->name)) + goto err; } + tl.sort(); + } + else + { + if (ha_discover_table_names(thd, db, dirp, &tl)) + goto err; } - DBUG_PRINT("info",("found: %d files", files->elements)); - my_dirend(dirp); - (void) ha_find_files(thd, db, path, wild, dir, files); + DBUG_PRINT("info",("found: %zu files", files->elements())); + my_dirend(dirp); DBUG_RETURN(FIND_FILES_OK); + +err: + my_dirend(dirp); + DBUG_RETURN(FIND_FILES_OOM); } @@ -2626,7 +2626,7 @@ static bool status_vars_inited= 0; C_MODE_START static int show_var_cmp(const void *var1, const void *var2) { - return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); + return strcasecmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); } C_MODE_END @@ -2831,6 +2831,17 @@ static bool show_status_array(THD *thd, const char *wild, name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) my_caseup_str(system_charset_info, name_buffer); + else + { + my_casedn_str(system_charset_info, name_buffer); + DBUG_ASSERT(name_buffer[0] >= 'a'); + DBUG_ASSERT(name_buffer[0] <= 'z'); + + /* traditionally status variables have a first letter uppercased */ + if (status_var) + name_buffer[0]-= 'a' - 'A'; + } + restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), @@ -3152,8 +3163,8 @@ int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond) int result; DBUG_ENTER("fill_schema_user_stats"); - if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) - DBUG_RETURN(1); + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL, true)) + DBUG_RETURN(0); /* Iterates through all the global stats and sends them to the client. @@ -3187,8 +3198,8 @@ int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond) int result; DBUG_ENTER("fill_schema_client_stats"); - if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) - DBUG_RETURN(1); + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL, true)) + DBUG_RETURN(0); /* Iterates through all the global stats and sends them to the client. @@ -3329,13 +3340,6 @@ void calc_sum_of_all_status(STATUS_VAR *to) /* This is only used internally, but we need it here as a forward reference */ extern ST_SCHEMA_TABLE schema_tables[]; -typedef struct st_lookup_field_values -{ - LEX_STRING db_value, table_value; - bool wild_db_value, wild_table_value; -} LOOKUP_FIELD_VALUES; - - /* Store record to I_S table, convert HEAP table to MyISAM if necessary @@ -3443,8 +3447,8 @@ bool get_lookup_value(THD *thd, Item_func *item_func, (uchar *) item_field->field_name, strlen(item_field->field_name), 0)) { - thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(), - tmp_str->length(), FALSE); + thd->make_lex_string(&lookup_field_vals->db_value, + tmp_str->ptr(), tmp_str->length()); } /* Lookup value is table name */ else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2, @@ -3452,8 +3456,8 @@ bool get_lookup_value(THD *thd, Item_func *item_func, (uchar *) item_field->field_name, strlen(item_field->field_name), 0)) { - thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(), - tmp_str->length(), FALSE); + thd->make_lex_string(&lookup_field_vals->table_value, + tmp_str->ptr(), tmp_str->length()); } } return 0; @@ -3630,7 +3634,7 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, LOOKUP_FIELD_VALUES *lookup_field_values) { LEX *lex= thd->lex; - const char *wild= lex->wild ? lex->wild->ptr() : NullS; + String *wild= lex->wild; bool rc= 0; bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES)); @@ -3638,8 +3642,8 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_DATABASES: if (wild) { - thd->make_lex_string(&lookup_field_values->db_value, - wild, strlen(wild), 0); + thd->make_lex_string(&lookup_field_values->db_value, + wild->ptr(), wild->length()); lookup_field_values->wild_db_value= 1; } break; @@ -3648,14 +3652,25 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_EVENTS: thd->make_lex_string(&lookup_field_values->db_value, - lex->select_lex.db, strlen(lex->select_lex.db), 0); + lex->select_lex.db, strlen(lex->select_lex.db)); if (wild) { thd->make_lex_string(&lookup_field_values->table_value, - wild, strlen(wild), 0); + wild->ptr(), wild->length()); lookup_field_values->wild_table_value= 1; } break; + case SQLCOM_SHOW_PLUGINS: + if (lex->ident.str) + thd->make_lex_string(&lookup_field_values->db_value, + lex->ident.str, lex->ident.length); + else if (lex->wild) + { + thd->make_lex_string(&lookup_field_values->db_value, + lex->wild->ptr(), lex->wild->length()); + lookup_field_values->wild_db_value= 1; + } + break; default: /* The "default" is for queries over I_S. @@ -3698,23 +3713,15 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) wild wild string idx_field_vals idx_field_vals->db_name contains db name or wild string - with_i_schema returns 1 if we added 'IS' name to list - otherwise returns 0 RETURN zero success non-zero error */ -int make_db_list(THD *thd, List<LEX_STRING> *files, - LOOKUP_FIELD_VALUES *lookup_field_vals, - bool *with_i_schema) +int make_db_list(THD *thd, Dynamic_array<LEX_STRING*> *files, + LOOKUP_FIELD_VALUES *lookup_field_vals) { - LEX_STRING *i_s_name_copy= 0; - i_s_name_copy= thd->make_lex_string(i_s_name_copy, - INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length, TRUE); - *with_i_schema= 0; if (lookup_field_vals->wild_db_value) { /* @@ -3727,12 +3734,11 @@ int make_db_list(THD *thd, List<LEX_STRING> *files, INFORMATION_SCHEMA_NAME.str, lookup_field_vals->db_value.str)) { - *with_i_schema= 1; - if (files->push_back(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; } - return (find_files(thd, files, NullS, mysql_data_home, - lookup_field_vals->db_value.str, 1) != FIND_FILES_OK); + return find_files(thd, files, 0, mysql_data_home, + &lookup_field_vals->db_value); } @@ -3748,12 +3754,11 @@ int make_db_list(THD *thd, List<LEX_STRING> *files, if (is_infoschema_db(lookup_field_vals->db_value.str, lookup_field_vals->db_value.length)) { - *with_i_schema= 1; - if (files->push_back(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; return 0; } - if (files->push_back(&lookup_field_vals->db_value)) + if (files->append_val(&lookup_field_vals->db_value)) return 1; return 0; } @@ -3762,17 +3767,15 @@ int make_db_list(THD *thd, List<LEX_STRING> *files, Create list of existing databases. It is used in case of select from information schema table */ - if (files->push_back(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; - *with_i_schema= 1; - return (find_files(thd, files, NullS, - mysql_data_home, NullS, 1) != FIND_FILES_OK); + return find_files(thd, files, 0, mysql_data_home, &null_lex_str); } struct st_add_schema_table { - List<LEX_STRING> *files; + Dynamic_array<LEX_STRING*> *files; const char *wild; }; @@ -3782,7 +3785,7 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, { LEX_STRING *file_name= 0; st_add_schema_table *data= (st_add_schema_table *)p_data; - List<LEX_STRING> *file_list= data->files; + Dynamic_array<LEX_STRING*> *file_list= data->files; const char *wild= data->wild; ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("add_schema_table"); @@ -3802,16 +3805,16 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, DBUG_RETURN(0); } - if ((file_name= thd->make_lex_string(file_name, schema_table->table_name, - strlen(schema_table->table_name), - TRUE)) && - !file_list->push_back(file_name)) + if ((file_name= thd->make_lex_string(schema_table->table_name, + strlen(schema_table->table_name))) && + !file_list->append(file_name)) DBUG_RETURN(0); DBUG_RETURN(1); } -int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild) +int schema_tables_add(THD *thd, Dynamic_array<LEX_STRING*> *files, + const char *wild) { LEX_STRING *file_name= 0; ST_SCHEMA_TABLE *tmp_schema_table= schema_tables; @@ -3835,9 +3838,9 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild) continue; } if ((file_name= - thd->make_lex_string(file_name, tmp_schema_table->table_name, - strlen(tmp_schema_table->table_name), TRUE)) && - !files->push_back(file_name)) + thd->make_lex_string(tmp_schema_table->table_name, + strlen(tmp_schema_table->table_name))) && + !files->append(file_name)) continue; DBUG_RETURN(1); } @@ -3862,7 +3865,6 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild) @param[in] table_names List of table names in database @param[in] lex pointer to LEX struct @param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct - @param[in] with_i_schema TRUE means that we add I_S tables to list @param[in] db_name database name @return Operation status @@ -3872,40 +3874,32 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild) */ static int -make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex, - LOOKUP_FIELD_VALUES *lookup_field_vals, - bool with_i_schema, LEX_STRING *db_name) +make_table_name_list(THD *thd, Dynamic_array<LEX_STRING*> *table_names, + LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals, + LEX_STRING *db_name) { char path[FN_REFLEN + 1]; build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0); if (!lookup_field_vals->wild_table_value && lookup_field_vals->table_value.str) { - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) { LEX_STRING *name; ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, lookup_field_vals->table_value.str); if (schema_table && !schema_table->hidden) { - if (!(name= - thd->make_lex_string(NULL, schema_table->table_name, - strlen(schema_table->table_name), TRUE)) || - table_names->push_back(name)) + if (!(name= thd->make_lex_string(schema_table->table_name, + strlen(schema_table->table_name))) || + table_names->append(name)) return 1; } } else { - if (table_names->push_back(&lookup_field_vals->table_value)) + if (table_names->append_val(&lookup_field_vals->table_value)) return 1; - /* - Check that table is relevant in current transaction. - (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc) - */ - (void) ha_find_files(thd, db_name->str, path, - lookup_field_vals->table_value.str, 0, - table_names); } return 0; } @@ -3914,12 +3908,12 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex, This call will add all matching the wildcards (if specified) IS tables to the list */ - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) return (schema_tables_add(thd, table_names, lookup_field_vals->table_value.str)); - find_files_result res= find_files(thd, table_names, db_name->str, path, - lookup_field_vals->table_value.str, 0); + find_files_result res= find_files(thd, table_names, db_name, path, + &lookup_field_vals->table_value); if (res != FIND_FILES_OK) { /* @@ -4015,10 +4009,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, These copies are used for make_table_list() while unaltered values are passed to process_table() functions. */ - if (!thd->make_lex_string(&db_name, orig_db_name->str, - orig_db_name->length, FALSE) || - !thd->make_lex_string(&table_name, orig_table_name->str, - orig_table_name->length, FALSE)) + if (!thd->make_lex_string(&db_name, + orig_db_name->str, orig_db_name->length) || + !thd->make_lex_string(&table_name, + orig_table_name->str, orig_table_name->length)) goto end; /* @@ -4085,12 +4079,14 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, of backward compatibility. */ if (!is_show_fields_or_keys && result && thd->is_error() && - thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) + (thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE || + thd->stmt_da->sql_errno() == ER_WRONG_OBJECT)) { /* Hide error for a non-existing table. For example, this error can occur when we use a where condition - with a db name and table, but the table does not exist. + with a db name and table, but the table does not exist or + there is a view with the same name. */ result= false; thd->clear_error(); @@ -4142,7 +4138,6 @@ end: @param[in] table TABLE struct for I_S table @param[in] db_name database name @param[in] table_name table name - @param[in] with_i_schema I_S table if TRUE @return Operation status @retval 0 success @@ -4150,37 +4145,28 @@ end: */ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, - LEX_STRING *db_name, LEX_STRING *table_name, - bool with_i_schema) + LEX_STRING *db_name, LEX_STRING *table_name) { TABLE *table= tables->table; - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) { table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), system_charset_info); } else if (tables->table_open_method != SKIP_OPEN_TABLE) { - enum legacy_db_type not_used; - char path[FN_REFLEN + 1]; - (void) build_table_filename(path, sizeof(path) - 1, db_name->str, - table_name->str, reg_ext, 0); - switch (dd_frm_type(thd, path, ¬_used)) { - case FRMTYPE_ERROR: - table->field[3]->store(STRING_WITH_LEN("ERROR"), - system_charset_info); - break; - case FRMTYPE_TABLE: - table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), - system_charset_info); - break; - case FRMTYPE_VIEW: - table->field[3]->store(STRING_WITH_LEN("VIEW"), - system_charset_info); - break; - default: - DBUG_ASSERT(0); + CHARSET_INFO *cs= system_charset_info; + handlerton *hton; + if (ha_table_exists(thd, db_name->str, table_name->str, &hton)) + { + if (hton == view_pseudo_hton) + table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); + else + table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); } + else + table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); + if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { thd->clear_error(); @@ -4335,10 +4321,6 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, TABLE tbl; TABLE_LIST table_list; uint res= 0; - int not_used; - my_hash_value_type hash_value; - char key[MAX_DBKEY_LENGTH]; - uint key_length; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; bzero((char*) &table_list, sizeof(TABLE_LIST)); @@ -4410,15 +4392,12 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, goto end; } - key_length= create_table_def_key(thd, key, &table_list, 0); - hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); - share= get_table_share(thd, &table_list, key, - key_length, OPEN_VIEW, ¬_used, hash_value); + share= get_table_share(thd, table_list.db, table_list.table_name, + GTS_TABLE | GTS_VIEW); if (!share) { res= 0; - goto end_unlock; + goto end; } if (share->is_view) @@ -4438,10 +4417,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, res= 1; goto end_share; } - } - if (share->is_view) - { if (open_new_frm(thd, share, table_name->str, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY), @@ -4467,10 +4443,10 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, free_root(&tbl.mem_root, MYF(0)); } + end_share: + mysql_mutex_lock(&LOCK_open); release_table_share(share); - -end_unlock: mysql_mutex_unlock(&LOCK_open); end: @@ -4560,14 +4536,12 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; TABLE *table= tables->table; + TABLE_LIST table_acl_check; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; LOOKUP_FIELD_VALUES lookup_field_vals; - LEX_STRING *db_name, *table_name; - bool with_i_schema; enum enum_schema_tables schema_table_idx; - List<LEX_STRING> db_names; - List_iterator_fast<LEX_STRING> it(db_names); + Dynamic_array<LEX_STRING*> db_names; COND *partial_cond= 0; int error= 1; Open_tables_backup open_tables_state_backup; @@ -4630,9 +4604,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'", - STR_OR_NIL(lookup_field_vals.db_value.str), - STR_OR_NIL(lookup_field_vals.table_value.str))); + DBUG_PRINT("info",("db_name='%s', table_name='%s'", + lookup_field_vals.db_value.str, + lookup_field_vals.table_value.str)); if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value) { @@ -4669,11 +4643,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema)) + bzero((char*) &table_acl_check, sizeof(table_acl_check)); + + if (make_db_list(thd, &db_names, &lookup_field_vals)) goto err; - it.rewind(); /* To get access to new elements in basis list */ - while ((db_name= it++)) + for (size_t i=0; i < db_names.elements(); i++) { + LEX_STRING *db_name= db_names.at(i); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, NULL, 0, 1) || @@ -4682,18 +4658,30 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0)) #endif { - List<LEX_STRING> table_names; + Dynamic_array<LEX_STRING*> table_names; int res= make_table_name_list(thd, &table_names, lex, - &lookup_field_vals, - with_i_schema, db_name); + &lookup_field_vals, db_name); if (res == 2) /* Not fatal error, continue */ continue; if (res) goto err; - List_iterator_fast<LEX_STRING> it_files(table_names); - while ((table_name= it_files++)) + for (size_t i=0; i < table_names.elements(); i++) { + LEX_STRING *table_name= table_names.at(i); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!(thd->col_access & TABLE_ACLS)) + { + table_acl_check.db= db_name->str; + table_acl_check.db_length= db_name->length; + table_acl_check.table_name= table_name->str; + table_acl_check.table_name_length= table_name->length; + table_acl_check.grant.privilege= thd->col_access; + if (check_grant(thd, TABLE_ACLS, &table_acl_check, TRUE, 1, TRUE)) + continue; + } +#endif restore_record(table, s->default_values); table->field[schema_table->idx_field1]-> store(db_name->str, db_name->length, system_charset_info); @@ -4721,14 +4709,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) /* SHOW TABLE NAMES command */ if (schema_table_idx == SCH_TABLE_NAMES) { - if (fill_schema_table_names(thd, tables, db_name, - table_name, with_i_schema)) + if (fill_schema_table_names(thd, tables, db_name, table_name)) continue; } else { if (!(table_open_method & ~OPEN_FRM_ONLY) && - !with_i_schema) + db_name != &INFORMATION_SCHEMA_NAME) { /* Here we need to filter out warnings, which can happen @@ -4762,11 +4749,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } } } - /* - If we have information schema its always the first table and only - the first table. Reset for other tables. - */ - with_i_schema= 0; } } @@ -4798,9 +4780,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) */ LOOKUP_FIELD_VALUES lookup_field_vals; - List<LEX_STRING> db_names; - LEX_STRING *db_name; - bool with_i_schema; + Dynamic_array<LEX_STRING*> db_names; HA_CREATE_INFO create; TABLE *table= tables->table; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -4813,15 +4793,14 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_PRINT("INDEX VALUES",("db_name: %s table_name: %s", lookup_field_vals.db_value.str, lookup_field_vals.table_value.str)); - if (make_db_list(thd, &db_names, &lookup_field_vals, - &with_i_schema)) + if (make_db_list(thd, &db_names, &lookup_field_vals)) DBUG_RETURN(1); /* If we have lookup db value we should check that the database exists */ if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value && - !with_i_schema) + db_names.at(0) != &INFORMATION_SCHEMA_NAME) { char path[FN_REFLEN+16]; uint path_len; @@ -4835,15 +4814,14 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } - List_iterator_fast<LEX_STRING> it(db_names); - while ((db_name=it++)) + for (size_t i=0; i < db_names.elements(); i++) { - if (with_i_schema) // information schema name is always first in list + LEX_STRING *db_name= db_names.at(i); + if (db_name == &INFORMATION_SCHEMA_NAME) { if (store_schema_shemata(thd, table, db_name, system_charset_info)) DBUG_RETURN(1); - with_i_schema= 0; continue; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -7473,20 +7451,20 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) break; case MYSQL_TYPE_DATE: if (!(item=new Item_return_date_time(fields_info->field_name, - MAX_DATE_WIDTH, + strlen(fields_info->field_name), fields_info->field_type))) DBUG_RETURN(0); break; case MYSQL_TYPE_TIME: if (!(item=new Item_return_date_time(fields_info->field_name, - MAX_TIME_FULL_WIDTH, + strlen(fields_info->field_name), fields_info->field_type))) DBUG_RETURN(0); break; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: if (!(item=new Item_return_date_time(fields_info->field_name, - MAX_DATETIME_WIDTH, + strlen(fields_info->field_name), fields_info->field_type))) DBUG_RETURN(0); break; @@ -7860,9 +7838,9 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, because of lower_case_table_names */ thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length, 0); + INFORMATION_SCHEMA_NAME.length); thd->make_lex_string(&table, schema_table->table_name, - strlen(schema_table->table_name), 0); + strlen(schema_table->table_name)); if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */ !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0), 0, 0, TL_READ, MDL_SHARED_READ)) @@ -8664,7 +8642,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, - {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, + {"PLUGIN_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library", @@ -8925,6 +8903,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"PLUGINS", plugin_fields_info, create_schema_table, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, + {"ALL_PLUGINS", plugin_fields_info, create_schema_table, + fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, {"PROFILING", query_profile_statistics_info, create_schema_table, |