List:Commits« Previous MessageNext Message »
From:gluh Date:February 8 2007 10:33am
Subject:bk commit into 5.1 tree (gluh:1.2368) BUG#19588
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of gluh. When gluh does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-02-08 14:33:02+04:00, gluh@stripped +11 -0
  Bug#19588 INFORMATION_SCHEMA performs much too slow on large servers
  optimization of 'WHERE' condition for I_S tables:
  extract base name & table name values from 'WHERE' when it's possible
  optimization of table opening:
  open .frm file only if we can obtain necessary values from .frm file
  skip table opening if we need base name & table name only(for I_S.TABLES table)

  sql/ha_ndbcluster.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +37 -30
    'char' changed to LEX_STRING  

  sql/ha_ndbcluster.h@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +1 -1
    'char' changed to LEX_STRING  

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +4 -4
    'char' changed to LEX_STRING  

  sql/handler.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +2 -2
    'char' changed to LEX_STRING  

  sql/handler.h@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +2 -2
    'char' changed to LEX_STRING  

  sql/mysql_priv.h@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +1 -1
    new mutex LOCK_information_schema

  sql/mysqld.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +4 -1
    new mutex LOCK_information_schema

  sql/sql_base.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +12 -9
    skip .MYD & .MYI files opening if it's possible

  sql/sql_show.cc@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +1004 -695
    optimization of 'WHERE' condition for I_S tables:
    extract base name & table name values from 'WHERE' when it's possible
    optimization of table opening:
    open .frm file only if we can obtain necessary values from .frm file
    skip table opening if we need base name & table name only(for I_S.TABLES table)
    

  sql/sql_show.h@stripped, 2007-02-08 14:32:59+04:00, gluh@stripped +1 -1
    'char' changed to LEX_STRING  

  sql/table.h@stripped, 2007-02-08 14:33:00+04:00, gluh@stripped +8 -2
    added 'open_method' to ST_FIELD_INFO struct
    added 'open_frm_only' to TABLE_LIST struct

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gluh
# Host:	eagle.(none)
# Root:	/home/gluh/MySQL/Bugs/5.1.19588

--- 1.289/sql/handler.cc	2006-12-23 23:19:49 +04:00
+++ 1.290/sql/handler.cc	2007-02-08 14:32:59 +04:00
@@ -2835,7 +2835,7 @@ struct st_find_files_args
   const char *path;
   const char *wild;
   bool dir;
-  List<char> *files;
+  List<LEX_STRING> *files;
 };
 
 static my_bool find_files_handlerton(THD *thd, st_plugin_int *plugin,
@@ -2855,7 +2855,7 @@ static my_bool find_files_handlerton(THD
 
 int
 ha_find_files(THD *thd,const char *db,const char *path,
-	      const char *wild, bool dir, List<char> *files)
+	      const char *wild, bool dir, List<LEX_STRING> *files)
 {
   int error= 0;
   DBUG_ENTER("ha_find_files");

--- 1.249/sql/handler.h	2006-12-23 23:19:49 +04:00
+++ 1.250/sql/handler.h	2007-02-08 14:32:59 +04:00
@@ -679,7 +679,7 @@ struct handlerton
    int (*find_files)(handlerton *hton, THD *thd,
                      const char *db,
                      const char *path,
-                     const char *wild, bool dir, List<char> *files);
+                     const char *wild, bool dir, List<LEX_STRING> *files);
    int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
                                  const char *name);
    uint32 license; /* Flag for Engine License */
@@ -1682,7 +1682,7 @@ int ha_create_table_from_engine(THD* thd
 int ha_discover(THD* thd, const char* dbname, const char* name,
                 const void** frmblob, uint* frmlen);
 int ha_find_files(THD *thd,const char *db,const char *path,
-                  const char *wild, bool dir,List<char>* files);
+                  const char *wild, bool dir, List<LEX_STRING>* files);
 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
 
 /* key cache */

--- 1.466/sql/mysql_priv.h	2006-12-23 23:19:51 +04:00
+++ 1.467/sql/mysql_priv.h	2007-02-08 14:32:59 +04:00
@@ -1616,7 +1616,7 @@ extern pthread_mutex_t LOCK_mysql_create
        LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock,
        LOCK_global_system_variables, LOCK_user_conn,
        LOCK_prepared_stmt_count,
-       LOCK_bytes_sent, LOCK_bytes_received;
+       LOCK_bytes_sent, LOCK_bytes_received, LOCK_information_schema;
 #ifdef HAVE_OPENSSL
 extern pthread_mutex_t LOCK_des_key_file;
 #endif

--- 1.603/sql/mysqld.cc	2006-12-23 23:19:51 +04:00
+++ 1.604/sql/mysqld.cc	2007-02-08 14:32:59 +04:00
@@ -575,7 +575,8 @@ pthread_mutex_t LOCK_mysql_create_db, LO
 		LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
 		LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
 	        LOCK_global_system_variables,
