From a8491ce548b290f07434c27af6b12ad430a5a21e Mon Sep 17 00:00:00 2001
From: unknown <gluh@gluh.mysql.r18.ru>
Date: Thu, 30 Dec 2004 15:20:40 +0300
Subject: [PATCH] wl#1629 SHOW with WHERE(final part, after review)   added
 syntax:   'show variables where', 'show status where', 'show open tables
 where'

mysql-test/r/grant_cache.result:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/r/information_schema.result:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/r/query_cache.result:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/r/temp_table.result:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/r/union.result:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/t/information_schema.test:
  wl#1629 SHOW with WHERE(final part,after review)
mysql-test/t/query_cache.test:
  wl#1629 SHOW with WHERE(final part,after review)
sql/item.cc:
  wl#1629 SHOW with WHERE(final part,after review)
sql/mysql_priv.h:
  wl#1629 SHOW with WHERE(final part,after review)
sql/sql_parse.cc:
  wl#1629 SHOW with WHERE(final part,after review)
sql/sql_select.cc:
  wl#1629 SHOW with WHERE(final part,after review)
sql/sql_show.cc:
  wl#1629 SHOW with WHERE(final part,after review)
sql/sql_yacc.yy:
  wl#1629 SHOW with WHERE(final part,after review)
sql/table.h:
  wl#1629 SHOW with WHERE(final part,after review)
---
 mysql-test/r/grant_cache.result        |  16 +-
 mysql-test/r/information_schema.result |  24 +-
 mysql-test/r/query_cache.result        |  10 +
 mysql-test/r/temp_table.result         |   2 +-
 mysql-test/r/union.result              |   8 +-
 mysql-test/t/information_schema.test   |   8 +
 mysql-test/t/query_cache.test          |  11 +
 sql/item.cc                            |   2 +-
 sql/mysql_priv.h                       |   4 -
 sql/sql_parse.cc                       |  25 +-
 sql/sql_select.cc                      |   8 +-
 sql/sql_show.cc                        | 334 ++++++++-----------------
 sql/sql_yacc.yy                        |  54 ++--
 sql/table.h                            |   2 +-
 14 files changed, 202 insertions(+), 306 deletions(-)

diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result
index 892f1d940a6..0c59ed1584c 100644
--- a/mysql-test/r/grant_cache.result
+++ b/mysql-test/r/grant_cache.result
@@ -59,7 +59,7 @@ Variable_name	Value
 Qcache_hits	0
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	0
+Qcache_not_cached	5
 select "user1";
 user1
 user1
@@ -71,7 +71,7 @@ Variable_name	Value
 Qcache_hits	0
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	1
+Qcache_not_cached	9
 select * from t1;
 a	b	c
 1	1	1
@@ -84,7 +84,7 @@ Variable_name	Value
 Qcache_hits	1
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	1
+Qcache_not_cached	12
 select a from t1 ;
 a
 1
@@ -97,7 +97,7 @@ Variable_name	Value
 Qcache_hits	2
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	1
+Qcache_not_cached	15
 select c from t1;
 c
 1
@@ -110,7 +110,7 @@ Variable_name	Value
 Qcache_hits	3
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	1
+Qcache_not_cached	18
 show grants for current_user();
 Grants for @localhost
 GRANT USAGE ON *.* TO ''@'localhost'
@@ -143,7 +143,7 @@ Variable_name	Value
 Qcache_hits	7
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	2
+Qcache_not_cached	22
 select "user3";
 user3
 user3
@@ -167,7 +167,7 @@ Variable_name	Value
 Qcache_hits	7
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	7
+Qcache_not_cached	30
 select "user4";
 user4
 user4
@@ -197,7 +197,7 @@ Variable_name	Value
 Qcache_hits	8
 show status like "Qcache_not_cached";
 Variable_name	Value
-Qcache_not_cached	8
+Qcache_not_cached	34
 set names binary;
 delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
 delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 037588afda8..cfa26052fb5 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1,3 +1,6 @@
