List:Commits« Previous MessageNext Message »
From:monty Date:June 22 2006 9:21am
Subject:bk commit into 5.1 tree (monty:1.2204)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of monty. When monty 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
  1.2204 06/06/22 12:21:41 monty@stripped +12 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.1
  into  mysql.com:/home/my/mysql-5.1

  sql/mysql_priv.h
    1.413 06/06/22 12:21:38 monty@stripped +0 -0
    SCCS merged

  sql/sql_show.cc
    1.353 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.563 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/sql_lex.cc
    1.190 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/sql_class.h
    1.301 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/sql_class.cc
    1.268 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/log_event.cc
    1.227 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.331 06/06/22 12:20:19 monty@stripped +0 -0
    Auto merged

  mysql-test/r/rpl_row_log_innodb.result
    1.11 06/06/22 12:20:18 monty@stripped +0 -2
    Auto merged

  mysql-test/r/rpl_row_log.result
    1.11 06/06/22 12:20:18 monty@stripped +0 -2
    Auto merged

  mysql-test/r/rpl_ndb_log.result
    1.13 06/06/22 12:20:18 monty@stripped +0 -2
    Auto merged

  mysql-test/extra/rpl_tests/rpl_log.test
    1.41 06/06/22 12:20:18 monty@stripped +0 -1
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	monty
# Host:	narttu.mysql.fi
# Root:	/home/my/mysql-5.1/RESYNC

--- 1.226/sql/log_event.cc	2006-06-16 01:49:48 +03:00
+++ 1.227/sql/log_event.cc	2006-06-22 12:20:19 +03:00
@@ -5682,7 +5682,7 @@
   /* If malloc fails, catched in is_valid() */
   if ((m_memory= my_malloc(m_colcnt, MYF(MY_WME))))
   {
-    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
+    m_coltype= reinterpret_cast<uchar*>(m_memory);
     for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
       m_coltype[i]= m_table->field[i]->type();
   }
@@ -5738,11 +5738,11 @@
 
   /* Extract the length of the various parts from the buffer */
   byte const* const ptr_dblen= (byte const*)vpart + 0;
-  m_dblen= *(unsigned char*) ptr_dblen;
+  m_dblen= *(uchar*) ptr_dblen;
 
   /* Length of database name + counter + terminating null */
   byte const* const ptr_tbllen= ptr_dblen + m_dblen + 2;
-  m_tbllen= *(unsigned char*) ptr_tbllen;
+  m_tbllen= *(uchar*) ptr_tbllen;
 
   /* Length of table name + counter + terminating null */
   byte const* const ptr_colcnt= ptr_tbllen + m_tbllen + 2;

--- 1.412/sql/mysql_priv.h	2006-06-22 01:53:31 +03:00
+++ 1.413/sql/mysql_priv.h	2006-06-22 12:21:38 +03:00
@@ -1588,6 +1588,7 @@
 extern const char* any_db;
 extern struct my_option my_long_options[];
 extern const LEX_STRING view_type;
+extern uint sql_command_flags[];
 extern TYPELIB log_output_typelib;
 
 /* optional things, have_* variables */

--- 1.267/sql/sql_class.cc	2006-06-19 13:14:21 +03:00
+++ 1.268/sql/sql_class.cc	2006-06-22 12:20:19 +03:00
@@ -516,6 +516,31 @@
   /* it doesn't make sense to add last_query_cost values */
 }
 
