List:Commits« Previous MessageNext Message »
From:gluh Date:August 2 2007 4:01pm
Subject:bk commit into 5.1 tree (gluh:1.2569)
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-08-02 19:01:21+05:00, gluh@stripped +17 -0
  WL#3732: Information schema optimization

  client/mysqldump.c@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +2 -1
    table type compare is changed to case insensitive

  mysql-test/r/information_schema.result@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped
+29 -11
    test result

  mysql-test/suite/ndb/r/ndb_alter_table.result@stripped, 2007-08-02 19:01:18+05:00,
gluh@stripped +4 -4
    result fix

  mysql-test/suite/ndb/r/ndb_temporary.result@stripped, 2007-08-02 19:01:18+05:00,
gluh@stripped +1 -1
    result fix

  mysql-test/t/information_schema.test@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped
+20 -0
    test case

  sql/ha_ndbcluster.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +39 -32
    char* variables changed to LEX_STRING

  sql/ha_ndbcluster.h@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +1 -1
    char* variables changed to LEX_STRING

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +4 -4
    char* variables changed to LEX_STRING

  sql/handler.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +2 -2
    char* variables changed to LEX_STRING

  sql/handler.h@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +2 -2
    char* variables changed to LEX_STRING

  sql/sql_base.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +10 -4
    Modified functions which are used during open table process
    according to table opening method and requested_object.

  sql/sql_select.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +76 -30
    Add support for I_S tables into select_describe() function

  sql/sql_show.cc@stripped, 2007-08-02 19:01:18+05:00, gluh@stripped +1414 -834
    1. Added initialization of 'open_method' to 'st_field_info' structs.
    2. Added initialization of 'i_s_requested_object' to 'ST_SCHEMA_TABLE' structs.
    3. New function which calculates database name and table name values 
       from 'where' condition if it's possible
       void get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *table,
                                    LOOKUP_FIELD_VALUES *lookup_field_vals);
    4. New function which set table open method
       setup_table_open_method(TABLE_LIST *tables,
                               ST_SCHEMA_TABLE *schema_table,
                               enum enum_schema_tables schema_table_idx)
    5. New function
       int make_db_list(THD *thd, List<LEX_STRING> *files,
                        LOOKUP_FIELD_VALUES *lookup_field_vals,
                        bool *with_i_schema)
    6. New function
       int make_table_name_list(THD *thd, List<LEX_STRING> *files, LEX *lex,
                                LOOKUP_FIELD_VALUES *lookup_field_vals,
                                bool with_i_schema, LEX_STRING *db_name)
    7. Modified 'get_all_tables' function according to new schema(see wl#3732).

  sql/sql_show.h@stripped, 2007-08-02 19:01:19+05:00, gluh@stripped +1 -1
    char* variables changed to LEX_STRING

  sql/table.cc@stripped, 2007-08-02 19:01:19+05:00, gluh@stripped +19 -3
    Modified functions which are used during open table process
    according to table opening method and requested_object.

  sql/table.h@stripped, 2007-08-02 19:01:19+05:00, gluh@stripped +12 -3
    1. added new constants(open_method)
    #define SKIP_OPEN_TABLE 0
    #define OPEN_FRM_ONLY   1
    #define OPEN_FULL_TABLE 2
    
    2. Added new field 'open_method' into struct st_field_info;
       uint open_method;
    
    3. Added new field into ST_SCHEMA_TABLE struct
       uint i_s_requested_object;  /* the object we need to open(TABLE | VIEW) */.
    4. Added new field to TABLE_LIST struct.
       uint i_s_requested_object;
       This field is set from ST_SCHEMA_TABLE.i_s_requested_object
       for processed table before opening.
    
    5. Added new fields to TABLE_LIST struct, used for 'explain select' for I_S table
       bool has_db_lookup_value;
       bool has_table_lookup_value;
       uint table_open_method;

  sql/unireg.h@stripped, 2007-08-02 19:01:19+05:00, gluh@stripped +5 -0
    added new constants

diff -Nrup a/client/mysqldump.c b/client/mysqldump.c
--- a/client/mysqldump.c	2007-07-21 05:18:13 +05:00
+++ b/client/mysqldump.c	2007-08-02 19:01:18 +05:00
@@ -4255,7 +4255,8 @@ char check_if_ignore_table(const char *t
       If these two types, we do want to skip dumping the table
     */
     if (!opt_no_data &&
-        (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM")))
+        (!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") ||
+         !strcmp(table_type,"MRG_ISAM")))
       result= IGNORE_DATA;
   }
   mysql_free_result(res);
diff -Nrup a/mysql-test/r/information_schema.result
b/mysql-test/r/information_schema.result
--- a/mysql-test/r/information_schema.result	2007-07-17 00:31:32 +05:00
+++ b/mysql-test/r/information_schema.result	2007-08-02 19:01:18 +05:00
@@ -289,8 +289,8 @@ explain select a.ROUTINE_NAME from infor
 information_schema.SCHEMATA b where
 a.ROUTINE_SCHEMA = b.SCHEMA_NAME;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	2	
-1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer
+1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	NULL	
+1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	NULL	Using where; Using join buffer
 select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
 mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1;
 ROUTINE_NAME	name
@@ -355,7 +355,7 @@ mysql
 test
 explain select * from v0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	#	ALL	NULL	NULL	NULL	NULL	NULL	
 create view v1 (c) as select table_name from information_schema.tables
 where table_name="v1";
 select * from v1;
@@ -679,17 +679,11 @@ where table_schema='test';
 table_name
 v2
 v3
-Warnings:
-Warning	1356	View 'test.v2' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
-Warning	1356	View 'test.v3' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
 select table_name from information_schema.views
 where table_schema='test';
 table_name
 v2
 v3
-Warnings:
-Warning	1356	View 'test.v2' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
-Warning	1356	View 'test.v3' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
 select column_name from information_schema.columns
 where table_schema='test';
 column_name
@@ -1337,11 +1331,11 @@ from information_schema.tables
 order by object_schema;
 explain select * from v1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	tables	ALL	NULL	NULL	NULL	NULL	2	Using filesort
+1	SIMPLE	tables	ALL	NULL	NULL	NULL	NULL	NULL	Open_frm_only; Scanned all databases; Using
filesort
 explain select * from (select table_name from information_schema.tables) as a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	0	const row not found
-2	DERIVED	tables	ALL	NULL	NULL	NULL	NULL	2	
+2	DERIVED	tables	ALL	NULL	NULL	NULL	NULL	NULL	Skip_open_table; Scanned all databases
 drop view v1;
 create table t1 (f1 int(11));
 create table t2 (f1 int(11), f2 int(11));
@@ -1445,4 +1439,28 @@ ABORTED_CONNECTS
 BINLOG_CACHE_DISK_USE
 DROP TABLE server_status;
 SET GLOBAL event_scheduler=0;
+explain select table_name from information_schema.views where
+table_schema='test' and table_name='v1';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	views	ALL	NULL	TABLE_SCHEMA,TABLE_NAME	NULL	NULL	NULL	Using where;
Open_frm_only; Scanned 0 databases
+explain select * from information_schema.tables;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	tables	ALL	NULL	NULL	NULL	NULL	NULL	Open_full_table; Scanned all databases
+explain select * from information_schema.collations;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	collations	ALL	NULL	NULL	NULL	NULL	NULL	
+explain select * from information_schema.tables where
+table_schema='test' and table_name= 't1';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	tables	ALL	NULL	TABLE_SCHEMA,TABLE_NAME	NULL	NULL	NULL	Using where;
Open_full_table; Scanned 0 databases
+explain select table_name, table_type from information_schema.tables
+where table_schema='test';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	tables	ALL	NULL	TABLE_SCHEMA	NULL	NULL	NULL	Using where; Open_frm_only; Scanned
1 database
+explain select b.table_name
+from information_schema.tables a, information_schema.columns b
+where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	a	ALL	NULL	TABLE_SCHEMA,TABLE_NAME	NULL	NULL	NULL	Using where; Skip_open_table;
Scanned 0 databases
+1	SIMPLE	b	ALL	NULL	NULL	NULL	NULL	NULL	Using where; Open_frm_only; Scanned all
databases; Using join buffer
 End of 5.1 tests.
diff -Nrup a/mysql-test/suite/ndb/r/ndb_alter_table.result
b/mysql-test/suite/ndb/r/ndb_alter_table.result
--- a/mysql-test/suite/ndb/r/ndb_alter_table.result	2007-06-27 17:27:32 +05:00
+++ b/mysql-test/suite/ndb/r/ndb_alter_table.result	2007-08-02 19:01:18 +05:00
@@ -34,13 +34,13 @@ col5 enum('PENDING', 'ACTIVE', 'DISABLED
 col6 int not null, to_be_deleted int)  ENGINE=ndbcluster;
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	NDBCLUSTER	10	Dynamic	0	#	#	#	0	#	1	#	#	#	latin1_swedish_ci	NULL		#
+t1	ndbcluster	10	Dynamic	0	#	#	#	0	#	1	#	#	#	latin1_swedish_ci	NULL		#
 SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
 insert into t1 values
 (0,4,3,5,"PENDING",1,7),(NULL,4,3,5,"PENDING",1,7),(31,4,3,5,"PENDING",1,7),
(7,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7), (100,4,3,5,"PENDING",1,7),
(99,4,3,5,"PENDING",1,7), (8,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	NDBCLUSTER	10	Dynamic	9	#	#	#	0	#	102	#	#	#	latin1_swedish_ci	NULL		#
+t1	ndbcluster	10	Dynamic	9	#	#	#	0	#	102	#	#	#	latin1_swedish_ci	NULL		#
 select * from t1 order by col1;
 col1	col2	col3	col4	col5	col6	to_be_deleted
 0	4	3	5	PENDING	1	7
@@ -60,7 +60,7 @@ change column col2 fourth varchar(30) no
 modify column col6 int not null first;
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	NDBCLUSTER	10	Dynamic	9	#	#	#	0	#	102	#	#	#	latin1_swedish_ci	NULL		#
+t1	ndbcluster	10	Dynamic	9	#	#	#	0	#	102	#	#	#	latin1_swedish_ci	NULL		#
 select * from t1 order by col1;
 col6	col1	col3	fourth	col4	col4_5	col5	col7	col8
 1	0	3	4	5		PENDING		0000-00-00 00:00:00
@@ -75,7 +75,7 @@ col6	col1	col3	fourth	col4	col4_5	col5	c
 insert into t1 values (2, NULL,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00');
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	NDBCLUSTER	10	Dynamic	10	#	#	#	0	#	103	#	#	#	latin1_swedish_ci	NULL		#
+t1	ndbcluster	10	Dynamic	10	#	#	#	0	#	103	#	#	#	latin1_swedish_ci	NULL		#
 select * from t1 order by col1;
 col6	col1	col3	fourth	col4	col4_5	col5	col7	col8
 1	0	3	4	5		PENDING		0000-00-00 00:00:00
diff -Nrup a/mysql-test/suite/ndb/r/ndb_temporary.result
b/mysql-test/suite/ndb/r/ndb_temporary.result
--- a/mysql-test/suite/ndb/r/ndb_temporary.result	2007-06-27 17:27:28 +05:00
+++ b/mysql-test/suite/ndb/r/ndb_temporary.result	2007-08-02 19:01:18 +05:00
@@ -9,7 +9,7 @@ SET SESSION storage_engine=NDBCLUSTER;
 create table t1 (a int key);
 select engine from information_schema.tables where table_name = 't1';
 engine
-NDBCLUSTER
+ndbcluster
 drop table t1;
 create temporary table t1 (a int key);
 show create table t1;
diff -Nrup a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
--- a/mysql-test/t/information_schema.test	2007-07-17 00:31:33 +05:00
+++ b/mysql-test/t/information_schema.test	2007-08-02 19:01:18 +05:00
@@ -1100,4 +1100,24 @@ SELECT variable_name FROM server_status;
 DROP TABLE server_status;
 SET GLOBAL event_scheduler=0;
 
+
+#
+# WL#3732 Information schema optimization
+# 
+
+explain select table_name from information_schema.views where
+table_schema='test' and table_name='v1';
+
+explain select * from information_schema.tables;
+explain select * from information_schema.collations;
+
+explain select * from information_schema.tables where
+table_schema='test' and table_name= 't1';
+explain select table_name, table_type from information_schema.tables
+where table_schema='test';
+
+explain select b.table_name
+from information_schema.tables a, information_schema.columns b
+where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name;
+
 --echo End of 5.1 tests.
diff -Nrup a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
--- a/sql/ha_ndbcluster.cc	2007-07-25 19:58:10 +05:00
+++ b/sql/ha_ndbcluster.cc	2007-08-02 19:01:18 +05:00
@@ -6883,7 +6883,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));
@@ -6950,21 +6950,22 @@ int ndbcluster_find_files(handlerton *ht
     my_hash_insert(&ndb_tables, (uchar*)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, (uchar*) file_name, strlen(file_name)))
+    DBUG_PRINT("info", ("%s", file_name->str));     
+    if (hash_search(&ndb_tables, (uchar*) 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))
     {
@@ -6972,33 +6973,34 @@ int ndbcluster_find_files(handlerton *ht
       // .ndb file did not exist on disk, another table type
       if (file_on_disk)
       {
-	// Ignore this ndb table
-	uchar *record= hash_search(&ndb_tables, (uchar*) file_name,
-                                   strlen(file_name));
+	// Ignore this ndb table 
+ 	uchar *record= hash_search(&ndb_tables, (uchar*) 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, (uchar*)file_name);
+      my_hash_insert(&ok_tables, (uchar*) 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) ==
HA_ERR_NO_SUCH_TABLE)    
+    if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name->str) ==
+        HA_ERR_NO_SUCH_TABLE)
     {
-      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));
     }
   }
 