+show variables variable_name where variable_name like "skip_show_database";
+variable_name
+skip_show_database
 grant all privileges on test.* to mysqltest_1@localhost;
 select * from information_schema.SCHEMATA where schema_name > 'm';
 CATALOG_NAME	SCHEMA_NAME	DEFAULT_CHARACTER_SET_NAME	SQL_PATH
@@ -321,11 +324,11 @@ show keys from v4;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
 select * from information_schema.views where TABLE_NAME like "v%";
 TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE
-NULL	test	v0	select `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata`	NONE	NO
-NULL	test	v1	select `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1')	NONE	NO
-NULL	test	v2	select `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2')	NONE	NO
-NULL	test	v3	select `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%')	NONE	NO
-NULL	test	v4	select `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%')	NONE	NO
+NULL	test	v0	select sql_no_cache `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata`	NONE	NO
+NULL	test	v1	select sql_no_cache `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1')	NONE	NO
+NULL	test	v2	select sql_no_cache `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2')	NONE	NO
+NULL	test	v3	select sql_no_cache `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%')	NONE	NO
+NULL	test	v4	select sql_no_cache `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%')	NONE	NO
 drop view v0, v1, v2, v3, v4;
 create table t1 (a int);
 grant select,update,insert on t1 to mysqltest_1@localhost;
@@ -661,3 +664,14 @@ select table_type from information_schema.tables
 where table_schema="mysql" and table_name="user";
 table_type
 BASE TABLE
+show open tables where `table` like "user";
+Database	Table	In_use	Name_locked
+mysql	user	0	0
+show status variable_name where variable_name like "%database%";
+variable_name
+Com_show_databases
+show variables variable_name where variable_name like "%database%";
+variable_name
+character_set_database
+collation_database
+skip_show_database
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 57c5da870ad..3568be8cc12 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -947,3 +947,13 @@ Variable_name	Value
 Qcache_hits	7
 DROP TABLE t1;
 SET GLOBAL query_cache_size=0;
+SET SESSION query_cache_type = 2;
+create table t1(a int);
+select table_name from information_schema.tables
+where table_schema="test";
+table_name
+t1
+drop table t1;
+select table_name from information_schema.tables
+where table_schema="test";
+table_name
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 10c0a2e3652..2dd58f54327 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -95,5 +95,5 @@ d
 show status like "created_tmp%tables";
 Variable_name	Value
 Created_tmp_disk_tables	0
-Created_tmp_tables	1
+Created_tmp_tables	2
 drop table t1;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 1fbba8ebbb7..334a2531c7f 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -851,27 +851,27 @@ count(*)
 26
 show status like 'Slow_queries';
 Variable_name	Value
-Slow_queries	0
+Slow_queries	1
 select count(*) from t1 where b=13;
 count(*)
 10
 show status like 'Slow_queries';
 Variable_name	Value
-Slow_queries	1
+Slow_queries	3
 select count(*) from t1 where b=13 union select count(*) from t1 where a=7;
 count(*)
 10
 26
 show status like 'Slow_queries';
 Variable_name	Value
-Slow_queries	2
+Slow_queries	5
 select count(*) from t1 where a=7 union select count(*) from t1 where b=13;
 count(*)
 26
 10
 show status like 'Slow_queries';
 Variable_name	Value