+/*
+  Add the difference between two status variable arrays to another one.
+
+  SYNOPSIS
+    add_diff_to_status
+    to_var       add to this array
+    from_var     from this array
+    dec_var      minus this array
+  
+  NOTE
+    This function assumes that all variables are long/ulong.
+*/
+
+void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
+                        STATUS_VAR *dec_var)
+{
+  ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR,
+						  last_system_status_var) +
+			sizeof(ulong));
+  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
+
+  while (to != end)
+    *(to++)+= *(from++) - *(dec++);
+}
+
 
 void THD::awake(THD::killed_state state_to_set)
 {

--- 1.300/sql/sql_class.h	2006-06-19 13:14:22 +03:00
+++ 1.301/sql/sql_class.h	2006-06-22 12:20:19 +03:00
@@ -343,7 +343,6 @@
 
 #define last_system_status_var com_stmt_close
 
-
 #ifdef MYSQL_SERVER
 
 void free_tmp_table(THD *thd, TABLE *entry);
@@ -833,6 +832,7 @@
   struct  rand_struct rand;		// used for authentication
   struct  system_variables variables;	// Changeable local variables
   struct  system_status_var status_var; // Per thread statistic vars
+  struct  system_status_var *initial_status_var; /* used by show status */
   THR_LOCK_INFO lock_info;              // Locking info of this thread
   THR_LOCK_OWNER main_lock_id;          // To use for conventional queries
   THR_LOCK_OWNER *lock_id;              // If not main_lock_id, points to
@@ -1310,6 +1310,10 @@
   {
     return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure();
   }
+  inline bool fill_information_schema_tables()
+  {
+    return !stmt_arena->is_stmt_prepare();
+  }
   inline gptr trans_alloc(unsigned int size)
   {
     return alloc_root(&transaction.mem_root,size);
@@ -1966,8 +1970,16 @@
   void cleanup();
 };
 
+/* Bits in sql_command_flags */
+
+#define CF_CHANGES_DATA		1
+#define CF_HAS_ROW_COUNT	2
+#define CF_STATUS_COMMAND	4
+#define CF_SHOW_TABLE_COMMAND	8
+
 /* Functions in sql_class.cc */
 
 void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
-
+void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
+                        STATUS_VAR *dec_var);
 #endif /* MYSQL_SERVER */

--- 1.189/sql/sql_lex.cc	2006-06-20 19:06:11 +03:00
+++ 1.190/sql/sql_lex.cc	2006-06-22 12:20:19 +03:00
@@ -168,7 +168,7 @@
   lex->select_lex.group_list.empty();
   lex->select_lex.order_list.empty();
   lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
-  lex->sql_command= lex->orig_sql_command= SQLCOM_END;
+  lex->sql_command= SQLCOM_END;
   lex->duplicates= DUP_ERROR;
   lex->ignore= 0;
   lex->sphead= NULL;

--- 1.562/sql/sql_parse.cc	2006-06-22 02:25:50 +03:00
+++ 1.563/sql/sql_parse.cc	2006-06-22 12:20:19 +03:00
@@ -68,6 +68,7 @@
 static bool check_db_used(THD *thd,TABLE_LIST *tables);
 static bool check_multi_update_lock(THD *thd);
 static void remove_escape(char *name);
+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
 
 const char *any_db="*any*";	// Special symbol for check_access
 
@@ -626,50 +627,79 @@
   sql_command is actually set to SQLCOM_END sometimes
   so we need the +1 to include it in the array.
 
-  numbers are:
-     0  - read-only query
-  != 0  - query that may change a table
+  See COMMAND_FLAG_xxx for different type of commands
      2  - query that returns meaningful ROW_COUNT() -
           a number of modified rows
 */
 
-char  uc_update_queries[SQLCOM_END+1];
+uint sql_command_flags[SQLCOM_END+1];
 
 void init_update_queries(void)
 {
-  bzero((gptr) &uc_update_queries, sizeof(uc_update_queries));
+  bzero((gptr) &sql_command_flags, sizeof(sql_command_flags));
 
-  uc_update_queries[SQLCOM_CREATE_TABLE]=1;
-  uc_update_queries[SQLCOM_CREATE_INDEX]=1;
-  uc_update_queries[SQLCOM_ALTER_TABLE]=1;
-  uc_update_queries[SQLCOM_UPDATE]=2;
-  uc_update_queries[SQLCOM_UPDATE_MULTI]=2;
-  uc_update_queries[SQLCOM_INSERT]=2;
-  uc_update_queries[SQLCOM_INSERT_SELECT]=2;
-  uc_update_queries[SQLCOM_DELETE]=2;
-  uc_update_queries[SQLCOM_DELETE_MULTI]=2;
-  uc_update_queries[SQLCOM_TRUNCATE]=1;
-  uc_update_queries[SQLCOM_DROP_TABLE]=1;
-  uc_update_queries[SQLCOM_LOAD]=1;
-  uc_update_queries[SQLCOM_CREATE_DB]=1;
-  uc_update_queries[SQLCOM_DROP_DB]=1;
-  uc_update_queries[SQLCOM_REPLACE]=2;
-  uc_update_queries[SQLCOM_REPLACE_SELECT]=2;
-  uc_update_queries[SQLCOM_RENAME_TABLE]=1;
-  uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
-  uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
-  uc_update_queries[SQLCOM_DROP_INDEX]=1;
-  uc_update_queries[SQLCOM_CREATE_VIEW]=1;
-  uc_update_queries[SQLCOM_DROP_VIEW]=1;
-  uc_update_queries[SQLCOM_CREATE_EVENT]=1;
-  uc_update_queries[SQLCOM_ALTER_EVENT]=1;
-  uc_update_queries[SQLCOM_DROP_EVENT]=1;  
+  sql_command_flags[SQLCOM_CREATE_TABLE]=   CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_CREATE_INDEX]=   CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_ALTER_TABLE]=    CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_TRUNCATE]=       CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_DROP_TABLE]=     CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_LOAD]=           CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_CREATE_DB]=      CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_DROP_DB]=        CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_RENAME_TABLE]=   CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_BACKUP_TABLE]=   CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_RESTORE_TABLE]=  CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_CREATE_VIEW]=    CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_DROP_VIEW]=      CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_CREATE_EVENT]=   CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_ALTER_EVENT]=    CF_CHANGES_DATA;
+  sql_command_flags[SQLCOM_DROP_EVENT]=     CF_CHANGES_DATA;  
+
+  sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_INSERT]=	    CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+
+  sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_TRIGGERS]=    CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_EVENTS]=      CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_PLUGINS]=     CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
+
+  sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
+                                                CF_SHOW_TABLE_COMMAND);
+  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
+                                                CF_SHOW_TABLE_COMMAND);
+
+  /*
+    The following is used to preserver CF_ROW_COUNT during the
+    a CALL or EXECUTE statement, so the value generated by the
+    last called (or executed) statement is preserved.
+    See mysql_execute_command() for how CF_ROW_COUNT is used.
+  */
+  sql_command_flags[SQLCOM_CALL]= 		CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_EXECUTE]= 		CF_HAS_ROW_COUNT;
 }
 