@@ -7009,12 +7011,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);
     }
   }
@@ -7025,16 +7027,16 @@ int ndbcluster_find_files(handlerton *ht
   List<char> create_list;
   for (i= 0 ; i < ndb_tables.records ; i++)
   {
-    file_name= (char*) hash_element(&ndb_tables, i);
-    if (!hash_search(&ok_tables, (uchar*) file_name, strlen(file_name)))
+    file_name_str= (char*) hash_element(&ndb_tables, i);
+    if (!hash_search(&ok_tables, (uchar*) 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));
       }
     }
   }
@@ -7043,14 +7045,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,
                                  FALSE,   /* if_exists */
                                  FALSE,   /* drop_temporary */ 
@@ -7065,11 +7067,16 @@ int ndbcluster_find_files(handlerton *ht
   pthread_mutex_lock(&LOCK_open);
   // 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= 0;
+      tmp_file_name= thd->make_lex_string(tmp_file_name, file_name_str,
+                                          strlen(file_name_str), TRUE);
+      files->push_back(tmp_file_name); 
+    }
   }
 
   pthread_mutex_unlock(&LOCK_open);
@@ -7083,8 +7090,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));
diff -Nrup a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
--- a/sql/ha_ndbcluster.h	2007-07-13 18:57:10 +05:00
+++ b/sql/ha_ndbcluster.h	2007-08-02 19:01:18 +05:00
@@ -563,7 +563,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);
diff -Nrup a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
--- a/sql/ha_ndbcluster_binlog.cc	2007-06-28 01:28:07 +05:00
+++ b/sql/ha_ndbcluster_binlog.cc	2007-08-02 19:01:18 +05:00
@@ -2480,8 +2480,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);
@@ -2493,8 +2493,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);
   }
   
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-07-19 15:54:28 +05:00
+++ b/sql/handler.cc	2007-08-02 19:01:18 +05:00
@@ -2857,7 +2857,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, plugin_ref plugin,
@@ -2877,7 +2877,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");
diff -Nrup a/sql/handler.h b/sql/handler.h
--- a/sql/handler.h	2007-07-17 01:59:16 +05:00
+++ b/sql/handler.h	2007-08-02 19:01:18 +05:00
@@ -700,7 +700,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 */
@@ -1841,7 +1841,7 @@ int ha_create_table_from_engine(THD* thd
 int ha_discover(THD* thd, const char* dbname, const char* name,
                 uchar** frmblob, size_t* 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 */
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc	2007-07-26 05:23:30 +05:00
+++ b/sql/sql_base.cc	2007-08-02 19:01:18 +05:00
@@ -2732,11 +2732,10 @@ bool reopen_table(TABLE *table)
     sql_print_error("Table %s had a open data handler in reopen_table",
 		    table->alias);
 #endif
+  bzero((char*) &table_list, sizeof(TABLE_LIST));
   table_list.db=         table->s->db.str;
   table_list.table_name= table->s->table_name.str;
   table_list.table=      table;
-  table_list.belong_to_view= 0;
-  table_list.next_local= 0;
 
   if (wait_for_locked_table_names(thd, &table_list))
     DBUG_RETURN(1);                             // Thread was killed
@@ -3276,15 +3275,19 @@ static int open_unireg_entry(THD *thd, T
   DBUG_ENTER("open_unireg_entry");
 
   safe_mutex_assert_owner(&LOCK_open);
-
 retry:
   if (!(share= get_table_share_with_create(thd, table_list, cache_key,
                                            cache_key_length, 
-                                           OPEN_VIEW, &error)))
+                                           OPEN_VIEW |
+                                           table_list->i_s_requested_object,
+                                           &error)))
     DBUG_RETURN(1);
 
   if (share->is_view)
   {
+    if (table_list->i_s_requested_object &  OPEN_TABLE_ONLY)
+      goto err;
+
     /* Open view */
     error= (int) open_new_frm(thd, share, alias,
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
@@ -3299,6 +3302,9 @@ retry:
     release_table_share(share, RELEASE_NORMAL);
     DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0);
   }