-		LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
+                LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
+                LOCK_information_schema;
 /*
   The below lock protects access to two global server variables:
   max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -1297,6 +1298,7 @@ static void clean_up_mutexes()
   (void) pthread_mutex_destroy(&LOCK_Acl);
   (void) rwlock_destroy(&LOCK_grant);
   (void) pthread_mutex_destroy(&LOCK_open);
+  (void) pthread_mutex_destroy(&LOCK_information_schema);
   (void) pthread_mutex_destroy(&LOCK_thread_count);
   (void) pthread_mutex_destroy(&LOCK_mapped_file);
   (void) pthread_mutex_destroy(&LOCK_status);
@@ -2877,6 +2879,7 @@ static int init_thread_environment()
   (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
   (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
   (void) pthread_mutex_init(&LOCK_open, NULL);
+  (void) pthread_mutex_init(&LOCK_information_schema, MY_MUTEX_INIT_FAST);
   (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
   (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
   (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);

--- 1.369/sql/sql_base.cc	2006-12-23 23:19:53 +04:00
+++ 1.370/sql/sql_base.cc	2007-02-08 14:32:59 +04:00
@@ -756,7 +756,7 @@ void intern_close_table(TABLE *table)
 
   free_io_cache(table);
   delete table->triggers;
-  if (table->file)                              // Not true if name lock
+  if (table->file || !table->db_stat)           // Not true if name lock
     VOID(closefrm(table, 1));			// close file
   DBUG_VOID_RETURN;
 }
@@ -1135,7 +1135,7 @@ bool close_thread_table(THD *thd, TABLE 
   TABLE *table= *table_ptr;
   DBUG_ENTER("close_thread_table");
   DBUG_ASSERT(table->key_read == 0);
-  DBUG_ASSERT(table->file->inited == handler::NONE);
+  DBUG_ASSERT(!table->db_stat || table->file->inited == handler::NONE);
 
   *table_ptr=table->next;
   if (table->s->version != refresh_version ||
@@ -2118,12 +2118,15 @@ TABLE *open_table(THD *thd, TABLE_LIST *
   table->insert_values= 0;
   table->used_keys= table->s->keys_for_keyread;
   table->fulltext_searched= 0;
-  table->file->ft_handler= 0;
   if (table->timestamp_field)
     table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
   table->pos_in_table_list= table_list;
   table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
-  table->clear_column_bitmaps();
+  if (table->file)
+  {
+    table->file->ft_handler= 0;
+    table->clear_column_bitmaps();
+  }
   DBUG_ASSERT(table->key_read == 0);
   DBUG_RETURN(table);
 }
@@ -2649,6 +2652,8 @@ static int open_unireg_entry(THD *thd, T
   int error;
   TABLE_SHARE *share;
   uint discover_retry_count= 0;
+  uint tmp_db_stat= table_list->open_frm_only ? 0 :
+    (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY);
   DBUG_ENTER("open_unireg_entry");
 
   safe_mutex_assert_owner(&LOCK_open);
@@ -2676,11 +2681,7 @@ retry:
     DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0);
   }
 
-  while ((error= open_table_from_share(thd, share, alias,
-                                       (uint) (HA_OPEN_KEYFILE |
-                                               HA_OPEN_RNDFILE |
-                                               HA_GET_INDEX |
-                                               HA_TRY_READ_ONLY),
+  while ((error= open_table_from_share(thd, share, alias, tmp_db_stat,
                                        (READ_KEYINFO | COMPUTE_TYPES |
                                         EXTRA_RECORD),
                                        thd->open_options, entry, FALSE)))
@@ -2811,6 +2812,8 @@ retry:
       }
     }
   }
+  if (table_list->open_frm_only)
+    entry->file= 0;
   DBUG_RETURN(0);
 
 err:

--- 1.381/sql/sql_show.cc	2006-12-23 23:19:55 +04:00
+++ 1.382/sql/sql_show.cc	2007-02-08 14:32:59 +04:00
@@ -492,13 +492,15 @@ bool mysqld_show_column_types(THD *thd)
 
 
 find_files_result
-find_files(THD *thd, List<char> *files, const char *db,
+find_files(THD *thd, List<LEX_STRING> *files, const char *db,
            const char *path, const char *wild, bool dir)
 {
   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
@@ -547,10 +549,16 @@ find_files(THD *thd, List<char> *files, 
 #endif
       if (!MY_S_ISDIR(file->mystat->st_mode))
         continue;
-      VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
+
+      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
       if (wild && wild_compare(uname, wild, 0))
         continue;
-      file->name= uname;
+      if (!(file_name= 
+            make_lex_string(thd, file_name, uname, file_name_len, TRUE)))
+      {
+        my_dirend(dirp);
+        DBUG_RETURN(FIND_FILES_OOM);
+      }
     }
     else
     {
@@ -559,16 +567,15 @@ find_files(THD *thd, List<char> *files, 
           is_prefix(file->name, tmp_file_prefix))
         continue;
       *ext=0;
-      VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
-      file->name= uname;
+      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
       if (wild)
       {
 	if (lower_case_table_names)
 	{
-	  if (wild_case_compare(files_charset_info, file->name, wild))
+	  if (wild_case_compare(files_charset_info, uname, wild))
 	    continue;
 	}
-	else if (wild_compare(file->name,wild,0))
+	else if (wild_compare(uname, wild, 0))
 	  continue;
       }
     }
@@ -578,14 +585,16 @@ find_files(THD *thd, List<char> *files, 
     {
       table_list.db= (char*) db;
       table_list.db_length= strlen(db);
-      table_list.table_name= file->name;
-      table_list.table_name_length= strlen(file->name);
+      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, 1, 1, 1))
         continue;
     }
 #endif
-    if (files->push_back(thd->strdup(file->name)))
+    if (!(file_name=
+          make_lex_string(thd, file_name, uname, file_name_len, TRUE)) ||
+        files->push_back(file_name))
     {
       my_dirend(dirp);
       DBUG_RETURN(FIND_FILES_OOM);
@@ -594,7 +603,7 @@ find_files(THD *thd, List<char> *files, 
   DBUG_PRINT("info",("found: %d files", files->elements));
   my_dirend(dirp);
 
-  VOID(ha_find_files(thd,db,path,wild,dir,files));
+  VOID(ha_find_files(thd, db, path, wild, dir, files));
 
   DBUG_RETURN(FIND_FILES_OK);
 }
@@ -2185,11 +2194,22 @@ LEX_STRING *make_lex_string(THD *thd, LE
                             const char* str, uint length,
                             bool allocate_lex_string)
 {
+  char *tmp_str;
+  LEX_STRING *tmp_lex_str;
   MEM_ROOT *mem= thd->mem_root;
   if (allocate_lex_string)
-    if (!(lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING))))
+  {
+    if (!multi_alloc_root(mem, &tmp_lex_str, sizeof(LEX_STRING),
+                          &tmp_str, length + 1, NullS))
       return 0;
-  lex_str->str= strmake_root(mem, str, length);
+    memcpy(tmp_str, str, length);
+    tmp_str[length]= 0;
+    tmp_lex_str->str= tmp_str;
+    tmp_lex_str->length= length;
+    return tmp_lex_str;
+  }
+  if (!(lex_str->str= strmake_root(mem, str, length)))
+    return 0;
   lex_str->length= length;
   return lex_str;
 }
@@ -2203,7 +2223,8 @@ extern ST_SCHEMA_TABLE schema_tables[];
 
 typedef struct st_index_field_values
 {
-  const char *db_value, *table_value;
+  LEX_STRING db_value, table_value;
+  bool wild_db_value, wild_table_value;
 } INDEX_FIELD_VALUES;
 
 
@@ -2235,38 +2256,11 @@ bool schema_table_store_record(THD *thd,
 }
 
 
-void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
-{
-  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-  switch (lex->sql_command) {
-  case SQLCOM_SHOW_DATABASES:
-    index_field_values->db_value= wild;
-    break;
-  case SQLCOM_SHOW_TABLES:
-  case SQLCOM_SHOW_TABLE_STATUS:
-  case SQLCOM_SHOW_TRIGGERS:
-  case SQLCOM_SHOW_EVENTS:
-    index_field_values->db_value= lex->select_lex.db;
-    index_field_values->table_value= wild;
-    break;
-  default:
-    index_field_values->db_value= NullS;
-    index_field_values->table_value= NullS;
-    break;
-  }
-}
-
-
 int make_table_list(THD *thd, SELECT_LEX *sel,
-                    char *db, char *table)
+                    LEX_STRING *db_name, LEX_STRING *table_name)
 {
   Table_ident *table_ident;
-  LEX_STRING ident_db, ident_table;
-  ident_db.str= db; 
-  ident_db.length= strlen(db);
-  ident_table.str= table;
-  ident_table.length= strlen(table);
-  table_ident= new Table_ident(thd, ident_db, ident_table, 1);
+  table_ident= new Table_ident(thd, *db_name, *table_name, 1);
   sel->init_query();
   if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
                              (List<String> *) 0, (List<String> *) 0))
@@ -2275,6 +2269,88 @@ int make_table_list(THD *thd, SELECT_LEX
 }
 
 
+void get_idx_val(THD *thd, Item_func *item_func, TABLE_LIST *table,
+                 INDEX_FIELD_VALUES *idx_field_vals)
+{
+  CHARSET_INFO *cs= system_charset_info;
+  ST_SCHEMA_TABLE *schema_table= table->schema_table;
+  ST_FIELD_INFO *field_info= schema_table->fields_info;
+  const char *field_name1= schema_table->idx_field1 >= 0 ?
+    field_info[schema_table->idx_field1].field_name : "";
+  const char *field_name2= schema_table->idx_field2 >= 0 ?
+    field_info[schema_table->idx_field2].field_name : "";
+
+  if (item_func->functype() == Item_func::EQ_FUNC)
+  {
+    int idx_field, idx_val;
+    char tmp[MAX_FIELD_WIDTH];
+    String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
+    Item_field *item_field;
+
+    if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
+        item_func->arguments()[1]->const_item())
+    {
+      idx_field= 0;
+      idx_val= 1;
+    }
+    else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
+             item_func->arguments()[0]->const_item())
+    {
+      idx_field= 1;
+      idx_val= 0;
+    }
+    else
+      return;
+
+    item_field= (Item_field*) item_func->arguments()[idx_field];
+    tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
+    if (table->table != item_field->field->table)
+      return;
+    if (!my_strcasecmp(system_charset_info, field_name1, 
+                       item_field->field_name))
+    {
+      idx_field_vals->db_value.str= thd->strmake(tmp_str->ptr(),
+                                                 tmp_str->length());
+      idx_field_vals->db_value.length= tmp_str->length();
+    }
+    else if (!my_strcasecmp(system_charset_info, field_name2,
+                            item_field->field_name))
+    {
+      idx_field_vals->table_value.str= thd->strmake(tmp_str->ptr(),
+                                                    tmp_str->length());
+      idx_field_vals->table_value.length= tmp_str->length();
+    }
+  }
+  return;
+}
+
+
+void calc_idx_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
+                               INDEX_FIELD_VALUES *idx_field_vals)
+{
+  if (!cond)
+    return;
+
+  if (cond->type() == Item::COND_ITEM)
+  {
+    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
+    {
+      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+      Item *item;
+      while ((item= li++))
+      {
+        if (item->type() == Item::FUNC_ITEM)
+          get_idx_val(thd, (Item_func*)item, table, idx_field_vals);
+      }
+    }
+    return;
+  }
+  else if (cond->type() == Item::FUNC_ITEM)
+    get_idx_val(thd, (Item_func*) cond, table, idx_field_vals);
+  return;
+}
+
+
 bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
 {
   if (item->type() == Item::FUNC_ITEM)
@@ -2371,6 +2447,40 @@ static COND * make_cond_for_info_schema(
 }
 
 
+void get_index_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
+                            INDEX_FIELD_VALUES *index_field_values)
+{
+  LEX *lex= thd->lex;
+  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
+  bzero((char*) index_field_values, sizeof(INDEX_FIELD_VALUES));
+  switch (lex->sql_command) {
+  case SQLCOM_SHOW_DATABASES:
+    if (wild)
+    {
+      index_field_values->db_value.str= (char*) wild;
+      index_field_values->db_value.length= strlen(wild);
+      index_field_values->wild_db_value= 1;
+    }
+    break;
+  case SQLCOM_SHOW_TABLES:
+  case SQLCOM_SHOW_TABLE_STATUS:
+  case SQLCOM_SHOW_TRIGGERS:
+  case SQLCOM_SHOW_EVENTS:
+    index_field_values->db_value.str= lex->select_lex.db;
+    index_field_values->db_value.length=strlen(lex->select_lex.db);
+    if (wild)
+    {
+      index_field_values->table_value.str= (char*)wild;
+      index_field_values->table_value.length= strlen(wild);
+      index_field_values->wild_table_value= 1;
+    }
+    break;
+  default:
+    calc_idx_values_from_cond(thd, cond, tables, index_field_values);
+    break;
+  }
+}
+
 enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
 {
   return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
@@ -2397,54 +2507,61 @@ enum enum_schema_tables get_schema_table
     non-zero              error
 */
 
-int make_db_list(THD *thd, List<char> *files,
+int make_db_list(THD *thd, List<LEX_STRING> *files,
                  INDEX_FIELD_VALUES *idx_field_vals,
                  bool *with_i_schema, bool is_wild_value)
 {
-  LEX *lex= thd->lex;
   *with_i_schema= 0;
-  get_index_field_values(lex, idx_field_vals);
-  if (is_wild_value)
+  if (idx_field_vals->wild_db_value)
   {
     /*
       This part of code is only for SHOW DATABASES command.
       idx_field_vals->db_value can be 0 when we don't use
       LIKE clause (see also get_index_field_values() function)
     */
-    if (!idx_field_vals->db_value ||
+    if (!idx_field_vals->db_value.str ||
         !wild_case_compare(system_charset_info, 
                            information_schema_name.str,
-                           idx_field_vals->db_value))
+                           idx_field_vals->db_value.str))
     {
       *with_i_schema= 1;
-      if (files->push_back(thd->strdup(information_schema_name.str)))
+      if (files->push_back(&information_schema_name))
         return 1;
     }
     return (find_files(thd, files, NullS, mysql_data_home,
-                       idx_field_vals->db_value, 1) != FIND_FILES_OK);
+                       idx_field_vals->db_value.str, 1) != FIND_FILES_OK);
   }
 
+
   /*
     This part of code is for SHOW TABLES, SHOW TABLE STATUS commands.
     idx_field_vals->db_value can't be 0 (see get_index_field_values()
     function).
   */
-  if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+  if (idx_field_vals->db_value.str)
   {
     if (!my_strcasecmp(system_charset_info, information_schema_name.str,
-                       idx_field_vals->db_value))
+                       idx_field_vals->db_value.str))
     {
       *with_i_schema= 1;
-      return files->push_back(thd->strdup(information_schema_name.str));
+      if (files->push_back(&information_schema_name))
+        return 1;
     }
-    return files->push_back(thd->strdup(idx_field_vals->db_value));
+    else
+    {
+      if (files->push_back(&idx_field_vals->db_value))
+        return 1;
+    }
+    VOID(ha_find_files(thd, NullS, mysql_data_home,
+                       idx_field_vals->db_value.str, 1, files));
+    return 0;
   }
 
   /*
     Create list of existing databases. It is used in case
     of select from information schema table
   */