-Slow_queries	3
+Slow_queries	7
 drop table t1;
 create table t1 (   RID int(11) not null default '0',   IID int(11) not null default '0',    nada varchar(50)  not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM;
 insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777');
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 66315fe7a29..ac36bbd6014 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -2,6 +2,7 @@
 # Test for information_schema.schemata &
 # show databases
 
+show variables variable_name where variable_name like "skip_show_database";
 grant all privileges on test.* to mysqltest_1@localhost;
 
 select * from information_schema.SCHEMATA where schema_name > 'm';
@@ -346,3 +347,10 @@ select TABLE_ROWS from information_schema.tables where
 table_schema="information_schema" and table_name="COLUMNS";
 select table_type from information_schema.tables
 where table_schema="mysql" and table_name="user";
+
+# test for 'show open tables ... where'
+show open tables where `table` like "user";
+# test for 'show status ... where'
+show status variable_name where variable_name like "%database%";
+# test for 'show variables ... where'
+show variables variable_name where variable_name like "%database%";
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index ed89184a0bc..26f939582e5 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -686,3 +686,14 @@ show status like "Qcache_hits";
 #
 DROP TABLE t1;
 SET GLOBAL query_cache_size=0;
+
+#
+# Information schema & query cache test
+#
+SET SESSION query_cache_type = 2;
+create table t1(a int);
+select table_name from information_schema.tables
+where table_schema="test";
+drop table t1;
+select table_name from information_schema.tables
+where table_schema="test";
diff --git a/sql/item.cc b/sql/item.cc
index 9117105f26e..a0a623d98c5 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2269,7 +2269,7 @@ enum_field_types Item::field_type() const
 
 Field *Item::make_string_field(TABLE *table)
 {
-  if (max_length > CONVERT_IF_BIGGER_TO_BLOB)
+  if (max_length > MAX_FIELD_WIDTH)
     return new Field_blob(max_length, maybe_null, name, table,
                           collation.collation);
   if (max_length > 0)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index d69669d097a..59619d2754b 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -720,10 +720,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
 void mysqld_list_processes(THD *thd,const char *user,bool verbose);
 int mysqld_show_status(THD *thd);
 int mysqld_show_variables(THD *thd,const char *wild);
-bool mysqld_show(THD *thd, const char *wild, show_var_st *variables,
-		enum enum_var_type value_type,
-		pthread_mutex_t *mutex,
-		struct system_status_var *status_var);
 int mysql_find_files(THD *thd,List<char> *files, const char *db,
                 const char *path, const char *wild, bool dir);
 bool mysqld_show_storage_engines(THD *thd);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4a357c6eefe..277fe676368 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1964,6 +1964,9 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
       break;
     }
 #endif
+  case SCH_OPEN_TABLES:
+  case SCH_VARIABLES:
+  case SCH_STATUS:
   case SCH_PROCEDURES:
   case SCH_CHARSETS:
   case SCH_COLLATIONS:
@@ -3121,25 +3124,6 @@ mysql_execute_command(THD *thd)
   case SQLCOM_SHOW_COLUMN_TYPES:
     res= mysqld_show_column_types(thd);
     break;
-  case SQLCOM_SHOW_STATUS:
-    STATUS_VAR tmp;
-    if (lex->option_type == OPT_GLOBAL)
-    {
-      pthread_mutex_lock(&LOCK_status);
-      calc_sum_of_all_status(&tmp);
-    }
-    res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
-		     status_vars, OPT_GLOBAL, &LOCK_status,
-		     (lex->option_type == OPT_GLOBAL ? 
-		      &tmp: &thd->status_var));
-    if (lex->option_type == OPT_GLOBAL)
-      pthread_mutex_unlock(&LOCK_status);
-    break;
-  case SQLCOM_SHOW_VARIABLES:
-    res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
-		     init_vars, lex->option_type,
-		     &LOCK_global_system_variables, 0);
-    break;
   case SQLCOM_SHOW_LOGS:
 #ifdef DONT_ALLOW_SHOW_COMMANDS
     my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
@@ -3153,9 +3137,6 @@ mysql_execute_command(THD *thd)
       break;
     }
 #endif
-  case SQLCOM_SHOW_OPEN_TABLES:
-    res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS));
-    break;
   case SQLCOM_CHANGE_DB:
     mysql_change_db(thd,select_lex->db);
     break;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 570774c8054..62d74971095 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3716,8 +3716,12 @@ choose_plan(JOIN *join, table_map join_tables)
     }
   }
 