+
+  if (table_list->i_s_requested_object &  OPEN_VIEW_ONLY)
+    goto err;
 
   while ((error= open_table_from_share(thd, share, alias,
                                        (uint) (HA_OPEN_KEYFILE |
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc	2007-07-26 04:41:01 +05:00
+++ b/sql/sql_select.cc	2007-08-02 19:01:18 +05:00
@@ -1624,6 +1624,10 @@ JOIN::exec()
     DBUG_VOID_RETURN;
   }
 
+  if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
+      get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
+    DBUG_VOID_RETURN;
+
   if (select_options & SELECT_DESCRIBE)
   {
     /*
@@ -1669,13 +1673,6 @@ JOIN::exec()
   */
   curr_join->examined_rows= 0;
 
-  if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) &&
-      !thd->lex->describe &&
-      get_schema_tables_result(curr_join, PROCESSED_BY_JOIN_EXEC))
-  {
-    DBUG_VOID_RETURN;
-  }
-
   /* Create a tmp table if distinct or if the sort is too complicated */
   if (need_tmp)
   {
@@ -12928,7 +12925,6 @@ create_sort_index(THD *thd, JOIN *join, 
 
   /* Fill schema tables with data before filesort if it's necessary */
   if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
-      !thd->lex->describe &&
       get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
     goto err;
 
@@ -15380,6 +15376,7 @@ static void select_describe(JOIN *join, 
     {
       JOIN_TAB *tab=join->join_tab+i;
       TABLE *table=tab->table;
+      TABLE_LIST *table_list= tab->table->pos_in_table_list;
       char buff[512]; 
       char buff1[512], buff2[512], buff3[512];
       char keylen_str_buf[64];
@@ -15515,37 +15512,68 @@ static void select_describe(JOIN *join, 
       }
       else
       {
-	item_list.push_back(item_null);
+        if (table_list->schema_table &&
+            table_list->schema_table->i_s_requested_object &
OPTIMIZE_I_S_TABLE)
+        {
+          const char *tmp_buff;
+          int f_idx;
+          if (table_list->has_db_lookup_value)
+          {
+            f_idx= table_list->schema_table->idx_field1;
+            tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
+            tmp2.append(tmp_buff, strlen(tmp_buff), cs);
+          }          
+          if (table_list->has_table_lookup_value)
+          {
+            if (table_list->has_db_lookup_value)
+              tmp2.append(',');
+            f_idx= table_list->schema_table->idx_field2;
+            tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
+            tmp2.append(tmp_buff, strlen(tmp_buff), cs);
+          }
+          if (tmp2.length())
+            item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
+          else
+            item_list.push_back(item_null);
+        }
+        else
+          item_list.push_back(item_null);
 	item_list.push_back(item_null);
 	item_list.push_back(item_null);
       }
       
       /* Add "rows" field to item_list. */
-      ha_rows examined_rows;
-      if (tab->select && tab->select->quick)
-        examined_rows= tab->select->quick->records;
-      else if (tab->type == JT_NEXT || tab->type == JT_ALL)
-        examined_rows= tab->table->file->records();
+      if (table_list->schema_table)
+      {
+        item_list.push_back(item_null);
+      }
       else
-        examined_rows=(ha_rows)join->best_positions[i].records_read; 
- 
-      item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, 
-                                       MY_INT64_NUM_DECIMAL_DIGITS));
-
-      /* Add "filtered" field to item_list. */
-      if (join->thd->lex->describe & DESCRIBE_EXTENDED)
       {
-        Item_float *filtered;
-        float f; 
-        if (examined_rows)
-          f= (float) (100.0 * join->best_positions[i].records_read /
-                      examined_rows);
+        ha_rows examined_rows;
+        if (tab->select && tab->select->quick)
+          examined_rows= tab->select->quick->records;
+        else if (tab->type == JT_NEXT || tab->type == JT_ALL)
+          examined_rows= tab->table->file->records();
         else
-          f= 0.0;
-        item_list.push_back((filtered= new Item_float(f)));
-        filtered->decimals= 2;
-      }
+          examined_rows=(ha_rows)join->best_positions[i].records_read; 
+ 
+        item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, 
+                                         MY_INT64_NUM_DECIMAL_DIGITS));
 
+        /* Add "filtered" field to item_list. */
+        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
+        {
+          Item_float *filtered;
+          float f; 
+          if (examined_rows)
+            f= (float) (100.0 * join->best_positions[i].records_read /
+                        examined_rows);
+          else
+            f= 0.0;
+          item_list.push_back((filtered= new Item_float(f)));
+          filtered->decimals= 2;
+        }
+      }
 
       /* Build "Extra" field and add it to item_list. */
       my_bool key_read=table->key_read;
@@ -15613,6 +15641,24 @@ static void select_describe(JOIN *join, 
               extra.append(STRING_WITH_LEN("; Using where"));
           }
 	}
+        if (table_list->schema_table &&
+            table_list->schema_table->i_s_requested_object &
OPTIMIZE_I_S_TABLE)
+        {
+          if (!table_list->table_open_method)
+            extra.append(STRING_WITH_LEN("; Skip_open_table"));
+          else if (table_list->table_open_method == OPEN_FRM_ONLY)
+            extra.append(STRING_WITH_LEN("; Open_frm_only"));
+          else
+            extra.append(STRING_WITH_LEN("; Open_full_table"));
+          if (table_list->has_db_lookup_value &&
+              table_list->has_table_lookup_value)
+            extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
+          else if (table_list->has_db_lookup_value ||
+                   table_list->has_table_lookup_value)
+            extra.append(STRING_WITH_LEN("; Scanned 1 database"));
+          else
+            extra.append(STRING_WITH_LEN("; Scanned all databases"));
+        }
 	if (key_read)
         {
           if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
diff -Nrup a/sql/sql_show.cc b/sql/sql_show.cc
--- a/sql/sql_show.cc	2007-07-18 22:37:54 +05:00
+++ b/sql/sql_show.cc	2007-08-02 19:01:18 +05:00
@@ -443,13 +443,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
@@ -498,10 +500,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= 
+            thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
+      {
+        my_dirend(dirp);
+        DBUG_RETURN(FIND_FILES_OOM);
+      }
     }
     else
     {
@@ -510,16 +518,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;
       }
     }
@@ -529,14 +536,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= 
+          thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
+        files->push_back(file_name))
     {
       my_dirend(dirp);
       DBUG_RETURN(FIND_FILES_OOM);
@@ -545,7 +554,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);
 }
@@ -2182,10 +2191,11 @@ LEX_STRING INFORMATION_SCHEMA_NAME= { C_
 /* This is only used internally, but we need it here as a forward reference */
 extern ST_SCHEMA_TABLE schema_tables[];
 
-typedef struct st_index_field_values
+typedef struct st_lookup_field_values
 {
-  const char *db_value, *table_value;
-} INDEX_FIELD_VALUES;
+  LEX_STRING db_value, table_value;
+  bool wild_db_value, wild_table_value;
+} LOOKUP_FIELD_VALUES;
 
 
 /*
@@ -2216,38 +2226,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))
     return 1;
@@ -2255,6 +2238,127 @@ int make_table_list(THD *thd, SELECT_LEX
 }
 
 
+/**
+  @brief    Get lookup value from the part of 'WHERE' condition 
+
+  @details This function gets lookup value from 
+           the part of 'WHERE' condition if it's possible and 
+           fill appropriate lookup_field_vals struct field
+           with this value.
+
+  @param[in]      thd                   thread handler
+  @param[in]      item_func             part of WHERE condition
+  @param[in]      table                 I_S table
+  @param[in, out] lookup_field_vals     Struct which holds lookup values 
+
+  @return         void
+*/
+
+void get_lookup_value(THD *thd, Item_func *item_func,
+                      TABLE_LIST *table, 
+                      LOOKUP_FIELD_VALUES *lookup_field_vals)
+{
+  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 ||
+      item_func->functype() == Item_func::EQUAL_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;
+    CHARSET_INFO *cs= system_charset_info;
+
+    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];
+    if (table->table != item_field->field->table)
+      return;
+    tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
+
+    /* Lookup value is database name */
+    if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
+                               (uchar *) item_field->field_name,
+                               strlen(item_field->field_name), 0))
+    {
+      thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
+                           tmp_str->length(), FALSE);
+    }
+    /* Lookup value is table name */
+    else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
+                                    strlen(field_name2),
+                                    (uchar *) item_field->field_name,
+                                    strlen(item_field->field_name), 0))
+    {
+      thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
+                           tmp_str->length(), FALSE);
+    }
+  }
+  return;
+}
+
+
+/**
+  @brief    Calculates lookup values from 'WHERE' condition 
+
+  @details This function calculates lookup value(database name, table name)
+           from 'WHERE' condition if it's possible and 
+           fill lookup_field_vals struct fields with these values.
+
+  @param[in]      thd                   thread handler
+  @param[in]      cond                  WHERE condition
+  @param[in]      table                 I_S table
+  @param[in, out] lookup_field_vals     Struct which holds lookup values 
+
+  @return         void
+*/
+
+void calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
+                                  LOOKUP_FIELD_VALUES *lookup_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_lookup_value(thd, (Item_func*)item, table, lookup_field_vals);
+        else
+          calc_lookup_values_from_cond(thd, item, table, lookup_field_vals);
+      }
+    }
+    return;
+  }
+  else if (cond->type() == Item::FUNC_ITEM)
+    get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals);
+  return;
+}
+
+
 bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
 {
   if (item->type() == Item::FUNC_ITEM)
@@ -2272,21 +2376,23 @@ bool uses_only_table_name_fields(Item *i
     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 : "";
+    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 (table->table != item_field->field->table ||
         (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
-                               (uchar *) item_field->field_name, 
+                               (uchar *) item_field->field_name,
                                strlen(item_field->field_name), 0) &&
          cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
-                               (uchar *) item_field->field_name, 
+                               (uchar *) item_field->field_name,
                                strlen(item_field->field_name), 0)))
       return 0;
   }
   else if (item->type() == Item::REF_ITEM)
     return uses_only_table_name_fields(item->real_item(), table);
-  if (item->type() == Item::SUBSELECT_ITEM &&
-      !item->const_item())
+
+  if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
     return 0;
 
   return 1;
@@ -2349,6 +2455,61 @@ static COND * make_cond_for_info_schema(
 }
 
 