-  if (files->push_back(thd->strdup(information_schema_name.str)))
+  if (files->push_back(&information_schema_name))
     return 1;
   *with_i_schema= 1;
   return (find_files(thd, files, NullS,
@@ -2452,8 +2569,10 @@ int make_db_list(THD *thd, List<char> *f
 }
 
 
-int schema_tables_add(THD *thd, List<char> *files, const char *wild)
+
+int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
 {
+  LEX_STRING *file_name= 0;
   ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
   for (; tmp_schema_table->table_name; tmp_schema_table++)
   {
@@ -2471,13 +2590,201 @@ int schema_tables_add(THD *thd, List<cha
       else if (wild_compare(tmp_schema_table->table_name, wild, 0))
         continue;
     }
-    if (files->push_back(thd->strdup(tmp_schema_table->table_name)))
-      return 1;
+    if ((file_name= make_lex_string(thd, file_name,
+                                    tmp_schema_table->table_name,
+                                    strlen(tmp_schema_table->table_name),
+                                    TRUE)) && !files->push_back(file_name))
+      continue;
+    return 1;
+  }
+  return 0;
+}
+
+
+/*
+  Create table names list.
+
+  SYNOPSIS
+    make_file_list()
+    thd                   thread handler
+    files                 List of tables in databases
+    lex                   LEX struc
+    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
+    db_name               database name
+
+  RETURN
+    zero                  success
+    1                     fatal error
+    2                     Not fatal error; Safe to ignore this file list
+*/
+
+int make_file_list(THD *thd, List<LEX_STRING> *files, LEX *lex,
+                   INDEX_FIELD_VALUES *idx_field_vals,
+                   bool with_i_schema, LEX_STRING *db_name)
+{
+  char path[FN_REFLEN];
+  if (!idx_field_vals->wild_table_value &&
+      idx_field_vals->table_value.str)
+  {
+    if (with_i_schema)
+    {
+      if (find_schema_table(thd, idx_field_vals->table_value.str))
+      {
+        if (files->push_back(&idx_field_vals->table_value))
+          return 1;
+      }
+    }
+    else
+    {    
+      if (files->push_back(&idx_field_vals->table_value))
+        return 1;
+    }
+    VOID(ha_find_files(thd, db_name->str, path, idx_field_vals->table_value.str,
+                       0, files));
+    return 0;
+  }
+
+  if (with_i_schema)      // information schema table names
+  {
+    return (schema_tables_add(thd, files, idx_field_vals->table_value.str));
+  }
+
+  build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
+  find_files_result res= find_files(thd, files, mysql_data_home,
+                                    path, idx_field_vals->table_value.str, 0);
+  if (res != FIND_FILES_OK)
+  {
+    /*
+      Downgrade errors about problems with database directory to
+      warnings if this is not a 'SHOW' command.  Another thread
+      may have dropped database, and we may still have a name
+      for that directory.
+    */
+    if (res == FIND_FILES_DIR)
+    {
+      if (lex->sql_command != SQLCOM_SELECT)
+        return 1;
+      thd->clear_error();
+      return 2;
+    }
+    return 1;
   }
   return 0;
 }
 
 
+static int fill_schema_show(THD *thd, LEX *lex, TABLE_LIST *tables,
+                            ST_SCHEMA_TABLE *schema_table,
+                            Open_tables_state *open_tables_state_backup)
+{
+  bool res;
+  LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
+  enum_sql_command save_sql_command= lex->sql_command;
+  TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
+    table_list.first;
+  TABLE *table= tables->table;
+  int error= 1;
+  DBUG_ENTER("fill_schema_show");
+
+  lex->all_selects_list= tables->schema_select_lex;
+  /*
+    Restore thd->temporary_tables to be able to process
+    temporary tables(only for 'show index' & 'show columns').
+    This should be changed when processing of temporary tables for
+    I_S tables will be done.
+  */
+  thd->temporary_tables= open_tables_state_backup->temporary_tables;
+  /*
+    Let us set fake sql_command so views won't try to merge
+    themselves into main statement. If we don't do this,
+    SELECT * from information_schema.xxxx will cause problems.
+    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
+  */
+  lex->sql_command= SQLCOM_SHOW_FIELDS;
+  res= open_normal_and_derived_tables(thd, show_table_list,
+                                      MYSQL_LOCK_IGNORE_FLUSH);
+  lex->sql_command= save_sql_command;
+  /*
+    get_all_tables() returns 1 on failure and 0 on success thus
+    return only these and not the result code of ::process_table()
+
+    We should use show_table_list->alias instead of 
+    show_table_list->table_name because table_name
+    could be changed during opening of I_S tables. It's safe
+    to use alias because alias contains original table name 
+    in this case(this part of code is used only for 
+    'show columns' & 'show statistics' commands).
+  */
+   db_name= &show_table_list->view_db;
+   table_name= make_lex_string(thd, &tmp_lex_string1,
+                               show_table_list->alias,
+                               strlen(show_table_list->alias), FALSE);
+   if (!show_table_list->view)
+     db_name= make_lex_string(thd, &tmp_lex_string,
+                              show_table_list->db,
+                              show_table_list->db_length, FALSE);
+      
+
+   error= test(schema_table->process_table(thd, show_table_list,
+                                           table, res, db_name,
+                                           table_name));
+   thd->temporary_tables= 0;
+   close_tables_for_reopen(thd, &show_table_list);
+   DBUG_RETURN(error);
+}
+
+
+
+static int fill_schema_table_names(THD *thd, LEX *lex, TABLE *table,
+                                   LEX_STRING *db_name, LEX_STRING *table_name,
+                                   bool with_i_schema)
+{
+  if (with_i_schema)
+  {
+    table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
+                           system_charset_info);
+  }
+  else
+  {
+    enum legacy_db_type not_used;
+    char path[FN_REFLEN], *end;
+    uint len;
+    len= build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
+    end= path + len;
+    len= FN_LEN - len;
+    my_snprintf(end, len, "/%s%s", table_name->str, reg_ext);
+    switch (mysql_frm_type(thd, path, &not_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);
+    }
+    if (thd->net.last_errno == ER_NO_SUCH_TABLE)
+    {
+      thd->clear_error();
+      return 0;
+    }
+  }
+  if (schema_table_store_record(thd, table))
+    return 1;
+  return 0;
+}
+
+
 int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
 {
   LEX *lex= thd->lex;
@@ -2485,29 +2792,27 @@ int get_all_tables(THD *thd, TABLE_LIST 
   SELECT_LEX *select_lex= &lex->select_lex;
   SELECT_LEX *old_all_select_lex= lex->all_selects_list;
   enum_sql_command save_sql_command= lex->sql_command;
-  SELECT_LEX *lsel= tables->schema_select_lex;
   ST_SCHEMA_TABLE *schema_table= tables->schema_table;
   SELECT_LEX sel;
   INDEX_FIELD_VALUES idx_field_vals;
-  char path[FN_REFLEN], *end, *base_name, *orig_base_name, *file_name;
-  uint len;
+  LEX_STRING *db_name, *table_name;
   bool with_i_schema;
   enum enum_schema_tables schema_table_idx;
-  List<char> bases;
-  List_iterator_fast<char> it(bases);
+  List<LEX_STRING> bases;
+  List_iterator_fast<LEX_STRING> it(bases);
   COND *partial_cond;
   Security_context *sctx= thd->security_ctx;
   uint derived_tables= lex->derived_tables; 
   int error= 1;
-  enum legacy_db_type not_used;
   Open_tables_state open_tables_state_backup;
   bool save_view_prepare_mode= lex->view_prepare_mode;
   Query_tables_list query_tables_list_backup;
   lex->view_prepare_mode= TRUE;
-  DBUG_ENTER("get_all_tables");
+  Field **ptr, *field;
+  uint open_table_method= 0, field_indx;
+  bool func_locked= 0;
 
-  LINT_INIT(end);
-  LINT_INIT(len);
+  DBUG_ENTER("get_all_tables");
 
   lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
 
@@ -2518,171 +2823,128 @@ int get_all_tables(THD *thd, TABLE_LIST 
   */
   thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
 
-  if (lsel)
-  {
-    TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
-    bool res;
 
-    lex->all_selects_list= lsel;
-    /*
-      Restore thd->temporary_tables to be able to process
-      temporary tables(only for 'show index' & 'show columns').
-      This should be changed when processing of temporary tables for
-      I_S tables will be done.
-    */
-    thd->temporary_tables= open_tables_state_backup.temporary_tables;
-    /*
-      Let us set fake sql_command so views won't try to merge
-      themselves into main statement. If we don't do this,
-      SELECT * from information_schema.xxxx will cause problems.
-      SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
-    */
-    lex->sql_command= SQLCOM_SHOW_FIELDS;
-    res= open_normal_and_derived_tables(thd, show_table_list,
-                                        MYSQL_LOCK_IGNORE_FLUSH);
-    lex->sql_command= save_sql_command;
-    /*
-      get_all_tables() returns 1 on failure and 0 on success thus
-      return only these and not the result code of ::process_table()
-
-      We should use show_table_list->alias instead of 
-      show_table_list->table_name because table_name
-      could be changed during opening of I_S tables. It's safe
-      to use alias because alias contains original table name 
-      in this case(this part of code is used only for 
-      'show columns' & 'show statistics' commands).
-    */
-    error= test(schema_table->process_table(thd, show_table_list,
-                                            table, res, 
-                                            (show_table_list->view ?
-                                             show_table_list->view_db.str :
-                                             show_table_list->db),
-                                            show_table_list->alias));
-    thd->temporary_tables= 0;
-    close_tables_for_reopen(thd, &show_table_list);
+  /* SHOW FIELDS, SHOW INDEXES */
+  if (tables->schema_select_lex)
+  {
+    error= fill_schema_show(thd, lex, tables, schema_table,
+                            &open_tables_state_backup);
     goto err;
   }
 
   schema_table_idx= get_schema_table_idx(schema_table);
+  get_index_field_values(thd, cond, tables, &idx_field_vals);
+  DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
+                             idx_field_vals.db_value.str,
+                             idx_field_vals.table_value.str));
+  if (idx_field_vals.db_value.length &&
+      !idx_field_vals.wild_db_value &&
+      idx_field_vals.table_value.length &&
+      !idx_field_vals.wild_table_value)
+    partial_cond= 0; 
+  else
+    partial_cond= make_cond_for_info_schema(cond, tables);
+
+  /*
+    determine which method will be used for table opening
+  */
+  field_indx= 0;
+  for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+  {
+
+    if (bitmap_is_set(tables->table->read_set, field->field_index))
+      open_table_method|= schema_table->fields_info[field_indx].open_method;
+    field_indx++;
+  }
+
+  /*
+    This lock is used to prevent simultaneous function execution
+    from other threads because function get_all_tables is
+    very heavy(disc,CPU load).
+  */
+  pthread_mutex_lock(&LOCK_information_schema);
+  func_locked= 1;
 
   if (make_db_list(thd, &bases, &idx_field_vals,
                    &with_i_schema, 0))
     goto err;
-
-  partial_cond= make_cond_for_info_schema(cond, tables);
   it.rewind(); /* To get access to new elements in basis list */
 
   /*
     Below we generate error for non existing database.
     (to save old behaviour for SHOW TABLES FROM db)
   */
-  while ((orig_base_name= base_name= it++) ||
-         ((sql_command_flags[save_sql_command] & CF_SHOW_TABLE_COMMAND) &&
-	  (base_name= select_lex->db) && !bases.elements))
+  while ((db_name= it++))
   {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-    if (!check_access(thd,SELECT_ACL, base_name, 
+    if (!check_access(thd,SELECT_ACL, db_name->str, 
                       &thd->col_access, 0, 1, with_i_schema) ||
         sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-	acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) ||
-	(grant_option && !check_grant_db(thd, base_name)))
+	acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
+	(grant_option && !check_grant_db(thd, db_name->str)))
 #endif
     {
-      List<char> files;
-      if (with_i_schema)                      // information schema table names
-      {
-        if (schema_tables_add(thd, &files, idx_field_vals.table_value))
-          goto err;
-      }
-      else
+      thd->no_warnings_for_error= 1;
+      List<LEX_STRING> files;      
+      int res= make_file_list(thd, &files, lex, &idx_field_vals,
+                              with_i_schema, db_name);
+      if (res == 2)   /* Not fatal error, continue */
+        continue;
+      if (res)
+        goto err;
+
+      List_iterator_fast<LEX_STRING> it_files(files);
+      while ((table_name= it_files++))
       {
-        len= build_table_filename(path, sizeof(path), base_name, "", "", 0);
-        end= path + len;
-        len= FN_LEN - len;
-        find_files_result res= find_files(thd, &files, base_name, 
-                                          path, idx_field_vals.table_value, 0);
-        if (res != FIND_FILES_OK)
+	restore_record(table, s->default_values);
+        table->field[schema_table->idx_field1]->
+          store(db_name->str, db_name->length, system_charset_info);
+        table->field[schema_table->idx_field2]->
+          store(table_name->str, table_name->length, system_charset_info);
+
+        if (!partial_cond || partial_cond->val_int())
         {
           /*
-            Downgrade errors about problems with database directory to
-            warnings if this is not a 'SHOW' command.  Another thread
-            may have dropped database, and we may still have a name
-            for that directory.
+            If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
+            we can skip table opening and we don't have index value for 
+            table name.
           */
-          if (res == FIND_FILES_DIR && lex->sql_command == SQLCOM_END)
+          if (!open_table_method && schema_table_idx == SCH_TABLES &&
+              !idx_field_vals.table_value.length)
           {
-            push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                         thd->net.last_errno, thd->net.last_error);
-            thd->clear_error();
+            if (schema_table_store_record(thd, table))
+              goto err;      /* Out of space in temporary table */
             continue;
           }
-          else
-          {
-            goto err;
-          }
-        }
-        if (lower_case_table_names)
-          orig_base_name= thd->strdup(base_name);
-      }
 
-      List_iterator_fast<char> it_files(files);
-      while ((file_name= it_files++))
-      {
-	restore_record(table, s->default_values);
-        table->field[schema_table->idx_field1]->
-          store(base_name, strlen(base_name), system_charset_info);
-        table->field[schema_table->idx_field2]->
-          store(file_name, strlen(file_name),system_charset_info);
-        if (!partial_cond || partial_cond->val_int())
-        {
+          /* SHOW TABLE NAMES command */
           if (schema_table_idx == SCH_TABLE_NAMES)
           {
-            if (lex->verbose ||
-                (sql_command_flags[save_sql_command] & CF_STATUS_COMMAND) == 0)
-            {
-              if (with_i_schema)
-              {
-                table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
-                                       system_charset_info);
-              }
-              else
-              {
-                my_snprintf(end, len, "/%s%s", file_name, reg_ext);
-                switch (mysql_frm_type(thd, path, &not_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);
-                }
-              }
-            }
-            if (schema_table_store_record(thd, table))
+            if (fill_schema_table_names(thd, lex, tables->table, db_name,
+                                        table_name, with_i_schema))
               goto err;
           }
           else
           {
             int res;
+            LEX_STRING tmp_lex_string, orig_db_name;
             /*
               Set the parent lex of 'sel' because it is needed by
               sel.init_query() which is called inside make_table_list.
             */
+            thd->no_warnings_for_error= 1;
             sel.parent_lex= lex;
-            if (make_table_list(thd, &sel, base_name, file_name))
+            /* db_name can be changed in make_table_list() func */
+            if (!make_lex_string(thd, &orig_db_name, db_name->str,
+                                 db_name->length, FALSE))
+              goto err;
+            if (make_table_list(thd, &sel, db_name, table_name))
               goto err;
             TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
             lex->all_selects_list= &sel;
             lex->derived_tables= 0;
             lex->sql_command= SQLCOM_SHOW_FIELDS;
+            show_table_list->open_frm_only= !(open_table_method & OPEN_FULL_TABLE);
             res= open_normal_and_derived_tables(thd, show_table_list,
                                                 MYSQL_LOCK_IGNORE_FLUSH);
             lex->sql_command= save_sql_command;
@@ -2693,10 +2955,21 @@ int get_all_tables(THD *thd, TABLE_LIST 
               to use alias because alias contains original table name 
               in this case.
             */
-            res= schema_table->process_table(thd, show_table_list, table,
-                                             res, orig_base_name,
-                                             show_table_list->alias);
-            close_tables_for_reopen(thd, &show_table_list);
+            if (thd->net.last_errno != ER_NO_SUCH_TABLE)
+            {
+              make_lex_string(thd, &tmp_lex_string, show_table_list->alias,
+                              strlen(show_table_list->alias), FALSE);
+              res= schema_table->process_table(thd, show_table_list, table,
+                                               res, &orig_db_name,
+                                               &tmp_lex_string);
+              close_tables_for_reopen(thd, &show_table_list);
+            }
+            else
+            {
+              /* Hide error for not existing table */
+              res= 0;
+              thd->clear_error();
+            }
             DBUG_ASSERT(!lex->query_tables_own_last);
             if (res)
               goto err;
@@ -2719,6 +2992,8 @@ err:
   lex->all_selects_list= old_all_select_lex;
   lex->view_prepare_mode= save_view_prepare_mode;
   lex->sql_command= save_sql_command;
+  if (func_locked)
+    pthread_mutex_unlock(&LOCK_information_schema);
   DBUG_RETURN(error);
 }
 
@@ -2742,24 +3017,29 @@ int fill_schema_shemata(THD *thd, TABLE_
   */
 
   INDEX_FIELD_VALUES idx_field_vals;
-  List<char> files;
-  char *file_name;
+  List<LEX_STRING> files;
+  LEX_STRING *file_name;
   bool with_i_schema;
   HA_CREATE_INFO create;
   TABLE *table= tables->table;
   Security_context *sctx= thd->security_ctx;
   DBUG_ENTER("fill_schema_shemata");
 
+  get_index_field_values(thd, cond, tables, &idx_field_vals);
+  DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
+                             idx_field_vals.db_value.str,
+                             idx_field_vals.table_value.str));
+
   if (make_db_list(thd, &files, &idx_field_vals,
                    &with_i_schema, 1))
     DBUG_RETURN(1);
 
-  List_iterator_fast<char> it(files);
+  List_iterator_fast<LEX_STRING> it(files);
   while ((file_name=it++))
   {
     if (with_i_schema)       // information schema name is always first in list
     {
-      if (store_schema_shemata(thd, table, file_name,
+      if (store_schema_shemata(thd, table, file_name->str,
                                system_charset_info))
         DBUG_RETURN(1);
       with_i_schema= 0;
@@ -2767,13 +3047,13 @@ int fill_schema_shemata(THD *thd, TABLE_
     }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
     if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-	acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
-	(grant_option && !check_grant_db(thd, file_name)))
+	acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name->str,0) ||
+	(grant_option && !check_grant_db(thd, file_name->str)))
 #endif
     {
-      load_db_opt_by_name(thd, file_name, &create);
+      load_db_opt_by_name(thd, file_name->str, &create);
 
-      if (store_schema_shemata(thd, table, file_name,
+      if (store_schema_shemata(thd, table, file_name->str,
                                create.default_table_charset))
         DBUG_RETURN(1);
     }
@@ -2784,8 +3064,8 @@ int fill_schema_shemata(THD *thd, TABLE_
 
 static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
 				    TABLE *table, bool res,
-				    const char *base_name,
-				    const char *file_name)
+				    LEX_STRING *db_name,
+				    LEX_STRING *table_name)
 {
   const char *tmp_buff;
   TIME time;
@@ -2793,8 +3073,8 @@ static int get_schema_tables_record(THD 
   DBUG_ENTER("get_schema_tables_record");
 
   restore_record(table, s->default_values);
-  table->field[1]->store(base_name, strlen(base_name), cs);
-  table->field[2]->store(file_name, strlen(file_name), cs);
+  table->field[1]->store(db_name->str, db_name->length, cs);
+  table->field[2]->store(table_name->str, table_name->length, cs);
   if (res)
   {
     /*
@@ -2820,9 +3100,6 @@ static int get_schema_tables_record(THD 
     TABLE *show_table= tables->table;
     TABLE_SHARE *share= show_table->s;
     handler *file= show_table->file;
-
-    file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
-               HA_STATUS_NO_LOCK);
     if (share->tmp_table == SYSTEM_TMP_TABLE)
       table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
     else if (share->tmp_table)
@@ -2836,17 +3113,17 @@ static int get_schema_tables_record(THD 
         continue;
       table->field[i]->set_notnull();
     }
-    tmp_buff= file->table_type();
+
+    tmp_buff= ha_get_storage_engine(share->db_type->db_type);
     table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
     table->field[5]->store((longlong) share->frm_version, TRUE);
-    enum row_type row_type = file->get_row_type();
-    switch (row_type) {
+    switch (share->row_type) {
     case ROW_TYPE_NOT_USED:
     case ROW_TYPE_DEFAULT:
       tmp_buff= ((share->db_options_in_use &
-		  HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
-		 (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
-		 "Dynamic" : "Fixed");
+                  HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
+                 (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
+                 "Dynamic" : "Fixed");
       break;
     case ROW_TYPE_FIXED:
       tmp_buff= "Fixed";
@@ -2868,106 +3145,112 @@ static int get_schema_tables_record(THD 
       break;
     }
     table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
-    if (!tables->schema_table)
-    {
-      table->field[7]->store((longlong) file->stats.records, TRUE);
-      table->field[7]->set_notnull();
-    }
-    table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
-    table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
-    if (file->stats.max_data_file_length)
-    {
-      table->field[10]->store((longlong) file->stats.max_data_file_length,
-                              TRUE);
-    }
-    table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
-    table->field[12]->store((longlong) file->stats.delete_length, TRUE);
-    if (show_table->found_next_number_field)
-    {
-      table->field[13]->store((longlong) file->stats.auto_increment_value,
-                              TRUE);
-      table->field[13]->set_notnull();
-    }
-    if (file->stats.create_time)
-    {
-      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-                                                file->stats.create_time);
-      table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-      table->field[14]->set_notnull();
-    }
-    if (file->stats.update_time)
-    {
-      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-                                                file->stats.update_time);
-      table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-      table->field[15]->set_notnull();
-    }
-    if (file->stats.check_time)
-    {
-      thd->variables.time_zone->gmt_sec_to_TIME(&time, file->stats.check_time);
-      table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-      table->field[16]->set_notnull();
-    }
-    tmp_buff= (share->table_charset ?
-               share->table_charset->name : "default");
-    table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
-    if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
-    {
-      table->field[18]->store((longlong) file->checksum(), TRUE);
-      table->field[18]->set_notnull();
-    }
 
-    char option_buff[350],*ptr;
-    ptr=option_buff;
-    if (share->min_rows)
-    {
-      ptr=strmov(ptr," min_rows=");
-      ptr=longlong10_to_str(share->min_rows,ptr,10);
-    }
-    if (share->max_rows)
+    if (file)
     {
-      ptr=strmov(ptr," max_rows=");
-      ptr=longlong10_to_str(share->max_rows,ptr,10);
-    }
-    if (share->avg_row_length)
-    {
-      ptr=strmov(ptr," avg_row_length=");
-      ptr=longlong10_to_str(share->avg_row_length,ptr,10);
-    }
-    if (share->db_create_options & HA_OPTION_PACK_KEYS)
-      ptr=strmov(ptr," pack_keys=1");
-    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
-      ptr=strmov(ptr," pack_keys=0");
-    if (share->db_create_options & HA_OPTION_CHECKSUM)
-      ptr=strmov(ptr," checksum=1");
-    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
-      ptr=strmov(ptr," delay_key_write=1");
-    if (share->row_type != ROW_TYPE_DEFAULT)
-      ptr=strxmov(ptr, " row_format=", 
-                  ha_row_type[(uint) share->row_type],
-                  NullS);
+      file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
+                 HA_STATUS_NO_LOCK);
+      if (!tables->schema_table)
+      {
+        table->field[7]->store((longlong) file->stats.records, TRUE);
+        table->field[7]->set_notnull();
+      }
+      table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
+      table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
+      if (file->stats.max_data_file_length)
+      {
+        table->field[10]->store((longlong) file->stats.max_data_file_length,
+                                TRUE);
+      }
+      table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
+      table->field[12]->store((longlong) file->stats.delete_length, TRUE);
+      if (show_table->found_next_number_field)
+      {
+        table->field[13]->store((longlong) file->stats.auto_increment_value,
+                                TRUE);
+        table->field[13]->set_notnull();
+      }
+      if (file->stats.create_time)
+      {
+        thd->variables.time_zone->gmt_sec_to_TIME(&time,
+                                                  file->stats.create_time);
+        table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+        table->field[14]->set_notnull();
+      }
+      if (file->stats.update_time)
+      {
+        thd->variables.time_zone->gmt_sec_to_TIME(&time,
+                                                  file->stats.update_time);
+        table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+        table->field[15]->set_notnull();
+      }
+      if (file->stats.check_time)
+      {
+        thd->variables.time_zone->gmt_sec_to_TIME(&time, file->stats.check_time);
+        table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+        table->field[16]->set_notnull();
+      }
+
+      char option_buff[350],*ptr;
+      ptr=option_buff;
+      if (share->min_rows)
+      {
+        ptr=strmov(ptr," min_rows=");
+        ptr=longlong10_to_str(share->min_rows,ptr,10);
+      }
+      if (share->max_rows)
+      {
+        ptr=strmov(ptr," max_rows=");
+        ptr=longlong10_to_str(share->max_rows,ptr,10);
+      }
+      if (share->avg_row_length)
+      {
+        ptr=strmov(ptr," avg_row_length=");
+        ptr=longlong10_to_str(share->avg_row_length,ptr,10);
+      }
+      if (share->db_create_options & HA_OPTION_PACK_KEYS)
+        ptr=strmov(ptr," pack_keys=1");
+      if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
+        ptr=strmov(ptr," pack_keys=0");
+      if (share->db_create_options & HA_OPTION_CHECKSUM)
+        ptr=strmov(ptr," checksum=1");
+      if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
+        ptr=strmov(ptr," delay_key_write=1");
+      if (share->row_type != ROW_TYPE_DEFAULT)
+        ptr=strxmov(ptr, " row_format=", 
+                    ha_row_type[(uint) share->row_type],
+                    NullS);
 #ifdef WITH_PARTITION_STORAGE_ENGINE
-    if (show_table->s->db_type == partition_hton && 
-        show_table->part_info != NULL && 
-        show_table->part_info->no_parts > 0)
-      ptr= strmov(ptr, " partitioned");
+      if (show_table->s->db_type == partition_hton && 
+          show_table->part_info != NULL && 
+          show_table->part_info->no_parts > 0)
+        ptr= strmov(ptr, " partitioned");
 #endif
-    table->field[19]->store(option_buff+1,
-                            (ptr == option_buff ? 0 : 
-                             (uint) (ptr-option_buff)-1), cs);
-    {
-      char *comment;
-      comment= show_table->file->update_table_comment(share->comment.str);
-      if (comment)
-      {
-        table->field[20]->store(comment,
-                                (comment == share->comment.str ?
-                                 share->comment.length : 
-                                 strlen(comment)), cs);
-        if (comment != share->comment.str)
-          my_free(comment, MYF(0));
+      table->field[19]->store(option_buff+1,
+                              (ptr == option_buff ? 0 : 
+                               (uint) (ptr-option_buff)-1), cs);
+      {
+        char *comment;
+        comment= show_table->file->update_table_comment(share->comment.str);
+        if (comment)
+        {
+          table->field[20]->store(comment,
+                                  (comment == share->comment.str ?
+                                   share->comment.length : 
+                                   strlen(comment)), cs);
+          if (comment != share->comment.str)
+            my_free(comment, MYF(0));
+        }
+      }
+      if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+      {
+        table->field[18]->store((longlong) file->checksum(), TRUE);
+        table->field[18]->set_notnull();
       }
     }
+    tmp_buff= (share->table_charset ?
+               share->table_charset->name : "default");
+    table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
   }
   DBUG_RETURN(schema_table_store_record(thd, table));
 }
@@ -2975,17 +3258,15 @@ static int get_schema_tables_record(THD 
 
 static int get_schema_column_record(THD *thd, struct st_table_list *tables,
 				    TABLE *table, bool res,
-				    const char *base_name,
-				    const char *file_name)
+				    LEX_STRING *db_name,
+				    LEX_STRING *table_name)
 {
   LEX *lex= thd->lex;
   const char *wild= lex->wild ? lex->wild->ptr() : NullS;
   CHARSET_INFO *cs= system_charset_info;
   TABLE *show_table;
-  handler *file;
   Field **ptr,*field;
   int count;
-  uint base_name_length, file_name_length;
   DBUG_ENTER("get_schema_column_record");
 
   if (res)
@@ -3005,12 +3286,8 @@ static int get_schema_column_record(THD 
   }
 
   show_table= tables->table;
-  file= show_table->file;
   count= 0;
-  file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
   restore_record(show_table, s->default_values);
-  base_name_length= strlen(base_name);
-  file_name_length= strlen(file_name);
   show_table->use_all_columns();               // Required for default
 
   for (ptr=show_table->field; (field= *ptr) ; ptr++)
@@ -3036,10 +3313,10 @@ static int get_schema_column_record(THD 
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
     uint col_access;
-    check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
+    check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
                  &tables->grant.privilege, 0, 0, test(tables->schema_table));
     col_access= get_column_grant(thd, &tables->grant, 
-                                 base_name, file_name,
+                                 db_name->str, table_name->str,
                                  field->field_name) & COL_ACLS;
     if (lex->sql_command != SQLCOM_SHOW_FIELDS  &&
         !tables->schema_table && !col_access)
@@ -3056,8 +3333,8 @@ static int get_schema_column_record(THD 
     table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
 
 #endif
-    table->field[1]->store(base_name, base_name_length, cs);
-    table->field[2]->store(file_name, file_name_length, cs);
+    table->field[1]->store(db_name->str, db_name->length, cs);
+    table->field[2]->store(table_name->str, table_name->length, cs);
     table->field[3]->store(field->field_name, strlen(field->field_name),
                            cs);
     table->field[4]->store((longlong) count, TRUE);
@@ -3470,8 +3747,8 @@ err:
 
 static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
 				  TABLE *table, bool res,
-				  const char *base_name,
-				  const char *file_name)
+				  LEX_STRING *db_name,
+				  LEX_STRING *table_name)
 {
   CHARSET_INFO *cs= system_charset_info;
   DBUG_ENTER("get_schema_stat_record");
@@ -3495,9 +3772,10 @@ static int get_schema_stat_record(THD *t
   {
     TABLE *show_table= tables->table;
     KEY *key_info=show_table->key_info;
-    show_table->file->info(HA_STATUS_VARIABLE |
-                           HA_STATUS_NO_LOCK |
-                           HA_STATUS_TIME);
+    if (show_table->file)
+      show_table->file->info(HA_STATUS_VARIABLE |
+                             HA_STATUS_NO_LOCK |
+                             HA_STATUS_TIME);
     for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
     {
       KEY_PART_INFO *key_part= key_info->key_part;
@@ -3505,30 +3783,35 @@ static int get_schema_stat_record(THD *t
       for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
       {
         restore_record(table, s->default_values);
-        table->field[1]->store(base_name, strlen(base_name), cs);
-        table->field[2]->store(file_name, strlen(file_name), cs);
+        table->field[1]->store(db_name->str, db_name->length, cs);
+        table->field[2]->store(table_name->str, table_name->length, cs);
         table->field[3]->store((longlong) ((key_info->flags &
                                             HA_NOSAME) ? 0 : 1), TRUE);
-        table->field[4]->store(base_name, strlen(base_name), cs);
+        table->field[4]->store(db_name->str, db_name->length, cs);
         table->field[5]->store(key_info->name, strlen(key_info->name), cs);
         table->field[6]->store((longlong) (j+1), TRUE);
         str=(key_part->field ? key_part->field->field_name :
              "?unknown field?");
         table->field[7]->store(str, strlen(str), cs);
-        if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
+        if (show_table->file)
         {
-          table->field[8]->store(((key_part->key_part_flag &
-                                   HA_REVERSE_SORT) ?
-                                  "D" : "A"), 1, cs);
-          table->field[8]->set_notnull();
-        }
-        KEY *key=show_table->key_info+i;
-        if (key->rec_per_key[j])
-        {
-          ha_rows records=(show_table->file->stats.records /
-                           key->rec_per_key[j]);
-          table->field[9]->store((longlong) records, TRUE);
-          table->field[9]->set_notnull();
+          if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
+          {
+            table->field[8]->store(((key_part->key_part_flag &
+                                     HA_REVERSE_SORT) ?
+                                    "D" : "A"), 1, cs);
+            table->field[8]->set_notnull();
+          }
+          KEY *key=show_table->key_info+i;
+          if (key->rec_per_key[j])
+          {
+            ha_rows records=(show_table->file->stats.records /
+                             key->rec_per_key[j]);
+            table->field[9]->store((longlong) records, TRUE);
+            table->field[9]->set_notnull();
+          }
+          str= show_table->file->index_type(i);
+          table->field[13]->store(str, strlen(str), cs);
         }
         if (!(key_info->flags & HA_FULLTEXT) &&
             (key_part->field &&
@@ -3542,8 +3825,6 @@ static int get_schema_stat_record(THD *t
         uint flags= key_part->field ? key_part->field->flags : 0;
         const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
         table->field[12]->store(pos, strlen(pos), cs);
-        pos= show_table->file->index_type(i);
-        table->field[13]->store(pos, strlen(pos), cs);
         if (!show_table->s->keys_in_use.is_set(i))
           table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
         else
@@ -3560,8 +3841,8 @@ static int get_schema_stat_record(THD *t
 
 static int get_schema_views_record(THD *thd, struct st_table_list *tables,
 				   TABLE *table, bool res,
-				   const char *base_name,
-				   const char *file_name)
+				   LEX_STRING *db_name,
+				   LEX_STRING *table_name)
 {
   CHARSET_INFO *cs= system_charset_info;
   DBUG_ENTER("get_schema_views_record");
@@ -3627,16 +3908,16 @@ static int get_schema_views_record(THD *
 }
 
 
-bool store_constraints(THD *thd, TABLE *table, const char *db,
-                       const char *tname, const char *key_name,
+bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
+                       LEX_STRING *table_name, const char *key_name,
                        uint key_len, const char *con_type, uint con_len)
 {
   CHARSET_INFO *cs= system_charset_info;
   restore_record(table, s->default_values);
-  table->field[1]->store(db, strlen(db), cs);
+  table->field[1]->store(db_name->str, db_name->length, cs);
   table->field[2]->store(key_name, key_len, cs);
-  table->field[3]->store(db, strlen(db), cs);
-  table->field[4]->store(tname, strlen(tname), cs);
+  table->field[3]->store(db_name->str, db_name->length, cs);
+  table->field[4]->store(table_name->str, table_name->length, cs);
   table->field[5]->store(con_type, con_len, cs);
   return schema_table_store_record(thd, table);
 }
@@ -3644,8 +3925,8 @@ bool store_constraints(THD *thd, TABLE *
 
 static int get_schema_constraints_record(THD *thd, struct st_table_list *tables,
 					 TABLE *table, bool res,
-					 const char *base_name,
-					 const char *file_name)
+					 LEX_STRING *db_name,
+					 LEX_STRING *table_name)
 {
   DBUG_ENTER("get_schema_constraints_record");
   if (res)
@@ -3672,14 +3953,14 @@ static int get_schema_constraints_record
 
       if (i == primary_key && !strcmp(key_info->name, primary_key_name))
       {
-        if (store_constraints(thd, table, base_name, file_name, key_info->name,
+        if (store_constraints(thd, table, db_name, table_name, key_info->name,
                               strlen(key_info->name),
                               STRING_WITH_LEN("PRIMARY KEY")))
           DBUG_RETURN(1);
       }
       else if (key_info->flags & HA_NOSAME)
       {
-        if (store_constraints(thd, table, base_name, file_name, key_info->name,
+        if (store_constraints(thd, table, db_name, table_name, key_info->name,
                               strlen(key_info->name),
                               STRING_WITH_LEN("UNIQUE")))
           DBUG_RETURN(1);
@@ -3691,7 +3972,7 @@ static int get_schema_constraints_record
     List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
     while ((f_key_info=it++))
     {
-      if (store_constraints(thd, table, base_name, file_name, 
+      if (store_constraints(thd, table, db_name, table_name, 
                             f_key_info->forein_id->str,
                             strlen(f_key_info->forein_id->str),
                             "FOREIGN KEY", 11))
@@ -3702,8 +3983,8 @@ static int get_schema_constraints_record
 }
 
 
-static bool store_trigger(THD *thd, TABLE *table, const char *db,
-                          const char *tname, LEX_STRING *trigger_name,
+static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
+                          LEX_STRING *table_name, LEX_STRING *trigger_name,
                           enum trg_event_type event,
                           enum trg_action_time_type timing,
                           LEX_STRING *trigger_stmt,
@@ -3715,12 +3996,12 @@ static bool store_trigger(THD *thd, TABL
   ulong sql_mode_len;
 
   restore_record(table, s->default_values);
-  table->field[1]->store(db, strlen(db), cs);
+  table->field[1]->store(db_name->str, db_name->length, cs);
   table->field[2]->store(trigger_name->str, trigger_name->length, cs);
   table->field[3]->store(trg_event_type_names[event].str,
                          trg_event_type_names[event].length, cs);
-  table->field[5]->store(db, strlen(db), cs);
-  table->field[6]->store(tname, strlen(tname), cs);
+  table->field[5]->store(db_name->str, db_name->length, cs);
+  table->field[6]->store(table_name->str, table_name->length, cs);
   table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
   table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
   table->field[11]->store(trg_action_time_type_names[timing].str,
@@ -3740,8 +4021,8 @@ static bool store_trigger(THD *thd, TABL
 
 static int get_schema_triggers_record(THD *thd, struct st_table_list *tables,
 				      TABLE *table, bool res,
-				      const char *base_name,
-				      const char *file_name)
+				      LEX_STRING *db_name,
+				      LEX_STRING *table_name)
 {
   DBUG_ENTER("get_schema_triggers_record");
   /*
@@ -3777,7 +4058,7 @@ static int get_schema_triggers_record(TH
                                        &definer_buffer))
           continue;
 
-        if (store_trigger(thd, table, base_name, file_name, &trigger_name,
+        if (store_trigger(thd, table, db_name, table_name, &trigger_name,
                          (enum trg_event_type) event,
                          (enum trg_action_time_type) timing, &trigger_stmt,
                          sql_mode,
@@ -3790,15 +4071,16 @@ static int get_schema_triggers_record(TH
 }
 
 
-void store_key_column_usage(TABLE *table, const char*db, const char *tname,
-                            const char *key_name, uint key_len, 
-                            const char *con_type, uint con_len, longlong idx)
+void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
+                            LEX_STRING *table_name, const char *key_name,
+                            uint key_len, const char *con_type, uint con_len,
+                            longlong idx)
 {
   CHARSET_INFO *cs= system_charset_info;
-  table->field[1]->store(db, strlen(db), cs);
+  table->field[1]->store(db_name->str, db_name->length, cs);
   table->field[2]->store(key_name, key_len, cs);
-  table->field[4]->store(db, strlen(db), cs);
-  table->field[5]->store(tname, strlen(tname), cs);
+  table->field[4]->store(db_name->str, db_name->length, cs);
+  table->field[5]->store(table_name->str, table_name->length, cs);
   table->field[6]->store(con_type, con_len, cs);
   table->field[7]->store((longlong) idx, TRUE);
 }
@@ -3807,8 +4089,8 @@ void store_key_column_usage(TABLE *table
 static int get_schema_key_column_usage_record(THD *thd,
 					      struct st_table_list *tables,
 					      TABLE *table, bool res,
-					      const char *base_name,
-					      const char *file_name)
+					      LEX_STRING *db_name,
+					      LEX_STRING *table_name)
 {
   DBUG_ENTER("get_schema_key_column_usage_record");
   if (res)
@@ -3840,7 +4122,7 @@ static int get_schema_key_column_usage_r
         {
           f_idx++;
           restore_record(table, s->default_values);
-          store_key_column_usage(table, base_name, file_name,
+          store_key_column_usage(table, db_name, table_name,
                                  key_info->name,
                                  strlen(key_info->name), 
                                  key_part->field->field_name, 
@@ -3867,7 +4149,7 @@ static int get_schema_key_column_usage_r
         r_info= it1++;
         f_idx++;
         restore_record(table, s->default_values);
-        store_key_column_usage(table, base_name, file_name,
+        store_key_column_usage(table, db_name, table_name,
                                f_key_info->forein_id->str,
                                f_key_info->forein_id->length,
                                f_info->str, f_info->length,
@@ -3919,6 +4201,8 @@ static void store_schema_partitions_reco
   CHARSET_INFO *cs= system_charset_info;
   PARTITION_INFO stat_info;
   TIME time;
+  if (!file)
+    return;
   file->get_dynamic_partition_info(&stat_info, part_id);
   table->field[12]->store((longlong) stat_info.records, TRUE);
   table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
@@ -3989,8 +4273,8 @@ static void store_schema_partitions_reco
 
 static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
                                         TABLE *table, bool res,
-                                        const char *base_name,
-                                        const char *file_name)
+                                        LEX_STRING *db_name,
+                                        LEX_STRING *table_name)
 {
   CHARSET_INFO *cs= system_charset_info;
   char buff[61];
@@ -4022,8 +4306,8 @@ static int get_schema_partitions_record(
     uint no_parts= part_info->no_parts;
 
     restore_record(table, s->default_values);
-    table->field[1]->store(base_name, strlen(base_name), cs);
-    table->field[2]->store(file_name, strlen(file_name), cs);
+    table->field[1]->store(db_name->str, db_name->length, cs);
+    table->field[2]->store(table_name->str, table_name->length, cs);
 
 
     /* Partition method*/
@@ -4464,7 +4748,7 @@ int fill_status(THD *thd, TABLE_LIST *ta
 static int
 get_referential_constraints_record(THD *thd, struct st_table_list *tables,
                                    TABLE *table, bool res,
-                                   const char *base_name, const char *file_name)
+                                   LEX_STRING *db_name, LEX_STRING *table_name)
 {
   CHARSET_INFO *cs= system_charset_info;
   DBUG_ENTER("get_referential_constraints_record");
@@ -4491,8 +4775,8 @@ get_referential_constraints_record(THD *
     while ((f_key_info= it++))
     {
       restore_record(table, s->default_values);
-      table->field[1]->store(base_name, strlen(base_name), cs);
-      table->field[9]->store(file_name, strlen(file_name), cs);
+      table->field[1]->store(db_name->str, db_name->length, cs);
+      table->field[9]->store(table_name->str, table_name->length, cs);
       table->field[2]->store(f_key_info->forein_id->str,
                              f_key_info->forein_id->length, cs);
       table->field[4]->store(f_key_info->referenced_db->str, 
@@ -4629,6 +4913,11 @@ TABLE *create_schema_table(THD *thd, TAB
                                  TMP_TABLE_ALL_COLUMNS),
                                 HA_POS_ERROR, table_list->alias)))
     DBUG_RETURN(0);
+  byte *bitmaps= thd->alloc(bitmap_buffer_size(field_count));
+  bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
+              FALSE);
+  table->read_set= &table->def_read_set;
+  bitmap_clear_all(table->read_set);
   table_list->schema_table_param= tmp_table_param;
   DBUG_RETURN(table);
 }
@@ -5208,442 +5497,459 @@ int fill_schema_session_variables(THD *t
 
 ST_FIELD_INFO schema_fields_info[]=
 {
-  {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
-  {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database", SKIP_OPEN},
+  {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO tables_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"},
-  {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
-  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
-  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
-  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
-  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
-  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
-  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
-  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
-  {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, "Auto_increment"},
-  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
-  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
-  {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
-  {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options"},
-  {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN},
+  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
+  {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version", OPEN_FRM_ONLY},
+  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FRM_ONLY},
+  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows", OPEN_FULL_TABLE},
+  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length",
+   OPEN_FULL_TABLE},
+  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length", OPEN_FULL_TABLE},
+  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length",
+   OPEN_FULL_TABLE},
+  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length", OPEN_FULL_TABLE},
+  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free", OPEN_FULL_TABLE},
+  {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, "Auto_increment",
+   OPEN_FULL_TABLE},
+  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time", OPEN_FULL_TABLE},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time", OPEN_FULL_TABLE},
+  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time", OPEN_FULL_TABLE},
+  {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
+  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum", OPEN_FRM_ONLY},
+  {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
+   OPEN_FULL_TABLE},
+  {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO columns_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"},
-  {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1, "Default"},
-  {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
-  {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-  {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type"},
-  {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"},
-  {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra"},
-  {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges"},
-  {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field", OPEN_FRM_ONLY},
+  {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FRM_ONLY},
+  {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1, "Default",
+   OPEN_FRM_ONLY},
+  {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
+  {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FRM_ONLY},
+  {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FRM_ONLY},
+  {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FRM_ONLY},
+  {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FRM_ONLY},
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
+  {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
+  {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
+  {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
+  {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
+  {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO charsets_fields_info[]=
 {
-  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
-  {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation"},
-  {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description"},
-  {"MAXLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", SKIP_OPEN},
+  {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation",
+   SKIP_OPEN},
+  {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description", SKIP_OPEN},
+  {"MAXLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO collation_fields_info[]=
 {
-  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation"},
-  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
-  {"ID", 11, MYSQL_TYPE_LONG, 0, 0, "Id"},
-  {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default"},
-  {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled"},
-  {"SORTLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN},
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", SKIP_OPEN},
+  {"ID", 11, MYSQL_TYPE_LONG, 0, 0, "Id", SKIP_OPEN},
+  {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN},
+  {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN},
+  {"SORTLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO engines_fields_info[]=
 {
-  {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine"},
-  {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support"},
-  {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-  {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions"},
-  {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA"},
-  {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN},
+  {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN},
+  {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN},
+  {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions", SKIP_OPEN},
+  {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA", SKIP_OPEN},
+  {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO events_fields_info[]=
 {
-  {"EVENT_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EVENT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
-  {"EVENT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-  {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
-  {"EXECUTE_AT", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Execute at"},
-  {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value"},
-  {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field"},
-  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"STARTS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Starts"},
-  {"ENDS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Ends"},
-  {"STATUS", 8, MYSQL_TYPE_STRING, 0, 0, "Status"},
-  {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
-  {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
-  {"LAST_EXECUTED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"EVENT_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"EVENT_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"EVENT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db", SKIP_OPEN},
+  {"EVENT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN},
+  {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN},
+  {"EXECUTE_AT", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Execute at", SKIP_OPEN},
+  {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value", SKIP_OPEN},
+  {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field", SKIP_OPEN},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"STARTS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Starts", SKIP_OPEN},
+  {"ENDS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Ends", SKIP_OPEN},
+  {"STATUS", 8, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN},
+  {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0, SKIP_OPEN},
+  {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0, SKIP_OPEN},
+  {"LAST_EXECUTED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, SKIP_OPEN},
+  {"EVENT_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 
 ST_FIELD_INFO coll_charset_app_fields_info[]=
 {
-  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO proc_fields_info[]=
 {
-  {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
-  {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
-  {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EXTERNAL_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EXTERNAL_LANGUAGE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"},
-  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created"},
-  {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified"},
-  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db", SKIP_OPEN},
+  {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN},
+  {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN},
+  {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"EXTERNAL_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"EXTERNAL_LANGUAGE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type", SKIP_OPEN},
+  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created", SKIP_OPEN},
+  {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified", SKIP_OPEN},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO stat_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, "Non_unique"},
-  {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name"},
-  {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, "Seq_in_index"},
-  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name"},
-  {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-  {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, "Cardinality"},
-  {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, "Sub_part"},
-  {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed"},
-  {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
-  {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type"},
-  {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
+  {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
+  {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name", OPEN_FRM_ONLY},
+  {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
+   OPEN_FRM_ONLY},
+  {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
+  {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, "Cardinality", OPEN_FULL_TABLE},
+  {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
+  {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
+  {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
+  {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type",
+   OPEN_FULL_TABLE},
+  {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO view_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO user_privileges_fields_info[]=
 {
-  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO schema_privileges_fields_info[]=
 {
-  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO table_privileges_fields_info[]=
 {
-  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO column_privileges_fields_info[]=
 {
-  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO table_constraints_fields_info[]=
 {
-  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO key_column_usage_fields_info[]=
 {
-  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0},
-  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0},
-  {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO table_names_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_"},
-  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_", SKIP_OPEN},
+  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type", OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO open_tables_fields_info[]=
 {
-  {"Database", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
-  {"Table",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"In_use", 1, MYSQL_TYPE_LONG, 0, 0, "In_use"},
-  {"Name_locked", 4, MYSQL_TYPE_LONG, 0, 0, "Name_locked"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"Database", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database", SKIP_OPEN},
+  {"Table",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN},
+  {"In_use", 1, MYSQL_TYPE_LONG, 0, 0, "In_use", SKIP_OPEN},
+  {"Name_locked", 4, MYSQL_TYPE_LONG, 0, 0, "Name_locked", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO triggers_fields_info[]=
 {
-  {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TRIGGER_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TRIGGER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger"},
-  {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event"},
-  {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EVENT_OBJECT_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"EVENT_OBJECT_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"ACTION_ORDER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
-  {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement"},
-  {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing"},
-  {"ACTION_REFERENCE_OLD_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ACTION_REFERENCE_NEW_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
-  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
-  {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TRIGGER_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TRIGGER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger", OPEN_FRM_ONLY},
+  {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FRM_ONLY},
+  {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"EVENT_OBJECT_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"EVENT_OBJECT_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table",
+   OPEN_FRM_ONLY},
+  {"ACTION_ORDER", 4, MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FRM_ONLY},
+  {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement",
+   OPEN_FRM_ONLY},
+  {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FRM_ONLY},
+  {"ACTION_REFERENCE_OLD_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FRM_ONLY},
+  {"ACTION_REFERENCE_NEW_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FRM_ONLY},
+  {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created", OPEN_FRM_ONLY},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FRM_ONLY},
+  {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO partitions_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SUBPARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-  {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"PARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"SUBPARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FRM_ONLY},
+  {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0,
+   OPEN_FRM_ONLY},
+  {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
+  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, OPEN_FULL_TABLE},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
+  {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO variables_fields_info[]=
 {
-  {"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
-  {"Value", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, "Value"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name", SKIP_OPEN},
+  {"Value", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, "Value", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO status_fields_info[]=
 {
-  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
-  {"VARIABLE_VALUE", 2207, MYSQL_TYPE_DECIMAL, 0, 0, "Value"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name", SKIP_OPEN},
+  {"VARIABLE_VALUE", 2207, MYSQL_TYPE_DECIMAL, 0, 0, "Value", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO system_variables_fields_info[]=
 {
-  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
-  {"VARIABLE_VALUE", 65535, MYSQL_TYPE_STRING, 0, 1, "Value"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name", SKIP_OPEN},
+  {"VARIABLE_VALUE", 65535, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO processlist_fields_info[]=
 {
-  {"ID", 4, MYSQL_TYPE_LONG, 0, 0, "Id"},
-  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User"},
-  {"HOST", LIST_PROCESS_HOST_LEN,  MYSQL_TYPE_STRING, 0, 0, "Host"},
-  {"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
-  {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
-  {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time"},
-  {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State"},
-  {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"ID", 4, MYSQL_TYPE_LONG, 0, 0, "Id", SKIP_OPEN},
+  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN},
+  {"HOST", LIST_PROCESS_HOST_LEN,  MYSQL_TYPE_STRING, 0, 0, "Host", SKIP_OPEN},
+  {"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN},
+  {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN},
+  {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time", SKIP_OPEN},
+  {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN},
+  {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 
 ST_FIELD_INFO plugin_fields_info[]=
 {
-  {"PLUGIN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status"},
-  {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type"},
-  {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PLUGIN_LIBRARY", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"},
-  {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PLUGIN_AUTHOR", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"PLUGIN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN},
+  {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN},
+  {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN},
+  {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"PLUGIN_LIBRARY", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Library", SKIP_OPEN},
+  {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"PLUGIN_AUTHOR", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 ST_FIELD_INFO files_fields_info[]=
 {
-  {"FILE_ID", 4, MYSQL_TYPE_LONG, 0, 0, 0},
-  {"FILE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"LOGFILE_GROUP_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"FULLTEXT_KEYS", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"DELETED_ROWS", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"UPDATE_COUNT", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"FREE_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"EXTENT_SIZE", 4, MYSQL_TYPE_LONG, 0, 0, 0},
-  {"INITIAL_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"CREATION_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
-  {"RECOVER_TIME", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONG, 0, 1, 0},
-  {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
-  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
-  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
-  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
-  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
-  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
-  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
-  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
-  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
-  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
-  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
-  {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"FILE_ID", 4, MYSQL_TYPE_LONG, 0, 0, 0, SKIP_OPEN},
+  {"FILE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"LOGFILE_GROUP_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"FULLTEXT_KEYS", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {"DELETED_ROWS", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"UPDATE_COUNT", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"FREE_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"EXTENT_SIZE", 4, MYSQL_TYPE_LONG, 0, 0, 0, SKIP_OPEN},
+  {"INITIAL_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"CREATION_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, SKIP_OPEN},
+  {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, SKIP_OPEN},
+  {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, SKIP_OPEN},
+  {"RECOVER_TIME", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN},
+  {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version", SKIP_OPEN},
+  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN},
+  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows", SKIP_OPEN},
+  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length", SKIP_OPEN},
+  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length", SKIP_OPEN},
+  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length", SKIP_OPEN},
+  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length", SKIP_OPEN},
+  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free", SKIP_OPEN},
+  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time", SKIP_OPEN},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time", SKIP_OPEN},
+  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time", SKIP_OPEN},
+  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum", SKIP_OPEN},
+  {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN},
+  {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 void init_fill_schema_files_row(TABLE* table)
@@ -5658,17 +5964,20 @@ void init_fill_schema_files_row(TABLE* t
 
 ST_FIELD_INFO referential_constraints_fields_info[]=
 {
-  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN}
 };
 
 

--- 1.156/sql/table.h	2006-12-23 23:19:56 +04:00
+++ 1.157/sql/table.h	2007-02-08 14:33:00 +04:00
@@ -504,6 +504,10 @@ enum enum_schema_tables
 };
 
 
+#define SKIP_OPEN       0
+#define OPEN_FRM_ONLY   1
+#define OPEN_FULL_TABLE 2
+
 typedef struct st_field_info
 {
   const char* field_name;
@@ -512,6 +516,7 @@ typedef struct st_field_info
   int value;
   bool maybe_null;
   const char* old_name;
+  uint open_method;
 } ST_FIELD_INFO;
 
 
@@ -529,8 +534,8 @@ typedef struct st_schema_table
   /* Handle fileds for old SHOW */
   int (*old_format) (THD *thd, struct st_schema_table *schema_table);
   int (*process_table) (THD *thd, struct st_table_list *tables,
-                        TABLE *table, bool res, const char *base_name,
-                        const char *file_name);
+                        TABLE *table, bool res, LEX_STRING *db_name,
+                        LEX_STRING *table_name);
   int idx_field1, idx_field2; 
   bool hidden;
 } ST_SCHEMA_TABLE;
@@ -810,6 +815,7 @@ typedef struct st_table_list
   bool          compact_view_format;    /* Use compact format for SHOW CREATE VIEW */
   /* view where processed */
   bool          where_processed;
+  bool          open_frm_only;
   /* FRMTYPE_ERROR if any type is acceptable */
   enum frm_type_enum required_type;
   handlerton	*db_type;		/* table_type for handler */

--- 1.3/sql/sql_show.h	2006-11-15 14:12:07 +04:00
+++ 1.4/sql/sql_show.h	2007-02-08 14:32:59 +04:00
@@ -16,7 +16,7 @@ enum find_files_result {
   FIND_FILES_DIR
 };
 
-find_files_result find_files(THD *thd, List<char> *files, const char *db,
+find_files_result find_files(THD *thd, List<LEX_STRING> *files, const char *db,
                              const char *path, const char *wild, bool dir);
 
 int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,

--- 1.376/sql/ha_ndbcluster.cc	2006-12-23 23:19:49 +04:00
+++ 1.377/sql/ha_ndbcluster.cc	2007-02-08 14:32:59 +04:00
@@ -6352,7 +6352,7 @@ int ndbcluster_find_all_files(THD *thd)
 int ndbcluster_find_files(handlerton *hton, THD *thd,
                           const char *db,
                           const char *path,
-                          const char *wild, bool dir, List<char> *files)
+                          const char *wild, bool dir, List<LEX_STRING> *files)
 {
   DBUG_ENTER("ndbcluster_find_files");
   DBUG_PRINT("enter", ("db: %s", db));
@@ -6419,21 +6419,22 @@ int ndbcluster_find_files(handlerton *ht
     my_hash_insert(&ndb_tables, (byte*)thd->strdup(elmt.name));
   }
 
-  char *file_name;
-  List_iterator<char> it(*files);
+  LEX_STRING *file_name;
+  List_iterator<LEX_STRING> it(*files);
   List<char> delete_list;
+  char *file_name_str;
   while ((file_name=it++))
   {
     bool file_on_disk= false;
-    DBUG_PRINT("info", ("%s", file_name));     
-    if (hash_search(&ndb_tables, file_name, strlen(file_name)))
+    DBUG_PRINT("info", ("%s", file_name->str));     
+    if (hash_search(&ndb_tables, file_name->str, file_name->length))
     {
-      DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name));
+      DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name->str));
       file_on_disk= true;
     }
     
     // Check for .ndb file with this name
-    build_table_filename(name, sizeof(name), db, file_name, ha_ndb_ext, 0);
+    build_table_filename(name, sizeof(name), db, file_name->str, ha_ndb_ext, 0);
     DBUG_PRINT("info", ("Check access for %s", name));
     if (my_access(name, F_OK))
     {
@@ -6442,31 +6443,32 @@ int ndbcluster_find_files(handlerton *ht
       if (file_on_disk)
       {
 	// Ignore this ndb table
-	gptr record=  hash_search(&ndb_tables, file_name, strlen(file_name));
+	gptr record=  hash_search(&ndb_tables, file_name->str,
+                                  file_name->length);
 	DBUG_ASSERT(record);
 	hash_delete(&ndb_tables, record);
 	push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 			    ER_TABLE_EXISTS_ERROR,
 			    "Local table %s.%s shadows ndb table",
-			    db, file_name);
+			    db, file_name->str);
       }
       continue;
     }
     if (file_on_disk) 
     {
       // File existed in NDB and as frm file, put in ok_tables list
-      my_hash_insert(&ok_tables, (byte*)file_name);
+      my_hash_insert(&ok_tables, (byte*)file_name->str);
       continue;
     }
     DBUG_PRINT("info", ("%s existed on disk", name));     
     // The .ndb file exists on disk, but it's not in list of tables in ndb
     // Verify that handler agrees table is gone.
-    if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name) == 0)    
+    if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name->str) == 0)
     {
-      DBUG_PRINT("info", ("NDB says %s does not exists", file_name));     
+      DBUG_PRINT("info", ("NDB says %s does not exists", file_name->str));     
       it.remove();
       // Put in list of tables to remove from disk
-      delete_list.push_back(thd->strdup(file_name));
+      delete_list.push_back(thd->strdup(file_name->str));
     }
   }
 
@@ -6477,12 +6479,12 @@ int ndbcluster_find_files(handlerton *ht
       build_table_filename(name, sizeof(name), db, "", "", 0);
     for (i= 0; i < ok_tables.records; i++)
     {
-      file_name= (char*)hash_element(&ok_tables, i);
+      file_name_str= (char*)hash_element(&ok_tables, i);
       end= end1 +
-        tablename_to_filename(file_name, end1, sizeof(name) - (end1 - name));
+        tablename_to_filename(file_name_str, end1, sizeof(name) - (end1 - name));
       pthread_mutex_lock(&LOCK_open);
       ndbcluster_create_binlog_setup(ndb, name, end-name,
-                                     db, file_name, TRUE);
+                                     db, file_name_str, TRUE);
       pthread_mutex_unlock(&LOCK_open);
     }
   }
@@ -6493,16 +6495,16 @@ int ndbcluster_find_files(handlerton *ht
   List<char> create_list;
   for (i= 0 ; i < ndb_tables.records ; i++)
   {
-    file_name= hash_element(&ndb_tables, i);
-    if (!hash_search(&ok_tables, file_name, strlen(file_name)))
+    file_name_str= hash_element(&ndb_tables, i);
+    if (!hash_search(&ok_tables, file_name_str, strlen(file_name_str)))
     {
-      build_table_filename(name, sizeof(name), db, file_name, reg_ext, 0);
+      build_table_filename(name, sizeof(name), db, file_name_str, reg_ext, 0);
       if (my_access(name, F_OK))
       {
-        DBUG_PRINT("info", ("%s must be discovered", file_name));
+        DBUG_PRINT("info", ("%s must be discovered", file_name_str));
         // File is in list of ndb tables and not in ok_tables
         // This table need to be created
-        create_list.push_back(thd->strdup(file_name));
+        create_list.push_back(thd->strdup(file_name_str));
       }
     }
   }
@@ -6514,14 +6516,14 @@ int ndbcluster_find_files(handlerton *ht
   {
     // Delete old files
     List_iterator_fast<char> it3(delete_list);
-    while ((file_name=it3++))
+    while ((file_name_str= it3++))
     {
-      DBUG_PRINT("info", ("Remove table %s/%s", db, file_name));
+      DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str));
       // Delete the table and all related files
       TABLE_LIST table_list;
       bzero((char*) &table_list,sizeof(table_list));
       table_list.db= (char*) db;
-      table_list.alias= table_list.table_name= (char*)file_name;
+      table_list.alias= table_list.table_name= (char*)file_name_str;
       (void)mysql_rm_table_part2(thd, &table_list,
                                                                  /* if_exists */ FALSE,
                                                                  /* drop_temporary */ FALSE,
@@ -6534,11 +6536,16 @@ int ndbcluster_find_files(handlerton *ht
 
   // Create new files
   List_iterator_fast<char> it2(create_list);
-  while ((file_name=it2++))
+  while ((file_name_str=it2++))
   {  
-    DBUG_PRINT("info", ("Table %s need discovery", file_name));
-    if (ndb_create_table_from_engine(thd, db, file_name) == 0)
-      files->push_back(thd->strdup(file_name)); 
+    DBUG_PRINT("info", ("Table %s need discovery", file_name_str));
+    if (ndb_create_table_from_engine(thd, db, file_name_str) == 0)
+    {
+      LEX_STRING *tmp_file_name= 
+        make_lex_string(thd, tmp_file_name, file_name_str,
+                        strlen(file_name_str), TRUE);
+      files->push_back(tmp_file_name); 
+    }
   }
 
   pthread_mutex_unlock(&LOCK_open);
@@ -6552,8 +6559,8 @@ int ndbcluster_find_files(handlerton *ht
     uint count = 0;
     while (count++ < files->elements)
     {
-      file_name = (char *)files->pop();
-      if (!strcmp(file_name, NDB_SCHEMA_TABLE))
+      file_name = (LEX_STRING *)files->pop();
+      if (!strcmp(file_name->str, NDB_SCHEMA_TABLE))
       {
         DBUG_PRINT("info", ("skip %s.%s table, it should be hidden to user",
                    NDB_REP_DB, NDB_SCHEMA_TABLE));

--- 1.160/sql/ha_ndbcluster.h	2006-12-23 23:19:49 +04:00
+++ 1.161/sql/ha_ndbcluster.h	2007-02-08 14:32:59 +04:00
@@ -988,7 +988,7 @@ extern SHOW_VAR ndb_status_variables[];
 int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
                         const void** frmblob, uint* frmlen);
 int ndbcluster_find_files(THD *thd,const char *db,const char *path,
-                          const char *wild, bool dir, List<char> *files);
+                          const char *wild, bool dir, List<LEX_STRING> *files);
 int ndbcluster_table_exists_in_engine(THD* thd,
                                       const char *db, const char *name);
 void ndbcluster_print_error(int error, const NdbOperation *error_op);

--- 1.90/sql/ha_ndbcluster_binlog.cc	2006-12-01 18:48:25 +04:00
+++ 1.91/sql/ha_ndbcluster_binlog.cc	2007-02-08 14:32:59 +04:00
@@ -2355,8 +2355,8 @@ ndbcluster_check_if_local_tables_in_db(T
 {
   DBUG_ENTER("ndbcluster_check_if_local_tables_in_db");
   DBUG_PRINT("info", ("Looking for files in directory %s", dbname));
-  char *tabname;
-  List<char> files;
+  LEX_STRING *tabname;
+  List<LEX_STRING> files;
   char path[FN_REFLEN];
 
   build_table_filename(path, sizeof(path), dbname, "", "", 0);
@@ -2368,8 +2368,8 @@ ndbcluster_check_if_local_tables_in_db(T
   DBUG_PRINT("info",("found: %d files", files.elements));
   while ((tabname= files.pop()))
   {
-    DBUG_PRINT("info", ("Found table %s", tabname));
-    if (ndbcluster_check_if_local_table(dbname, tabname))
+    DBUG_PRINT("info", ("Found table %s", tabname->str));
+    if (ndbcluster_check_if_local_table(dbname, tabname->str))
       DBUG_RETURN(true);
   }
   
Thread
bk commit into 5.1 tree (gluh:1.2368) BUG#19588gluh8 Feb