+
 bool is_update_query(enum enum_sql_command command)
 {
   DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
-  return uc_update_queries[command] != 0;
+  return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
 }
 
 /*
@@ -733,7 +763,8 @@
   if (check_command < (uint) SQLCOM_END)
   {
     /* Check that we have not done too many updates / hour */
-    if (uc->user_resources.updates && uc_update_queries[check_command] &&
+    if (uc->user_resources.updates &&
+        (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
 	uc->updates++ >= uc->user_resources.updates)
     {
       net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
@@ -2290,8 +2321,6 @@
   TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
   table_list->schema_select_lex= sel;
   table_list->schema_table_reformed= 1;
-  statistic_increment(thd->status_var.com_stat[lex->orig_sql_command],
-                      &LOCK_status);
   DBUG_RETURN(0);
 }
 
@@ -2458,7 +2487,7 @@
     */
     if (opt_readonly &&
 	!(thd->security_ctx->master_access & SUPER_ACL) &&
-	uc_update_queries[lex->sql_command] &&
+	(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) &&
 	!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
 	  (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
 	((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
@@ -2470,9 +2499,8 @@
 #ifdef HAVE_REPLICATION
   } /* endif unlikely slave */
 #endif
-  if(lex->orig_sql_command == SQLCOM_END)
-    statistic_increment(thd->status_var.com_stat[lex->sql_command],
-                        &LOCK_status);
+  statistic_increment(thd->status_var.com_stat[lex->sql_command],
+                      &LOCK_status);
 
 #ifdef HAVE_ROW_BASED_REPLICATION
   if (lex->binlog_row_based_if_mixed)
@@ -2480,77 +2508,61 @@
 #endif /*HAVE_ROW_BASED_REPLICATION*/
 
   switch (lex->sql_command) {
-  case SQLCOM_SELECT:
+  case SQLCOM_SHOW_EVENTS:
+    if ((res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
+                           is_schema_db(thd->lex->select_lex.db))))
+      break;
+    /* fall through */
+  case SQLCOM_SHOW_STATUS_PROC:
+  case SQLCOM_SHOW_STATUS_FUNC:
+    res= execute_sqlcom_select(thd, all_tables);
+    break;
+  case SQLCOM_SHOW_STATUS:
   {
-    /* assign global limit variable if limit is not given */
-    {
-      SELECT_LEX *param= lex->unit.global_parameters;
-      if (!param->explicit_limit)
-	param->select_limit=
-          new Item_int((ulonglong)thd->variables.select_limit);
-    }
-
-    select_result *result=lex->result;
+    system_status_var old_status_var= thd->status_var;
+    thd->initial_status_var= &old_status_var;
+    res= execute_sqlcom_select(thd, all_tables);
+    /* Don't log SHOW STATUS commands to slow query log */
+    thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
+                           SERVER_QUERY_NO_GOOD_INDEX_USED);
+    /*
+      restore status variables, as we don't want 'show status' to cause
+      changes
+    */
+    pthread_mutex_lock(&LOCK_status);
+    add_diff_to_status(&global_status_var, &thd->status_var,
+                       &old_status_var);
+    thd->status_var= old_status_var;
+    pthread_mutex_unlock(&LOCK_status);
+    break;
+  }
+  case SQLCOM_SHOW_DATABASES:
+  case SQLCOM_SHOW_TABLES:
+  case SQLCOM_SHOW_TRIGGERS:
+  case SQLCOM_SHOW_TABLE_STATUS:
+  case SQLCOM_SHOW_OPEN_TABLES:
+  case SQLCOM_SHOW_PLUGINS:
+  case SQLCOM_SHOW_FIELDS:
+  case SQLCOM_SHOW_KEYS:
+  case SQLCOM_SHOW_VARIABLES:
+  case SQLCOM_SHOW_CHARSETS:
+  case SQLCOM_SHOW_COLLATIONS:
+  case SQLCOM_SELECT:
+    thd->status_var.last_query_cost= 0.0;
     if (all_tables)
     {
-      if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
-          lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC &&
-          lex->orig_sql_command != SQLCOM_SHOW_EVENTS)
-        res= check_table_access(thd,
-                                lex->exchange ? SELECT_ACL | FILE_ACL :
-                                SELECT_ACL,
-                                all_tables, 0);
-      else if (lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
-        res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
-                       is_schema_db(thd->lex->select_lex.db));
+      res= check_table_access(thd,
+                              lex->exchange ? SELECT_ACL | FILE_ACL :
+                              SELECT_ACL,
+                              all_tables, 0);
     }
     else
       res= check_access(thd,
-			lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
-			any_db, 0, 0, 0, 0);
-    if (res)
-      goto error;
-
-    if (!(res= open_and_lock_tables(thd, all_tables)))
-    {
-      if (lex->describe)
-      {
-        /*
-          We always use select_send for EXPLAIN, even if it's an EXPLAIN
-          for SELECT ... INTO OUTFILE: a user application should be able
-          to prepend EXPLAIN to any query and receive output for it,
-          even if the query itself redirects the output.
-        */
-	if (!(result= new select_send()))
-	  goto error;
-	else
-	  thd->send_explain_fields(result);
-	res= mysql_explain_union(thd, &thd->lex->unit, result);
-	if (lex->describe & DESCRIBE_EXTENDED)
-	{
-	  char buff[1024];
-	  String str(buff,(uint32) sizeof(buff), system_charset_info);
-	  str.length(0);
-	  thd->lex->unit.print(&str);
-	  str.append('\0');
-	  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-		       ER_YES, str.ptr());
-	}
-	result->send_eof();
-        delete result;
-      }
-      else
-      {
-	if (!result && !(result= new select_send()))
-          goto error;
-	query_cache_store_query(thd, all_tables);
-	res= handle_select(thd, lex, result, 0);
-        if (result != lex->result)
-          delete result;
-      }
-    }
+                        lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
+                        any_db, 0, 0, 0, 0);
+    if (!res)
+      res= execute_sqlcom_select(thd, all_tables);
     break;
-  }
   case SQLCOM_PREPARE:
   {
     mysql_sql_stmt_prepare(thd);
@@ -4826,6 +4838,7 @@
       }
       break;
     }