-  /* Store the cost of this query into a user variable */
-  last_query_cost= join->best_read;
+  /* 
+    Store the cost of this query into a user variable
+    Don't update last_query_cost for 'show status' command
+  */
+  if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
+    last_query_cost= join->best_read;
 
   DBUG_VOID_RETURN;
 }
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d075e428aa0..ee0a40bef71 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -44,46 +44,6 @@ static int
 view_store_create_info(THD *thd, TABLE_LIST *table, String *packet);
 
 
-/***************************************************************************
-  List all open tables in a database
-***************************************************************************/
-
-bool mysqld_show_open_tables(THD *thd,const char *wild)
-{
-  List<Item> field_list;
-  OPEN_TABLE_LIST *open_list;
-  Protocol *protocol= thd->protocol;
-  DBUG_ENTER("mysqld_show_open_tables");
-
-  field_list.push_back(new Item_empty_string("Database",NAME_LEN));
-  field_list.push_back(new Item_empty_string("Table",NAME_LEN));
-  field_list.push_back(new Item_return_int("In_use", 1, MYSQL_TYPE_TINY));
-  field_list.push_back(new Item_return_int("Name_locked", 4, MYSQL_TYPE_TINY));
-
-  if (protocol->send_fields(&field_list,
-                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-    DBUG_RETURN(TRUE);
-
-  if (!(open_list=list_open_tables(thd,wild)) && thd->is_fatal_error)
-    DBUG_RETURN(TRUE);
-
-  for (; open_list ; open_list=open_list->next)
-  {
-    protocol->prepare_for_resend();
-    protocol->store(open_list->db, system_charset_info);
-    protocol->store(open_list->table, system_charset_info);
-    protocol->store_tiny((longlong) open_list->in_use);
-    protocol->store_tiny((longlong) open_list->locked);
-    if (protocol->write())
-    {
-      DBUG_RETURN(TRUE);
-    }
-  }
-  send_eof(thd);
-  DBUG_RETURN(FALSE);
-}
-
-
 /***************************************************************************
 ** List all table types supported 
 ***************************************************************************/
@@ -373,172 +333,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
 }
 
 
-/***************************************************************************
-** List all columns in a table_list->real_name
-***************************************************************************/
-
-bool
-mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
-		   bool verbose)
-{
-  TABLE *table;
-  handler *file;
-  char tmp[MAX_FIELD_WIDTH];
-  char tmp1[MAX_FIELD_WIDTH];
-  Item *item;
-  Protocol *protocol= thd->protocol;
-  int res;
-  DBUG_ENTER("mysqld_show_fields");
-  DBUG_PRINT("enter",("db: %s  table: %s",table_list->db,
-                      table_list->real_name));
-
-  table_list->lock_type= TL_UNLOCK;
-  if (open_and_lock_tables(thd, table_list))
-  {
-    DBUG_RETURN(TRUE);
-  }
-  table= table_list->table;
-  file=table->file;
-  file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  (void) get_table_grant(thd, table_list);
-#endif
-  List<Item> field_list;
-  field_list.push_back(new Item_empty_string("Field",NAME_LEN));
-  field_list.push_back(new Item_empty_string("Type",40));
-  if (verbose)
-    field_list.push_back(new Item_empty_string("Collation",40));
-  field_list.push_back(new Item_empty_string("Null",1));
-  field_list.push_back(new Item_empty_string("Key",3));
-  field_list.push_back(item=new Item_empty_string("Default",NAME_LEN));
-  item->maybe_null=1;
-  field_list.push_back(new Item_empty_string("Extra",20));
-  if (verbose)
-  {
-    field_list.push_back(new Item_empty_string("Privileges",80));
-    field_list.push_back(new Item_empty_string("Comment",255));
-  }
-        // Send first number of fields and records
-  if (protocol->send_records_num(&field_list, (ulonglong)file->records) ||
-      protocol->send_fields(&field_list, Protocol::SEND_EOF))
-    DBUG_RETURN(TRUE);
-  restore_record(table,default_values);      // Get empty record
-
-  Field **ptr,*field;
-  for (ptr=table->field; (field= *ptr) ; ptr++)
-  {
-    if (!wild || !wild[0] || 
-        !wild_case_compare(system_charset_info, field->field_name,wild))
-    {
-      {
-        byte *pos;
-        uint flags=field->flags;
-        String type(tmp,sizeof(tmp), system_charset_info);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-        uint col_access;
-#endif
-	protocol->prepare_for_resend();
-        protocol->store(field->field_name, system_charset_info);
-        field->sql_type(type);
-        protocol->store(type.ptr(), type.length(), system_charset_info);
-	if (verbose)
-	  protocol->store(field->has_charset() ? field->charset()->name : "NULL",
-			system_charset_info);
-        /*
-          Even if TIMESTAMP field can't contain NULL as its value it
-          will accept NULL if you will try to insert such value and will
-          convert NULL value to current TIMESTAMP. So YES here means
-          that NULL is allowed for assignment (but may be won't be
-          returned).
-        */
-        pos=(byte*) ((flags & NOT_NULL_FLAG) &&
-                     field->type() != FIELD_TYPE_TIMESTAMP ?
-                     "" : "YES");
-        protocol->store((const char*) pos, system_charset_info);
-        pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
-                     (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
-                     (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
-        protocol->store((char*) pos, system_charset_info);
-
-        if (table->timestamp_field == field &&
-            field->unireg_check != Field::TIMESTAMP_UN_FIELD)
-        {
-          /*
-            We have NOW() as default value but we use CURRENT_TIMESTAMP form
-            because it is more SQL standard compatible
-          */
-          protocol->store("CURRENT_TIMESTAMP", system_charset_info);
-        }
-        else if (field->unireg_check != Field::NEXT_NUMBER &&
-                 !field->is_null() &&
-                 !(field->flags & NO_DEFAULT_VALUE_FLAG))
-        {                                               // Not null by default
-          /*
-            Note: we have to convert the default value into
-            system_charset_info before sending.
-            This is necessary for "SET NAMES binary":
-            If the client character set is binary, we want to
-            send metadata in UTF8 rather than in the column's
-            character set.
-            This conversion also makes "SHOW COLUMNS" and
-            "SHOW CREATE TABLE" output consistent. Without
-            this conversion the default values were displayed
-            differently.
-          */
-          String def(tmp1,sizeof(tmp1), system_charset_info);
-          type.set(tmp, sizeof(tmp), field->charset());
-          field->val_str(&type);
-          uint dummy_errors;
-          def.copy(type.ptr(), type.length(), type.charset(), 
-                   system_charset_info, &dummy_errors);
-          protocol->store(def.ptr(), def.length(), def.charset());
-        }
-        else if (field->unireg_check == Field::NEXT_NUMBER ||
-                 field->maybe_null())
-          protocol->store_null();                       // Null as default
-        else
-          protocol->store("",0, system_charset_info);	// empty string
-
-        char *end=tmp;
-        if (field->unireg_check == Field::NEXT_NUMBER)
-          end=strmov(tmp,"auto_increment");
-        protocol->store(tmp,(uint) (end-tmp), system_charset_info);
-
-	if (verbose)
-	{
-	  /* Add grant options & comments */
-	  end=tmp;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-          col_access= get_column_grant(thd, &table_list->grant,
-                                       table_list->db,
-                                       table_list->real_name,
-                                       field->field_name) & COL_ACLS;
-	  for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
-	  {
-	    if (col_access & 1)
-	    {
-	      *end++=',';
-	      end=strmov(end,grant_types.type_names[bitnr]);
-	    }
-	  }
-#else
-	  end=strmov(end,"");
-#endif
-	  protocol->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1),
-			  system_charset_info);
-	  protocol->store(field->comment.str, field->comment.length,
-			  system_charset_info);
-	}
-        if (protocol->write())
-          DBUG_RETURN(TRUE);
-      }
-    }
-  }
-  send_eof(thd);
-  DBUG_RETURN(FALSE);
-}
-
-
 bool
 mysqld_show_create(THD *thd, TABLE_LIST *table_list)
 {
@@ -1419,16 +1213,15 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
 
 
 static bool show_status_array(THD *thd, const char *wild,
-                             show_var_st *variables,
-                             enum enum_var_type value_type,
-                             struct system_status_var *status_var,
-                             const char *prefix)
+                              show_var_st *variables,
+                              enum enum_var_type value_type,
+                              struct system_status_var *status_var,
+                              const char *prefix, TABLE *table)
 {
   char buff[1024], *prefix_end;
   /* the variable name should not be longer then 80 characters */
   char name_buffer[80];
   int len;
-  Protocol *protocol= thd->protocol;
   LEX_STRING null_lex_str;
   DBUG_ENTER("show_status_array");
 
@@ -1446,7 +1239,7 @@ static bool show_status_array(THD *thd, const char *wild,
     if (show_type == SHOW_VARS)
     {
       show_status_array(thd, wild, (show_var_st *) variables->value,
-                        value_type, status_var, variables->name);
+                        value_type, status_var, variables->name, table);
     }
     else
     {
@@ -1456,10 +1249,6 @@ static bool show_status_array(THD *thd, const char *wild,
         char *value=variables->value;
         const char *pos, *end;
         long nr;
-
-        protocol->prepare_for_resend();
-        protocol->store(name_buffer, system_charset_info);
-
         if (show_type == SHOW_SYS)
         {
           show_type= ((sys_var*) value)->type();
@@ -1728,9 +1517,11 @@ static bool show_status_array(THD *thd, const char *wild,
         default:
           break;
         }
-        if (protocol->store(pos, (uint32) (end - pos), system_charset_info) ||
-            protocol->write())
-          DBUG_RETURN(TRUE);                               /* purecov: inspected */
+        restore_record(table, default_values);
+        table->field[0]->store(name_buffer, strlen(name_buffer),
+                               system_charset_info);
+        table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
+        table->file->write_row(table->record[0]);        
       }
     }
   }
@@ -1742,25 +1533,14 @@ static bool show_status_array(THD *thd, const char *wild,
 bool mysqld_show(THD *thd, const char *wild, show_var_st *variables,
                  enum enum_var_type value_type,
                  pthread_mutex_t *mutex,
-                 struct system_status_var *status_var)
+                 struct system_status_var *status_var, TABLE *table)
 {
-  List<Item> field_list;
-  Protocol *protocol= thd->protocol;
   DBUG_ENTER("mysqld_show");
-
   ha_update_statistics();                    /* Export engines statistics */
-
-  field_list.push_back(new Item_empty_string("Variable_name",30));
-  field_list.push_back(new Item_empty_string("Value",256));
-  if (protocol->send_fields(&field_list,
-                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-    DBUG_RETURN(TRUE); /* purecov: inspected */
-
   pthread_mutex_lock(mutex);
-  if (show_status_array(thd, wild, variables, value_type, status_var, ""))
+  if (show_status_array(thd, wild, variables, value_type, status_var, "", table))
     goto err;
   pthread_mutex_unlock(mutex);
-  send_eof(thd);
   DBUG_RETURN(FALSE);
 
  err:
@@ -1944,6 +1724,12 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
 }
 
 
+enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
+{
+  return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
+}
+
+
 /*
   Add 'information_schema' name to db_names list
 
@@ -2034,8 +1820,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
   bool with_i_schema;
   List<char> bases;
   lex->all_selects_list= &sel;
-  enum enum_schema_tables schema_table_idx=
-    (enum enum_schema_tables) (schema_table - &schema_tables[0]);
+  enum enum_schema_tables schema_table_idx= get_schema_table_idx(schema_table);
   thr_lock_type lock_type= TL_UNLOCK;
   if (schema_table_idx == SCH_TABLES)
     lock_type= TL_READ;
@@ -3047,6 +2832,62 @@ static int get_schema_key_column_usage_record(THD *thd,
 }
 
 
+int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+  DBUG_ENTER("fill_open_tables");
+  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
+  TABLE *table= tables->table;
+  CHARSET_INFO *cs= system_charset_info;
+  OPEN_TABLE_LIST *open_list;
+  if (!(open_list=list_open_tables(thd,wild)) && thd->is_fatal_error)
+    DBUG_RETURN(1);
+
+  for (; open_list ; open_list=open_list->next)
+  {
+    restore_record(table, default_values);
+    table->field[0]->store(open_list->db, strlen(open_list->db), cs);
+    table->field[1]->store(open_list->table, strlen(open_list->table), cs);
+    table->field[2]->store((longlong) open_list->in_use);
+    table->field[3]->store((longlong)  open_list->locked);
+    table->file->write_row(table->record[0]);
+  }
+  DBUG_RETURN(0);
+}
+
+
+int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+  DBUG_ENTER("fill_variables");
+  LEX *lex= thd->lex;
+  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
+  int res= mysqld_show(thd, wild, init_vars, lex->option_type,
+                       &LOCK_global_system_variables, 0, tables->table);
+  DBUG_RETURN(res);
+}
+
+
+int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+  DBUG_ENTER("fill_status");
+  LEX *lex= thd->lex;
+  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
+  int res= 0;
+  STATUS_VAR tmp;
+
+  if (lex->option_type == OPT_GLOBAL)
+  {
+    pthread_mutex_lock(&LOCK_status);
+    calc_sum_of_all_status(&tmp);
+  }
+  res= mysqld_show(thd, wild, status_vars, OPT_GLOBAL, &LOCK_status,
+                   (lex->option_type == OPT_GLOBAL ?
+                    &tmp: &thd->status_var), tables->table);
+  if (lex->option_type == OPT_GLOBAL)
+    pthread_mutex_unlock(&LOCK_status);
+  DBUG_RETURN(res);
+}
+
+
 /*
   Find schema_tables elment by name
 
@@ -3353,6 +3194,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
   table->next= thd->derived_tables;
   thd->derived_tables= table;
   table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
+  lex->safe_to_cache_query= 0;
   DBUG_RETURN(0);
 }
 
@@ -3690,6 +3532,24 @@ ST_FIELD_INFO table_names_fields_info[]=
 };
 
 
+ST_FIELD_INFO open_tables_fields_info[]=
+{
+  {"Database", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
+  {"Table",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
+  {"In_use", 1, MYSQL_TYPE_LONG, 0, 0, "In_use"},
+  {"Name_locked", 4, MYSQL_TYPE_LONG, 0, 0, "Name_locked"},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
+ST_FIELD_INFO variables_fields_info[]=
+{
+  {"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
+  {"Value", 255, MYSQL_TYPE_STRING, 0, 0, "Value"},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
 /*
   Description of ST_FIELD_INFO in table.h
 */
@@ -3728,6 +3588,12 @@ ST_SCHEMA_TABLE schema_tables[]=
     get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
   {"TABLE_NAMES", table_names_fields_info, create_schema_table,
    get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+  {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
+   fill_open_tables, make_old_format, 0, -1, -1, 1},
+  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
+   make_old_format, 0, -1, -1, 1},
+  {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
+   make_old_format, 0, -1, -1, 1},
   {0, 0, 0, 0, 0, 0, 0, 0, 0}
 };
 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5c03a4c98ef..463f18c05db 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5899,12 +5899,15 @@ show_param:
              if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
                YYABORT;
            }
-	| OPEN_SYM TABLES opt_db wild
-	  {
-	    LEX *lex= Lex;
-	    lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
-	    lex->select_lex.db= $3;
-	  }
+        | OPEN_SYM TABLES ext_select_item_list opt_db wild_and_where
+          {
+            LEX *lex= Lex;
+            lex->sql_command= SQLCOM_SELECT;
+            lex->orig_sql_command= SQLCOM_SHOW_OPEN_TABLES;
+            lex->select_lex.db= $4;
+            if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
+              YYABORT;
+          }
 	| ENGINE_SYM storage_engines 
 	  { Lex->create_info.db_type= $2; }
 	  show_engine_param
@@ -5980,22 +5983,28 @@ show_param:
           { Lex->sql_command = SQLCOM_SHOW_WARNS;}
         | ERRORS opt_limit_clause_init
           { Lex->sql_command = SQLCOM_SHOW_ERRORS;}
-	| opt_var_type STATUS_SYM wild
+        | opt_var_type STATUS_SYM ext_select_item_list wild_and_where
           {
-	    THD *thd= YYTHD;
-	    thd->lex->sql_command= SQLCOM_SHOW_STATUS;
-	    thd->lex->option_type= (enum_var_type) $1;
-	  }	
+            LEX *lex= Lex;
+            lex->sql_command= SQLCOM_SELECT;
+            lex->orig_sql_command= SQLCOM_SHOW_STATUS;
+            lex->option_type= (enum_var_type) $1;
+            if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
+              YYABORT;
+          }
         | INNOBASE_SYM STATUS_SYM
           { Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; WARN_DEPRECATED("SHOW INNODB STATUS", "SHOW ENGINE INNODB STATUS"); }
 	| opt_full PROCESSLIST_SYM
 	  { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
-	| opt_var_type VARIABLES wild
-	  {
-	    THD *thd= YYTHD;
-	    thd->lex->sql_command= SQLCOM_SHOW_VARIABLES;
-	    thd->lex->option_type= (enum_var_type) $1;
-	  }
+        | opt_var_type  VARIABLES ext_select_item_list wild_and_where
+          {
+            LEX *lex= Lex;
+            lex->sql_command= SQLCOM_SELECT;
+            lex->orig_sql_command= SQLCOM_SHOW_VARIABLES;
+            lex->option_type= (enum_var_type) $1;
+            if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
+              YYABORT;
+          }
         | charset ext_select_item_list wild_and_where
           {
             LEX *lex= Lex;
@@ -6143,12 +6152,6 @@ opt_db:
 	/* empty */  { $$= 0; }
 	| from_or_in ident { $$= $2.str; };
 
-wild:
-	/* empty */
-	| LIKE TEXT_STRING_sys
-	  { Lex->wild=  new (YYTHD->mem_root) String($2.str, $2.length,
-                                                      system_charset_info); };
-
 opt_full:
 	/* empty */ { Lex->verbose=0; }
 	| FULL	    { Lex->verbose=1; };
@@ -6186,7 +6189,10 @@ ext_select_item_list:
         mysql_init_select(lex);
         lex->current_select->parsing_place= SELECT_LIST;
       }
-      /* empty */
+      ext_select_item_list2;
+
+ext_select_item_list2:
+      /* empty */        {}
       | select_item_list {};
 
 
diff --git a/sql/table.h b/sql/table.h
index a804376ee3c..4d158d1835d 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -223,7 +223,7 @@ enum enum_schema_tables
   SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_PROCEDURES, SCH_STATISTICS,
   SCH_VIEWS, SCH_USER_PRIVILEGES, SCH_SCHEMA_PRIVILEGES, SCH_TABLE_PRIVILEGES,
   SCH_COLUMN_PRIVILEGES, SCH_TABLE_CONSTRAINTS, SCH_KEY_COLUMN_USAGE,
-  SCH_TABLE_NAMES
+  SCH_TABLE_NAMES, SCH_OPEN_TABLES, SCH_STATUS, SCH_VARIABLES
 };
 
 
-- 
2.30.9