+/**
+  @brief   Calculate lookup values(database name, table name)
+
+  @details This function calculates lookup values(database name, table name)
+           from 'WHERE' condition or wild values (for 'SHOW' commands only)
+           from LEX struct and fill lookup_field_vals struct field
+           with these values.
+
+  @param[in]      thd                   thread handler
+  @param[in]      cond                  WHERE condition
+  @param[in]      table                 I_S table
+  @param[in, out] lookup_field_vals     Struct which holds lookup values 
+
+  @return         void
+*/
+
+void get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
+                             LOOKUP_FIELD_VALUES *lookup_field_values)
+{
+  LEX *lex= thd->lex;
+  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
+  bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
+  switch (lex->sql_command) {
+  case SQLCOM_SHOW_DATABASES:
+    if (wild)
+    {
+      lookup_field_values->db_value.str= (char*) wild;
+      lookup_field_values->db_value.length= strlen(wild);
+      lookup_field_values->wild_db_value= 1;
+    }
+    break;
+  case SQLCOM_SHOW_TABLES:
+  case SQLCOM_SHOW_TABLE_STATUS:
+  case SQLCOM_SHOW_TRIGGERS:
+  case SQLCOM_SHOW_EVENTS:
+    lookup_field_values->db_value.str= lex->select_lex.db;
+    lookup_field_values->db_value.length=strlen(lex->select_lex.db);
+    if (wild)
+    {
+      lookup_field_values->table_value.str= (char*)wild;
+      lookup_field_values->table_value.length= strlen(wild);
+      lookup_field_values->wild_table_value= 1;
+    }
+    break;
+  default:
+    /*
+      The "default" is for queries over I_S.
+      All previous cases handle SHOW commands.
+    */
+    calc_lookup_values_from_cond(thd, cond, tables, lookup_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]);
@@ -2366,81 +2527,83 @@ enum enum_schema_tables get_schema_table
     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
-    is_wild_value         if value is 1 then idx_field_vals->db_name is
-                          wild string otherwise it's db name; 
+                          otherwise returns 0 
 
   RETURN
     zero                  success
     non-zero              error
 */
 
-int make_db_list(THD *thd, List<char> *files,
-                 INDEX_FIELD_VALUES *idx_field_vals,
-                 bool *with_i_schema, bool is_wild_value)
+int make_db_list(THD *thd, List<LEX_STRING> *files,
+                 LOOKUP_FIELD_VALUES *lookup_field_vals,
+                 bool *with_i_schema)
 {
-  LEX *lex= thd->lex;
   *with_i_schema= 0;
-  get_index_field_values(lex, idx_field_vals);
-
-  if (is_wild_value)
+  if (lookup_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 (!lookup_field_vals->db_value.str ||
         !wild_case_compare(system_charset_info, 
                            INFORMATION_SCHEMA_NAME.str,
-                           idx_field_vals->db_value))
+                           lookup_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);
+                       lookup_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 we have db lookup vaule we just add it to list and
+    exit from the function
   */
-  if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+  if (lookup_field_vals->db_value.str)
   {
     if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
-                       idx_field_vals->db_value))
+                       lookup_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 0;
     }
-    return files->push_back(thd->strdup(idx_field_vals->db_value));
+    if (files->push_back(&lookup_field_vals->db_value))
+      return 1;
+    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,
                      mysql_data_home, NullS, 1) != FIND_FILES_OK);
 }
 
+
 struct st_add_schema_table 
 {
-  List<char> *files;
+  List<LEX_STRING> *files;
   const char *wild;
 };
 
+
 static my_bool add_schema_table(THD *thd, plugin_ref plugin,
                                 void* p_data)
 {
+  LEX_STRING *file_name= 0;
   st_add_schema_table *data= (st_add_schema_table *)p_data;
-  List<char> *file_list= data->files;
+  List<LEX_STRING> *file_list= data->files;
   const char *wild= data->wild;
   ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
   DBUG_ENTER("add_schema_table");
@@ -2460,14 +2623,18 @@ static my_bool add_schema_table(THD *thd
       DBUG_RETURN(0);
   }
 
-  if (file_list->push_back(thd->strdup(schema_table->table_name)))
-    DBUG_RETURN(1);
-
-  DBUG_RETURN(0);
+  if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
+                                       strlen(schema_table->table_name),
+                                       TRUE)) &&
+      !file_list->push_back(file_name))
+    DBUG_RETURN(0);
+  DBUG_RETURN(1);
 }
 
-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;
   st_add_schema_table add_data;
   DBUG_ENTER("schema_tables_add");
@@ -2488,8 +2655,12 @@ 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)))
-      DBUG_RETURN(1);
+    if ((file_name= 
+         thd->make_lex_string(file_name, tmp_schema_table->table_name,
+                              strlen(tmp_schema_table->table_name), TRUE)) &&
+        !files->push_back(file_name))
+      continue;
+    DBUG_RETURN(1);
   }
 
   add_data.files= files;
@@ -2502,37 +2673,381 @@ int schema_tables_add(THD *thd, List<cha
 }
 
 
+/**
+  @brief          Create table names list
+
+  @details        The function creates the list of table names in
+                  database
+
+  @param[in]      thd                   thread handler
+  @param[in]      table_names           List of table names in database
+  @param[in]      lex                   pointer to LEX struct
+  @param[in]      lookup_field_vals     pointer to LOOKUP_FIELD_VALUE struct
+  @param[in]      with_i_schema         TRUE means that we add I_S tables to list
+  @param[in]      db_name               database name
+
+  @return         Operation status
+    @retval       0           ok
+    @retval       1           fatal error
+    @retval       2           Not fatal error; Safe to ignore this file list
+*/
+
+static int
+make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
+                     LOOKUP_FIELD_VALUES *lookup_field_vals,
+                     bool with_i_schema, LEX_STRING *db_name)
+{
+  char path[FN_REFLEN];
+  build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
+  if (!lookup_field_vals->wild_table_value &&
+      lookup_field_vals->table_value.str)
+  {
+    if (with_i_schema)
+    {
+      if (find_schema_table(thd, lookup_field_vals->table_value.str))
+      {
+        if (table_names->push_back(&lookup_field_vals->table_value))
+          return 1;
+      }
+    }
+    else
+    {    
+      if (table_names->push_back(&lookup_field_vals->table_value))
+        return 1;
+      /*
+        Check that table is relevant in current transaction.
+        (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc)
+      */
+      VOID(ha_find_files(thd, db_name->str, path,
+                         lookup_field_vals->table_value.str, 0,
+                         table_names));
+    }
+    return 0;
+  }
+
+  /*
+    This call will add all matching the wildcards (if specified) IS tables
+    to the list
+  */
+  if (with_i_schema)
+    return (schema_tables_add(thd, table_names,
+                              lookup_field_vals->table_value.str));
+
+  find_files_result res= find_files(thd, table_names, db_name->str, path,
+                                    lookup_field_vals->table_value.str, 0);
+  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;
+}
+
+
+/**
+  @brief          Fill I_S table for SHOW COLUMNS|INDEX commands
+
+  @param[in]      thd                      thread handler
+  @param[in]      tables                   TABLE_LIST for I_S table
+  @param[in]      schema_table             pointer to I_S structure
+  @param[in]      open_tables_state_backup pointer to Open_tables_state object
+                                           which is used to save|restore original
+                                           status of variables related to
+                                           open tables state
+
+  @return         Operation status
+    @retval       0           success
+    @retval       1           error
+*/
+
+static int 
+fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
+                              ST_SCHEMA_TABLE *schema_table,
+                              Open_tables_state *open_tables_state_backup)
+{
+  LEX *lex= thd->lex;
+  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).
+  */
+   table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
+                                    strlen(show_table_list->alias), FALSE);
+   if (!show_table_list->view)
+     db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
+                                   show_table_list->db_length, FALSE);
+   else
+     db_name= &show_table_list->view_db;
+      
+
+   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);
+}
+
+
+/**
+  @brief          Fill I_S table for SHOW TABLE NAMES commands
+
+  @param[in]      thd                      thread handler
+  @param[in]      table                    TABLE struct for I_S table
+  @param[in]      db_name                  database name
+  @param[in]      table_name               table name
+  @param[in]      with_i_schema            I_S table if TRUE
+
+  @return         Operation status
+    @retval       0           success
+    @retval       1           error
+*/
+
+static int fill_schema_table_names(THD *thd, 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];
+    (void) build_table_filename(path, sizeof(path), db_name->str, 
+                                table_name->str, reg_ext, 0);
+    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;
+}
+
+
+/**
+  @brief          Get open table method
+
+  @details        The function calculates the method which will be used
+                  for table opening:
+                  SKIP_OPEN_TABLE - do not open table
+                  OPEN_FRM_ONLY   - open FRM file only
+                  OPEN_FULL_TABLE - open FRM, data, index files
+  @param[in]      tables               I_S table table_list
+  @param[in]      schema_table         I_S table struct
+  @param[in]      schema_table_idx     I_S table index
+
+  @return         return a set of flags
+    @retval       SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
+*/
+
+static uint get_table_open_method(TABLE_LIST *tables,
+                                  ST_SCHEMA_TABLE *schema_table,
+                                  enum enum_schema_tables schema_table_idx)
+{
+  /*
+    determine which method will be used for table opening
+  */
+  if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
+  {
+    Field **ptr, *field;
+    int table_open_method= 0, field_indx= 0;
+    for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+    {
+      if (bitmap_is_set(tables->table->read_set, field->field_index))
+        table_open_method|= schema_table->fields_info[field_indx].open_method;
+      field_indx++;
+    }
+    return table_open_method;
+  }
+  /* I_S tables which use get_all_tables but can not be optimized */
+  return (uint) OPEN_FULL_TABLE;
+}
+
+
+/**
+  @brief          Fill I_S table with data from FRM file only
+
+  @param[in]      thd                      thread handler
+  @param[in]      table                    TABLE struct for I_S table
+  @param[in]      schema_table             I_S table struct
+  @param[in]      db_name                  database name
+  @param[in]      table_name               table name
+  @param[in]      schema_table_idx         I_S table index
+
+  @return         Operation status
+    @retval       0           Table is processed and we can continue
+                              with new table
+    @retval       1           It's view and we have to use
+                              open_tables function for this table
+*/
+
+static int fill_schema_table_from_frm(THD *thd,TABLE *table,
+                                      ST_SCHEMA_TABLE *schema_table, 
+                                      LEX_STRING *db_name,
+                                      LEX_STRING *table_name,
+                                      enum enum_schema_tables schema_table_idx)
+{
+  TABLE_SHARE share;
+  TABLE tbl;
+  TABLE_LIST table_list;
+  char path[FN_REFLEN];
+  uint res;
+  bzero((char*) &table_list, sizeof(TABLE_LIST));
+  bzero((char*) &tbl, sizeof(TABLE));
+  (void) build_table_filename(path, sizeof(path), db_name->str,
+                              table_name->str, "", 0);
+  init_tmp_table_share(&share, "", 0, "", path);
+  if (!(res= open_table_def(thd, &share, OPEN_VIEW)))
+  {
+    share.tmp_table= NO_TMP_TABLE;
+    tbl.s= &share;
+    table_list.table= &tbl;
+    if (schema_table->i_s_requested_object & OPEN_TABLE_FROM_SHARE)
+    {
+      if (share.is_view ||
+          open_table_from_share(thd, &share, table_name->str, 0,
+                                (READ_KEYINFO | COMPUTE_TYPES |
+                                 EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
+                                thd->open_options, &tbl, FALSE))
+      {
+        share.tmp_table= INTERNAL_TMP_TABLE;
+        free_table_share(&share);
+        return (share.is_view && 
+                !(schema_table->i_s_requested_object & 
+                  ~(OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE)));
+      }
+    }
+    table_list.view= (st_lex*) share.is_view;
+    res= schema_table->process_table(thd, &table_list, table,
+                                     res, db_name, table_name);
+    share.tmp_table= INTERNAL_TMP_TABLE;
+    if (schema_table->i_s_requested_object & OPEN_TABLE_FROM_SHARE)
+      closefrm(&tbl, true);
+    else
+      free_table_share(&share);
+  }
+
+  if (res)
+    thd->clear_error();
+  return 0;
+}
+
+
+
+
+/**
+  @brief          Fill I_S tables whose data is retrieved from
+                  FRM, data and index files 
+
+  @details        The information schema tables are internally represented as
+                  temporary tables that are filled at query execution time.
+                  Those I_S tables whose data is retrieved from
+                  FRM, data and index files are filled by the function
+                  get_all_tables().
+
+  @param[in]      thd                      thread handler
+  @param[in]      tables                   I_S table
+  @param[in]      cond                     'WHERE' condition
+
+  @return         Operation status
+    @retval       0                        success
+    @retval       1                        error
+*/
+
 int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
 {
   LEX *lex= thd->lex;
   TABLE *table= tables->table;
-  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], *base_name, *orig_base_name, *file_name;
-  uint len;
+  LOOKUP_FIELD_VALUES lookup_field_vals;
+  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> db_names;
+  List_iterator_fast<LEX_STRING> it(db_names);
   COND *partial_cond;
   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;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   Security_context *sctx= thd->security_ctx;
 #endif
+  uint table_open_method;
   DBUG_ENTER("get_all_tables");
 
-  LINT_INIT(len);
-
   lex->view_prepare_mode= TRUE;
   lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
 
@@ -2543,183 +3058,145 @@ int get_all_tables(THD *thd, TABLE_LIST 
   */
   thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
 
+  /* 
+    this branch processes SHOW FIELDS, SHOW INDEXES commands.
+    see sql_parse.cc, prepare_schema_table() function where
+    this values are initialized
+  */
   if (lsel && lsel->table_list.first)
   {
-    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);
+    error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
+                                         &open_tables_state_backup);
     goto err;
   }
 
   schema_table_idx= get_schema_table_idx(schema_table);