+#ifdef NOT_USED
   case SQLCOM_SHOW_STATUS_PROC:
     {
       res= sp_show_status_procedure(thd, (lex->wild ?
@@ -4838,6 +4851,7 @@
 					 lex->wild->ptr() : NullS));
       break;
     }
+#endif
 #ifndef DBUG_OFF
   case SQLCOM_SHOW_PROC_CODE:
   case SQLCOM_SHOW_FUNC_CODE:
@@ -5162,13 +5176,10 @@
   /*
     The return value for ROW_COUNT() is "implementation dependent" if the
     statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
-    wants.
-
-    We do not change the value for a CALL or EXECUTE statement, so the value
-    generated by the last called (or executed) statement is preserved.
-   */
-  if (lex->sql_command != SQLCOM_CALL && lex->sql_command != SQLCOM_EXECUTE &&
-      uc_update_queries[lex->sql_command]<2)
+    wants. We also keep the last value in case of SQLCOM_CALL or
+    SQLCOM_EXECUTE.
+  */
+  if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
     thd->row_count_func= -1;
   DBUG_RETURN(res || thd->net.report_error);
 
@@ -5178,6 +5189,59 @@
 }
 
 
+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
+{
+  LEX	*lex= thd->lex;
+  select_result *result=lex->result;
+  bool res;
+  /* assign global limit variable if limit is not given */
+  {
+    SELECT_LEX *param= lex->unit.global_parameters;
+    if (!param->explicit_limit)
+      param->select_limit=
+        new Item_int((ulonglong) thd->variables.select_limit);
+  }
+  if (!(res= open_and_lock_tables(thd, all_tables)))
+  {
+    if (lex->describe)
+    {
+      /*
+        We always use select_send for EXPLAIN, even if it's an EXPLAIN
+        for SELECT ... INTO OUTFILE: a user application should be able
+        to prepend EXPLAIN to any query and receive output for it,
+        even if the query itself redirects the output.
+      */
+      if (!(result= new select_send()))
+        return 1;
+      thd->send_explain_fields(result);
+      res= mysql_explain_union(thd, &thd->lex->unit, result);
+      if (lex->describe & DESCRIBE_EXTENDED)
+      {
+        char buff[1024];
+        String str(buff,(uint32) sizeof(buff), system_charset_info);
+        str.length(0);
+        thd->lex->unit.print(&str);
+        str.append('\0');
+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                     ER_YES, str.ptr());
+      }
+      result->send_eof();
+      delete result;
+    }
+    else
+    {
+      if (!result && !(result= new select_send()))
+        return 1;
+      query_cache_store_query(thd, all_tables);
+      res= handle_select(thd, lex, result, 0);
+      if (result != lex->result)
+        delete result;
+    }
+  }
+  return res;
+}
+
+
 /*
   Check grants for commands which work only with one table and all other
   tables belonging to subselects or implicitly opened tables.
@@ -6283,7 +6347,7 @@
     ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
     if (!schema_table ||
         (schema_table->hidden && 
-         lex->orig_sql_command == SQLCOM_END))  // not a 'show' command
+         (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0))
     {
       my_error(ER_UNKNOWN_TABLE, MYF(0),
                ptr->table_name, information_schema_name.str);

--- 1.352/sql/sql_show.cc	2006-06-20 15:51:24 +03:00
+++ 1.353/sql/sql_show.cc	2006-06-22 12:20:19 +03:00
@@ -2148,7 +2148,7 @@
 void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
 {
   const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-  switch (lex->orig_sql_command) {
+  switch (lex->sql_command) {
   case SQLCOM_SHOW_DATABASES:
     index_field_values->db_value= wild;
     break;
@@ -2337,10 +2337,9 @@
   /*
     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). lex->orig_sql_command can be not equal to SQLCOM_END
-    only in case of executing of SHOW commands.
+    function).
   */