+  get_lookup_field_values(thd, cond, tables, &lookup_field_vals);
+  DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
+                             lookup_field_vals.db_value.str,
+                             lookup_field_vals.table_value.str));
+  if (lookup_field_vals.db_value.length &&
+      !lookup_field_vals.wild_db_value &&
+      lookup_field_vals.table_value.length &&
+      !lookup_field_vals.wild_table_value)
+    partial_cond= 0; 
+  else
+    partial_cond= make_cond_for_info_schema(cond, tables);
+
+  if (lookup_field_vals.db_value.length && !lookup_field_vals.wild_db_value)
+    tables->has_db_lookup_value= TRUE;
+  if (lookup_field_vals.table_value.length &&
+      !lookup_field_vals.wild_table_value) 
+    tables->has_table_lookup_value= TRUE;
+
+  tables->table_open_method= table_open_method=
+    get_table_open_method(tables, schema_table, schema_table_idx);
 
-  if (make_db_list(thd, &bases, &idx_field_vals,
-                   &with_i_schema, 0))
+  if (lex->describe)
+  {
+    /* EXPLAIN SELECT */
+    error= 0;
     goto err;
+  }
 
-  partial_cond= make_cond_for_info_schema(cond, tables);
+  if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
+    goto err;
   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) ||
-	!check_grant_db(thd, base_name))
+	acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
+	!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> table_names;
+      int res= make_table_name_list(thd, &table_names, lex,
+                                    &lookup_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(table_names);
+      while ((table_name= it_files++))
       {
-        len= build_table_filename(path, sizeof(path), base_name, "", "", 0);
-        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 lookup value for 
+            table name or lookup value is wild string(table name list is
+            already created by make_table_name_list() function).
           */
-          if (res == FIND_FILES_DIR && lex->sql_command == SQLCOM_END)
+          if (!table_open_method && schema_table_idx == SCH_TABLES &&
+              (!lookup_field_vals.table_value.length ||
+               lookup_field_vals.wild_table_value))
           {
-            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
-              {
-                build_table_filename(path, sizeof(path),
-                                     base_name, file_name, reg_ext, 0);
-
-                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))
-              goto err;
+            if (fill_schema_table_names(thd, tables->table, db_name,
+                                        table_name, with_i_schema))
+              continue;
           }
           else
           {
+            if (!(table_open_method & ~OPEN_FRM_ONLY) && 
+                !with_i_schema)
+            {
+              if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
+                                              table_name, schema_table_idx))
+                continue;
+            }
+
             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 (!thd->make_lex_string(&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->i_s_requested_object=
+              schema_table->i_s_requested_object;
             res= open_normal_and_derived_tables(thd, show_table_list,
                                                 MYSQL_LOCK_IGNORE_FLUSH);
             lex->sql_command= save_sql_command;
-            /* 
-              They can drop table after table names list creation and
-              before table opening. We open non existing table and 
-              get ER_NO_SUCH_TABLE error. In this case we do not store
-              the record into I_S table and clear error.
-            */
+            
             if (thd->net.last_errno == ER_NO_SUCH_TABLE)
             {
+              /*
+                Hide error for not existing table.
+                This error can occur for example when we use
+                where condition with db name and table name and this
+                table does not exist.
+              */
               res= 0;
               thd->clear_error();
             }
@@ -2732,12 +3209,14 @@ int get_all_tables(THD *thd, TABLE_LIST 
                 to use alias because alias contains original table name 
                 in this case.
               */
+              thd->make_lex_string(&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_base_name,
-                                               show_table_list->alias);
+                                               res, &orig_db_name,
+                                               &tmp_lex_string);
               close_tables_for_reopen(thd, &show_table_list);
-              DBUG_ASSERT(!lex->query_tables_own_last);
             }
+            DBUG_ASSERT(!lex->query_tables_own_last);
             if (res)
               goto err;
           }
@@ -2763,11 +3242,11 @@ err:
 }
 
 
-bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name,
+bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
                           CHARSET_INFO *cs)
 {
   restore_record(table, s->default_values);
-  table->field[1]->store(db_name, strlen(db_name), system_charset_info);
+  table->field[1]->store(db_name->str, db_name->length, system_charset_info);
   table->field[2]->store(cs->csname, strlen(cs->csname),
system_charset_info);
   table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
   return schema_table_store_record(thd, table);
@@ -2781,9 +3260,9 @@ int fill_schema_shemata(THD *thd, TABLE_
     Returning error status in this case leads to client hangup.
   */
 
-  INDEX_FIELD_VALUES idx_field_vals;
-  List<char> files;
-  char *file_name;
+  LOOKUP_FIELD_VALUES lookup_field_vals;
+  List<LEX_STRING> db_names;
+  LEX_STRING *db_name;
   bool with_i_schema;
   HA_CREATE_INFO create;
   TABLE *table= tables->table;
@@ -2792,16 +3271,20 @@ int fill_schema_shemata(THD *thd, TABLE_
 #endif
   DBUG_ENTER("fill_schema_shemata");
 
-  if (make_db_list(thd, &files, &idx_field_vals,
-                   &with_i_schema, 1))
+  get_lookup_field_values(thd, cond, tables, &lookup_field_vals);
+  DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
+                             lookup_field_vals.db_value.str,
+                             lookup_field_vals.table_value.str));
+  if (make_db_list(thd, &db_names, &lookup_field_vals,
+                   &with_i_schema))
     DBUG_RETURN(1);
 
-  List_iterator_fast<char> it(files);
-  while ((file_name=it++))
+  List_iterator_fast<LEX_STRING> it(db_names);
+  while ((db_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, db_name,
                                system_charset_info))
         DBUG_RETURN(1);
       with_i_schema= 0;
@@ -2809,13 +3292,12 @@ 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) ||
-	!check_grant_db(thd, file_name))
+	acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
+	!check_grant_db(thd, db_name->str))
 #endif
     {
-      load_db_opt_by_name(thd, file_name, &create);
-
-      if (store_schema_shemata(thd, table, file_name,
+      load_db_opt_by_name(thd, db_name->str, &create);
+      if (store_schema_shemata(thd, table, db_name,
                                create.default_table_charset))
         DBUG_RETURN(1);
     }
@@ -2826,8 +3308,8 @@ int fill_schema_shemata(THD *thd, TABLE_
 
 static int get_schema_tables_record(THD *thd, 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;
   MYSQL_TIME time;
@@ -2835,8 +3317,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)
   {
     /*
@@ -2859,12 +3341,11 @@ static int get_schema_tables_record(THD 
   }
   else
   {
+    char option_buff[350],*ptr;
     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);
+    handlerton *tmp_db_type= share->db_type();
     if (share->tmp_table == SYSTEM_TMP_TABLE)
       table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
     else if (share->tmp_table)
@@ -2878,89 +3359,15 @@ static int get_schema_tables_record(THD 
         continue;
       table->field[i]->set_notnull();
     }
-    tmp_buff= file->table_type();
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+    if (share->db_type() == partition_hton &&
+        share->partition_info_len)
+      tmp_db_type= share->default_part_db_type;
+#endif
+    tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_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) {
-    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");
-      break;
-    case ROW_TYPE_FIXED:
-      tmp_buff= "Fixed";
-      break;
-    case ROW_TYPE_DYNAMIC:
-      tmp_buff= "Dynamic";
-      break;
-    case ROW_TYPE_COMPRESSED:
-      tmp_buff= "Compressed";
-      break;
-    case ROW_TYPE_REDUNDANT:
-      tmp_buff= "Redundant";
-      break;
-    case ROW_TYPE_COMPACT:
-      tmp_buff= "Compact";
-      break;
-    case ROW_TYPE_PAGES:
-      tmp_buff= "Paged";
-      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,
-                                                (my_time_t) 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,
-                                                (my_time_t) 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,
-                                                (my_time_t) 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)
     {
@@ -2998,17 +3405,91 @@ static int get_schema_tables_record(THD 
     table->field[19]->store(option_buff+1,
                             (ptr == option_buff ? 0 : 
                              (uint) (ptr-option_buff)-1), cs);
+
+    if (share->comment.str)
+      table->field[20]->store(share->comment.str, share->comment.length, cs);
+
+    if(file)
     {
-      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));
+      file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
+                 HA_STATUS_NO_LOCK);
+      enum row_type row_type = file->get_row_type();
+      switch (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");
+        break;
+      case ROW_TYPE_FIXED:
+        tmp_buff= "Fixed";
+        break;
+      case ROW_TYPE_DYNAMIC:
+        tmp_buff= "Dynamic";
+        break;
+      case ROW_TYPE_COMPRESSED:
+        tmp_buff= "Compressed";
+        break;
+      case ROW_TYPE_REDUNDANT:
+        tmp_buff= "Redundant";
+        break;
+      case ROW_TYPE_COMPACT:
+        tmp_buff= "Compact";
+        break;
+      case ROW_TYPE_PAGES:
+        tmp_buff= "Paged";
+        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,
+                                                  (my_time_t)
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,
+                                                  (my_time_t)
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,
+                                                  (my_time_t) 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();
       }
     }
   }
@@ -3018,17 +3499,15 @@ static int get_schema_tables_record(THD 
 
 static int get_schema_column_record(THD *thd, 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)
@@ -3048,15 +3527,11 @@ 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++)
+  for (ptr= show_table->field; (field= *ptr) ; ptr++)
   {
     const char *tmp_buff;
     uchar *pos;
@@ -3079,10 +3554,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)
@@ -3099,8 +3574,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);
@@ -3525,8 +4000,8 @@ err:
 
 static int get_schema_stat_record(THD *thd, 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");
@@ -3538,7 +4013,7 @@ static int get_schema_stat_record(THD *t
         I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
         rather than in SHOW KEYS
       */
-      if (!tables->view)
+      if (thd->net.last_errno)
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                      thd->net.last_errno, thd->net.last_error);
       thd->clear_error();
@@ -3549,10 +4024,11 @@ static int get_schema_stat_record(THD *t
   else if (!tables->view)
   {
     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);
+    KEY *key_info=show_table->s->key_info;
+    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;
@@ -3560,35 +4036,40 @@ 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 &&
              key_part->length !=
-             show_table->field[key_part->fieldnr-1]->key_length()))
+             show_table->s->field[key_part->fieldnr-1]->key_length()))
         {
           table->field[10]->store((longlong) key_part->length /
                                   key_part->field->charset()->mbmaxlen, TRUE);
@@ -3597,8 +4078,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
@@ -3615,19 +4094,28 @@ static int get_schema_stat_record(THD *t
 
 static int get_schema_views_record(THD *thd, 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");
+  LEX_STRING *tmp_db_name, *tmp_table_name;
   char definer[USER_HOST_BUFF_SIZE];
   uint definer_len;
   bool updatable_view;
+  /*
+    if SELECT FROM I_S.VIEWS uses only fields
+    which have OPEN_FRM_ONLY flag then 'tables'
+    structure is zeroed and only tables->view is set.
+    (see fill_schema_table_from_frm() function).
+    So we should disable other fields filling.
+  */
+  bool only_share= !tables->definer.user.str;
 
   if (tables->view)
   {
     Security_context *sctx= thd->security_ctx;
-    if (!tables->allowed_show)
+    if (!only_share && !tables->allowed_show)
     {
       if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
                          sctx->priv_user) &&
@@ -3636,77 +4124,85 @@ static int get_schema_views_record(THD *
         tables->allowed_show= TRUE;
     }
     restore_record(table, s->default_values);
-    table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
-    table->field[2]->store(tables->view_name.str, tables->view_name.length,
cs);
-    if (tables->allowed_show)
+    tmp_db_name= &tables->view_db;
+    tmp_table_name= &tables->view_name;
+    if (only_share)
     {
-      table->field[3]->store(tables->view_body_utf8.str,
-                             tables->view_body_utf8.length,
-                             cs);
+      tmp_db_name= db_name;
+      tmp_table_name= table_name;
     }
+    table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs);
+    table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs);
 
-    if (tables->with_check != VIEW_CHECK_NONE)
+    if (!only_share)
     {
-      if (tables->with_check == VIEW_CHECK_LOCAL)
-        table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
+      if (tables->allowed_show)
+      {
+        table->field[3]->store(tables->view_body_utf8.str,
+                               tables->view_body_utf8.length,
+                               cs);
+      }
+
+      if (tables->with_check != VIEW_CHECK_NONE)
+      {
+        if (tables->with_check == VIEW_CHECK_LOCAL)
+          table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
+        else
+          table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
+      }
       else
-        table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
-    }
-    else
-      table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
+        table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
 
-    updatable_view= 0;
-    if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
-    {
-      /*
-        We should use tables->view->select_lex.item_list here and
-        can not use Field_iterator_view because the view always uses
-        temporary algorithm during opening for I_S and
-        TABLE_LIST fields 'field_translation' & 'field_translation_end'
-        are uninitialized is this case.
-      */
-      List<Item> *fields= &tables->view->select_lex.item_list;
-      List_iterator<Item> it(*fields);
-      Item *item;
-      Item_field *field;
-      /*
-        chech that at least one coulmn in view is updatable
-      */
-      while ((item= it++))
+      updatable_view= 0;
+      if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
       {
-        if ((field= item->filed_for_view_update()) && field->field
&&
-            !field->field->table->pos_in_table_list->schema_table)
+        /*
+          We should use tables->view->select_lex.item_list here and
+          can not use Field_iterator_view because the view always uses
+          temporary algorithm during opening for I_S and
+          TABLE_LIST fields 'field_translation' & 'field_translation_end'
+          are uninitialized is this case.
+        */
+        List<Item> *fields= &tables->view->select_lex.item_list;
+        List_iterator<Item> it(*fields);
+        Item *item;
+        Item_field *field;
+        /*
+          chech that at least one coulmn in view is updatable
+        */
+        while ((item= it++))
         {
-          updatable_view= 1;
-          break;
+          if ((field= item->filed_for_view_update()) && field->field
&&
+              !field->field->table->pos_in_table_list->schema_table)
+          {
+            updatable_view= 1;
+            break;
+          }
         }
       }
-    }
-    if (updatable_view)
-      table->field[5]->store(STRING_WITH_LEN("YES"), cs);
-    else
-      table->field[5]->store(STRING_WITH_LEN("NO"), cs);
-    definer_len= (strxmov(definer, tables->definer.user.str, "@",
-                          tables->definer.host.str, NullS) - definer);
-    table->field[6]->store(definer, definer_len, cs);
-    if (tables->view_suid)
-      table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
-    else
-      table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
-
-    table->field[8]->store(
-      tables->view_creation_ctx->get_client_cs()->csname,
-      strlen(tables->view_creation_ctx->get_client_cs()->csname),
-      cs);
-
-    table->field[9]->store(
-      tables->view_creation_ctx->get_connection_cl()->name,
-      strlen(tables->view_creation_ctx->get_connection_cl()->name),
-      cs);
+      if (updatable_view)
+        table->field[5]->store(STRING_WITH_LEN("YES"), cs);
+      else
+        table->field[5]->store(STRING_WITH_LEN("NO"), cs);
+      definer_len= (strxmov(definer, tables->definer.user.str, "@",
+                            tables->definer.host.str, NullS) - definer);
+      table->field[6]->store(definer, definer_len, cs);
+      if (tables->view_suid)
+        table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
+      else
+        table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
 
+     
table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname,
+                             strlen(tables->view_creation_ctx->
+                                    get_client_cs()->csname), cs);
+      table->field[9]->store(tables->view_creation_ctx->
+                             get_connection_cl()->name,
+                             strlen(tables->view_creation_ctx->
+                                    get_connection_cl()->name),cs);
+    }
     if (schema_table_store_record(thd, table))
       DBUG_RETURN(1);
-    if (res)
+    if (res && thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
                    thd->net.last_errno, thd->net.last_error);
   }
@@ -3716,16 +4212,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);
 }
@@ -3733,13 +4229,13 @@ bool store_constraints(THD *thd, TABLE *
 
 static int get_schema_constraints_record(THD *thd, 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)
   {
-    if (!tables->view)
+    if (thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                    thd->net.last_errno, thd->net.last_error);
     thd->clear_error();
@@ -3761,14 +4257,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);
@@ -3780,7 +4276,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))
@@ -3791,8 +4287,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,
@@ -3806,12 +4302,12 @@ static bool store_trigger(THD *thd, TABL
   LEX_STRING sql_mode_rep;
 
   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,
@@ -3834,8 +4330,8 @@ static bool store_trigger(THD *thd, TABL
 
 static int get_schema_triggers_record(THD *thd, 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");
   /*
@@ -3844,7 +4340,7 @@ static int get_schema_triggers_record(TH
   */
   if (res)
   {
-    if (!tables->view)
+    if (thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                    thd->net.last_errno, thd->net.last_error);
     thd->clear_error();
@@ -3878,7 +4374,7 @@ static int get_schema_triggers_record(TH
                                        &db_cl_name))
           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,
@@ -3894,15 +4390,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);
 }
@@ -3911,13 +4408,13 @@ void store_key_column_usage(TABLE *table
 static int get_schema_key_column_usage_record(THD *thd,
 					      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)
   {
-    if (!tables->view)
+    if (thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                    thd->net.last_errno, thd->net.last_error);
     thd->clear_error();
@@ -3944,7 +4441,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, 
@@ -3971,7 +4468,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,
@@ -4096,8 +4593,8 @@ static void store_schema_partitions_reco
 
 static int get_schema_partitions_record(THD *thd, 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];
@@ -4112,7 +4609,7 @@ static int get_schema_partitions_record(
 
   if (res)
   {
-    if (!tables->view)
+    if (thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                    thd->net.last_errno, thd->net.last_error);
     thd->clear_error();
@@ -4128,8 +4625,8 @@ static int get_schema_partitions_record(
     uint part_pos= 0, part_id= 0;
 
     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*/
@@ -4642,14 +5139,14 @@ int fill_status(THD *thd, TABLE_LIST *ta
 static int
 get_referential_constraints_record(THD *thd, 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");
 
   if (res)
   {
-    if (!tables->view)
+    if (thd->net.last_errno)
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                    thd->net.last_errno, thd->net.last_error);
     thd->clear_error();
@@ -4669,8 +5166,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, 
@@ -4740,7 +5237,7 @@ static my_bool find_schema_table_in_plug
 
   RETURN
     0	table not found
-    #   pointer to 'shema_tables' element
+    #   pointer to 'schema_tables' element
 */
 
 ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
@@ -4883,6 +5380,12 @@ TABLE *create_schema_table(THD *thd, TAB
                                  TMP_TABLE_ALL_COLUMNS),
                                 HA_POS_ERROR, table_list->alias)))
     DBUG_RETURN(0);
+  my_bitmap_map* bitmaps=
+    (my_bitmap_map*) 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);
 }
@@ -5226,6 +5729,13 @@ bool get_schema_tables_result(JOIN *join
     {
       bool is_subselect= (&lex->unit != lex->current_select->master_unit()
&&
                           lex->current_select->master_unit()->item);
+
+
+      /* skip I_S optimizations specific to get_all_tables */
+      if (thd->lex->describe &&
+          (table_list->schema_table->fill_table != get_all_tables))
+        continue;
+
       /*
         If schema table is already processed and
         the statement is not a subselect then
@@ -5305,479 +5815,537 @@ int fill_schema_files(THD *thd, TABLE_LI
 
 ST_FIELD_INFO schema_fields_info[]=
 {
-  {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SCHEMA_NAME", NAME_CHAR_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_TABLE},
+  {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
+   SKIP_OPEN_TABLE},
+  {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0,
+   SKIP_OPEN_TABLE},
+  {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO tables_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
+   SKIP_OPEN_TABLE},
+  {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
   {"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version"},
-  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
+  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
   {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
   {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
   {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
   {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
   {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
   {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
   {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment"},
-  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time"},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time"},
-  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time"},
-  {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
+  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
+  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
+  {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
   {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "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}
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
+  {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
+   OPEN_FRM_ONLY},
+  {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO columns_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
+   OPEN_FRM_ONLY},
   {"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-   MY_I_S_UNSIGNED, 0},
+   MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
   {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
-   1, "Default"},
-  {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
-  {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+   1, "Default", OPEN_FRM_ONLY},
+  {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
+  {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
   {"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
-   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
   {"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
-   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
   {"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
-   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
   {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
-   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 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}
+   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 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_TABLE}
 };
 
 
 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_LONGLONG, 0, 0, "Maxlen"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
+   SKIP_OPEN_TABLE},
+  {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation",
+   SKIP_OPEN_TABLE},
+  {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
+   SKIP_OPEN_TABLE},
+  {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 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_LONGLONG, 0, 0, "Sortlen"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE},
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
+   SKIP_OPEN_TABLE},
+  {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
+   SKIP_OPEN_TABLE},
+  {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
+  {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
+  {"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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_TABLE},
+  {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
+  {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
+  {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions", SKIP_OPEN_TABLE},
+  {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA", SKIP_OPEN_TABLE},
+  {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO events_fields_info[]=
 {
-  {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
-  {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-  {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone"},
-  {"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_DATETIME, 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_DATETIME, 0, 1, "Starts"},
-  {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends"},
-  {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status"},
-  {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0},
-  {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0},
-  {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator"},
+  {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
+   SKIP_OPEN_TABLE},
+  {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
+   SKIP_OPEN_TABLE},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
+  {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
+  {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
+  {"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
+  {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
+   SKIP_OPEN_TABLE},
+  {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
+   SKIP_OPEN_TABLE},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
+  {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
+  {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
+  {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
   {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "character_set_client"},
+   "character_set_client", SKIP_OPEN_TABLE},
   {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "collation_connection"},
+   "collation_connection", SKIP_OPEN_TABLE},
   {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "Database Collation"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+   "Database Collation", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 
 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_TABLE},
+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO proc_fields_info[]=
 {
-  {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
-  {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-  {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
-  {"DTD_IDENTIFIER", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"EXTERNAL_LANGUAGE", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"},
-  {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created"},
-  {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified"},
-  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
+  {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
+   SKIP_OPEN_TABLE},
+  {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
+   SKIP_OPEN_TABLE},
+  {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
+  {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   SKIP_OPEN_TABLE},
+  {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   SKIP_OPEN_TABLE},
+  {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type",
+   SKIP_OPEN_TABLE},
+  {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE},
+  {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment",
+   SKIP_OPEN_TABLE},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
   {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "character_set_client"},
+   "character_set_client", SKIP_OPEN_TABLE},
   {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "collation_connection"},
+   "collation_connection", SKIP_OPEN_TABLE},
   {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "Database Collation"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+   "Database Collation", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO stat_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique"},
-  {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name"},
-  {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index"},
-  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name"},
-  {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation"},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
+  {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
+  {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
+   OPEN_FRM_ONLY},
+  {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
+  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
+   OPEN_FRM_ONLY},
+  {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
   {"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
-   "Cardinality"},
-  {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 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}
+   "Cardinality", OPEN_FULL_TABLE},
+  {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 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_TABLE}
 };
 
 
 ST_FIELD_INFO view_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_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},
-  {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+  {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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_CHAR_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},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_CHAR_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},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_CHAR_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},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PRIVILEGE_TYPE", NAME_CHAR_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},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO table_constraints_fields_info[]=
 {
-  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_TYPE", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO key_column_usage_fields_info[]=
 {
-  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0},
-  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"REFERENCED_COLUMN_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO table_names_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_"},
-  {"TABLE_TYPE", NAME_CHAR_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},
+  {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
+   SKIP_OPEN_TABLE},
+  {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
+   OPEN_FRM_ONLY},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO open_tables_fields_info[]=
 {
-  {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
-  {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use"},
-  {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+  {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
+   SKIP_OPEN_TABLE},
+  {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
+  {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
+  {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO triggers_fields_info[]=
 {
-  {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TRIGGER_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-  {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_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_DATETIME, 0, 1, "Created"},
-  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
-  {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
+  {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger",
+   OPEN_FULL_TABLE},
+  {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE},
+  {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table",
+   OPEN_FULL_TABLE},
+  {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
+  {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement",
+   OPEN_FULL_TABLE},
+  {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE},
+  {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE},
+  {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE},
   {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "character_set_client"},
+   "character_set_client", OPEN_FULL_TABLE},
   {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "collation_connection"},
+   "collation_connection", OPEN_FULL_TABLE},
   {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-   "Database Collation"},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+   "Database Collation", OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO partitions_fields_info[]=
 {
-  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
   {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
   {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 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_LONGLONG, 0, MY_I_S_UNSIGNED, 0},
-  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0},
-  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
+  {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
+  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
+   OPEN_FULL_TABLE},
+  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
+   OPEN_FULL_TABLE},
+  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
+   OPEN_FULL_TABLE},
   {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
-  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0},
-  {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0},
-  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
+  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
+   OPEN_FULL_TABLE},
+  {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
+   OPEN_FULL_TABLE},
+  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
+  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
   {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
-  {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO variables_fields_info[]=
 {
-  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
-  {"VARIABLE_VALUE", 20480, 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_TABLE},
+  {"VARIABLE_VALUE", 20480, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO processlist_fields_info[]=
 {
-  {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id"},
-  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User"},
-  {"HOST", LIST_PROCESS_HOST_LEN,  MYSQL_TYPE_STRING, 0, 0, "Host"},
-  {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
-  {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
-  {"TIME", 7, MYSQL_TYPE_LONGLONG, 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_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
+  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
+  {"HOST", LIST_PROCESS_HOST_LEN,  MYSQL_TYPE_STRING, 0, 0, "Host",
+   SKIP_OPEN_TABLE},
+  {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
+  {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
+  {"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
+  {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
+  {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
+   SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
 ST_FIELD_INFO plugin_fields_info[]=
 {
-  {"PLUGIN_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"},
-  {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"PLUGIN_AUTHOR", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
+   SKIP_OPEN_TABLE},
+  {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
+  {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
+  {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
+   SKIP_OPEN_TABLE},
+  {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 ST_FIELD_INFO files_fields_info[]=
 {
-  {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0},
-  {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0},
+  {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   SKIP_OPEN_TABLE},
+  {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
+   SKIP_OPEN_TABLE},
+  {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
   {"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
   {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
   {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0},
-  {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0},
-  {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
-  {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
+  {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
+  {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
   {"VERSION", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version"},
-  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", SKIP_OPEN_TABLE},
+  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
   {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
   {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
   {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
   {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
   {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
   {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free"},
-  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time"},
-  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time"},
-  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time"},
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
+  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
+  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
+  {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
   {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0, 
-   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "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}
+   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
+  {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+  {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 void init_fill_schema_files_row(TABLE* table)
@@ -5792,18 +6360,24 @@ 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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"REFERENCED_TABLE_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"CONSTRAINT_NAME", NAME_CHAR_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_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+  {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+   OPEN_FULL_TABLE},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
 
@@ -5817,69 +6391,75 @@ ST_FIELD_INFO referential_constraints_fi
 ST_SCHEMA_TABLE schema_tables[]=
 {
   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
-   fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
+   fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
   {"COLLATIONS", collation_fields_info, create_schema_table, 
-   fill_schema_collation, make_old_format, 0, -1, -1, 0},
+   fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
   {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
-   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0},
+   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
   {"COLUMNS", columns_fields_info, create_schema_table, 
-   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
+   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
+   OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE},
   {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
-    fill_schema_column_privileges, 0, 0, -1, -1, 0},
+   fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
   {"ENGINES", engines_fields_info, create_schema_table,
-   fill_schema_engines, make_old_format, 0, -1, -1, 0},
+   fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
   {"EVENTS", events_fields_info, create_schema_table,
-   Events::fill_schema_events, make_old_format, 0, -1, -1, 0},
+   Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
   {"FILES", files_fields_info, create_schema_table,
-   fill_schema_files, 0, 0, -1, -1, 0},
+   fill_schema_files, 0, 0, -1, -1, 0, 0},
   {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
-   fill_status, make_old_format, 0, -1, -1, 0},
+   fill_status, make_old_format, 0, -1, -1, 0, 0},
   {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
-   fill_variables, make_old_format, 0, -1, -1, 0},
+   fill_variables, make_old_format, 0, -1, -1, 0, 0},
   {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-    get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
+   get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
+   OPEN_TABLE_ONLY},
   {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
-   fill_open_tables, make_old_format, 0, -1, -1, 1},
+   fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
   {"PARTITIONS", partitions_fields_info, create_schema_table,
-   get_all_tables, 0, get_schema_partitions_record, 1, 2, 0},
+   get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY},
   {"PLUGINS", plugin_fields_info, create_schema_table,
-    fill_plugins, make_old_format, 0, -1, -1, 0},
+   fill_plugins, make_old_format, 0, -1, -1, 0, 0},
   {"PROCESSLIST", processlist_fields_info, create_schema_table,
-    fill_schema_processlist, make_old_format, 0, -1, -1, 0},
+   fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
   {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
    create_schema_table, get_all_tables, 0, get_referential_constraints_record,
-   1, 9, 0},
+   1, 9, 0, OPEN_TABLE_ONLY},
   {"ROUTINES", proc_fields_info, create_schema_table, 
-    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
+   fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
   {"SCHEMATA", schema_fields_info, create_schema_table,
-   fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0},
+   fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0, 0},
   {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-    fill_schema_schema_privileges, 0, 0, -1, -1, 0},
+   fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0},
   {"SESSION_STATUS", variables_fields_info, create_schema_table,
-    fill_status, make_old_format, 0, -1, -1, 0},
+   fill_status, make_old_format, 0, -1, -1, 0, 0},
   {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
-    fill_variables, make_old_format, 0, -1, -1, 0},
+   fill_variables, make_old_format, 0, -1, -1, 0, 0},
   {"STATISTICS", stat_fields_info, create_schema_table, 
-    get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0},
+   get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
+   OPEN_TABLE_ONLY|OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE},
   {"STATUS", variables_fields_info, create_schema_table, fill_status, 
-   make_old_format, 0, -1, -1, 1},
+   make_old_format, 0, -1, -1, 1, 0},
   {"TABLES", tables_fields_info, create_schema_table, 
-   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
+   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
+   OPTIMIZE_I_S_TABLE},
   {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
-    get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
+   get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
   {"TABLE_NAMES", table_names_fields_info, create_schema_table,
-   get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+   get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
   {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
-    fill_schema_table_privileges, 0, 0, -1, -1, 0},
+   fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
   {"TRIGGERS", triggers_fields_info, create_schema_table,
-   get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
+   get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
+   OPEN_TABLE_ONLY},
   {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-    fill_schema_user_privileges, 0, 0, -1, -1, 0},
+   fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-   make_old_format, 0, -1, -1, 1},
+   make_old_format, 0, -1, -1, 1, 0},
   {"VIEWS", view_fields_info, create_schema_table, 
-    get_all_tables, 0, get_schema_views_record, 1, 2, 0},
-  {0, 0, 0, 0, 0, 0, 0, 0, 0}
+   get_all_tables, 0, get_schema_views_record, 1, 2, 0,
+   OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
+  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 };
 
 
diff -Nrup a/sql/sql_show.h b/sql/sql_show.h
--- a/sql/sql_show.h	2007-07-17 01:59:17 +05:00
+++ b/sql/sql_show.h	2007-08-02 19:01:19 +05:00
@@ -29,7 +29,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,
diff -Nrup a/sql/table.cc b/sql/table.cc
--- a/sql/table.cc	2007-07-26 05:23:30 +05:00
+++ b/sql/table.cc	2007-08-02 19:01:19 +05:00
@@ -515,7 +515,15 @@ int open_table_def(THD *thd, TABLE_SHARE
   {
     if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
         (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
+    {
+      /* Open view only */
+      if (db_flags & OPEN_VIEW_ONLY)
+      {
+        error_given= 1;
+        goto err;
+      }
       table_type= 1;
+    }
     else
     {
       error= 6;                                 // Unkown .frm version
@@ -1573,9 +1581,17 @@ int open_table_from_share(THD *thd, TABL
   outparam->keys_in_use_for_query.init();
 
   /* Allocate handler */
-  if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
-                                        share->db_type())))
-    goto err;
+  outparam->file= 0;
+  if (!(prgflag & OPEN_FRM_FILE_ONLY))
+  {
+    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
+                                          share->db_type())))
+      goto err;
+  }
+  else
+  {
+    DBUG_ASSERT(!db_stat);
+  }
 
   error= 4;
   outparam->reginfo.lock_type= TL_UNLOCK;