-  if (lex->orig_sql_command != SQLCOM_END)
+  if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
   {
     if (!my_strcasecmp(system_charset_info, information_schema_name.str,
                        idx_field_vals->db_value))
@@ -2419,12 +2418,6 @@
   LINT_INIT(end);
   LINT_INIT(len);
 
-  /*
-    Let us set fake sql_command so views won't try to merge
-    themselves into main statement.
-  */
-  lex->sql_command= SQLCOM_SHOW_FIELDS;
-
   lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
 
   /*
@@ -2447,8 +2440,16 @@
       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()
@@ -2479,13 +2480,13 @@
 
   partial_cond= make_cond_for_info_schema(cond, tables);
   it.rewind(); /* To get access to new elements in basis list */
+
+  /*
+    Below we generate error for non existing database.
+    (to save old behaviour for SHOW TABLES FROM db)
+  */
   while ((orig_base_name= base_name= it++) ||
-	 /*
-	   generate error for non existing database.
-	   (to save old behaviour for SHOW TABLES FROM db)
-	 */
-	 ((lex->orig_sql_command == SQLCOM_SHOW_TABLES ||
-           lex->orig_sql_command == SQLCOM_SHOW_TABLE_STATUS) &&
+         ((sql_command_flags[save_sql_command] & CF_SHOW_TABLE_COMMAND) &&
 	  (base_name= select_lex->db) && !bases.elements))
   {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -2526,7 +2527,8 @@
         {
           if (schema_table_idx == SCH_TABLE_NAMES)
           {
-            if (lex->verbose || lex->orig_sql_command == SQLCOM_END)
+            if (lex->verbose ||
+                (sql_command_flags[save_sql_command] & CF_STATUS_COMMAND) == 0)
             {
               if (with_i_schema)
               {
@@ -2570,8 +2572,10 @@
             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;
             res= open_normal_and_derived_tables(thd, show_table_list,
                                                 MYSQL_LOCK_IGNORE_FLUSH);
+            lex->sql_command= save_sql_command;
             /*
               We should use show_table_list->alias instead of 
               show_table_list->table_name because table_name
@@ -2881,7 +2885,7 @@
 
   if (res)
   {
-    if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS)
+    if (lex->sql_command != SQLCOM_SHOW_FIELDS)
     {
       /*
         I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
@@ -2932,7 +2936,7 @@
     col_access= get_column_grant(thd, &tables->grant, 
                                  base_name, file_name,
                                  field->field_name) & COL_ACLS;
-    if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS  && 
+    if (lex->sql_command != SQLCOM_SHOW_FIELDS  &&
         !tables->schema_table && !col_access)
       continue;
     end= tmp;
@@ -2977,7 +2981,7 @@
       table->field[5]->set_notnull();
     }
     else if (field->unireg_check == Field::NEXT_NUMBER ||
-             lex->orig_sql_command != SQLCOM_SHOW_FIELDS ||
+             lex->sql_command != SQLCOM_SHOW_FIELDS ||
              field->maybe_null())
       table->field[5]->set_null();                // Null as default
     else
@@ -3247,16 +3251,18 @@
   get_field(thd->mem_root, proc_table->field[11], &definer);
   if (!full_access)
     full_access= !strcmp(sp_user, definer.ptr());
-  if (!full_access && check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(),
-                                                proc_table->field[2]->val_int() ==
+  if (!full_access && check_some_routine_access(thd, sp_db.ptr(),
+                                                sp_name.ptr(),
+                                                proc_table->field[2]->
+                                                val_int() ==
                                                 TYPE_ENUM_PROCEDURE))
     return 0;
 
-  if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
+  if (lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
       proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
-      lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC &&
+      lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
       proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION ||
-      lex->orig_sql_command == SQLCOM_END)
+      (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
   {
     restore_record(table, s->default_values);
     if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
@@ -3367,7 +3373,7 @@
   DBUG_ENTER("get_schema_stat_record");
   if (res)
   {
-    if (thd->lex->orig_sql_command != SQLCOM_SHOW_KEYS)
+    if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
     {
       /*
         I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
@@ -4158,7 +4164,7 @@
     optimized. It's guaranteed in case of SHOW EVENTS that the user
     has access.
   */
-  if (thd->lex->orig_sql_command != SQLCOM_SHOW_EVENTS &&
+  if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
       check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
                    is_schema_db(et.dbname.str)))
     DBUG_RETURN(0);
@@ -4388,7 +4394,7 @@
     If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
     be NULL. Let's do an assert anyway.
   */
-  if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+  if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
   {
     DBUG_ASSERT(thd->lex->select_lex.db);
     if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
@@ -4416,7 +4422,7 @@
                   will save use from doing a table scan and comparing
                   every single row's `db` with the schema which we show.
   */
-  if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+  if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
     ret= events_table_index_read_for_db(thd, schema_table, event_table);
   else
     ret= events_table_scan_all(thd, schema_table, event_table);
@@ -4482,7 +4488,7 @@
                          (SHOW_VAR *)all_status_vars.buffer,
                          OPT_GLOBAL,
                          (lex->option_type == OPT_GLOBAL ?
-                          &tmp: &thd->status_var), "",tables->table);
+                          &tmp: thd->initial_status_var), "",tables->table);
   pthread_mutex_unlock(&LOCK_status);
   DBUG_RETURN(res);
 }
@@ -4675,8 +4681,8 @@
     schema_table        pointer to 'schema_tables' element
 
   RETURN
-   -1	errror
-    0	success
+   1	error
+   0	success
 */
 
 int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
@@ -4999,7 +5005,7 @@
       break;
 
     TABLE_LIST *table_list= tab->table->pos_in_table_list;
-    if (table_list->schema_table && thd->fill_derived_tables())
+    if (table_list->schema_table && thd->fill_information_schema_tables())
     {
       bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
                           lex->current_select->master_unit()->item);
Thread
bk commit into 5.1 tree (monty:1.2204)monty22 Jun