diff -Nrup a/sql/table.h b/sql/table.h
--- a/sql/table.h	2007-07-23 21:09:45 +05:00
+++ b/sql/table.h	2007-08-02 19:01:19 +05:00
@@ -623,6 +623,10 @@ enum enum_schema_tables
 #define MY_I_S_UNSIGNED   2
 
 
+#define SKIP_OPEN_TABLE 0                // do not open table
+#define OPEN_FRM_ONLY   1                // open FRM file only
+#define OPEN_FULL_TABLE 2                // open FRM,MYD, MYI files
+
 typedef struct st_field_info
 {
   const char* field_name;
@@ -631,6 +635,7 @@ typedef struct st_field_info
   int value;
   uint field_flags;        // Field atributes(maybe_null, signed, unsigned etc.)
   const char* old_name;
+  uint open_method;
 } ST_FIELD_INFO;
 
 
@@ -647,11 +652,11 @@ typedef struct st_schema_table
   int (*fill_table) (THD *thd, TABLE_LIST *tables, COND *cond);
   /* Handle fileds for old SHOW */
   int (*old_format) (THD *thd, struct st_schema_table *schema_table);
-  int (*process_table) (THD *thd, TABLE_LIST *tables,
-                        TABLE *table, bool res, const char *base_name,
-                        const char *file_name);
+  int (*process_table) (THD *thd, TABLE_LIST *tables, TABLE *table,
+                        bool res, LEX_STRING *db_name, LEX_STRING *table_name);
   int idx_field1, idx_field2; 
   bool hidden;
+  uint i_s_requested_object;  /* the object we need to open(TABLE | VIEW) */
 } ST_SCHEMA_TABLE;
 
 
@@ -995,6 +1000,10 @@ struct TABLE_LIST
   */
   uint8 trg_event_map;
 
+  uint i_s_requested_object;
+  bool has_db_lookup_value;
+  bool has_table_lookup_value;
+  uint table_open_method;
   enum enum_schema_table_state schema_table_state;
   void calc_md5(char *buffer);
   void set_underlying_merge();
diff -Nrup a/sql/unireg.h b/sql/unireg.h
--- a/sql/unireg.h	2007-07-09 10:08:42 +05:00
+++ b/sql/unireg.h	2007-08-02 19:01:19 +05:00
@@ -153,6 +153,11 @@
 #define OPEN_VIEW		8192	/* Allow open on view */
 #define OPEN_VIEW_NO_PARSE     16384    /* Open frm only if it's a view,
                                            but do not parse view itself */
+#define OPEN_FRM_FILE_ONLY     32768    /* Open frm file only */
+#define OPEN_TABLE_ONLY        OPEN_FRM_FILE_ONLY*2 /* Open view only */
+#define OPEN_VIEW_ONLY         OPEN_TABLE_ONLY*2    /* Open table only */
+#define OPEN_TABLE_FROM_SHARE  OPEN_VIEW_ONLY*2     /* For I_S tables*/
+#define OPTIMIZE_I_S_TABLE     OPEN_TABLE_FROM_SHARE*2 /* For I_S tables*/
 #define SC_INFO_LENGTH 4		/* Form format constant */
 #define TE_INFO_LENGTH 3
 #define MTYP_NOEMPTY_BIT 128
Thread
bk commit into 5.1 tree (gluh:1.2569)gluh2 Aug
  • Re: bk commit into 5.1 tree (gluh:1.2569)Sergei Golubchik2 Aug