[Pkg-mysql-commits] r969 - branches/etch-5.0/debian/patches

Christian Hammers ch at alioth.debian.org
Tue Nov 6 21:09:15 UTC 2007


Author: ch
Date: 2007-11-06 21:09:15 +0000 (Tue, 06 Nov 2007)
New Revision: 969

Modified:
   branches/etch-5.0/debian/patches/92_SECURITY_CVE-2007-2692_thd_privs.dpatch
Log:
"Keep your patches clean!" :)


Modified: branches/etch-5.0/debian/patches/92_SECURITY_CVE-2007-2692_thd_privs.dpatch
===================================================================
--- branches/etch-5.0/debian/patches/92_SECURITY_CVE-2007-2692_thd_privs.dpatch	2007-11-06 21:06:03 UTC (rev 968)
+++ branches/etch-5.0/debian/patches/92_SECURITY_CVE-2007-2692_thd_privs.dpatch	2007-11-06 21:09:15 UTC (rev 969)
@@ -17,1695 +17,6 @@
  #define is_schema_db(X) \
    !my_strcasecmp(system_charset_info, information_schema_name.str, (X))
  
-diff -urNad mysql-5.0-etch~/sql/mysql_priv.h.orig mysql-5.0-etch/sql/mysql_priv.h.orig
---- mysql-5.0-etch~/sql/mysql_priv.h.orig	1970-01-01 01:00:00.000000000 +0100
-+++ mysql-5.0-etch/sql/mysql_priv.h.orig	2007-05-28 18:56:15.000000000 +0200
-@@ -0,0 +1,1685 @@
-+/* Copyright (C) 2000-2003 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2 of the License, or
-+   (at your option) any later version.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+/*
-+  Mostly this file is used in the server. But a little part of it is used in
-+  mysqlbinlog too (definition of SELECT_DISTINCT and others).
-+  The consequence is that 90% of the file is wrapped in #ifndef MYSQL_CLIENT,
-+  except the part which must be in the server and in the client.
-+*/
-+
-+#ifndef MYSQL_CLIENT
-+
-+#include <my_global.h>
-+#include <mysql_version.h>
-+#include <mysql_embed.h>
-+#include <my_sys.h>
-+#include <my_time.h>
-+#include <m_string.h>
-+#include <hash.h>
-+#include <signal.h>
-+#include <thr_lock.h>
-+#include <my_base.h>			/* Needed by field.h */
-+#include "sql_bitmap.h"
-+#include "sql_array.h"
-+
-+#ifdef __EMX__
-+#undef write  /* remove pthread.h macro definition for EMX */
-+#endif
-+
-+/* TODO convert all these three maps to Bitmap classes */
-+typedef ulonglong table_map;          /* Used for table bits in join */
-+#if MAX_INDEXES <= 64
-+typedef Bitmap<64>  key_map;          /* Used for finding keys */
-+#else
-+typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */
-+#endif
-+typedef ulong key_part_map;           /* Used for finding key parts */
-+typedef ulong nesting_map;  /* Used for flags of nesting constructs */
-+/*
-+  Used to identify NESTED_JOIN structures within a join (applicable only to
-+  structures that have not been simplified away and embed more the one
-+  element)
-+*/
-+typedef ulonglong nested_join_map;
-+
-+/* query_id */
-+typedef ulonglong query_id_t;
-+extern query_id_t query_id;
-+
-+/* increment query_id and return it.  */
-+inline query_id_t next_query_id() { return query_id++; }
-+
-+/* useful constants */
-+extern const key_map key_map_empty;
-+extern key_map key_map_full;          /* Should be threaded as const */
-+extern const char *primary_key_name;
-+
-+#include "mysql_com.h"
-+#include <violite.h>
-+#include "unireg.h"
-+
-+void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
-+gptr sql_alloc(unsigned size);
-+gptr sql_calloc(unsigned size);
-+char *sql_strdup(const char *str);
-+char *sql_strmake(const char *str,uint len);
-+gptr sql_memdup(const void * ptr,unsigned size);
-+void sql_element_free(void *ptr);
-+char *sql_strmake_with_convert(const char *str, uint32 arg_length,
-+			       CHARSET_INFO *from_cs,
-+			       uint32 max_res_length,
-+			       CHARSET_INFO *to_cs, uint32 *result_length);
-+void kill_one_thread(THD *thd, ulong id, bool only_kill_query);
-+bool net_request_file(NET* net, const char* fname);
-+char* query_table_status(THD *thd,const char *db,const char *table_name);
-+
-+#define x_free(A)	{ my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
-+#define safeFree(x)	{ if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
-+#define PREV_BITS(type,A)	((type) (((type) 1 << (A)) -1))
-+#define all_bits_set(A,B) ((A) & (B) != (B))
-+
-+extern CHARSET_INFO *system_charset_info, *files_charset_info ;
-+extern CHARSET_INFO *national_charset_info, *table_alias_charset;
-+
-+
-+enum Derivation
-+{
-+  DERIVATION_IGNORABLE= 5,
-+  DERIVATION_COERCIBLE= 4,
-+  DERIVATION_SYSCONST= 3,
-+  DERIVATION_IMPLICIT= 2,
-+  DERIVATION_NONE= 1,
-+  DERIVATION_EXPLICIT= 0
-+};
-+
-+
-+typedef struct my_locale_st
-+{
-+  const char *name;
-+  const char *description;
-+  const bool is_ascii;
-+  TYPELIB *month_names;
-+  TYPELIB *ab_month_names;
-+  TYPELIB *day_names;
-+  TYPELIB *ab_day_names;
-+#ifdef __cplusplus 
-+  my_locale_st(const char *name_par, const char *descr_par, bool is_ascii_par,
-+               TYPELIB *month_names_par, TYPELIB *ab_month_names_par,
-+               TYPELIB *day_names_par, TYPELIB *ab_day_names_par) : 
-+    name(name_par), description(descr_par), is_ascii(is_ascii_par),
-+    month_names(month_names_par), ab_month_names(ab_month_names_par),
-+    day_names(day_names_par), ab_day_names(ab_day_names_par)
-+  {}
-+#endif
-+} MY_LOCALE;
-+
-+extern MY_LOCALE my_locale_en_US;
-+extern MY_LOCALE *my_locales[];
-+
-+MY_LOCALE *my_locale_by_name(const char *name);
-+
-+/***************************************************************************
-+  Configuration parameters
-+****************************************************************************/
-+
-+#define ACL_CACHE_SIZE		256
-+#define MAX_PASSWORD_LENGTH	32
-+#define HOST_CACHE_SIZE		128
-+#define MAX_ACCEPT_RETRY	10	// Test accept this many times
-+#define MAX_FIELDS_BEFORE_HASH	32
-+#define USER_VARS_HASH_SIZE     16
-+#define TABLE_OPEN_CACHE_MIN    64
-+#define TABLE_OPEN_CACHE_DEFAULT 64
-+
-+/* 
-+ Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
-+ Drake, libc6 2.3.6-0ubuntu2, Linux kernel 2.6.15-27-686, on x86.  (Added 
-+ 100 bytes as reasonable buffer against growth and other environments'
-+ requirements.)
-+
-+ Feel free to raise this by the smallest amount you can to get the
-+ "execution_constants" test to pass.
-+ */
-+#define STACK_MIN_SIZE          10788   // Abort if less stack during eval.
-+
-+#define STACK_MIN_SIZE_FOR_OPEN 1024*80
-+#define STACK_BUFF_ALLOC	256	// For stack overrun checks
-+#ifndef MYSQLD_NET_RETRY_COUNT
-+#define MYSQLD_NET_RETRY_COUNT  10	// Abort read after this many int.
-+#endif
-+#define TEMP_POOL_SIZE          128
-+
-+#define QUERY_ALLOC_BLOCK_SIZE		8192
-+#define QUERY_ALLOC_PREALLOC_SIZE   	8192
-+#define TRANS_ALLOC_BLOCK_SIZE		4096
-+#define TRANS_ALLOC_PREALLOC_SIZE	4096
-+#define RANGE_ALLOC_BLOCK_SIZE		2048
-+#define ACL_ALLOC_BLOCK_SIZE		1024
-+#define UDF_ALLOC_BLOCK_SIZE		1024
-+#define TABLE_ALLOC_BLOCK_SIZE		1024
-+#define BDB_LOG_ALLOC_BLOCK_SIZE	1024
-+#define WARN_ALLOC_BLOCK_SIZE		2048
-+#define WARN_ALLOC_PREALLOC_SIZE	1024
-+
-+/*
-+  The following parameters is to decide when to use an extra cache to
-+  optimise seeks when reading a big table in sorted order
-+*/
-+#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (10L*1024*1024)
-+#define MIN_ROWS_TO_USE_TABLE_CACHE	 100
-+#define MIN_ROWS_TO_USE_BULK_INSERT	 100
-+
-+/*
-+  The following is used to decide if MySQL should use table scanning
-+  instead of reading with keys.  The number says how many evaluation of the
-+  WHERE clause is comparable to reading one extra row from a table.
-+*/
-+#define TIME_FOR_COMPARE   5	// 5 compares == one read
-+
-+/*
-+  Number of comparisons of table rowids equivalent to reading one row from a 
-+  table.
-+*/
-+#define TIME_FOR_COMPARE_ROWID  (TIME_FOR_COMPARE*2)
-+
-+/*
-+  For sequential disk seeks the cost formula is:
-+    DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST * #blocks_to_skip  
-+  
-+  The cost of average seek 
-+    DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*BLOCKS_IN_AVG_SEEK =1.0.
-+*/
-+#define DISK_SEEK_BASE_COST ((double)0.5)
-+
-+#define BLOCKS_IN_AVG_SEEK  128
-+
-+#define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK)
-+
-+
-+/*
-+  Number of rows in a reference table when refereed through a not unique key.
-+  This value is only used when we don't know anything about the key
-+  distribution.
-+*/
-+#define MATCHING_ROWS_IN_OTHER_TABLE 10
-+
-+/* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */
-+#define KEY_DEFAULT_PACK_LENGTH 8
-+
-+/* Characters shown for the command in 'show processlist' */
-+#define PROCESS_LIST_WIDTH 100
-+
-+#define PRECISION_FOR_DOUBLE 53
-+#define PRECISION_FOR_FLOAT  24
-+
-+/* The following can also be changed from the command line */
-+#define CONNECT_TIMEOUT		5		// Do not wait long for connect
-+#define DEFAULT_CONCURRENCY	10
-+#define DELAYED_LIMIT		100		/* pause after xxx inserts */
-+#define DELAYED_QUEUE_SIZE	1000
-+#define DELAYED_WAIT_TIMEOUT	5*60		/* Wait for delayed insert */
-+#define FLUSH_TIME		0		/* Don't flush tables */
-+#define MAX_CONNECT_ERRORS	10		// errors before disabling host
-+
-+#ifdef HAVE_INNOBASE_DB
-+#define IF_INNOBASE_DB(A, B) (A)
-+#else
-+#define IF_INNOBASE_DB(A, B) (B)
-+#endif
-+#ifdef __NETWARE__
-+#define IF_NETWARE(A,B) (A)
-+#else
-+#define IF_NETWARE(A,B) (B)
-+#endif
-+
-+#if defined(__WIN__) || defined(OS2)
-+#define IF_WIN(A,B) (A)
-+#undef	FLUSH_TIME
-+#define FLUSH_TIME	1800			/* Flush every half hour */
-+
-+#define INTERRUPT_PRIOR -2
-+#define CONNECT_PRIOR	-1
-+#define WAIT_PRIOR	0
-+#define QUERY_PRIOR	2
-+#else
-+#define IF_WIN(A,B) (B)
-+#define INTERRUPT_PRIOR 10
-+#define CONNECT_PRIOR	9
-+#define WAIT_PRIOR	8
-+#define QUERY_PRIOR	6
-+#endif /* __WIN92__ */
-+
-+	/* Bits from testflag */
-+#define TEST_PRINT_CACHED_TABLES 1
-+#define TEST_NO_KEY_GROUP	 2
-+#define TEST_MIT_THREAD		4
-+#define TEST_BLOCKING		8
-+#define TEST_KEEP_TMP_TABLES	16
-+#define TEST_NO_THREADS		32	/* For debugging under Linux */
-+#define TEST_READCHECK		64	/* Force use of readcheck */
-+#define TEST_NO_EXTRA		128
-+#define TEST_CORE_ON_SIGNAL	256	/* Give core if signal */
-+#define TEST_NO_STACKTRACE	512
-+#define TEST_SIGINT		1024	/* Allow sigint on threads */
-+#define TEST_SYNCHRONIZATION    2048    /* get server to do sleep in
-+                                           some places */
-+#endif
-+
-+/*
-+   This is included in the server and in the client.
-+   Options for select set by the yacc parser (stored in lex->options).
-+
-+   XXX:
-+   log_event.h defines OPTIONS_WRITTEN_TO_BIN_LOG to specify what THD
-+   options list are written into binlog. These options can NOT change their
-+   values, or it will break replication between version.
-+
-+   context is encoded as following:
-+   SELECT - SELECT_LEX_NODE::options
-+   THD    - THD::options
-+   intern - neither. used only as
-+            func(..., select_node->options | thd->options | OPTION_XXX, ...)
-+
-+   TODO: separate three contexts above, move them to separate bitfields.
-+*/
-+
-+#define SELECT_DISTINCT         (1L << 0)       // SELECT, user
-+#define SELECT_STRAIGHT_JOIN    (1L << 1)       // SELECT, user
-+#define SELECT_DESCRIBE         (1L << 2)       // SELECT, user
-+#define SELECT_SMALL_RESULT     (1L << 3)       // SELECT, user
-+#define SELECT_BIG_RESULT       (1L << 4)       // SELECT, user
-+#define OPTION_FOUND_ROWS       (1L << 5)       // SELECT, user
-+#define OPTION_TO_QUERY_CACHE   (1L << 6)       // SELECT, user
-+#define SELECT_NO_JOIN_CACHE    (1L << 7)       // intern
-+#define OPTION_BIG_TABLES       (1L << 8)       // THD, user
-+#define OPTION_BIG_SELECTS      (1L << 9)       // THD, user
-+#define OPTION_LOG_OFF          (1L << 10)      // THD, user
-+#define OPTION_UPDATE_LOG       (1L << 11)      // THD, user, unused
-+#define TMP_TABLE_ALL_COLUMNS   (1L << 12)      // SELECT, intern
-+#define OPTION_WARNINGS         (1L << 13)      // THD, user
-+#define OPTION_AUTO_IS_NULL     (1L << 14)      // THD, user, binlog
-+#define OPTION_FOUND_COMMENT    (1L << 15)      // SELECT, intern, parser
-+#define OPTION_SAFE_UPDATES     (1L << 16)      // THD, user
-+#define OPTION_BUFFER_RESULT    (1L << 17)      // SELECT, user
-+#define OPTION_BIN_LOG          (1L << 18)      // THD, user
-+#define OPTION_NOT_AUTOCOMMIT   (1L << 19)      // THD, user
-+#define OPTION_BEGIN            (1L << 20)      // THD, intern
-+#define OPTION_TABLE_LOCK       (1L << 21)      // THD, intern
-+#define OPTION_QUICK            (1L << 22)      // SELECT (for DELETE)
-+#define OPTION_QUOTE_SHOW_CREATE (1L << 23)     // THD, user
-+
-+/* Thr following is used to detect a conflict with DISTINCT
-+   in the user query has requested */
-+#define SELECT_ALL              (1L << 24)      // SELECT, user, parser
-+
-+/* Set if we are updating a non-transaction safe table */
-+#define OPTION_STATUS_NO_TRANS_UPDATE   (1L << 25) // THD, intern
-+
-+/* The following can be set when importing tables in a 'wrong order'
-+   to suppress foreign key checks */
-+#define OPTION_NO_FOREIGN_KEY_CHECKS    (1L << 26) // THD, user, binlog
-+/* The following speeds up inserts to InnoDB tables by suppressing unique
-+   key checks in some cases */
-+#define OPTION_RELAXED_UNIQUE_CHECKS    (1L << 27) // THD, user, binlog
-+#define SELECT_NO_UNLOCK                (1L << 28) // SELECT, intern
-+#define OPTION_SCHEMA_TABLE             (1L << 29) // SELECT, intern
-+/* Flag set if setup_tables already done */
-+#define OPTION_SETUP_TABLES_DONE        (1L << 30) // intern
-+/* If not set then the thread will ignore all warnings with level notes. */
-+#define OPTION_SQL_NOTES                (1UL << 31) // THD, user
-+/* 
-+  Force the used temporary table to be a MyISAM table (because we will use
-+  fulltext functions when reading from it.
-+*/
-+#define TMP_TABLE_FORCE_MYISAM          (LL(1) << 32)
-+
-+/*
-+  Maximum length of time zone name that we support
-+  (Time zone name is char(64) in db). mysqlbinlog needs it.
-+*/
-+#define MAX_TIME_ZONE_NAME_LENGTH 72
-+
-+/* The rest of the file is included in the server only */
-+#ifndef MYSQL_CLIENT
-+
-+/* Bits for different SQL modes modes (including ANSI mode) */
-+#define MODE_REAL_AS_FLOAT              1
-+#define MODE_PIPES_AS_CONCAT            2
-+#define MODE_ANSI_QUOTES                4
-+#define MODE_IGNORE_SPACE		8
-+#define MODE_NOT_USED			16
-+#define MODE_ONLY_FULL_GROUP_BY		32
-+#define MODE_NO_UNSIGNED_SUBTRACTION	64
-+#define MODE_NO_DIR_IN_CREATE		128
-+#define MODE_POSTGRESQL			256
-+#define MODE_ORACLE			512
-+#define MODE_MSSQL			1024
-+#define MODE_DB2			2048
-+#define MODE_MAXDB			4096
-+#define MODE_NO_KEY_OPTIONS             8192
-+#define MODE_NO_TABLE_OPTIONS           16384 
-+#define MODE_NO_FIELD_OPTIONS           32768
-+#define MODE_MYSQL323                   65536
-+#define MODE_MYSQL40                    (MODE_MYSQL323*2)
-+#define MODE_ANSI	                (MODE_MYSQL40*2)
-+#define MODE_NO_AUTO_VALUE_ON_ZERO      (MODE_ANSI*2)
-+#define MODE_NO_BACKSLASH_ESCAPES       (MODE_NO_AUTO_VALUE_ON_ZERO*2)
-+#define MODE_STRICT_TRANS_TABLES	(MODE_NO_BACKSLASH_ESCAPES*2)
-+#define MODE_STRICT_ALL_TABLES		(MODE_STRICT_TRANS_TABLES*2)
-+#define MODE_NO_ZERO_IN_DATE		(MODE_STRICT_ALL_TABLES*2)
-+#define MODE_NO_ZERO_DATE		(MODE_NO_ZERO_IN_DATE*2)
-+#define MODE_INVALID_DATES		(MODE_NO_ZERO_DATE*2)
-+#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2)
-+#define MODE_TRADITIONAL		(MODE_ERROR_FOR_DIVISION_BY_ZERO*2)
-+#define MODE_NO_AUTO_CREATE_USER	(MODE_TRADITIONAL*2)
-+#define MODE_HIGH_NOT_PRECEDENCE	(MODE_NO_AUTO_CREATE_USER*2)
-+#define MODE_NO_ENGINE_SUBSTITUTION     (MODE_HIGH_NOT_PRECEDENCE*2)
-+/*
-+  Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
-+  use strictly more than 64 bits by adding one more define above, you should
-+  contact the replication team because the replication code should then be
-+  updated (to store more bytes on disk).
-+
-+  NOTE: When adding new SQL_MODE types, make sure to also add them to
-+  ../scripts/mysql_create_system_tables.sh and
-+  ../scripts/mysql_fix_privilege_tables.sql
-+*/
-+
-+#define RAID_BLOCK_SIZE 1024
-+
-+#define MY_CHARSET_BIN_MB_MAXLEN 1
-+
-+// uncachable cause
-+#define UNCACHEABLE_DEPENDENT   1
-+#define UNCACHEABLE_RAND        2
-+#define UNCACHEABLE_SIDEEFFECT	4
-+// forcing to save JOIN for explain
-+#define UNCACHEABLE_EXPLAIN     8
-+/* Don't evaluate subqueries in prepare even if they're not correlated */
-+#define UNCACHEABLE_PREPARE    16
-+
-+#ifdef EXTRA_DEBUG
-+/*
-+  Sync points allow us to force the server to reach a certain line of code
-+  and block there until the client tells the server it is ok to go on.
-+  The client tells the server to block with SELECT GET_LOCK()
-+  and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
-+  concurrency problems
-+*/
-+#define DBUG_SYNC_POINT(lock_name,lock_timeout) \
-+ debug_sync_point(lock_name,lock_timeout)
-+void debug_sync_point(const char* lock_name, uint lock_timeout);
-+#else
-+#define DBUG_SYNC_POINT(lock_name,lock_timeout)
-+#endif /* EXTRA_DEBUG */
-+
-+/* BINLOG_DUMP options */
-+
-+#define BINLOG_DUMP_NON_BLOCK   1
-+
-+/* sql_show.cc:show_log_files() */
-+#define SHOW_LOG_STATUS_FREE "FREE"
-+#define SHOW_LOG_STATUS_INUSE "IN USE"
-+
-+struct st_table_list;
-+class String;
-+void view_store_options(THD *thd, st_table_list *table, String *buff);
-+
-+/* Options to add_table_to_list() */
-+#define TL_OPTION_UPDATING	1
-+#define TL_OPTION_FORCE_INDEX	2
-+#define TL_OPTION_IGNORE_LEAVES 4
-+#define TL_OPTION_ALIAS         8
-+
-+/* Some portable defines */
-+
-+#define portable_sizeof_char_ptr 8
-+
-+#define tmp_file_prefix "#sql"			/* Prefix for tmp tables */
-+#define tmp_file_prefix_length 4
-+
-+/* Flags for calc_week() function.  */
-+#define WEEK_MONDAY_FIRST    1
-+#define WEEK_YEAR            2
-+#define WEEK_FIRST_WEEKDAY   4
-+
-+#define STRING_BUFFER_USUAL_SIZE 80
-+
-+enum enum_parsing_place
-+{
-+  NO_MATTER,
-+  IN_HAVING,
-+  SELECT_LIST,
-+  IN_WHERE,
-+  IN_ON
-+};
-+
-+struct st_table;
-+class THD;
-+
-+/* Struct to handle simple linked lists */
-+
-+typedef struct st_sql_list {
-+  uint elements;
-+  byte *first;
-+  byte **next;
-+
-+  st_sql_list() {}                              /* Remove gcc warning */
-+  inline void empty()
-+  {
-+    elements=0;
-+    first=0;
-+    next= &first;
-+  }
-+  inline void link_in_list(byte *element,byte **next_ptr)
-+  {
-+    elements++;
-+    (*next)=element;
-+    next= next_ptr;
-+    *next=0;
-+  }
-+  inline void save_and_clear(struct st_sql_list *save)
-+  {
-+    *save= *this;
-+    empty();
-+  }
-+  inline void push_front(struct st_sql_list *save)
-+  {
-+    *save->next= first;				/* link current list last */
-+    first= save->first;
-+    elements+= save->elements;
-+  }
-+  inline void push_back(struct st_sql_list *save)
-+  {
-+    if (save->first)
-+    {
-+      *next= save->first;
-+      next= save->next;
-+      elements+= save->elements;
-+    }
-+  }
-+} SQL_LIST;
-+
-+
-+extern pthread_key(THD*, THR_THD);
-+inline THD *_current_thd(void)
-+{
-+  return my_pthread_getspecific_ptr(THD*,THR_THD);
-+}
-+#define current_thd _current_thd()
-+
-+/*
-+  External variables
-+*/
-+extern ulong server_id, concurrency;
-+
-+
-+typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
-+                                      uint key_length,
-+                                      ulonglong *engine_data);
-+#include "sql_string.h"
-+#include "sql_list.h"
-+#include "sql_map.h"
-+#include "my_decimal.h"
-+#include "handler.h"
-+#include "parse_file.h"
-+#include "table.h"
-+#include "sql_error.h"
-+#include "field.h"				/* Field definitions */
-+#include "protocol.h"
-+#include "sql_udf.h"
-+class user_var_entry;
-+class Security_context;
-+enum enum_var_type
-+{
-+  OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
-+};
-+class sys_var;
-+class Comp_creator;
-+typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
-+#include "item.h"
-+extern my_decimal decimal_zero;
-+
-+/* sql_parse.cc */
-+void free_items(Item *item);
-+void cleanup_items(Item *item);
-+class THD;
-+void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
-+bool check_one_table_access(THD *thd, ulong privilege,
-+			   TABLE_LIST *tables);
-+bool check_single_table_access(THD *thd, ulong privilege,
-+			   TABLE_LIST *tables);
-+bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
-+			  bool is_proc, bool no_errors);
-+bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
-+bool check_merge_table_access(THD *thd, char *db,
-+			      TABLE_LIST *table_list);
-+bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
-+bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
-+bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
-+bool mysql_multi_update_prepare(THD *thd);
-+bool mysql_multi_delete_prepare(THD *thd);
-+bool mysql_insert_select_prepare(THD *thd);
-+bool update_precheck(THD *thd, TABLE_LIST *tables);
-+bool delete_precheck(THD *thd, TABLE_LIST *tables);
-+bool insert_precheck(THD *thd, TABLE_LIST *tables);
-+bool create_table_precheck(THD *thd, TABLE_LIST *tables,
-+                           TABLE_LIST *create_table);
-+int append_query_string(CHARSET_INFO *csinfo,
-+                        String const *from, String *to);
-+
-+void get_default_definer(THD *thd, LEX_USER *definer);
-+LEX_USER *create_default_definer(THD *thd);
-+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
-+LEX_USER *get_current_user(THD *thd, LEX_USER *user);
-+bool check_string_length(LEX_STRING *str,
-+                         const char *err_msg, uint max_length);
-+
-+enum enum_mysql_completiontype {
-+  ROLLBACK_RELEASE=-2, ROLLBACK=1,  ROLLBACK_AND_CHAIN=7,
-+  COMMIT_RELEASE=-1,   COMMIT=0,    COMMIT_AND_CHAIN=6
-+};
-+
-+int end_trans(THD *thd, enum enum_mysql_completiontype completion);
-+
-+Item *negate_expression(THD *thd, Item *expr);
-+#include "sql_class.h"
-+#include "sql_acl.h"
-+#include "tztime.h"
-+#include "opt_range.h"
-+
-+#ifdef HAVE_QUERY_CACHE
-+struct Query_cache_query_flags
-+{
-+  unsigned int client_long_flag:1;
-+  unsigned int client_protocol_41:1;
-+  unsigned int more_results_exists:1;
-+  unsigned int pkt_nr;
-+  uint character_set_client_num;
-+  uint character_set_results_num;
-+  uint collation_connection_num;
-+  ha_rows limit;
-+  Time_zone *time_zone;
-+  ulong sql_mode;
-+  ulong max_sort_length;
-+  ulong group_concat_max_len;
-+  MY_LOCALE *lc_time_names;
-+};
-+#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
-+#include "sql_cache.h"
-+#define query_cache_store_query(A, B) query_cache.store_query(A, B)
-+#define query_cache_destroy() query_cache.destroy()
-+#define query_cache_result_size_limit(A) query_cache.result_size_limit(A)
-+#define query_cache_init() query_cache.init()
-+#define query_cache_resize(A) query_cache.resize(A)
-+#define query_cache_set_min_res_unit(A) query_cache.set_min_res_unit(A)
-+#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
-+#define query_cache_invalidate1(A) query_cache.invalidate(A)
-+#define query_cache_send_result_to_client(A, B, C) \
-+  query_cache.send_result_to_client(A, B, C)
-+#define query_cache_invalidate_by_MyISAM_filename_ref \
-+  &query_cache_invalidate_by_MyISAM_filename
-+#else
-+#define QUERY_CACHE_FLAGS_SIZE 0
-+#define query_cache_store_query(A, B)
-+#define query_cache_destroy()
-+#define query_cache_result_size_limit(A)
-+#define query_cache_init()
-+#define query_cache_resize(A)
-+#define query_cache_set_min_res_unit(A)
-+#define query_cache_invalidate3(A, B, C)
-+#define query_cache_invalidate1(A)
-+#define query_cache_send_result_to_client(A, B, C) 0
-+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
-+
-+#define query_cache_abort(A)
-+#define query_cache_end_of_result(A)
-+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
-+#endif /*HAVE_QUERY_CACHE*/
-+
-+bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
-+bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
-+bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
-+void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
-+bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
-+                    my_bool drop_temporary);
-+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
-+			 bool drop_temporary, bool drop_view, bool log_query);
-+int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
-+				   bool if_exists, bool drop_temporary,
-+				   bool log_query);
-+int quick_rm_table(enum db_type base,const char *db,
-+		   const char *table_name);
-+void close_cached_table(THD *thd, TABLE *table);
-+bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
-+bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
-+                      char *new_table_name, char *new_table_alias,
-+                      bool skip_error);
-+bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
-+void mysql_parse(THD *thd,char *inBuf,uint length);
-+bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
-+bool is_update_query(enum enum_sql_command command);
-+bool alloc_query(THD *thd, const char *packet, uint packet_length);
-+void mysql_init_select(LEX *lex);
-+void mysql_reset_thd_for_next_command(THD *thd);
-+void mysql_init_query(THD *thd, uchar *buf, uint length);
-+bool mysql_new_select(LEX *lex, bool move_down);
-+void create_select_for_variable(const char *var_name);
-+void mysql_init_multi_delete(LEX *lex);
-+bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
-+void init_max_user_conn(void);
-+void init_update_queries(void);
-+void free_max_user_conn(void);
-+pthread_handler_t handle_one_connection(void *arg);
-+pthread_handler_t handle_bootstrap(void *arg);
-+void end_thread(THD *thd,bool put_in_cache);
-+void flush_thread_cache();
-+bool mysql_execute_command(THD *thd);
-+bool do_command(THD *thd);
-+bool dispatch_command(enum enum_server_command command, THD *thd,
-+		      char* packet, uint packet_length);
-+void log_slow_statement(THD *thd);
-+bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
-+
-+bool table_cache_init(void);
-+void table_cache_free(void);
-+uint cached_tables(void);
-+void kill_mysql(void);
-+void close_connection(THD *thd, uint errcode, bool lock);
-+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, 
-+                          bool *write_to_binlog);
-+bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv,
-+		  bool no_grant, bool no_errors, bool schema_db);
-+bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
-+			bool no_errors);
-+bool check_global_access(THD *thd, ulong want_access);
-+
-+bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
-+bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
-+
-+bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list,
-+                          HA_CHECK_OPT* check_opt);
-+bool mysql_check_table(THD* thd, TABLE_LIST* table_list,
-+                       HA_CHECK_OPT* check_opt);
-+bool mysql_repair_table(THD* thd, TABLE_LIST* table_list,
-+                        HA_CHECK_OPT* check_opt);
-+bool mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
-+                         HA_CHECK_OPT* check_opt);
-+bool mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
-+                          HA_CHECK_OPT* check_opt);
-+bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list,
-+                              LEX_STRING *key_cache_name);
-+bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
-+int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
-+                             KEY_CACHE *dst_cache);
-+TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
-+
-+bool mysql_xa_recover(THD *thd);
-+
-+bool check_simple_select();
-+
-+SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length,
-+                                  SORT_FIELD *sortorder);
-+int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
-+		List<Item> &fields, List <Item> &all_fields, ORDER *order);
-+int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
-+		List<Item> &fields, List<Item> &all_fields, ORDER *order,
-+		bool *hidden_group_fields);
-+
-+bool handle_select(THD *thd, LEX *lex, select_result *result,
-+                   ulong setup_tables_done_option);
-+bool mysql_select(THD *thd, Item ***rref_pointer_array,
-+                  TABLE_LIST *tables, uint wild_num,  List<Item> &list,
-+                  COND *conds, uint og_num, ORDER *order, ORDER *group,
-+                  Item *having, ORDER *proc_param, ulonglong select_type, 
-+                  select_result *result, SELECT_LEX_UNIT *unit, 
-+                  SELECT_LEX *select_lex);
-+void free_underlaid_joins(THD *thd, SELECT_LEX *select);
-+bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
-+                         select_result *result);
-+int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
-+			 select_result *result);
-+bool mysql_union(THD *thd, LEX *lex, select_result *result,
-+                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option);
-+bool mysql_handle_derived(LEX *lex, bool (*processor)(THD *thd,
-+                                                      LEX *lex,
-+                                                      TABLE_LIST *table));
-+bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
-+bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
-+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
-+			Item ***copy_func, Field **from_field,
-+                        Field **def_field,
-+			bool group, bool modify_item,
-+			bool table_cant_handle_bit_fields,
-+                        bool make_copy_field,
-+                        uint convert_blob_length);
-+void sp_prepare_create_field(THD *thd, create_field *sql_field);
-+int prepare_create_field(create_field *sql_field, 
-+			 uint *blob_columns, 
-+			 int *timestamps, int *timestamps_with_niladic,
-+			 uint table_flags);
-+bool mysql_create_table(THD *thd,const char *db, const char *table_name,
-+                        HA_CREATE_INFO *create_info,
-+                        List<create_field> &fields, List<Key> &keys,
-+                        bool tmp_table, uint select_field_count);
-+
-+bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
-+                       HA_CREATE_INFO *create_info,
-+                       TABLE_LIST *table_list,
-+                       List<create_field> &fields,
-+                       List<Key> &keys,
-+                       uint order_num, ORDER *order, bool ignore,
-+                       ALTER_INFO *alter_info, bool do_send_ok);
-+bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
-+bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
-+                             HA_CREATE_INFO *create_info,
-+                             Table_ident *src_table);
-+bool mysql_rename_table(enum db_type base,
-+			const char *old_db,
-+			const char * old_name,
-+			const char *new_db,
-+			const char * new_name);
-+bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
-+bool mysql_drop_index(THD *thd, TABLE_LIST *table_list,
-+                      ALTER_INFO *alter_info);
-+bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
-+                          Item **conds, uint order_num, ORDER *order);
-+int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
-+		 List<Item> &values,COND *conds,
-+		 uint order_num, ORDER *order, ha_rows limit,
-+		 enum enum_duplicates handle_duplicates, bool ignore);
-+bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
-+                        List<Item> *fields, List<Item> *values,
-+                        COND *conds, ulonglong options,
-+                        enum enum_duplicates handle_duplicates, bool ignore,
-+                        SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex);
-+bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
-+                          List<Item> &fields, List_item *values,
-+                          List<Item> &update_fields,
-+                          List<Item> &update_values, enum_duplicates duplic,
-+                          COND **where, bool select_insert);
-+bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
-+                  List<List_item> &values, List<Item> &update_fields,
-+                  List<Item> &update_values, enum_duplicates flag,
-+                  bool ignore);
-+int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
-+                                           TABLE_LIST *table_list);
-+void mark_fields_used_by_triggers_for_insert_stmt(THD *thd, TABLE *table,
-+                                                  enum_duplicates duplic);
-+bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
-+bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
-+                  SQL_LIST *order, ha_rows rows, ulonglong options,
-+                  bool reset_auto_increment);
-+bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok);
-+bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create);
-+TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
-+TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
-+		  bool *refresh, uint flags);
-+bool reopen_name_locked_table(THD* thd, TABLE_LIST* table);
-+TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
-+bool reopen_table(TABLE *table,bool locked);
-+bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
-+void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
-+			  bool send_refresh);
-+bool close_data_tables(THD *thd,const char *db, const char *table_name);
-+bool wait_for_tables(THD *thd);
-+bool table_is_used(TABLE *table, bool wait_for_name_lock);
-+bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
-+void abort_locked_tables(THD *thd,const char *db, const char *table_name);
-+void execute_init_command(THD *thd, sys_var_str *init_command_var,
-+			  rw_lock_t *var_mutex);
-+extern Field *not_found_field;
-+extern Field *view_ref_found;
-+
-+enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
-+				  IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
-+                                  IGNORE_EXCEPT_NON_UNIQUE};
-+Field *
-+find_field_in_tables(THD *thd, Item_ident *item,
-+                     TABLE_LIST *first_table, TABLE_LIST *last_table,
-+                     Item **ref, find_item_error_report_type report_error,
-+                     bool check_privileges, bool register_tree_change);
-+Field *
-+find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
-+                        const char *name, uint length,
-+                        const char *item_name, const char *db_name,
-+                        const char *table_name, Item **ref,
-+                        bool check_privileges, bool allow_rowid,
-+                        uint *cached_field_index_ptr,
-+                        bool register_tree_change, TABLE_LIST **actual_table);
-+Field *
-+find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
-+                    bool allow_rowid, uint *cached_field_index_ptr);
-+
-+#ifdef HAVE_OPENSSL
-+#include <openssl/des.h>
-+struct st_des_keyblock
-+{
-+  DES_cblock key1, key2, key3;
-+};
-+struct st_des_keyschedule
-+{
-+  DES_key_schedule ks1, ks2, ks3;
-+};
-+extern char *des_key_file;
-+extern struct st_des_keyschedule des_keyschedule[10];
-+extern uint des_default_key;
-+extern pthread_mutex_t LOCK_des_key_file;
-+bool load_des_key_file(const char *file_name);
-+#endif /* HAVE_OPENSSL */
-+
-+/* sql_do.cc */
-+bool mysql_do(THD *thd, List<Item> &values);
-+
-+/* sql_analyse.h */
-+bool append_escaped(String *to_str, String *from_str);
-+
-+/* sql_show.cc */
-+bool mysqld_show_open_tables(THD *thd,const char *wild);
-+bool mysqld_show_logs(THD *thd);
-+void append_identifier(THD *thd, String *packet, const char *name,
-+		       uint length);
-+int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
-+void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
-+int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
-+bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
-+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_storage_engines(THD *thd);
-+bool mysqld_show_privileges(THD *thd);
-+bool mysqld_show_column_types(THD *thd);
-+bool mysqld_help (THD *thd, const char *text);
-+void calc_sum_of_all_status(STATUS_VAR *to);
-+
-+void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
-+                    const LEX_STRING *definer_host);
-+
-+
-+/* information schema */
-+extern LEX_STRING information_schema_name;
-+LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
-+                            const char* str, uint length,
-+                            bool allocate_lex_string);
-+ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name);
-+ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
-+int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
-+                         enum enum_schema_tables schema_table_idx);
-+int make_schema_select(THD *thd,  SELECT_LEX *sel,
-+                       enum enum_schema_tables schema_table_idx);
-+int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list);
-+int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
-+int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
-+int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
-+int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
-+bool get_schema_tables_result(JOIN *join,
-+                              enum enum_schema_table_state executed_place);
-+#define is_schema_db(X) \
-+  !my_strcasecmp(system_charset_info, information_schema_name.str, (X))
-+
-+/* sql_prepare.cc */
-+
-+void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length);
-+void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
-+void mysql_stmt_close(THD *thd, char *packet);
-+void mysql_sql_stmt_prepare(THD *thd);
-+void mysql_sql_stmt_execute(THD *thd);
-+void mysql_sql_stmt_close(THD *thd);
-+void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
-+void mysql_stmt_reset(THD *thd, char *packet);
-+void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
-+void reinit_stmt_before_use(THD *thd, LEX *lex);
-+
-+/* sql_handler.cc */
-+bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
-+bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
-+bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
-+                   List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
-+int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
-+                   bool is_locked);
-+void mysql_ha_mark_tables_for_reopen(THD *thd, TABLE *table);
-+/* mysql_ha_flush mode_flags bits */
-+#define MYSQL_HA_CLOSE_FINAL        0x00
-+#define MYSQL_HA_REOPEN_ON_USAGE    0x01
-+#define MYSQL_HA_FLUSH_ALL          0x02
-+
-+/* sql_base.cc */
-+#define TMP_TABLE_KEY_EXTRA 8
-+void set_item_name(Item *item,char *pos,uint length);
-+bool add_field_to_list(THD *thd, char *field_name, enum enum_field_types type,
-+		       char *length, char *decimal,
-+		       uint type_modifier,
-+		       Item *default_value, Item *on_update_value,
-+		       LEX_STRING *comment,
-+		       char *change, List<String> *interval_list,
-+		       CHARSET_INFO *cs,
-+		       uint uint_geom_type);
-+create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
-+				char *length, char *decimals,
-+				uint type_modifier, 
-+				Item *default_value, Item *on_update_value,
-+				LEX_STRING *comment, char *change, 
-+				List<String> *interval_list, CHARSET_INFO *cs,
-+				uint uint_geom_type);
-+void store_position_for_column(const char *name);
-+bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
-+bool push_new_name_resolution_context(THD *thd,
-+                                      TABLE_LIST *left_op,
-+                                      TABLE_LIST *right_op);
-+void add_join_on(TABLE_LIST *b,Item *expr);
-+void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
-+bool add_proc_to_list(THD *thd, Item *item);
-+TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
-+void update_non_unique_table_error(TABLE_LIST *update,
-+                                   const char *operation,
-+                                   TABLE_LIST *duplicate);
-+
-+SQL_SELECT *make_select(TABLE *head, table_map const_tables,
-+			table_map read_tables, COND *conds,
-+                        bool allow_null_cond,  int *error);
-+extern Item **not_found_item;
-+Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
-+                          find_item_error_report_type report_error,
-+                          bool *unaliased);
-+bool get_key_map_from_key_list(key_map *map, TABLE *table,
-+                               List<String> *index_list);
-+bool insert_fields(THD *thd, Name_resolution_context *context,
-+		   const char *db_name, const char *table_name,
-+                   List_iterator<Item> *it, bool any_privileges);
-+bool setup_tables(THD *thd, Name_resolution_context *context,
-+                  List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
-+                  Item **conds, TABLE_LIST **leaves, bool select_insert);
-+bool setup_tables_and_check_access (THD *thd, 
-+                                    Name_resolution_context *context,
-+                                    List<TABLE_LIST> *from_clause, 
-+                                    TABLE_LIST *tables, Item **conds, 
-+                                    TABLE_LIST **leaves, 
-+                                    bool select_insert,
-+                                    ulong want_access_first,
-+                                    ulong want_access);
-+int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
-+	       List<Item> *sum_func_list, uint wild_num);
-+bool setup_fields(THD *thd, Item** ref_pointer_array,
-+                  List<Item> &item, bool set_query_id,
-+                  List<Item> *sum_func_list, bool allow_sum_func);
-+inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
-+                                     List<Item> &item, bool set_query_id,
-+                                     List<Item> *sum_func_list,
-+                                     bool allow_sum_func)
-+{
-+  bool res;
-+  thd->lex->select_lex.no_wrap_view_item= TRUE;
-+  res= setup_fields(thd, ref_pointer_array, item, set_query_id, sum_func_list,
-+                    allow_sum_func);
-+  thd->lex->select_lex.no_wrap_view_item= FALSE;
-+  return res;
-+}
-+int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
-+		COND **conds);
-+int setup_ftfuncs(SELECT_LEX* select);
-+int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
-+void wait_for_refresh(THD *thd);
-+int open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags);
-+int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
-+bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
-+bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
-+int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
-+TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
-+			    const char *table_name, bool link_in_list);
-+bool rm_temporary_table(enum db_type base, char *path);
-+void free_io_cache(TABLE *entry);
-+void intern_close_table(TABLE *entry);
-+bool close_thread_table(THD *thd, TABLE **table_ptr);
-+void close_temporary_tables(THD *thd);
-+void close_tables_for_reopen(THD *thd, TABLE_LIST **tables);
-+TABLE_LIST *find_table_in_list(TABLE_LIST *table,
-+                               st_table_list *TABLE_LIST::*link,
-+                               const char *db_name,
-+                               const char *table_name);
-+TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list);
-+TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
-+bool close_temporary_table(THD *thd, const char *db, const char *table_name);
-+void close_temporary(TABLE *table, bool delete_table);
-+bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
-+			    const char *table_name);
-+void remove_db_from_cache(const char *db);
-+void flush_tables();
-+bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
-+
-+/* bits for last argument to remove_table_from_cache() */
-+#define RTFC_NO_FLAG                0x0000
-+#define RTFC_OWNED_BY_THD_FLAG      0x0001
-+#define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
-+#define RTFC_CHECK_KILLED_FLAG      0x0004
-+bool remove_table_from_cache(THD *thd, const char *db, const char *table,
-+                             uint flags);
-+
-+bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
-+void copy_field_from_tmp_record(Field *field,int offset);
-+bool fill_record(THD *thd, Field **field, List<Item> &values,
-+                 bool ignore_errors);
-+bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
-+                                          List<Item> &values,
-+                                          bool ignore_errors,
-+                                          Table_triggers_list *triggers,
-+                                          enum trg_event_type event);
-+bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
-+                                          List<Item> &values,
-+                                          bool ignore_errors,
-+                                          Table_triggers_list *triggers,
-+                                          enum trg_event_type event);
-+OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
-+
-+inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
-+                                             const char *db_name,
-+                                             const char *table_name)
-+{
-+  return find_table_in_list(table, &TABLE_LIST::next_global,
-+                            db_name, table_name);
-+}
-+
-+inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
-+                                            const char *db_name,
-+                                            const char *table_name)
-+{
-+  return find_table_in_list(table, &TABLE_LIST::next_local,
-+                            db_name, table_name);
-+}
-+
-+
-+/* sql_calc.cc */
-+bool eval_const_cond(COND *cond);
-+
-+/* sql_load.cc */
-+bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
-+	        List<Item> &fields_vars, List<Item> &set_fields,
-+                List<Item> &set_values_list,
-+                enum enum_duplicates handle_duplicates, bool ignore,
-+                bool local_file);
-+int write_record(THD *thd, TABLE *table, COPY_INFO *info);
-+
-+/* sql_manager.cc */
-+/* bits set in manager_status */
-+#define MANAGER_BERKELEY_LOG_CLEANUP    (1L << 0)
-+extern ulong volatile manager_status;
-+extern bool volatile manager_thread_in_use, mqh_used;
-+extern pthread_t manager_thread;
-+pthread_handler_t handle_manager(void *arg);
-+
-+/* sql_test.cc */
-+#ifndef DBUG_OFF
-+void print_where(COND *cond,const char *info);
-+void print_cached_tables(void);
-+void TEST_filesort(SORT_FIELD *sortorder,uint s_length);
-+void print_plan(JOIN* join,uint idx, double record_count, double read_time,
-+                double current_read_time, const char *info);
-+#endif
-+void mysql_print_status();
-+/* key.cc */
-+int find_ref_key(TABLE *form,Field *field, uint *offset);
-+void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
-+void key_restore(byte *to_record, byte *from_key, KEY *key_info,
-+                 uint key_length);
-+bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length);
-+void key_unpack(String *to,TABLE *form,uint index);
-+bool is_key_used(TABLE *table, uint idx, List<Item> &fields);
-+int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length);
-+
-+bool init_errmessage(void);
-+void sql_perror(const char *message);
-+
-+void vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-+void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
-+void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
-+void sql_print_information(const char *format, ...)
-+  ATTRIBUTE_FORMAT(printf, 1, 2);
-+
-+
-+bool fn_format_relative_to_data_home(my_string to, const char *name,
-+				     const char *dir, const char *extension);
-+File open_binlog(IO_CACHE *log, const char *log_file_name,
-+                 const char **errmsg);
-+
-+/* mysqld.cc */
-+extern void MYSQLerror(const char*);
-+void refresh_status(THD *thd);
-+
-+/* item_func.cc */
-+extern bool check_reserved_words(LEX_STRING *name);
-+
-+/* strfunc.cc */
-+ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
-+		   char **err_pos, uint *err_len, bool *set_warning);
-+uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
-+uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
-+void unhex_type2(TYPELIB *lib);
-+uint check_word(TYPELIB *lib, const char *val, const char *end,
-+		const char **end_of_word);
-+
-+
-+bool is_keyword(const char *name, uint len);
-+
-+#define MY_DB_OPT_FILE "db.opt"
-+bool check_db_dir_existence(const char *db_name);
-+bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
-+bool load_db_opt_by_name(THD *thd, const char *db_name,
-+                         HA_CREATE_INFO *db_create_info);
-+bool my_dbopt_init(void);
-+void my_dbopt_cleanup(void);
-+void my_dbopt_free(void);
-+
-+/*
-+  External variables
-+*/
-+
-+extern time_t start_time;
-+extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
-+	    mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
-+            def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
-+#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
-+extern MY_TMPDIR mysql_tmpdir_list;
-+extern const char *command_name[];
-+extern const char *first_keyword, *my_localhost, *delayed_user, *binary_keyword;
-+extern const char **errmesg;			/* Error messages */
-+extern const char *myisam_recover_options_str;
-+extern const char *in_left_expr_name, *in_additional_cond;
-+extern const char * const triggers_file_ext;
-+extern const char * const trigname_file_ext;
-+extern Eq_creator eq_creator;
-+extern Ne_creator ne_creator;
-+extern Gt_creator gt_creator;
-+extern Lt_creator lt_creator;
-+extern Ge_creator ge_creator;
-+extern Le_creator le_creator;
-+extern char language[FN_REFLEN], reg_ext[FN_EXTLEN];
-+extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
-+extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
-+extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
-+extern double log_10[32];
-+extern ulonglong log_10_int[20];
-+extern ulonglong keybuff_size;
-+extern ulonglong thd_startup_options;
-+extern ulong refresh_version,flush_version, thread_id;
-+extern ulong binlog_cache_use, binlog_cache_disk_use;
-+extern ulong aborted_threads,aborted_connects;
-+extern ulong delayed_insert_timeout;
-+extern ulong delayed_insert_limit, delayed_queue_size;
-+extern ulong delayed_insert_threads, delayed_insert_writes;
-+extern ulong delayed_rows_in_use,delayed_insert_errors;
-+extern ulong slave_open_temp_tables;
-+extern ulong query_cache_size, query_cache_min_res_unit;
-+extern ulong slow_launch_threads, slow_launch_time;
-+extern ulong table_cache_size;
-+extern ulong max_connections,max_connect_errors, connect_timeout;
-+extern ulong slave_net_timeout, slave_trans_retries;
-+extern uint max_user_connections;
-+extern ulong what_to_log,flush_time;
-+extern ulong query_buff_size, thread_stack;
-+extern ulong max_prepared_stmt_count, prepared_stmt_count;
-+extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
-+extern ulong max_binlog_size, max_relay_log_size;
-+extern ulong rpl_recovery_rank, thread_cache_size;
-+extern ulong back_log;
-+extern ulong specialflag, current_pid;
-+extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
-+extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size;
-+extern ulong tc_log_page_waits;
-+extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
-+extern uint test_flags,select_errors,ha_open_options;
-+extern uint protocol_version, mysqld_port, dropping_tables;
-+extern uint delay_key_write_options, lower_case_table_names;
-+extern bool opt_endinfo, using_udf_functions;
-+extern my_bool locked_in_memory;
-+extern bool opt_using_transactions, mysqld_embedded;
-+extern bool using_update_log, opt_large_files, server_id_supplied;
-+extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
-+extern my_bool opt_log_queries_not_using_indexes;
-+extern bool opt_disable_networking, opt_skip_show_db;
-+extern my_bool opt_character_set_client_handshake;
-+extern bool volatile abort_loop, shutdown_in_progress, grant_option;
-+extern uint volatile thread_count, thread_running, global_read_lock;
-+extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
-+extern my_bool opt_safe_show_db, opt_local_infile;
-+extern my_bool opt_slave_compressed_protocol, use_temp_pool;
-+extern my_bool opt_readonly, lower_case_file_system;
-+extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
-+extern my_bool opt_secure_auth;
-+extern my_bool opt_log_slow_admin_statements;
-+extern my_bool sp_automatic_privileges, opt_noacl;
-+extern my_bool opt_old_style_user_limits, trust_function_creators;
-+extern uint opt_crash_binlog_innodb;
-+extern char *shared_memory_base_name, *mysqld_unix_port;
-+extern my_bool opt_enable_shared_memory;
-+extern char *default_tz_name;
-+extern my_bool opt_large_pages;
-+extern uint opt_large_page_size;
-+
-+extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
-+extern FILE *bootstrap_file;
-+extern int bootstrap_error;
-+extern FILE *stderror_file;
-+extern pthread_key(MEM_ROOT**,THR_MALLOC);
-+extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
-+       LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
-+       LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
-+       LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
-+       LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock,
-+       LOCK_global_system_variables, LOCK_user_conn,
-+       LOCK_prepared_stmt_count,
-+       LOCK_bytes_sent, LOCK_bytes_received;
-+#ifdef HAVE_OPENSSL
-+extern pthread_mutex_t LOCK_des_key_file;
-+#endif
-+extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
-+extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
-+extern pthread_cond_t COND_global_read_lock;
-+extern pthread_attr_t connection_attrib;
-+extern I_List<THD> threads;
-+extern I_List<NAMED_LIST> key_caches;
-+extern MY_BITMAP temp_pool;
-+extern String my_empty_string;
-+extern const String my_null_string;
-+extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
-+extern struct system_variables global_system_variables;
-+extern struct system_variables max_system_variables;
-+extern struct system_status_var global_status_var;
-+extern struct rand_struct sql_rand;
-+
-+extern const char *opt_date_time_formats[];
-+extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
-+
-+extern String null_string;
-+extern HASH open_cache;
-+extern TABLE *unused_tables;
-+extern I_List<i_string> binlog_do_db, binlog_ignore_db;
-+extern const char* any_db;
-+extern struct my_option my_long_options[];
-+extern const LEX_STRING view_type;
-+
-+/* optional things, have_* variables */
-+
-+#ifdef HAVE_INNOBASE_DB
-+extern handlerton innobase_hton;
-+#define have_innodb innobase_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_innodb;
-+#endif
-+#ifdef HAVE_BERKELEY_DB
-+extern handlerton berkeley_hton;
-+#define have_berkeley_db berkeley_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_berkeley_db;
-+#endif
-+#ifdef HAVE_EXAMPLE_DB
-+extern handlerton example_hton;
-+#define have_example_db example_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_example_db;
-+#endif
-+#ifdef HAVE_ARCHIVE_DB
-+extern handlerton archive_hton;
-+#define have_archive_db archive_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_archive_db;
-+#endif
-+#ifdef HAVE_CSV_DB
-+extern handlerton tina_hton;
-+#define have_csv_db tina_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_csv_db;
-+#endif
-+#ifdef HAVE_FEDERATED_DB
-+extern handlerton federated_hton;
-+#define have_federated_db federated_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_federated_db;
-+#endif
-+#ifdef HAVE_BLACKHOLE_DB
-+extern handlerton blackhole_hton;
-+#define have_blackhole_db blackhole_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_blackhole_db;
-+#endif
-+#ifdef HAVE_NDBCLUSTER_DB
-+extern handlerton ndbcluster_hton;
-+#define have_ndbcluster ndbcluster_hton.state
-+#else
-+extern SHOW_COMP_OPTION have_ndbcluster;
-+#endif
-+
-+/* MRG_MYISAM handler is always built, but may be skipped */
-+extern handlerton myisammrg_hton;
-+#define have_merge_db myisammrg_hton.state
-+
-+extern SHOW_COMP_OPTION have_isam;
-+extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_dlopen;
-+extern SHOW_COMP_OPTION have_query_cache;
-+extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
-+extern SHOW_COMP_OPTION have_crypt;
-+extern SHOW_COMP_OPTION have_compress;
-+
-+#ifndef __WIN__
-+extern pthread_t signal_thread;
-+#endif
-+
-+#ifdef HAVE_OPENSSL
-+extern struct st_VioSSLFd * ssl_acceptor_fd;
-+#endif /* HAVE_OPENSSL */
-+
-+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
-+                              uint flags, bool *need_reopen);
-+/* mysql_lock_tables() and open_table() flags bits */
-+#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK      0x0001
-+#define MYSQL_LOCK_IGNORE_FLUSH                 0x0002
-+#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN        0x0004
-+#define MYSQL_OPEN_IGNORE_LOCKED_TABLES         0x0008
-+
-+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
-+void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
-+void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
-+void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
-+void mysql_lock_abort(THD *thd, TABLE *table);
-+bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
-+MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
-+TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
-+                                      TABLE_LIST *haystack);
-+bool lock_global_read_lock(THD *thd);
-+void unlock_global_read_lock(THD *thd);
-+bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
-+                              bool is_not_commit);
-+void start_waiting_global_read_lock(THD *thd);
-+bool make_global_read_lock_block_commit(THD *thd);
-+bool set_protect_against_global_read_lock(void);
-+void unset_protect_against_global_read_lock(void);
-+void broadcast_refresh(void);
-+
-+/* Lock based on name */
-+int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
-+int lock_table_name(THD *thd, TABLE_LIST *table_list);
-+void unlock_table_name(THD *thd, TABLE_LIST *table_list);
-+bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
-+bool lock_table_names(THD *thd, TABLE_LIST *table_list);
-+void unlock_table_names(THD *thd, TABLE_LIST *table_list,
-+			TABLE_LIST *last_table);
-+
-+
-+/* old unireg functions */
-+
-+void unireg_init(ulong options);
-+void unireg_end(void);
-+bool mysql_create_frm(THD *thd, my_string file_name,
-+                      const char *db, const char *table,
-+		      HA_CREATE_INFO *create_info,
-+		      List<create_field> &create_field,
-+		      uint key_count,KEY *key_info,handler *db_type);
-+int rea_create_table(THD *thd, my_string file_name,
-+                     const char *db, const char *table,
-+                     HA_CREATE_INFO *create_info,
-+		     List<create_field> &create_field,
-+		     uint key_count,KEY *key_info);
-+int format_number(uint inputflag,uint max_length,my_string pos,uint length,
-+		  my_string *errpos);
-+int openfrm(THD *thd, const char *name,const char *alias,uint filestat,
-+            uint prgflag, uint ha_open_flags, TABLE *outparam);
-+int readfrm(const char *name, const void** data, uint* length);
-+int writefrm(const char* name, const void* data, uint len);
-+int closefrm(TABLE *table);
-+int read_string(File file, gptr *to, uint length);
-+void free_blobs(TABLE *table);
-+int set_zone(int nr,int min_zone,int max_zone);
-+ulong convert_period_to_month(ulong period);
-+ulong convert_month_to_period(ulong month);
-+void get_date_from_daynr(long daynr,uint *year, uint *month,
-+			 uint *day);
-+my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *not_exist);
-+bool str_to_time_with_warn(const char *str,uint length,TIME *l_time);
-+timestamp_type str_to_datetime_with_warn(const char *str, uint length,
-+                                         TIME *l_time, uint flags);
-+void localtime_to_TIME(TIME *to, struct tm *from);
-+void calc_time_from_sec(TIME *to, long seconds, long microseconds);
-+
-+void make_truncated_value_warning(THD *thd, const char *str_val,
-+				  uint str_length, timestamp_type time_type,
-+                                  const char *field_name);
-+extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
-+					       const char *format_str,
-+					       uint format_length);
-+extern DATE_TIME_FORMAT *date_time_format_copy(THD *thd,
-+					       DATE_TIME_FORMAT *format);
-+const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
-+				     timestamp_type type);
-+extern bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
-+			   timestamp_type type, String *str);
-+void make_datetime(const DATE_TIME_FORMAT *format, const TIME *l_time,
-+                   String *str);
-+void make_date(const DATE_TIME_FORMAT *format, const TIME *l_time,
-+               String *str);
-+void make_time(const DATE_TIME_FORMAT *format, const TIME *l_time,
-+               String *str);
-+
-+int test_if_number(char *str,int *res,bool allow_wildcards);
-+void change_byte(byte *,uint,char,char);
-+void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
-+		      SQL_SELECT *select,
-+		      int use_record_cache, bool print_errors);
-+void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, 
-+                          bool print_error, uint idx);
-+void end_read_record(READ_RECORD *info);
-+ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
-+		 uint s_length, SQL_SELECT *select,
-+		 ha_rows max_rows, ha_rows *examined_rows);
-+void filesort_free_buffers(TABLE *table, bool full);
-+void change_double_for_sort(double nr,byte *to);
-+double my_double_round(double value, int dec, bool truncate);
-+int get_quick_record(SQL_SELECT *select);
-+int calc_weekday(long daynr,bool sunday_first_day_of_week);
-+uint calc_week(TIME *l_time, uint week_behaviour, uint *year);
-+void find_date(char *pos,uint *vek,uint flag);
-+TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
-+TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings);
-+ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
-+ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
-+		     const char *newname);
-+ulong next_io_size(ulong pos);
-+void append_unescaped(String *res, const char *pos, uint length);
-+int create_frm(THD *thd, char *name, const char *db, const char *table,
-+               uint reclength,uchar *fileinfo,
-+	       HA_CREATE_INFO *create_info, uint keys);
-+void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
-+int rename_file_ext(const char * from,const char * to,const char * ext);
-+bool check_db_name(char *db);
-+bool check_column_name(const char *name);
-+bool check_table_name(const char *name, uint length);
-+char *get_field(MEM_ROOT *mem, Field *field);
-+bool get_field(MEM_ROOT *mem, Field *field, class String *res);
-+int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
-+
-+/* from hostname.cc */
-+struct in_addr;
-+my_string ip_to_hostname(struct in_addr *in,uint *errors);
-+void inc_host_errors(struct in_addr *in);
-+void reset_host_errors(struct in_addr *in);
-+bool hostname_cache_init();
-+void hostname_cache_free();
-+void hostname_cache_refresh(void);
-+
-+/* sql_cache.cc */
-+extern bool sql_cache_init();
-+extern void sql_cache_free();
-+extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
-+
-+/* item_func.cc */
-+Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
-+		     LEX_STRING component);
-+int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
-+                        LEX_STRING &name, user_var_entry **out_entry);
-+/* log.cc */
-+bool flush_error_log(void);
-+
-+/* sql_list.cc */
-+void free_list(I_List <i_string_pair> *list);
-+void free_list(I_List <i_string> *list);
-+
-+/* sql_yacc.cc */
-+extern int MYSQLparse(void *thd);
-+#ifndef DBUG_OFF
-+extern void turn_parser_debug_on();
-+#endif
-+
-+/* frm_crypt.cc */
-+#ifdef HAVE_CRYPTED_FRM
-+SQL_CRYPT *get_crypt_for_frm(void);
-+#endif
-+
-+#include "sql_view.h"
-+
-+/* Some inline functions for more speed */
-+
-+inline bool add_item_to_list(THD *thd, Item *item)
-+{
-+  return thd->lex->current_select->add_item_to_list(thd, item);
-+}
-+
-+inline bool add_value_to_list(THD *thd, Item *value)
-+{
-+  return thd->lex->value_list.push_back(value);
-+}
-+
-+inline bool add_order_to_list(THD *thd, Item *item, bool asc)
-+{
-+  return thd->lex->current_select->add_order_to_list(thd, item, asc);
-+}
-+
-+inline bool add_group_to_list(THD *thd, Item *item, bool asc)
-+{
-+  return thd->lex->current_select->add_group_to_list(thd, item, asc);
-+}
-+
-+inline void mark_as_null_row(TABLE *table)
-+{
-+  table->null_row=1;
-+  table->status|=STATUS_NULL_ROW;
-+  bfill(table->null_flags,table->s->null_bytes,255);
-+}
-+
-+inline void table_case_convert(char * name, uint length)
-+{
-+  if (lower_case_table_names)
-+    files_charset_info->cset->casedn(files_charset_info,
-+                                     name, length, name, length);
-+}
-+
-+inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
-+{
-+  return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
-+}
-+
-+inline ulong sql_rnd_with_mutex()
-+{
-+  pthread_mutex_lock(&LOCK_thread_count);
-+  ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
-+  pthread_mutex_unlock(&LOCK_thread_count);
-+  return tmp;
-+}
-+
-+Comp_creator *comp_eq_creator(bool invert);
-+Comp_creator *comp_ge_creator(bool invert);
-+Comp_creator *comp_gt_creator(bool invert);
-+Comp_creator *comp_le_creator(bool invert);
-+Comp_creator *comp_lt_creator(bool invert);
-+Comp_creator *comp_ne_creator(bool invert);
-+
-+Item * all_any_subquery_creator(Item *left_expr,
-+				chooser_compare_func_creator cmp,
-+				bool all,
-+				SELECT_LEX *select_lex);
-+
-+/*
-+  clean/setup table fields and map
-+
-+  SYNOPSYS
-+    setup_table_map()
-+    table - TABLE structure pointer (which should be setup)
-+    table_list TABLE_LIST structure pointer (owner of TABLE)
-+    tablenr - table number
-+*/
-+
-+inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
-+{
-+  table->used_fields= 0;
-+  table->const_table= 0;
-+  table->null_row= 0;
-+  table->status= STATUS_NO_RECORD;
-+  table->keys_in_use_for_query= table->s->keys_in_use;
-+  table->maybe_null= table_list->outer_join;
-+  TABLE_LIST *embedding= table_list->embedding;
-+  while (!table->maybe_null && embedding)
-+  {
-+    table->maybe_null= embedding->outer_join;
-+    embedding= embedding->embedding;
-+  }
-+  table->tablenr= tablenr;
-+  table->map= (table_map) 1 << tablenr;
-+  table->force_index= table_list->force_index;
-+}
-+
-+
-+/*
-+  SYNOPSYS
-+    hexchar_to_int()
-+    convert a hex digit into number
-+*/
-+
-+inline int hexchar_to_int(char c)
-+{
-+  if (c <= '9' && c >= '0')
-+    return c-'0';
-+  c|=32;
-+  if (c <= 'f' && c >= 'a')
-+    return c-'a'+10;
-+  return -1;
-+}
-+
-+/*
-+  is_user_table()
-+  return true if the table was created explicitly
-+*/
-+
-+inline bool is_user_table(TABLE * table)
-+{
-+  const char *name= table->s->table_name;
-+  return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
-+}
-+
-+/*
-+  Some functions that are different in the embedded library and the normal
-+  server
-+*/
-+
-+#ifndef EMBEDDED_LIBRARY
-+extern "C" void unireg_abort(int exit_code);
-+void kill_delayed_threads(void);
-+bool check_stack_overrun(THD *thd, long margin, char *dummy);
-+#else
-+#define unireg_abort(exit_code) DBUG_RETURN(exit_code)
-+inline void kill_delayed_threads(void) {}
-+#define check_stack_overrun(A, B, C) 0
-+#endif
-+
-+#endif /* MYSQL_CLIENT */
 diff -urNad mysql-5.0-etch~/sql/sql_parse.cc mysql-5.0-etch/sql/sql_parse.cc
 --- mysql-5.0-etch~/sql/sql_parse.cc	2007-05-28 18:56:15.000000000 +0200
 +++ mysql-5.0-etch/sql/sql_parse.cc	2007-05-28 19:12:52.000000000 +0200
@@ -1934,7582 +245,6 @@
          (tables->table && (int)tables->table->s->tmp_table) ||
          my_tz_check_n_skip_implicit_tables(&tables,
                                             thd->lex->time_zone_tables_used))
-diff -urNad mysql-5.0-etch~/sql/sql_parse.cc.orig mysql-5.0-etch/sql/sql_parse.cc.orig
---- mysql-5.0-etch~/sql/sql_parse.cc.orig	1970-01-01 01:00:00.000000000 +0100
-+++ mysql-5.0-etch/sql/sql_parse.cc.orig	2007-05-28 18:56:15.000000000 +0200
-@@ -0,0 +1,7572 @@
-+/* Copyright (C) 2000-2003 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2 of the License, or
-+   (at your option) any later version.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#define MYSQL_LEX 1
-+#include "mysql_priv.h"
-+#include "sql_repl.h"
-+#include "repl_failsafe.h"
-+#include <m_ctype.h>
-+#include <myisam.h>
-+#include <my_dir.h>
-+
-+#ifdef HAVE_INNOBASE_DB
-+#include "ha_innodb.h"
-+#endif
-+
-+#ifdef HAVE_NDBCLUSTER_DB
-+#include "ha_ndbcluster.h"
-+#endif
-+
-+#include "sp_head.h"
-+#include "sp.h"
-+#include "sp_cache.h"
-+
-+#ifdef HAVE_OPENSSL
-+/*
-+  Without SSL the handshake consists of one packet. This packet
-+  has both client capabilites and scrambled password.
-+  With SSL the handshake might consist of two packets. If the first
-+  packet (client capabilities) has CLIENT_SSL flag set, we have to
-+  switch to SSL and read the second packet. The scrambled password
-+  is in the second packet and client_capabilites field will be ignored.
-+  Maybe it is better to accept flags other than CLIENT_SSL from the
-+  second packet?
-+*/
-+#define SSL_HANDSHAKE_SIZE      2
-+#define NORMAL_HANDSHAKE_SIZE   6
-+#define MIN_HANDSHAKE_SIZE      2
-+#else
-+#define MIN_HANDSHAKE_SIZE      6
-+#endif /* HAVE_OPENSSL */
-+
-+/* Used in error handling only */
-+#define SP_TYPE_STRING(LP) \
-+  ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
-+#define SP_COM_STRING(LP) \
-+  ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
-+   (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
-+   (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
-+   (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
-+   "FUNCTION" : "PROCEDURE")
-+
-+#ifdef SOLARIS
-+extern "C" int gethostname(char *name, int namelen);
-+#endif
-+
-+static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
-+static void decrease_user_connections(USER_CONN *uc);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+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 append_file_to_dir(THD *thd, const char **filename_ptr,
-+			       const char *table_name);
-+
-+const char *any_db="*any*";	// Special symbol for check_access
-+
-+const char *command_name[]={
-+  "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB",
-+  "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist",
-+  "Connect","Kill","Debug","Ping","Time","Delayed insert","Change user",
-+  "Binlog Dump","Table Dump",  "Connect Out", "Register Slave",
-+  "Prepare", "Execute", "Long Data", "Close stmt",
-+  "Reset stmt", "Set option", "Fetch",
-+  "Error"					// Last command number
-+};
-+
-+const char *xa_state_names[]={
-+  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
-+};
-+
-+#ifdef __WIN__
-+static void  test_signal(int sig_ptr)
-+{
-+#if !defined( DBUG_OFF)
-+  MessageBox(NULL,"Test signal","DBUG",MB_OK);
-+#endif
-+#if defined(OS2)
-+  fprintf(stderr, "Test signal %d\n", sig_ptr);
-+  fflush(stderr);
-+#endif
-+}
-+static void init_signals(void)
-+{
-+  int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
-+  for (int i=0 ; i < 7 ; i++)
-+    signal( signals[i], test_signal) ;
-+}
-+#endif
-+
-+static void unlock_locked_tables(THD *thd)
-+{
-+  if (thd->locked_tables)
-+  {
-+    thd->lock=thd->locked_tables;
-+    thd->locked_tables=0;			// Will be automatically closed
-+    close_thread_tables(thd);			// Free tables
-+  }
-+}
-+
-+
-+static bool end_active_trans(THD *thd)
-+{
-+  int error=0;
-+  DBUG_ENTER("end_active_trans");
-+  if (unlikely(thd->in_sub_stmt))
-+  {
-+    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+    DBUG_RETURN(1);
-+  }
-+  if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+  {
-+    my_error(ER_XAER_RMFAIL, MYF(0),
-+             xa_state_names[thd->transaction.xid_state.xa_state]);
-+    DBUG_RETURN(1);
-+  }
-+  if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
-+		      OPTION_TABLE_LOCK))
-+  {
-+    DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options));
-+    /* Safety if one did "drop table" on locked tables */
-+    if (!thd->locked_tables)
-+      thd->options&= ~OPTION_TABLE_LOCK;
-+    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+    if (ha_commit(thd))
-+      error=1;
-+    thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
-+  }
-+  DBUG_RETURN(error);
-+}
-+
-+static bool begin_trans(THD *thd)
-+{
-+  int error=0;
-+  if (unlikely(thd->in_sub_stmt))
-+  {
-+    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+    return 1;
-+  }
-+  if (thd->locked_tables)
-+  {
-+    thd->lock=thd->locked_tables;
-+    thd->locked_tables=0;			// Will be automatically closed
-+    close_thread_tables(thd);			// Free tables
-+  }
-+  if (end_active_trans(thd))
-+    error= -1;
-+  else
-+  {
-+    LEX *lex= thd->lex;
-+    thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
-+		   OPTION_BEGIN);
-+    thd->server_status|= SERVER_STATUS_IN_TRANS;
-+    if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
-+      error= ha_start_consistent_snapshot(thd);
-+  }
-+  return error;
-+}
-+
-+#ifdef HAVE_REPLICATION
-+/*
-+  Returns true if all tables should be ignored
-+*/
-+inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
-+{
-+  return table_rules_on && tables && !tables_ok(thd,tables);
-+}
-+#endif
-+
-+
-+static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
-+{
-+  for (TABLE_LIST *table= tables; table; table= table->next_global)
-+  {
-+    DBUG_ASSERT(table->db && table->table_name);
-+    if (table->updating &&
-+        !find_temporary_table(thd, table->db, table->table_name))
-+      return 1;
-+  }
-+  return 0;
-+}
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static HASH hash_user_connections;
-+
-+static int get_or_create_user_conn(THD *thd, const char *user,
-+				   const char *host,
-+				   USER_RESOURCES *mqh)
-+{
-+  int return_val= 0;
-+  uint temp_len, user_len;
-+  char temp_user[USER_HOST_BUFF_SIZE];
-+  struct  user_conn *uc;
-+
-+  DBUG_ASSERT(user != 0);
-+  DBUG_ASSERT(host != 0);
-+
-+  user_len= strlen(user);
-+  temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
-+  (void) pthread_mutex_lock(&LOCK_user_conn);
-+  if (!(uc = (struct  user_conn *) hash_search(&hash_user_connections,
-+					       (byte*) temp_user, temp_len)))
-+  {
-+    /* First connection for user; Create a user connection object */
-+    if (!(uc= ((struct user_conn*)
-+	       my_malloc(sizeof(struct user_conn) + temp_len+1,
-+			 MYF(MY_WME)))))
-+    {
-+      net_send_error(thd, 0, NullS);		// Out of memory
-+      return_val= 1;
-+      goto end;
-+    }
-+    uc->user=(char*) (uc+1);
-+    memcpy(uc->user,temp_user,temp_len+1);
-+    uc->host= uc->user + user_len +  1;
-+    uc->len= temp_len;
-+    uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
-+    uc->user_resources= *mqh;
-+    uc->intime= thd->thr_create_time;
-+    if (my_hash_insert(&hash_user_connections, (byte*) uc))
-+    {
-+      my_free((char*) uc,0);
-+      net_send_error(thd, 0, NullS);		// Out of memory
-+      return_val= 1;
-+      goto end;
-+    }
-+  }
-+  thd->user_connect=uc;
-+  uc->connections++;
-+end:
-+  (void) pthread_mutex_unlock(&LOCK_user_conn);
-+  return return_val;
-+
-+}
-+#endif /* !NO_EMBEDDED_ACCESS_CHECKS */
-+
-+
-+/*
-+  Check if user exist and password supplied is correct. 
-+
-+  SYNOPSIS
-+    check_user()
-+    thd          thread handle, thd->security_ctx->{host,user,ip} are used
-+    command      originator of the check: now check_user is called
-+                 during connect and change user procedures; used for 
-+                 logging.
-+    passwd       scrambled password received from client
-+    passwd_len   length of scrambled password
-+    db           database name to connect to, may be NULL
-+    check_count  dont know exactly
-+
-+    Note, that host, user and passwd may point to communication buffer.
-+    Current implementation does not depend on that, but future changes
-+    should be done with this in mind; 'thd' is INOUT, all other params
-+    are 'IN'.
-+
-+  RETURN VALUE
-+    0  OK; thd->security_ctx->user/master_access/priv_user/db_access and
-+       thd->db are updated; OK is sent to client;
-+   -1  access denied or handshake error; error is sent to client;
-+   >0  error, not sent to client
-+*/
-+
-+int check_user(THD *thd, enum enum_server_command command, 
-+	       const char *passwd, uint passwd_len, const char *db,
-+	       bool check_count)
-+{
-+  DBUG_ENTER("check_user");
-+  
-+#ifdef NO_EMBEDDED_ACCESS_CHECKS
-+  thd->main_security_ctx.master_access= GLOBAL_ACLS;       // Full rights
-+  /* Change database if necessary */
-+  if (db && db[0])
-+  {
-+    /*
-+      thd->db is saved in caller and needs to be freed by caller if this
-+      function returns 0
-+    */
-+    thd->reset_db(NULL, 0);
-+    if (mysql_change_db(thd, db, FALSE))
-+    {
-+      /* Send the error to the client */
-+      net_send_error(thd);
-+      DBUG_RETURN(-1);
-+    }
-+  }
-+  send_ok(thd);
-+  DBUG_RETURN(0);
-+#else
-+
-+  my_bool opt_secure_auth_local;
-+  pthread_mutex_lock(&LOCK_global_system_variables);
-+  opt_secure_auth_local= opt_secure_auth;
-+  pthread_mutex_unlock(&LOCK_global_system_variables);
-+  
-+  /*
-+    If the server is running in secure auth mode, short scrambles are 
-+    forbidden.
-+  */
-+  if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
-+  {
-+    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
-+    mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-+    DBUG_RETURN(-1);
-+  }
-+  if (passwd_len != 0 &&
-+      passwd_len != SCRAMBLE_LENGTH &&
-+      passwd_len != SCRAMBLE_LENGTH_323)
-+    DBUG_RETURN(ER_HANDSHAKE_ERROR);
-+
-+  /*
-+    Clear thd->db as it points to something, that will be freed when 
-+    connection is closed. We don't want to accidentally free a wrong pointer
-+    if connect failed. Also in case of 'CHANGE USER' failure, current
-+    database will be switched to 'no database selected'.
-+  */
-+  thd->reset_db(NULL, 0);
-+
-+  USER_RESOURCES ur;
-+  int res= acl_getroot(thd, &ur, passwd, passwd_len);
-+#ifndef EMBEDDED_LIBRARY
-+  if (res == -1)
-+  {
-+    /*
-+      This happens when client (new) sends password scrambled with
-+      scramble(), but database holds old value (scrambled with
-+      scramble_323()). Here we please client to send scrambled_password
-+      in old format.
-+    */
-+    NET *net= &thd->net;
-+    if (opt_secure_auth_local)
-+    {
-+      net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
-+                       thd->main_security_ctx.user,
-+                       thd->main_security_ctx.host_or_ip);
-+      mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
-+                      thd->main_security_ctx.user,
-+                      thd->main_security_ctx.host_or_ip);
-+      DBUG_RETURN(-1);
-+    }
-+    /* We have to read very specific packet size */
-+    if (send_old_password_request(thd) ||
-+        my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
-+    {
-+      inc_host_errors(&thd->remote.sin_addr);
-+      DBUG_RETURN(ER_HANDSHAKE_ERROR);
-+    }
-+    /* Final attempt to check the user based on reply */
-+    /* So as passwd is short, errcode is always >= 0 */
-+    res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
-+  }
-+#endif /*EMBEDDED_LIBRARY*/
-+  /* here res is always >= 0 */
-+  if (res == 0)
-+  {
-+    if (!(thd->main_security_ctx.master_access &
-+          NO_ACCESS)) // authentication is OK
-+    {
-+      DBUG_PRINT("info",
-+                 ("Capabilities: %lu  packet_length: %ld  Host: '%s'  "
-+                  "Login user: '%s' Priv_user: '%s'  Using password: %s "
-+                  "Access: %lu  db: '%s'",
-+                  thd->client_capabilities,
-+                  thd->max_client_packet_length,
-+                  thd->main_security_ctx.host_or_ip,
-+                  thd->main_security_ctx.user,
-+                  thd->main_security_ctx.priv_user,
-+                  passwd_len ? "yes": "no",
-+                  thd->main_security_ctx.master_access,
-+                  (thd->db ? thd->db : "*none*")));
-+
-+      if (check_count)
-+      {
-+        VOID(pthread_mutex_lock(&LOCK_thread_count));
-+        bool count_ok= thread_count <= max_connections + delayed_insert_threads
-+                       || (thd->main_security_ctx.master_access & SUPER_ACL);
-+        VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+        if (!count_ok)
-+        {                                         // too many connections
-+          net_send_error(thd, ER_CON_COUNT_ERROR);
-+          DBUG_RETURN(-1);
-+        }
-+      }
-+
-+      /* Why logging is performed before all checks've passed? */
-+      mysql_log.write(thd, command,
-+                      (thd->main_security_ctx.priv_user ==
-+                       thd->main_security_ctx.user ?
-+                       (char*) "%s@%s on %s" :
-+                       (char*) "%s@%s as anonymous on %s"),
-+                      thd->main_security_ctx.user,
-+                      thd->main_security_ctx.host_or_ip,
-+                      db ? db : (char*) "");
-+
-+      /*
-+        This is the default access rights for the current database.  It's
-+        set to 0 here because we don't have an active database yet (and we
-+        may not have an active database to set.
-+      */
-+      thd->main_security_ctx.db_access=0;
-+
-+      /* Don't allow user to connect if he has done too many queries */
-+      if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
-+	   max_user_connections) &&
-+	  get_or_create_user_conn(thd,
-+            (opt_old_style_user_limits ? thd->main_security_ctx.user :
-+             thd->main_security_ctx.priv_user),
-+            (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
-+             thd->main_security_ctx.priv_host),
-+            &ur))
-+	DBUG_RETURN(-1);
-+      if (thd->user_connect &&
-+	  (thd->user_connect->user_resources.conn_per_hour ||
-+	   thd->user_connect->user_resources.user_conn ||
-+	   max_user_connections) &&
-+	  check_for_max_user_connections(thd, thd->user_connect))
-+	DBUG_RETURN(-1);
-+
-+      /* Change database if necessary */
-+      if (db && db[0])
-+      {
-+        if (mysql_change_db(thd, db, FALSE))
-+        {
-+          /* Send error to the client */
-+          net_send_error(thd);
-+          if (thd->user_connect)
-+            decrease_user_connections(thd->user_connect);
-+          DBUG_RETURN(-1);
-+        }
-+      }
-+      send_ok(thd);
-+      thd->password= test(passwd_len);          // remember for error messages 
-+      /* Ready to handle queries */
-+      DBUG_RETURN(0);
-+    }
-+  }
-+  else if (res == 2) // client gave short hash, server has long hash
-+  {
-+    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
-+    mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE));
-+    DBUG_RETURN(-1);
-+  }
-+  net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
-+                   thd->main_security_ctx.user,
-+                   thd->main_security_ctx.host_or_ip,
-+                   passwd_len ? ER(ER_YES) : ER(ER_NO));
-+  mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
-+                  thd->main_security_ctx.user,
-+                  thd->main_security_ctx.host_or_ip,
-+                  passwd_len ? ER(ER_YES) : ER(ER_NO));
-+  DBUG_RETURN(-1);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+/*
-+  Check for maximum allowable user connections, if the mysqld server is
-+  started with corresponding variable that is greater then 0.
-+*/
-+
-+extern "C" byte *get_key_conn(user_conn *buff, uint *length,
-+			      my_bool not_used __attribute__((unused)))
-+{
-+  *length=buff->len;
-+  return (byte*) buff->user;
-+}
-+
-+extern "C" void free_user(struct user_conn *uc)
-+{
-+  my_free((char*) uc,MYF(0));
-+}
-+
-+void init_max_user_conn(void)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
-+		   0,0,
-+		   (hash_get_key) get_key_conn, (hash_free_key) free_user,
-+		   0);
-+#endif
-+}
-+
-+
-+/*
-+  check if user has already too many connections
-+  
-+  SYNOPSIS
-+  check_for_max_user_connections()
-+  thd			Thread handle
-+  uc			User connect object
-+
-+  NOTES
-+    If check fails, we decrease user connection count, which means one
-+    shouldn't call decrease_user_connections() after this function.
-+
-+  RETURN
-+    0	ok
-+    1	error
-+*/
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+
-+static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
-+{
-+  int error=0;
-+  DBUG_ENTER("check_for_max_user_connections");
-+
-+  (void) pthread_mutex_lock(&LOCK_user_conn);
-+  if (max_user_connections && !uc->user_resources.user_conn &&
-+      max_user_connections < (uint) uc->connections)
-+  {
-+    net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user);
-+    error=1;
-+    goto end;
-+  }
-+  time_out_user_resource_limits(thd, uc);
-+  if (uc->user_resources.user_conn &&
-+      uc->user_resources.user_conn < uc->connections)
-+  {
-+    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-+                     "max_user_connections",
-+                     (long) uc->user_resources.user_conn);
-+    error= 1;
-+    goto end;
-+  }
-+  if (uc->user_resources.conn_per_hour &&
-+      uc->user_resources.conn_per_hour <= uc->conn_per_hour)
-+  {
-+    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-+                     "max_connections_per_hour",
-+                     (long) uc->user_resources.conn_per_hour);
-+    error=1;
-+    goto end;
-+  }
-+  uc->conn_per_hour++;
-+
-+  end:
-+  if (error)
-+    uc->connections--; // no need for decrease_user_connections() here
-+  (void) pthread_mutex_unlock(&LOCK_user_conn);
-+  DBUG_RETURN(error);
-+}
-+
-+/*
-+  Decrease user connection count
-+
-+  SYNOPSIS
-+    decrease_user_connections()
-+    uc			User connection object
-+
-+  NOTES
-+    If there is a n user connection object for a connection
-+    (which only happens if 'max_user_connections' is defined or
-+    if someone has created a resource grant for a user), then
-+    the connection count is always incremented on connect.
-+
-+    The user connect object is not freed if some users has
-+    'max connections per hour' defined as we need to be able to hold
-+    count over the lifetime of the connection.
-+*/
-+
-+static void decrease_user_connections(USER_CONN *uc)
-+{
-+  DBUG_ENTER("decrease_user_connections");
-+  (void) pthread_mutex_lock(&LOCK_user_conn);
-+  DBUG_ASSERT(uc->connections);
-+  if (!--uc->connections && !mqh_used)
-+  {
-+    /* Last connection for user; Delete it */
-+    (void) hash_delete(&hash_user_connections,(byte*) uc);
-+  }
-+  (void) pthread_mutex_unlock(&LOCK_user_conn);
-+  DBUG_VOID_RETURN;
-+}
-+
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+
-+
-+void free_max_user_conn(void)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  hash_free(&hash_user_connections);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+
-+/*
-+  Mark all commands that somehow changes a table
-+  This is used to check number of updates / hour
-+
-+  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
-+     2  - query that returns meaningful ROW_COUNT() -
-+          a number of modified rows
-+*/
-+
-+char  uc_update_queries[SQLCOM_END+1];
-+
-+void init_update_queries(void)
-+{
-+  bzero((gptr) &uc_update_queries, sizeof(uc_update_queries));
-+
-+  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;
-+}
-+
-+bool is_update_query(enum enum_sql_command command)
-+{
-+  DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
-+  return uc_update_queries[command] != 0;
-+}
-+
-+/*
-+  Reset per-hour user resource limits when it has been more than
-+  an hour since they were last checked
-+
-+  SYNOPSIS:
-+    time_out_user_resource_limits()
-+    thd			Thread handler
-+    uc			User connection details
-+
-+  NOTE:
-+    This assumes that the LOCK_user_conn mutex has been acquired, so it is
-+    safe to test and modify members of the USER_CONN structure.
-+*/
-+
-+static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
-+{
-+  time_t check_time = thd->start_time ?  thd->start_time : time(NULL);
-+  DBUG_ENTER("time_out_user_resource_limits");
-+
-+  /* If more than a hour since last check, reset resource checking */
-+  if (check_time  - uc->intime >= 3600)
-+  {
-+    uc->questions=1;
-+    uc->updates=0;
-+    uc->conn_per_hour=0;
-+    uc->intime=check_time;
-+  }
-+
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+  Check if maximum queries per hour limit has been reached
-+  returns 0 if OK.
-+*/
-+
-+static bool check_mqh(THD *thd, uint check_command)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  bool error= 0;
-+  USER_CONN *uc=thd->user_connect;
-+  DBUG_ENTER("check_mqh");
-+  DBUG_ASSERT(uc != 0);
-+
-+  (void) pthread_mutex_lock(&LOCK_user_conn);
-+
-+  time_out_user_resource_limits(thd, uc);
-+
-+  /* Check that we have not done too many questions / hour */
-+  if (uc->user_resources.questions &&
-+      uc->questions++ >= uc->user_resources.questions)
-+  {
-+    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions",
-+                     (long) uc->user_resources.questions);
-+    error=1;
-+    goto end;
-+  }
-+  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] &&
-+	uc->updates++ >= uc->user_resources.updates)
-+    {
-+      net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
-+                       (long) uc->user_resources.updates);
-+      error=1;
-+      goto end;
-+    }
-+  }
-+end:
-+  (void) pthread_mutex_unlock(&LOCK_user_conn);
-+  DBUG_RETURN(error);
-+#else
-+  return (0);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+static void reset_mqh(LEX_USER *lu, bool get_them= 0)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  (void) pthread_mutex_lock(&LOCK_user_conn);
-+  if (lu)  // for GRANT
-+  {
-+    USER_CONN *uc;
-+    uint temp_len=lu->user.length+lu->host.length+2;
-+    char temp_user[USER_HOST_BUFF_SIZE];
-+
-+    memcpy(temp_user,lu->user.str,lu->user.length);
-+    memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
-+    temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
-+    if ((uc = (struct  user_conn *) hash_search(&hash_user_connections,
-+						(byte*) temp_user, temp_len)))
-+    {
-+      uc->questions=0;
-+      get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
-+      uc->updates=0;
-+      uc->conn_per_hour=0;
-+    }
-+  }
-+  else
-+  {
-+    /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */
-+    for (uint idx=0;idx < hash_user_connections.records; idx++)
-+    {
-+      USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections,
-+						      idx);
-+      if (get_them)
-+	get_mqh(uc->user,uc->host,uc);
-+      uc->questions=0;
-+      uc->updates=0;
-+      uc->conn_per_hour=0;
-+    }
-+  }
-+  (void) pthread_mutex_unlock(&LOCK_user_conn);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+void thd_init_client_charset(THD *thd, uint cs_number)
-+{
-+  /*
-+   Use server character set and collation if
-+   - opt_character_set_client_handshake is not set
-+   - client has not specified a character set
-+   - client character set is the same as the servers
-+   - client character set doesn't exists in server
-+  */
-+  if (!opt_character_set_client_handshake ||
-+      !(thd->variables.character_set_client= get_charset(cs_number, MYF(0))) ||
-+      !my_strcasecmp(&my_charset_latin1,
-+                     global_system_variables.character_set_client->name,
-+                     thd->variables.character_set_client->name))
-+  {
-+    thd->variables.character_set_client=
-+      global_system_variables.character_set_client;
-+    thd->variables.collation_connection=
-+      global_system_variables.collation_connection;
-+    thd->variables.character_set_results=
-+      global_system_variables.character_set_results;
-+  }
-+  else
-+  {
-+    thd->variables.character_set_results=
-+      thd->variables.collation_connection= 
-+      thd->variables.character_set_client;
-+  }
-+}
-+
-+
-+/*
-+    Perform handshake, authorize client and update thd ACL variables.
-+  SYNOPSIS
-+    check_connection()
-+    thd  thread handle
-+
-+  RETURN
-+     0  success, OK is sent to user, thd is updated.
-+    -1  error, which is sent to user
-+   > 0  error code (not sent to user)
-+*/
-+
-+#ifndef EMBEDDED_LIBRARY
-+static int check_connection(THD *thd)
-+{
-+  uint connect_errors= 0;
-+  NET *net= &thd->net;
-+  ulong pkt_len= 0;
-+  char *end;
-+
-+  DBUG_PRINT("info",
-+             ("New connection received on %s", vio_description(net->vio)));
-+#ifdef SIGNAL_WITH_VIO_CLOSE
-+  thd->set_active_vio(net->vio);
-+#endif
-+
-+  if (!thd->main_security_ctx.host)         // If TCP/IP connection
-+  {
-+    char ip[30];
-+
-+    if (vio_peer_addr(net->vio, ip, &thd->peer_port))
-+      return (ER_BAD_HOST_ERROR);
-+    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0))))
-+      return (ER_OUT_OF_RESOURCES);
-+    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
-+    vio_in_addr(net->vio,&thd->remote.sin_addr);
-+    if (!(specialflag & SPECIAL_NO_RESOLVE))
-+    {
-+      vio_in_addr(net->vio,&thd->remote.sin_addr);
-+      thd->main_security_ctx.host=
-+        ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
-+      /* Cut very long hostnames to avoid possible overflows */
-+      if (thd->main_security_ctx.host)
-+      {
-+        if (thd->main_security_ctx.host != my_localhost)
-+          thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
-+                                          HOSTNAME_LENGTH)]= 0;
-+        thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-+      }
-+      if (connect_errors > max_connect_errors)
-+        return(ER_HOST_IS_BLOCKED);
-+    }
-+    DBUG_PRINT("info",("Host: %s  ip: %s",
-+		       (thd->main_security_ctx.host ?
-+                        thd->main_security_ctx.host : "unknown host"),
-+		       (thd->main_security_ctx.ip ?
-+                        thd->main_security_ctx.ip : "unknown ip")));
-+    if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
-+      return(ER_HOST_NOT_PRIVILEGED);
-+  }
-+  else /* Hostname given means that the connection was on a socket */
-+  {
-+    DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
-+    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-+    thd->main_security_ctx.ip= 0;
-+    /* Reset sin_addr */
-+    bzero((char*) &thd->remote, sizeof(thd->remote));
-+  }
-+  vio_keepalive(net->vio, TRUE);
-+  {
-+    /* buff[] needs to big enough to hold the server_version variable */
-+    char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
-+    ulong client_flags = (CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
-+			  CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION);
-+
-+    if (opt_using_transactions)
-+      client_flags|=CLIENT_TRANSACTIONS;
-+#ifdef HAVE_COMPRESS
-+    client_flags |= CLIENT_COMPRESS;
-+#endif /* HAVE_COMPRESS */
-+#ifdef HAVE_OPENSSL
-+    if (ssl_acceptor_fd)
-+      client_flags |= CLIENT_SSL;       /* Wow, SSL is available! */
-+#endif /* HAVE_OPENSSL */
-+
-+    end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
-+    int4store((uchar*) end, thd->thread_id);
-+    end+= 4;
-+    /*
-+      So as check_connection is the only entry point to authorization
-+      procedure, scramble is set here. This gives us new scramble for
-+      each handshake.
-+    */
-+    create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
-+    /*
-+      Old clients does not understand long scrambles, but can ignore packet
-+      tail: that's why first part of the scramble is placed here, and second
-+      part at the end of packet.
-+    */
-+    end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-+   
-+    int2store(end, client_flags);
-+    /* write server characteristics: up to 16 bytes allowed */
-+    end[2]=(char) default_charset_info->number;
-+    int2store(end+3, thd->server_status);
-+    bzero(end+5, 13);
-+    end+= 18;
-+    /* write scramble tail */
-+    end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323, 
-+                 SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
-+
-+    /* At this point we write connection message and read reply */
-+    if (net_write_command(net, (uchar) protocol_version, "", 0, buff,
-+			  (uint) (end-buff)) ||
-+	(pkt_len= my_net_read(net)) == packet_error ||
-+	pkt_len < MIN_HANDSHAKE_SIZE)
-+    {
-+      inc_host_errors(&thd->remote.sin_addr);
-+      return(ER_HANDSHAKE_ERROR);
-+    }
-+  }
-+#ifdef _CUSTOMCONFIG_
-+#include "_cust_sql_parse.h"
-+#endif
-+  if (connect_errors)
-+    reset_host_errors(&thd->remote.sin_addr);
-+  if (thd->packet.alloc(thd->variables.net_buffer_length))
-+    return(ER_OUT_OF_RESOURCES);
-+
-+  thd->client_capabilities=uint2korr(net->read_pos);
-+  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
-+  {
-+    thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
-+    thd->max_client_packet_length= uint4korr(net->read_pos+4);
-+    DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
-+    thd_init_client_charset(thd, (uint) net->read_pos[8]);
-+    thd->update_charset();
-+    end= (char*) net->read_pos+32;
-+  }
-+  else
-+  {
-+    thd->max_client_packet_length= uint3korr(net->read_pos+2);
-+    end= (char*) net->read_pos+5;
-+  }
-+
-+  if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
-+    thd->variables.sql_mode|= MODE_IGNORE_SPACE;
-+#ifdef HAVE_OPENSSL
-+  DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
-+  if (thd->client_capabilities & CLIENT_SSL)
-+  {
-+    /* Do the SSL layering. */
-+    if (!ssl_acceptor_fd)
-+    {
-+      inc_host_errors(&thd->remote.sin_addr);
-+      return(ER_HANDSHAKE_ERROR);
-+    }
-+    DBUG_PRINT("info", ("IO layer change in progress..."));
-+    if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
-+    {
-+      DBUG_PRINT("error", ("Failed to accept new SSL connection"));
-+      inc_host_errors(&thd->remote.sin_addr);
-+      return(ER_HANDSHAKE_ERROR);
-+    }
-+    DBUG_PRINT("info", ("Reading user information over SSL layer"));
-+    if ((pkt_len= my_net_read(net)) == packet_error ||
-+	pkt_len < NORMAL_HANDSHAKE_SIZE)
-+    {
-+      DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
-+			   pkt_len));
-+      inc_host_errors(&thd->remote.sin_addr);
-+      return(ER_HANDSHAKE_ERROR);
-+    }
-+  }
-+#endif
-+
-+  if (end >= (char*) net->read_pos+ pkt_len +2)
-+  {
-+    inc_host_errors(&thd->remote.sin_addr);
-+    return(ER_HANDSHAKE_ERROR);
-+  }
-+
-+  if (thd->client_capabilities & CLIENT_INTERACTIVE)
-+    thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
-+  if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
-+      opt_using_transactions)
-+    net->return_status= &thd->server_status;
-+  net->read_timeout=(uint) thd->variables.net_read_timeout;
-+
-+  char *user= end;
-+  char *passwd= strend(user)+1;
-+  uint user_len= passwd - user - 1;
-+  char *db= passwd;
-+  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
-+  char user_buff[USERNAME_LENGTH + 1];	// buffer to store user in utf8
-+  uint dummy_errors;
-+
-+  /*
-+    Old clients send null-terminated string as password; new clients send
-+    the size (1 byte) + string (not null-terminated). Hence in case of empty
-+    password both send '\0'.
-+  */
-+  uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
-+    *passwd++ : strlen(passwd);
-+  db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
-+    db + passwd_len + 1 : 0;
-+  uint db_len= db ? strlen(db) : 0;
-+
-+  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
-+  {
-+    inc_host_errors(&thd->remote.sin_addr);
-+    return ER_HANDSHAKE_ERROR;
-+  }
-+
-+  /* Since 4.1 all database names are stored in utf8 */
-+  if (db)
-+  {
-+    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-+                             system_charset_info,
-+                             db, db_len,
-+                             thd->charset(), &dummy_errors)]= 0;
-+    db= db_buff;
-+  }
-+
-+  user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
-+                                       system_charset_info, user, user_len,
-+                                       thd->charset(), &dummy_errors)]= '\0';
-+  user= user_buff;
-+
-+  /* If username starts and ends in "'", chop them off */
-+  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
-+  {
-+    user[user_len-1]= 0;
-+    user++;
-+    user_len-= 2;
-+  }
-+
-+  if (thd->main_security_ctx.user)
-+    x_free(thd->main_security_ctx.user);
-+  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
-+    return (ER_OUT_OF_RESOURCES);
-+  return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
-+}
-+
-+
-+void execute_init_command(THD *thd, sys_var_str *init_command_var,
-+			  rw_lock_t *var_mutex)
-+{
-+  Vio* save_vio;
-+  ulong save_client_capabilities;
-+
-+  thd->proc_info= "Execution of init_command";
-+  /*
-+    We need to lock init_command_var because
-+    during execution of init_command_var query
-+    values of init_command_var can't be changed
-+  */
-+  rw_rdlock(var_mutex);
-+  thd->query= init_command_var->value;
-+  thd->query_length= init_command_var->value_length;
-+  save_client_capabilities= thd->client_capabilities;
-+  thd->client_capabilities|= CLIENT_MULTI_QUERIES;
-+  /*
-+    We don't need return result of execution to client side.
-+    To forbid this we should set thd->net.vio to 0.
-+  */
-+  save_vio= thd->net.vio;
-+  thd->net.vio= 0;
-+  thd->net.no_send_error= 0;
-+  dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
-+  rw_unlock(var_mutex);
-+  thd->client_capabilities= save_client_capabilities;
-+  thd->net.vio= save_vio;
-+}
-+
-+
-+pthread_handler_t handle_one_connection(void *arg)
-+{
-+  THD *thd=(THD*) arg;
-+  uint launch_time  =
-+    (uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time);
-+  if (launch_time >= slow_launch_time)
-+    statistic_increment(slow_launch_threads,&LOCK_status );
-+
-+  pthread_detach_this_thread();
-+
-+#if !defined( __WIN__) && !defined(OS2)	// Win32 calls this in pthread_create
-+  /* The following calls needs to be done before we call DBUG_ macros */
-+  if (!(test_flags & TEST_NO_THREADS) & my_thread_init())
-+  {
-+    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+    statistic_increment(aborted_connects,&LOCK_status);
-+    end_thread(thd,0);
-+    return 0;
-+  }
-+#endif
-+
-+  /*
-+    handle_one_connection() is the only way a thread would start
-+    and would always be on top of the stack, therefore, the thread
-+    stack always starts at the address of the first local variable
-+    of handle_one_connection, which is thd. We need to know the
-+    start of the stack so that we could check for stack overruns.
-+  */
-+  DBUG_PRINT("info", ("handle_one_connection called by thread %lu\n",
-+		      thd->thread_id));
-+  /* now that we've called my_thread_init(), it is safe to call DBUG_* */
-+
-+#if defined(__WIN__)
-+  init_signals();
-+#elif !defined(OS2) && !defined(__NETWARE__)
-+  sigset_t set;
-+  VOID(sigemptyset(&set));			// Get mask in use
-+  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-+#endif
-+  thd->thread_stack= (char*) &thd;
-+  if (thd->store_globals())
-+  {
-+    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+    statistic_increment(aborted_connects,&LOCK_status);
-+    end_thread(thd,0);
-+    return 0;
-+  }
-+
-+  do
-+  {
-+    int error;
-+    NET *net= &thd->net;
-+    Security_context *sctx= thd->security_ctx;
-+    net->no_send_error= 0;
-+
-+    if ((error=check_connection(thd)))
-+    {						// Wrong permissions
-+      if (error > 0)
-+	net_printf_error(thd, error, sctx->host_or_ip);
-+#ifdef __NT__
-+      if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
-+	my_sleep(1000);				/* must wait after eof() */
-+#endif
-+      statistic_increment(aborted_connects,&LOCK_status);
-+      goto end_thread;
-+    }
-+#ifdef __NETWARE__
-+    netware_reg_user(sctx->ip, sctx->user, "MySQL");
-+#endif
-+    if (thd->variables.max_join_size == HA_POS_ERROR)
-+      thd->options |= OPTION_BIG_SELECTS;
-+    if (thd->client_capabilities & CLIENT_COMPRESS)
-+      net->compress=1;				// Use compression
-+
-+    thd->version= refresh_version;
-+    thd->proc_info= 0;
-+    thd->command= COM_SLEEP;
-+    thd->set_time();
-+    thd->init_for_queries();
-+
-+    if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
-+    {
-+      execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
-+      if (thd->query_error)
-+      {
-+	thd->killed= THD::KILL_CONNECTION;
-+        sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-+                          thd->thread_id,(thd->db ? thd->db : "unconnected"),
-+                          sctx->user ? sctx->user : "unauthenticated",
-+                          sctx->host_or_ip, "init_connect command failed");
-+        sql_print_warning("%s", net->last_error);
-+      }
-+      thd->proc_info=0;
-+      thd->set_time();
-+      thd->init_for_queries();
-+    }
-+
-+    while (!net->error && net->vio != 0 &&
-+           !(thd->killed == THD::KILL_CONNECTION))
-+    {
-+      net->no_send_error= 0;
-+      if (do_command(thd))
-+	break;
-+    }
-+    if (thd->user_connect)
-+      decrease_user_connections(thd->user_connect);
-+    if (net->error && net->vio != 0 && net->report_error)
-+    {
-+      if (!thd->killed && thd->variables.log_warnings > 1)
-+	sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-+                          thd->thread_id,(thd->db ? thd->db : "unconnected"),
-+                          sctx->user ? sctx->user : "unauthenticated",
-+                          sctx->host_or_ip,
-+                          (net->last_errno ? ER(net->last_errno) :
-+                           ER(ER_UNKNOWN_ERROR)));
-+      net_send_error(thd, net->last_errno, NullS);
-+      statistic_increment(aborted_threads,&LOCK_status);
-+    }
-+    else if (thd->killed)
-+    {
-+      statistic_increment(aborted_threads,&LOCK_status);
-+    }
-+    
-+end_thread:
-+    close_connection(thd, 0, 1);
-+    end_thread(thd,1);
-+    /*
-+      If end_thread returns, we are either running with --one-thread
-+      or this thread has been schedule to handle the next query
-+    */
-+    thd= current_thd;
-+    thd->thread_stack= (char*) &thd;
-+  } while (!(test_flags & TEST_NO_THREADS));
-+  /* The following is only executed if we are not using --one-thread */
-+  return(0);					/* purecov: deadcode */
-+}
-+
-+#endif /* EMBEDDED_LIBRARY */
-+
-+/*
-+  Execute commands from bootstrap_file.
-+  Used when creating the initial grant tables
-+*/
-+
-+pthread_handler_t handle_bootstrap(void *arg)
-+{
-+  THD *thd=(THD*) arg;
-+  FILE *file=bootstrap_file;
-+  char *buff;
-+
-+  /* The following must be called before DBUG_ENTER */
-+  thd->thread_stack= (char*) &thd;
-+  if (my_thread_init() || thd->store_globals())
-+  {
-+#ifndef EMBEDDED_LIBRARY
-+    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+#endif
-+    thd->fatal_error();
-+    goto end;
-+  }
-+  DBUG_ENTER("handle_bootstrap");
-+
-+#ifndef EMBEDDED_LIBRARY
-+  pthread_detach_this_thread();
-+  thd->thread_stack= (char*) &thd;
-+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
-+  sigset_t set;
-+  VOID(sigemptyset(&set));			// Get mask in use
-+  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-+#endif
-+#endif /* EMBEDDED_LIBRARY */
-+
-+  if (thd->variables.max_join_size == HA_POS_ERROR)
-+    thd->options |= OPTION_BIG_SELECTS;
-+
-+  thd->proc_info=0;
-+  thd->version=refresh_version;
-+  thd->security_ctx->priv_user=
-+    thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
-+  /*
-+    Make the "client" handle multiple results. This is necessary
-+    to enable stored procedures with SELECTs and Dynamic SQL
-+    in init-file.
-+  */
-+  thd->client_capabilities|= CLIENT_MULTI_RESULTS;
-+
-+  buff= (char*) thd->net.buff;
-+  thd->init_for_queries();
-+  while (fgets(buff, thd->net.max_packet, file))
-+  {
-+   ulong length= (ulong) strlen(buff);
-+   while (buff[length-1] != '\n' && !feof(file))
-+   {
-+     /*
-+       We got only a part of the current string. Will try to increase
-+       net buffer then read the rest of the current string.
-+     */
-+     if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
-+     {
-+       net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
-+       thd->fatal_error();
-+       break;
-+     }
-+     buff= (char*) thd->net.buff;
-+     fgets(buff + length, thd->net.max_packet - length, file);
-+     length+= (ulong) strlen(buff + length);
-+   }
-+   if (thd->is_fatal_error)
-+     break;
-+
-+    while (length && (my_isspace(thd->charset(), buff[length-1]) ||
-+           buff[length-1] == ';'))
-+      length--;
-+    buff[length]=0;
-+    thd->query_length=length;
-+    thd->query= thd->memdup_w_gap(buff, length+1, 
-+				  thd->db_length+1+QUERY_CACHE_FLAGS_SIZE);
-+    thd->query[length] = '\0';
-+    /*
-+      We don't need to obtain LOCK_thread_count here because in bootstrap
-+      mode we have only one thread.
-+    */
-+    thd->query_id=next_query_id();
-+    mysql_parse(thd,thd->query,length);
-+    close_thread_tables(thd);			// Free tables
-+    if (thd->is_fatal_error)
-+      break;
-+    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
-+#ifdef USING_TRANSACTIONS
-+    free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
-+#endif
-+  }
-+
-+  /* thd->fatal_error should be set in case something went wrong */
-+end:
-+  bootstrap_error= thd->is_fatal_error;
-+
-+  net_end(&thd->net);
-+  thd->cleanup();
-+  delete thd;
-+
-+#ifndef EMBEDDED_LIBRARY
-+  (void) pthread_mutex_lock(&LOCK_thread_count);
-+  thread_count--;
-+  (void) pthread_mutex_unlock(&LOCK_thread_count);
-+  (void) pthread_cond_broadcast(&COND_thread_count);
-+  my_thread_end();
-+  pthread_exit(0);
-+#endif
-+  DBUG_RETURN(0);
-+}
-+
-+
-+    /* This works because items are allocated with sql_alloc() */
-+
-+void cleanup_items(Item *item)
-+{
-+  DBUG_ENTER("cleanup_items");  
-+  for (; item ; item=item->next)
-+    item->cleanup();
-+  DBUG_VOID_RETURN;
-+}
-+
-+/*
-+  Handle COM_TABLE_DUMP command
-+
-+  SYNOPSIS
-+    mysql_table_dump
-+      thd           thread handle
-+      db            database name or an empty string. If empty,
-+                    the current database of the connection is used
-+      tbl_name      name of the table to dump
-+
-+  NOTES
-+    This function is written to handle one specific command only.
-+
-+  RETURN VALUE
-+    0               success
-+    1               error, the error message is set in THD
-+*/
-+
-+static
-+int mysql_table_dump(THD* thd, char* db, char* tbl_name)
-+{
-+  TABLE* table;
-+  TABLE_LIST* table_list;
-+  int error = 0;
-+  DBUG_ENTER("mysql_table_dump");
-+  db = (db && db[0]) ? db : thd->db;
-+  if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
-+    DBUG_RETURN(1); // out of memory
-+  table_list->db= db;
-+  table_list->table_name= table_list->alias= tbl_name;
-+  table_list->lock_type= TL_READ_NO_INSERT;
-+  table_list->prev_global= &table_list;	// can be removed after merge with 4.1
-+
-+  if (!db || check_db_name(db))
-+  {
-+    my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL");
-+    goto err;
-+  }
-+  if (lower_case_table_names)
-+    my_casedn_str(files_charset_info, tbl_name);
-+  remove_escape(table_list->table_name);
-+
-+  if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
-+    DBUG_RETURN(1);
-+
-+  if (check_one_table_access(thd, SELECT_ACL, table_list))
-+    goto err;
-+  thd->free_list = 0;
-+  thd->query_length=(uint) strlen(tbl_name);
-+  thd->query = tbl_name;
-+  if ((error = mysqld_dump_create_info(thd, table_list, -1)))
-+  {
-+    my_error(ER_GET_ERRNO, MYF(0), my_errno);
-+    goto err;
-+  }
-+  net_flush(&thd->net);
-+  if ((error= table->file->dump(thd,-1)))
-+    my_error(ER_GET_ERRNO, MYF(0), error);
-+
-+err:
-+  DBUG_RETURN(error);
-+}
-+
-+/*
-+  Ends the current transaction and (maybe) begin the next
-+
-+  SYNOPSIS
-+    end_trans()
-+      thd            Current thread
-+      completion     Completion type
-+
-+  RETURN
-+    0 - OK
-+*/
-+
-+int end_trans(THD *thd, enum enum_mysql_completiontype completion)
-+{
-+  bool do_release= 0;
-+  int res= 0;
-+  DBUG_ENTER("end_trans");
-+
-+  if (unlikely(thd->in_sub_stmt))
-+  {
-+    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+    DBUG_RETURN(1);
-+  }
-+  if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+  {
-+    my_error(ER_XAER_RMFAIL, MYF(0),
-+             xa_state_names[thd->transaction.xid_state.xa_state]);
-+    DBUG_RETURN(1);
-+  }
-+  switch (completion) {
-+  case COMMIT:
-+    /*
-+     We don't use end_active_trans() here to ensure that this works
-+     even if there is a problem with the OPTION_AUTO_COMMIT flag
-+     (Which of course should never happen...)
-+    */
-+    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+    res= ha_commit(thd);
-+    thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
-+    break;
-+  case COMMIT_RELEASE:
-+    do_release= 1; /* fall through */
-+  case COMMIT_AND_CHAIN:
-+    res= end_active_trans(thd);
-+    if (!res && completion == COMMIT_AND_CHAIN)
-+      res= begin_trans(thd);
-+    break;
-+  case ROLLBACK_RELEASE:
-+    do_release= 1; /* fall through */
-+  case ROLLBACK:
-+  case ROLLBACK_AND_CHAIN:
-+  {
-+    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+    if (ha_rollback(thd))
-+      res= -1;
-+    thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
-+    if (!res && (completion == ROLLBACK_AND_CHAIN))
-+      res= begin_trans(thd);
-+    break;
-+  }
-+  default:
-+    res= -1;
-+    my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
-+    DBUG_RETURN(-1);
-+  }
-+
-+  if (res < 0)
-+    my_error(thd->killed_errno(), MYF(0));
-+  else if ((res == 0) && do_release)
-+    thd->killed= THD::KILL_CONNECTION;
-+
-+  DBUG_RETURN(res);
-+}
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/*
-+  Read one command from socket and execute it (query or simple command).
-+  This function is called in loop from thread function.
-+  SYNOPSIS
-+    do_command()
-+  RETURN VALUE
-+    0  success
-+    1  request of thread shutdown (see dispatch_command() description)
-+*/
-+
-+bool do_command(THD *thd)
-+{
-+  char *packet;
-+  uint old_timeout;
-+  ulong packet_length;
-+  NET *net;
-+  enum enum_server_command command;
-+  DBUG_ENTER("do_command");
-+
-+  net= &thd->net;
-+  /*
-+    indicator of uninitialized lex => normal flow of errors handling
-+    (see my_message_sql)
-+  */
-+  thd->lex->current_select= 0;
-+
-+  packet=0;
-+  old_timeout=net->read_timeout;
-+  /* Wait max for 8 hours */
-+  net->read_timeout=(uint) thd->variables.net_wait_timeout;
-+  thd->clear_error();				// Clear error message
-+
-+  net_new_transaction(net);
-+  if ((packet_length=my_net_read(net)) == packet_error)
-+  {
-+    DBUG_PRINT("info",("Got error %d reading command from socket %s",
-+		       net->error,
-+		       vio_description(net->vio)));
-+    /* Check if we can continue without closing the connection */
-+    if (net->error != 3)
-+    {
-+      statistic_increment(aborted_threads,&LOCK_status);
-+      DBUG_RETURN(TRUE);			// We have to close it.
-+    }
-+    net_send_error(thd, net->last_errno, NullS);
-+    net->error= 0;
-+    DBUG_RETURN(FALSE);
-+  }
-+  else
-+  {
-+    packet=(char*) net->read_pos;
-+    command = (enum enum_server_command) (uchar) packet[0];
-+    if (command >= COM_END)
-+      command= COM_END;				// Wrong command
-+    DBUG_PRINT("info",("Command on %s = %d (%s)",
-+		       vio_description(net->vio), command,
-+		       command_name[command]));
-+  }
-+  net->read_timeout=old_timeout;		// restore it
-+  /*
-+    packet_length contains length of data, as it was stored in packet
-+    header. In case of malformed header, packet_length can be zero.
-+    If packet_length is not zero, my_net_read ensures that this number
-+    of bytes was actually read from network. Additionally my_net_read
-+    sets packet[packet_length]= 0 (thus if packet_length == 0,
-+    command == packet[0] == COM_SLEEP).
-+    In dispatch_command packet[packet_length] points beyond the end of packet.
-+  */
-+  DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
-+}
-+#endif  /* EMBEDDED_LIBRARY */
-+
-+
-+/*
-+   Perform one connection-level (COM_XXXX) command.
-+
-+  SYNOPSIS
-+    dispatch_command()
-+    thd             connection handle
-+    command         type of command to perform 
-+    packet          data for the command, packet is always null-terminated
-+    packet_length   length of packet + 1 (to show that data is
-+                    null-terminated) except for COM_SLEEP, where it
-+                    can be zero.
-+  RETURN VALUE
-+    0   ok
-+    1   request of thread shutdown, i. e. if command is
-+        COM_QUIT/COM_SHUTDOWN
-+*/
-+
-+bool dispatch_command(enum enum_server_command command, THD *thd,
-+		      char* packet, uint packet_length)
-+{
-+  NET *net= &thd->net;
-+  bool error= 0;
-+  DBUG_ENTER("dispatch_command");
-+
-+  if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
-+    thd->killed= THD::NOT_KILLED;
-+
-+  thd->command=command;
-+  /*
-+    Commands which always take a long time are logged into
-+    the slow log only if opt_log_slow_admin_statements is set.
-+  */
-+  thd->enable_slow_log= TRUE;
-+  thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
-+  thd->set_time();
-+  VOID(pthread_mutex_lock(&LOCK_thread_count));
-+  thd->query_id=query_id;
-+  if (command != COM_STATISTICS && command != COM_PING)
-+    next_query_id();
-+  thread_running++;
-+  /* TODO: set thd->lex->sql_command to SQLCOM_END here */
-+  VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+
-+  thd->server_status&=
-+           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
-+  switch (command) {
-+  case COM_INIT_DB:
-+  {
-+    LEX_STRING tmp;
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB],
-+			&LOCK_status);
-+    thd->convert_string(&tmp, system_charset_info,
-+			packet, strlen(packet), thd->charset());
-+    if (!mysql_change_db(thd, tmp.str, FALSE))
-+    {
-+      mysql_log.write(thd,command,"%s",thd->db);
-+      send_ok(thd);
-+    }
-+    break;
-+  }
-+#ifdef HAVE_REPLICATION
-+  case COM_REGISTER_SLAVE:
-+  {
-+    if (!register_slave(thd, (uchar*)packet, packet_length))
-+      send_ok(thd);
-+    break;
-+  }
-+#endif
-+  case COM_TABLE_DUMP:
-+  {
-+    char *db, *tbl_name;
-+    uint db_len= *(uchar*) packet;
-+    if (db_len >= packet_length || db_len > NAME_LEN)
-+    {
-+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+      break;
-+    }
-+    uint tbl_len= *(uchar*) (packet + db_len + 1);
-+    if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN)
-+    {
-+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+      break;
-+    }
-+
-+    statistic_increment(thd->status_var.com_other, &LOCK_status);
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    db= thd->alloc(db_len + tbl_len + 2);
-+    if (!db)
-+    {
-+      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
-+      break;
-+    }
-+    tbl_name= strmake(db, packet + 1, db_len)+1;
-+    strmake(tbl_name, packet + db_len + 2, tbl_len);
-+    mysql_table_dump(thd, db, tbl_name);
-+    break;
-+  }
-+  case COM_CHANGE_USER:
-+  {
-+    thd->change_user();
-+    thd->clear_error();                         // if errors from rollback
-+
-+    statistic_increment(thd->status_var.com_other, &LOCK_status);
-+    char *user= (char*) packet;
-+    char *passwd= strend(user)+1;
-+    /*
-+      Old clients send null-terminated string ('\0' for empty string) for
-+      password.  New clients send the size (1 byte) + string (not null
-+      terminated, so also '\0' for empty string).
-+    */
-+    char db_buff[NAME_LEN+1];               // buffer to store db in utf8
-+    char *db= passwd;
-+    uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
-+      *passwd++ : strlen(passwd);
-+    db+= passwd_len + 1;
-+#ifndef EMBEDDED_LIBRARY
-+    /* Small check for incoming packet */
-+    if ((uint) ((uchar*) db - net->read_pos) > packet_length)
-+    {
-+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+      break;
-+    }
-+#endif
-+    /* Convert database name to utf8 */
-+    uint dummy_errors;
-+    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-+                             system_charset_info, db, strlen(db),
-+                             thd->charset(), &dummy_errors)]= 0;
-+    db= db_buff;
-+
-+    /* Save user and privileges */
-+    uint save_db_length= thd->db_length;
-+    char *save_db= thd->db;
-+    Security_context save_security_ctx= *thd->security_ctx;
-+    USER_CONN *save_user_connect= thd->user_connect;
-+
-+    if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
-+    {
-+      thd->security_ctx->user= save_security_ctx.user;
-+      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
-+      break;
-+    }
-+
-+    /* Clear variables that are allocated */
-+    thd->user_connect= 0;
-+    int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
-+
-+    if (res)
-+    {
-+      /* authentication failure, we shall restore old user */
-+      if (res > 0)
-+        my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+      x_free(thd->security_ctx->user);
-+      *thd->security_ctx= save_security_ctx;
-+      thd->user_connect= save_user_connect;
-+      thd->db= save_db;
-+      thd->db_length= save_db_length;
-+    }
-+    else
-+    {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+      /* we've authenticated new user */
-+      if (save_user_connect)
-+	decrease_user_connections(save_user_connect);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+      x_free((gptr) save_db);
-+      x_free((gptr)  save_security_ctx.user);
-+    }
-+    break;
-+  }
-+  case COM_STMT_EXECUTE:
-+  {
-+    mysql_stmt_execute(thd, packet, packet_length);
-+    break;
-+  }
-+  case COM_STMT_FETCH:
-+  {
-+    mysql_stmt_fetch(thd, packet, packet_length);
-+    break;
-+  }
-+  case COM_STMT_SEND_LONG_DATA:
-+  {
-+    mysql_stmt_get_longdata(thd, packet, packet_length);
-+    break;
-+  }
-+  case COM_STMT_PREPARE:
-+  {
-+    mysql_stmt_prepare(thd, packet, packet_length);
-+    break;
-+  }
-+  case COM_STMT_CLOSE:
-+  {
-+    mysql_stmt_close(thd, packet);
-+    break;
-+  }
-+  case COM_STMT_RESET:
-+  {
-+    mysql_stmt_reset(thd, packet);
-+    break;
-+  }
-+  case COM_QUERY:
-+  {
-+    if (alloc_query(thd, packet, packet_length))
-+      break;					// fatal error is set
-+    char *packet_end= thd->query + thd->query_length;
-+    /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
-+    const char *format= "%.*b";
-+    mysql_log.write(thd,command, format, thd->query_length, thd->query);
-+    DBUG_PRINT("query",("%-.4096s",thd->query));
-+
-+    if (!(specialflag & SPECIAL_NO_PRIOR))
-+      my_pthread_setprio(pthread_self(),QUERY_PRIOR);
-+
-+    mysql_parse(thd,thd->query, thd->query_length);
-+
-+    while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
-+    {
-+      char *packet= thd->lex->found_semicolon;
-+      net->no_send_error= 0;
-+      /*
-+        Multiple queries exits, execute them individually
-+      */
-+      if (thd->lock || thd->open_tables || thd->derived_tables ||
-+          thd->prelocked_mode)
-+        close_thread_tables(thd);
-+      ulong length= (ulong)(packet_end-packet);
-+
-+      log_slow_statement(thd);
-+
-+      /* Remove garbage at start of query */
-+      while (my_isspace(thd->charset(), *packet) && length > 0)
-+      {
-+        packet++;
-+        length--;
-+      }
-+      VOID(pthread_mutex_lock(&LOCK_thread_count));
-+      thd->query_length= length;
-+      thd->query= packet;
-+      thd->query_id= next_query_id();
-+      thd->set_time(); /* Reset the query start time. */
-+      /* TODO: set thd->lex->sql_command to SQLCOM_END here */
-+      VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+      mysql_parse(thd, packet, length);
-+    }
-+
-+    if (!(specialflag & SPECIAL_NO_PRIOR))
-+      my_pthread_setprio(pthread_self(),WAIT_PRIOR);
-+    DBUG_PRINT("info",("query ready"));
-+    break;
-+  }
-+  case COM_FIELD_LIST:				// This isn't actually needed
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+               MYF(0));	/* purecov: inspected */
-+    break;
-+#else
-+  {
-+    char *fields, *pend;
-+    /* Locked closure of all tables */
-+    TABLE_LIST *locked_tables= NULL;
-+    TABLE_LIST table_list;
-+    LEX_STRING conv_name;
-+    /* Saved variable value */
-+    my_bool old_innodb_table_locks= 
-+              IF_INNOBASE_DB(thd->variables.innodb_table_locks, FALSE);
-+    /* used as fields initializator */
-+    lex_start(thd, 0, 0);
-+
-+
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
-+			&LOCK_status);
-+    bzero((char*) &table_list,sizeof(table_list));
-+    if (thd->copy_db_to(&table_list.db, 0))
-+      break;
-+    pend= strend(packet);
-+    thd->convert_string(&conv_name, system_charset_info,
-+			packet, (uint) (pend-packet), thd->charset());
-+    table_list.alias= table_list.table_name= conv_name.str;
-+    packet= pend+1;
-+
-+    if (!my_strcasecmp(system_charset_info, table_list.db,
-+                       information_schema_name.str))
-+    {
-+      ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
-+      if (schema_table)
-+        table_list.schema_table= schema_table;
-+    }
-+
-+    thd->query_length= strlen(packet);       // for simplicity: don't optimize
-+    if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
-+      break;
-+    mysql_log.write(thd,command,"%s %s",table_list.table_name, fields);
-+    if (lower_case_table_names)
-+      my_casedn_str(files_charset_info, table_list.table_name);
-+    remove_escape(table_list.table_name);	// This can't have wildcards
-+
-+    if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
-+		     0, 0, test(table_list.schema_table)))
-+      break;
-+    if (grant_option &&
-+	check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
-+      break;
-+    /* init structures for VIEW processing */
-+    table_list.select_lex= &(thd->lex->select_lex);
-+    mysql_init_query(thd, (uchar*)"", 0);
-+    thd->lex->
-+      select_lex.table_list.link_in_list((byte*) &table_list,
-+                                         (byte**) &table_list.next_local);
-+    thd->lex->add_to_query_tables(&table_list);
-+
-+    /* switch on VIEW optimisation: do not fill temporary tables */
-+    thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
-+    mysqld_list_fields(thd,&table_list,fields);
-+    thd->lex->unit.cleanup();
-+    thd->cleanup_after_query();
-+    break;
-+  }
-+#endif
-+  case COM_QUIT:
-+    /* We don't calculate statistics for this command */
-+    mysql_log.write(thd,command,NullS);
-+    net->error=0;				// Don't give 'abort' message
-+    error=TRUE;					// End server
-+    break;
-+
-+  case COM_CREATE_DB:				// QQ: To be removed
-+    {
-+      char *db=thd->strdup(packet), *alias;
-+      HA_CREATE_INFO create_info;
-+
-+      statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB],
-+			  &LOCK_status);
-+      // null test to handle EOM
-+      if (!db || !(alias= thd->strdup(db)) || check_db_name(db))
-+      {
-+	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
-+	break;
-+      }
-+      if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db)))
-+	break;
-+      mysql_log.write(thd,command,packet);
-+      bzero(&create_info, sizeof(create_info));
-+      mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db),
-+                      &create_info, 0);
-+      break;
-+    }
-+  case COM_DROP_DB:				// QQ: To be removed
-+    {
-+      statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB],
-+			  &LOCK_status);
-+      char *db=thd->strdup(packet);
-+      /*  null test to handle EOM */
-+      if (!db || check_db_name(db))
-+      {
-+	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
-+	break;
-+      }
-+      if (check_access(thd,DROP_ACL,db,0,1,0,is_schema_db(db)))
-+	break;
-+      if (thd->locked_tables || thd->active_transaction())
-+      {
-+	my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+                   ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+	break;
-+      }
-+      mysql_log.write(thd,command,db);
-+      mysql_rm_db(thd, db, 0, 0);
-+      break;
-+    }
-+#ifndef EMBEDDED_LIBRARY
-+  case COM_BINLOG_DUMP:
-+    {
-+      ulong pos;
-+      ushort flags;
-+      uint32 slave_server_id;
-+
-+      statistic_increment(thd->status_var.com_other,&LOCK_status);
-+      thd->enable_slow_log= opt_log_slow_admin_statements;
-+      if (check_global_access(thd, REPL_SLAVE_ACL))
-+	break;
-+
-+      /* TODO: The following has to be changed to an 8 byte integer */
-+      pos = uint4korr(packet);
-+      flags = uint2korr(packet + 4);
-+      thd->server_id=0; /* avoid suicide */
-+      if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
-+	kill_zombie_dump_threads(slave_server_id);
-+      thd->server_id = slave_server_id;
-+
-+      mysql_log.write(thd, command, "Log: '%s'  Pos: %ld", packet+10,
-+                      (long) pos);
-+      mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
-+      unregister_slave(thd,1,1);
-+      /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
-+      error = TRUE;
-+      net->error = 0;
-+      break;
-+    }
-+#endif
-+  case COM_REFRESH:
-+  {
-+    bool not_used;
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_FLUSH],
-+                        &LOCK_status);
-+    ulong options= (ulong) (uchar) packet[0];
-+    if (check_global_access(thd,RELOAD_ACL))
-+      break;
-+    mysql_log.write(thd,command,NullS);
-+    if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
-+      send_ok(thd);
-+    break;
-+  }
-+#ifndef EMBEDDED_LIBRARY
-+  case COM_SHUTDOWN:
-+  {
-+    statistic_increment(thd->status_var.com_other, &LOCK_status);
-+    if (check_global_access(thd,SHUTDOWN_ACL))
-+      break; /* purecov: inspected */
-+    /*
-+      If the client is < 4.1.3, it is going to send us no argument; then
-+      packet_length is 1, packet[0] is the end 0 of the packet. Note that
-+      SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
-+      packet[0].
-+    */
-+    enum mysql_enum_shutdown_level level=
-+      (enum mysql_enum_shutdown_level) (uchar) packet[0];
-+    DBUG_PRINT("quit",("Got shutdown command for level %u", level));
-+    if (level == SHUTDOWN_DEFAULT)
-+      level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
-+    else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
-+    {
-+      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
-+      break;
-+    }
-+    DBUG_PRINT("quit",("Got shutdown command for level %u", level));
-+    mysql_log.write(thd,command,NullS);
-+    send_eof(thd);
-+#ifdef __WIN__
-+    sleep(1);					// must wait after eof()
-+#endif
-+#ifndef OS2
-+    send_eof(thd);				// This is for 'quit request'
-+#endif
-+    close_connection(thd, 0, 1);
-+    close_thread_tables(thd);			// Free before kill
-+    kill_mysql();
-+    error=TRUE;
-+    break;
-+  }
-+#endif
-+  case COM_STATISTICS:
-+  {
-+    mysql_log.write(thd,command,NullS);
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
-+			&LOCK_status);
-+#ifndef EMBEDDED_LIBRARY
-+    char buff[200];
-+#else
-+    char *buff= thd->net.last_error;
-+#endif
-+
-+    STATUS_VAR current_global_status_var;
-+    calc_sum_of_all_status(&current_global_status_var);
-+
-+    ulong uptime = (ulong) (thd->start_time - start_time);
-+    sprintf((char*) buff,
-+	    "Uptime: %lu  Threads: %d  Questions: %lu  Slow queries: %lu  Opens: %lu  Flush tables: %lu  Open tables: %u  Queries per second avg: %.3f",
-+	    uptime,
-+	    (int) thread_count, (ulong) thd->query_id,
-+	    current_global_status_var.long_query_count,
-+	    current_global_status_var.opened_tables, refresh_version, cached_tables(),
-+	    (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) :
-+	     (double) 0));
-+#ifdef SAFEMALLOC
-+    if (sf_malloc_cur_memory)				// Using SAFEMALLOC
-+      sprintf(strend(buff), "  Memory in use: %ldK  Max memory used: %ldK",
-+	      (sf_malloc_cur_memory+1023L)/1024L,
-+	      (sf_malloc_max_memory+1023L)/1024L);
-+#endif
-+#ifndef EMBEDDED_LIBRARY
-+    VOID(my_net_write(net, buff,(uint) strlen(buff)));
-+    VOID(net_flush(net));
-+#endif
-+    break;
-+  }
-+  case COM_PING:
-+    statistic_increment(thd->status_var.com_other, &LOCK_status);
-+    send_ok(thd);				// Tell client we are alive
-+    break;
-+  case COM_PROCESS_INFO:
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST],
-+			&LOCK_status);
-+    if (!thd->security_ctx->priv_user[0] &&
-+        check_global_access(thd, PROCESS_ACL))
-+      break;
-+    mysql_log.write(thd,command,NullS);
-+    mysqld_list_processes(thd,
-+			  thd->security_ctx->master_access & PROCESS_ACL ? 
-+			  NullS : thd->security_ctx->priv_user, 0);
-+    break;
-+  case COM_PROCESS_KILL:
-+  {
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_KILL], &LOCK_status);
-+    ulong id=(ulong) uint4korr(packet);
-+    kill_one_thread(thd,id,false);
-+    break;
-+  }
-+  case COM_SET_OPTION:
-+  {
-+    statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION],
-+			&LOCK_status);
-+    enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet);
-+    switch (command) {
-+    case MYSQL_OPTION_MULTI_STATEMENTS_ON:
-+      thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
-+      send_eof(thd);
-+      break;
-+    case MYSQL_OPTION_MULTI_STATEMENTS_OFF:
-+      thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
-+      send_eof(thd);
-+      break;
-+    default:
-+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+      break;
-+    }
-+    break;
-+  }
-+  case COM_DEBUG:
-+    statistic_increment(thd->status_var.com_other, &LOCK_status);
-+    if (check_global_access(thd, SUPER_ACL))
-+      break;					/* purecov: inspected */
-+    mysql_print_status();
-+    mysql_log.write(thd,command,NullS);
-+    send_eof(thd);
-+    break;
-+  case COM_SLEEP:
-+  case COM_CONNECT:				// Impossible here
-+  case COM_TIME:				// Impossible from client
-+  case COM_DELAYED_INSERT:
-+  case COM_END:
-+  default:
-+    my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+    break;
-+  }
-+  if (thd->lock || thd->open_tables || thd->derived_tables ||
-+      thd->prelocked_mode)
-+  {
-+    thd->proc_info="closing tables";
-+    close_thread_tables(thd);			/* Free tables */
-+  }
-+  /*
-+    assume handlers auto-commit (if some doesn't - transaction handling
-+    in MySQL should be redesigned to support it; it's a big change,
-+    and it's not worth it - better to commit explicitly only writing
-+    transactions, read-only ones should better take care of themselves.
-+    saves some work in 2pc too)
-+    see also sql_base.cc - close_thread_tables()
-+  */
-+  bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
-+  if (!thd->active_transaction())
-+    thd->transaction.xid_state.xid.null();
-+
-+  /* report error issued during command execution */
-+  if (thd->killed_errno() && !thd->net.report_error)
-+    thd->send_kill_message();
-+  if (thd->net.report_error)
-+    net_send_error(thd);
-+
-+  log_slow_statement(thd);
-+
-+  thd->proc_info="cleaning up";
-+  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
-+  thd->proc_info=0;
-+  thd->command=COM_SLEEP;
-+  thd->query=0;
-+  thd->query_length=0;
-+  thread_running--;
-+  VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+  thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
-+  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
-+  DBUG_RETURN(error);
-+}
-+
-+
-+void log_slow_statement(THD *thd)
-+{
-+  time_t start_of_query;
-+
-+  /*
-+    The following should never be true with our current code base,
-+    but better to keep this here so we don't accidently try to log a
-+    statement in a trigger or stored function
-+  */
-+  if (unlikely(thd->in_sub_stmt))
-+    return;                                     // Don't set time for sub stmt
-+
-+  start_of_query= thd->start_time;
-+  thd->end_time();				// Set start time
-+
-+  /*
-+    Do not log administrative statements unless the appropriate option is
-+    set; do not log into slow log if reading from backup.
-+  */
-+  if (thd->enable_slow_log && !thd->user_time)
-+  {
-+    thd->proc_info="logging slow query";
-+
-+    if ((ulong) (thd->start_time - thd->time_after_lock) >
-+	thd->variables.long_query_time ||
-+        (thd->server_status &
-+	  (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
-+        (specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES) &&
-+        /* == SQLCOM_END unless this is a SHOW command */
-+        thd->lex->orig_sql_command == SQLCOM_END)
-+    {
-+      thd->status_var.long_query_count++;
-+      mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
-+    }
-+  }
-+}
-+
-+
-+/*
-+  Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
-+
-+  SYNOPSIS
-+    prepare_schema_table()
-+      thd              thread handle
-+      lex              current lex
-+      table_ident      table alias if it's used
-+      schema_table_idx the type of the INFORMATION_SCHEMA table to be
-+                       created
-+
-+  DESCRIPTION
-+    This function is used in the parser to convert a SHOW or DESCRIBE
-+    table_name command to a SELECT from INFORMATION_SCHEMA.
-+    It prepares a SELECT_LEX and a TABLE_LIST object to represent the
-+    given command as a SELECT parse tree.
-+
-+  NOTES
-+    Due to the way this function works with memory and LEX it cannot
-+    be used outside the parser (parse tree transformations outside
-+    the parser break PS and SP).
-+
-+  RETURN VALUE
-+    0                 success
-+    1                 out of memory or SHOW commands are not allowed
-+                      in this version of the server.
-+*/
-+
-+int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
-+                         enum enum_schema_tables schema_table_idx)
-+{
-+  DBUG_ENTER("prepare_schema_table");
-+  SELECT_LEX *sel= 0;
-+  switch (schema_table_idx) {
-+  case SCH_SCHEMATA:
-+#if defined(DONT_ALLOW_SHOW_COMMANDS)
-+    my_message(ER_NOT_ALLOWED_COMMAND,
-+               ER(ER_NOT_ALLOWED_COMMAND), MYF(0));   /* purecov: inspected */
-+    DBUG_RETURN(1);
-+#else
-+    if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
-+	check_global_access(thd, SHOW_DB_ACL))
-+      DBUG_RETURN(1);
-+    break;
-+#endif
-+  case SCH_TABLE_NAMES:
-+  case SCH_TABLES:
-+  case SCH_VIEWS:
-+  case SCH_TRIGGERS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND,
-+               ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
-+    DBUG_RETURN(1);
-+#else
-+    {
-+      char *db;
-+      if (lex->select_lex.db == NULL &&
-+          thd->copy_db_to(&lex->select_lex.db, 0))
-+      {
-+        DBUG_RETURN(1);
-+      }
-+      db= lex->select_lex.db;
-+      remove_escape(db);				// Fix escaped '_'
-+      if (check_db_name(db))
-+      {
-+        my_error(ER_WRONG_DB_NAME, MYF(0), db);
-+        DBUG_RETURN(1);
-+      }
-+      if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
-+                       is_schema_db(db)))
-+        DBUG_RETURN(1);			        /* purecov: inspected */
-+      if (!thd->col_access && check_grant_db(thd,db))
-+      {
-+	my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+                 thd->security_ctx->priv_user, thd->security_ctx->priv_host,
-+                 db);
-+	DBUG_RETURN(1);
-+      }
-+      break;
-+    }
-+#endif
-+  case SCH_COLUMNS:
-+  case SCH_STATISTICS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND,
-+               ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
-+    DBUG_RETURN(1);
-+#else
-+    if (table_ident)
-+    {
-+      TABLE_LIST **query_tables_last= lex->query_tables_last;
-+      sel= new SELECT_LEX();
-+      /* 'parent_lex' is used in init_query() so it must be before it. */
-+      sel->parent_lex= lex;
-+      sel->init_query();
-+      if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, 
-+                                 (List<String> *) 0, (List<String> *) 0))
-+        DBUG_RETURN(1);
-+      lex->query_tables_last= query_tables_last;
-+      TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first;
-+      char *db= table_list->db;
-+      remove_escape(db);			// Fix escaped '_'
-+      remove_escape(table_list->table_name);
-+      if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
-+                       &table_list->grant.privilege, 0, 0,
-+                       test(table_list->schema_table)))
-+        DBUG_RETURN(1);				/* purecov: inspected */
-+      if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2,
-+                                      UINT_MAX, 0))
-+        DBUG_RETURN(1);
-+      break;
-+    }
-+#endif
-+  case SCH_OPEN_TABLES:
-+  case SCH_VARIABLES:
-+  case SCH_STATUS:
-+  case SCH_PROCEDURES:
-+  case SCH_CHARSETS:
-+  case SCH_COLLATIONS:
-+  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
-+  case SCH_USER_PRIVILEGES:
-+  case SCH_SCHEMA_PRIVILEGES:
-+  case SCH_TABLE_PRIVILEGES:
-+  case SCH_COLUMN_PRIVILEGES:
-+  case SCH_TABLE_CONSTRAINTS:
-+  case SCH_KEY_COLUMN_USAGE:
-+  default:
-+    break;
-+  }
-+  
-+  SELECT_LEX *select_lex= lex->current_select;
-+  if (make_schema_select(thd, select_lex, schema_table_idx))
-+  {
-+    DBUG_RETURN(1);
-+  }
-+  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);
-+}
-+
-+
-+/*
-+  Read query from packet and store in thd->query
-+  Used in COM_QUERY and COM_STMT_PREPARE
-+
-+  DESCRIPTION
-+    Sets the following THD variables:
-+      query
-+      query_length
-+
-+  RETURN VALUES
-+    FALSE ok
-+    TRUE  error;  In this case thd->fatal_error is set
-+*/
-+
-+bool alloc_query(THD *thd, const char *packet, uint packet_length)
-+{
-+  packet_length--;				// Remove end null
-+  /* Remove garbage at start and end of query */
-+  while (my_isspace(thd->charset(),packet[0]) && packet_length > 0)
-+  {
-+    packet++;
-+    packet_length--;
-+  }
-+  const char *pos= packet + packet_length;     // Point at end null
-+  while (packet_length > 0 &&
-+	 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
-+  {
-+    pos--;
-+    packet_length--;
-+  }
-+  /* We must allocate some extra memory for query cache */
-+  thd->query_length= 0;                        // Extra safety: Avoid races
-+  if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
-+					      packet_length,
-+					      thd->db_length+ 1 +
-+					      QUERY_CACHE_FLAGS_SIZE)))
-+    return TRUE;
-+  thd->query[packet_length]=0;
-+  thd->query_length= packet_length;
-+
-+  /* Reclaim some memory */
-+  thd->packet.shrink(thd->variables.net_buffer_length);
-+  thd->convert_buffer.shrink(thd->variables.net_buffer_length);
-+
-+  return FALSE;
-+}
-+
-+static void reset_one_shot_variables(THD *thd) 
-+{
-+  thd->variables.character_set_client=
-+    global_system_variables.character_set_client;
-+  thd->variables.collation_connection=
-+    global_system_variables.collation_connection;
-+  thd->variables.collation_database=
-+    global_system_variables.collation_database;
-+  thd->variables.collation_server=
-+    global_system_variables.collation_server;
-+  thd->update_charset();
-+  thd->variables.time_zone=
-+    global_system_variables.time_zone;
-+  thd->one_shot_set= 0;
-+}
-+
-+
-+/*
-+  Execute command saved in thd and lex->sql_command
-+
-+  SYNOPSIS
-+    mysql_execute_command()
-+      thd                       Thread handle
-+
-+  IMPLEMENTATION
-+
-+    Before every operation that can request a write lock for a table
-+    wait if a global read lock exists. However do not wait if this
-+    thread has locked tables already. No new locks can be requested
-+    until the other locks are released. The thread that requests the
-+    global read lock waits for write locked tables to become unlocked.
-+
-+    Note that wait_if_global_read_lock() sets a protection against a new
-+    global read lock when it succeeds. This needs to be released by
-+    start_waiting_global_read_lock() after the operation.
-+
-+  RETURN
-+    FALSE       OK
-+    TRUE        Error
-+*/
-+
-+bool
-+mysql_execute_command(THD *thd)
-+{
-+  bool res= FALSE;
-+  bool need_start_waiting= FALSE; // have protection against global read lock
-+  int  result= 0;
-+  LEX  *lex= thd->lex;
-+  /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
-+  SELECT_LEX *select_lex= &lex->select_lex;
-+  /* first table of first SELECT_LEX */
-+  TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
-+  /* list of all tables in query */
-+  TABLE_LIST *all_tables;
-+  /* most outer SELECT_LEX_UNIT of query */
-+  SELECT_LEX_UNIT *unit= &lex->unit;
-+  /* Saved variable value */
-+  DBUG_ENTER("mysql_execute_command");
-+  thd->net.no_send_error= 0;
-+
-+  /*
-+    Remember first generated insert id value of the previous
-+    statement.  We remember it here at the beginning of the statement,
-+    and also in Item_func_last_insert_id::fix_fields() and
-+    sys_var_last_insert_id::value_ptr().  Last two places are required
-+    because LAST_INSERT_ID() and @@LAST_INSERT_ID may also be used in
-+    expression that is not executed with mysql_execute_command().
-+
-+    And we remember it here because some statements read
-+    @@LAST_INSERT_ID indirectly, like "SELECT * FROM t1 WHERE id IS
-+    NULL", that may replace "id IS NULL" with "id = <LAST_INSERT_ID>".
-+  */
-+  thd->current_insert_id= thd->last_insert_id;
-+
-+  /*
-+    In many cases first table of main SELECT_LEX have special meaning =>
-+    check that it is first table in global list and relink it first in 
-+    queries_tables list if it is necessary (we need such relinking only
-+    for queries with subqueries in select list, in this case tables of
-+    subqueries will go to global list first)
-+
-+    all_tables will differ from first_table only if most upper SELECT_LEX
-+    do not contain tables.
-+
-+    Because of above in place where should be at least one table in most
-+    outer SELECT_LEX we have following check:
-+    DBUG_ASSERT(first_table == all_tables);
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+  */
-+  lex->first_lists_tables_same();
-+  /* should be assigned after making first tables same */
-+  all_tables= lex->query_tables;
-+  /* set context for commands which do not use setup_tables */
-+  select_lex->
-+    context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
-+                                       table_list.first);
-+
-+  /*
-+    Reset warning count for each query that uses tables
-+    A better approach would be to reset this for any commands
-+    that is not a SHOW command or a select that only access local
-+    variables, but for now this is probably good enough.
-+    Don't reset warnings when executing a stored routine.
-+  */
-+  if ((all_tables || &lex->select_lex != lex->all_selects_list ||
-+       lex->sroutines.records) && !thd->spcont ||
-+      lex->time_zone_tables_used)
-+    mysql_reset_errors(thd, 0);
-+
-+#ifdef HAVE_REPLICATION
-+  if (unlikely(thd->slave_thread))
-+  {
-+    /*
-+      Check if statment should be skipped because of slave filtering
-+      rules
-+
-+      Exceptions are:
-+      - UPDATE MULTI: For this statement, we want to check the filtering
-+        rules later in the code
-+      - SET: we always execute it (Not that many SET commands exists in
-+        the binary log anyway -- only 4.1 masters write SET statements,
-+	in 5.0 there are no SET statements in the binary log)
-+      - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
-+        have stale files on slave caused by exclusion of one tmp table).
-+    */
-+    if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
-+	!(lex->sql_command == SQLCOM_SET_OPTION) &&
-+	!(lex->sql_command == SQLCOM_DROP_TABLE &&
-+          lex->drop_temporary && lex->drop_if_exists) &&
-+        all_tables_not_ok(thd, all_tables))
-+    {
-+      /* we warn the slave SQL thread */
-+      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+      if (thd->one_shot_set)
-+      {
-+        /*
-+          It's ok to check thd->one_shot_set here:
-+
-+          The charsets in a MySQL 5.0 slave can change by both a binlogged
-+          SET ONE_SHOT statement and the event-internal charset setting, 
-+          and these two ways to change charsets do not seems to work
-+          together.
-+
-+          At least there seems to be problems in the rli cache for
-+          charsets if we are using ONE_SHOT.  Note that this is normally no
-+          problem because either the >= 5.0 slave reads a 4.1 binlog (with
-+          ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
-+        */
-+        reset_one_shot_variables(thd);
-+      }
-+      DBUG_RETURN(0);
-+    }
-+  }
-+  else
-+  {
-+#endif /* HAVE_REPLICATION */
-+    /*
-+      When option readonly is set deny operations which change non-temporary
-+      tables. Except for the replication thread and the 'super' users.
-+    */
-+    if (opt_readonly &&
-+        !(thd->security_ctx->master_access & SUPER_ACL) &&
-+        uc_update_queries[lex->sql_command] &&
-+        !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
-+          (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
-+        !((lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary) &&
-+        ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
-+          some_non_temp_table_to_be_updated(thd, all_tables)))
-+    {
-+      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-+      DBUG_RETURN(-1);
-+    }
-+#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);
-+
-+  switch (lex->sql_command) {
-+  case SQLCOM_SELECT:
-+  {
-+    /* 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;
-+    if (all_tables)
-+    {
-+      if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
-+          lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC)
-+        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;
-+      }
-+    }
-+    break;
-+  }
-+  case SQLCOM_PREPARE:
-+  {
-+    mysql_sql_stmt_prepare(thd);
-+    break;
-+  }
-+  case SQLCOM_EXECUTE:
-+  {
-+    mysql_sql_stmt_execute(thd);
-+    break;
-+  }
-+  case SQLCOM_DEALLOCATE_PREPARE:
-+  {
-+    mysql_sql_stmt_close(thd);
-+    break;
-+  }
-+  case SQLCOM_DO:
-+    if (check_table_access(thd, SELECT_ACL, all_tables, 0) ||
-+        open_and_lock_tables(thd, all_tables))
-+      goto error;
-+
-+    res= mysql_do(thd, *lex->insert_list);
-+    break;
-+
-+  case SQLCOM_EMPTY_QUERY:
-+    send_ok(thd);
-+    break;
-+
-+  case SQLCOM_HELP:
-+    res= mysqld_help(thd,lex->help_arg);
-+    break;
-+
-+#ifndef EMBEDDED_LIBRARY
-+  case SQLCOM_PURGE:
-+  {
-+    if (check_global_access(thd, SUPER_ACL))
-+      goto error;
-+    /* PURGE MASTER LOGS TO 'file' */
-+    res = purge_master_logs(thd, lex->to_log);
-+    break;
-+  }
-+  case SQLCOM_PURGE_BEFORE:
-+  {
-+    Item *it;
-+
-+    if (check_global_access(thd, SUPER_ACL))
-+      goto error;
-+    /* PURGE MASTER LOGS BEFORE 'data' */
-+    it= (Item *)lex->value_list.head();
-+    if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
-+        it->check_cols(1))
-+    {
-+      my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
-+      goto error;
-+    }
-+    it= new Item_func_unix_timestamp(it);
-+    /*
-+      it is OK only emulate fix_fieds, because we need only
-+      value of constant
-+    */
-+    it->quick_fix_field();
-+    res = purge_master_logs_before_date(thd, (ulong)it->val_int());
-+    break;
-+  }
-+#endif
-+  case SQLCOM_SHOW_WARNS:
-+  {
-+    res= mysqld_show_warnings(thd, (ulong)
-+			      ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
-+			       (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
-+			       (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
-+			       ));
-+    break;
-+  }
-+  case SQLCOM_SHOW_ERRORS:
-+  {
-+    res= mysqld_show_warnings(thd, (ulong)
-+			      (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
-+    break;
-+  }
-+  case SQLCOM_SHOW_NEW_MASTER:
-+  {
-+    if (check_global_access(thd, REPL_SLAVE_ACL))
-+      goto error;
-+    /* This query don't work now. See comment in repl_failsafe.cc */
-+#ifndef WORKING_NEW_MASTER
-+    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER");
-+    goto error;
-+#else
-+    res = show_new_master(thd);
-+    break;
-+#endif
-+  }
-+
-+#ifdef HAVE_REPLICATION
-+  case SQLCOM_SHOW_SLAVE_HOSTS:
-+  {
-+    if (check_global_access(thd, REPL_SLAVE_ACL))
-+      goto error;
-+    res = show_slave_hosts(thd);
-+    break;
-+  }
-+  case SQLCOM_SHOW_BINLOG_EVENTS:
-+  {
-+    if (check_global_access(thd, REPL_SLAVE_ACL))
-+      goto error;
-+    res = mysql_show_binlog_events(thd);
-+    break;
-+  }
-+#endif
-+
-+  case SQLCOM_BACKUP_TABLE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL, all_tables, 0) ||
-+	check_global_access(thd, FILE_ACL))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res = mysql_backup_table(thd, first_table);
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+  case SQLCOM_RESTORE_TABLE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, INSERT_ACL, all_tables, 0) ||
-+	check_global_access(thd, FILE_ACL))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res = mysql_restore_table(thd, first_table);
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+  case SQLCOM_ASSIGN_TO_KEYCACHE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+        check_access(thd, INDEX_ACL, first_table->db,
-+                     &first_table->grant.privilege, 0, 0,
-+                     test(first_table->schema_table)))
-+      goto error;
-+    res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
-+    break;
-+  }
-+  case SQLCOM_PRELOAD_KEYS:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_access(thd, INDEX_ACL, first_table->db,
-+                     &first_table->grant.privilege, 0, 0,
-+                     test(first_table->schema_table)))
-+      goto error;
-+    res = mysql_preload_keys(thd, first_table);
-+    break;
-+  }
-+#ifdef HAVE_REPLICATION
-+  case SQLCOM_CHANGE_MASTER:
-+  {
-+    if (check_global_access(thd, SUPER_ACL))
-+      goto error;
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    res = change_master(thd,active_mi);
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+    break;
-+  }
-+  case SQLCOM_SHOW_SLAVE_STAT:
-+  {
-+    /* Accept one of two privileges */
-+    if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
-+      goto error;
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    res = show_master_info(thd,active_mi);
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+    break;
-+  }
-+  case SQLCOM_SHOW_MASTER_STAT:
-+  {
-+    /* Accept one of two privileges */
-+    if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
-+      goto error;
-+    res = show_binlog_info(thd);
-+    break;
-+  }
-+
-+  case SQLCOM_LOAD_MASTER_DATA: // sync with master
-+    if (check_global_access(thd, SUPER_ACL))
-+      goto error;
-+    if (end_active_trans(thd))
-+      goto error;
-+    else
-+      res = load_master_data(thd);
-+    break;
-+#endif /* HAVE_REPLICATION */
-+#ifdef HAVE_NDBCLUSTER_DB
-+  case SQLCOM_SHOW_NDBCLUSTER_STATUS:
-+    {
-+      res = ndbcluster_show_status(thd);
-+      break;
-+    }
-+#endif
-+#ifdef HAVE_INNOBASE_DB
-+  case SQLCOM_SHOW_INNODB_STATUS:
-+    {
-+      if (check_global_access(thd, SUPER_ACL))
-+	goto error;
-+      res = innodb_show_status(thd);
-+      break;
-+    }
-+  case SQLCOM_SHOW_MUTEX_STATUS:
-+    {
-+      if (check_global_access(thd, SUPER_ACL))
-+        goto error;
-+      res = innodb_mutex_show_status(thd);
-+      break;
-+    }
-+#endif
-+#ifdef HAVE_REPLICATION
-+  case SQLCOM_LOAD_MASTER_TABLE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    DBUG_ASSERT(first_table->db); /* Must be set in the parser */
-+
-+    if (check_access(thd, CREATE_ACL, first_table->db,
-+		     &first_table->grant.privilege, 0, 0,
-+                     test(first_table->schema_table)))
-+      goto error;				/* purecov: inspected */
-+    if (grant_option)
-+    {
-+      /* Check that the first table has CREATE privilege */
-+      if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
-+	goto error;
-+    }
-+    if (strlen(first_table->table_name) > NAME_LEN)
-+    {
-+      my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->table_name);
-+      break;
-+    }
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    /*
-+      fetch_master_table will send the error to the client on failure.
-+      Give error if the table already exists.
-+    */
-+    if (!fetch_master_table(thd, first_table->db, first_table->table_name,
-+			    active_mi, 0, 0))
-+    {
-+      send_ok(thd);
-+    }
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+    break;
-+  }
-+#endif /* HAVE_REPLICATION */
-+
-+  case SQLCOM_CREATE_TABLE:
-+  {
-+    /* If CREATE TABLE of non-temporary table, do implicit commit */
-+    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+    {
-+      if (end_active_trans(thd))
-+      {
-+	res= -1;
-+	break;
-+      }
-+    }
-+    else 
-+    {
-+      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
-+      thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
-+    }
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    bool link_to_local;
-+    // Skip first table, which is the table we are creating
-+    TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
-+    TABLE_LIST *select_tables= lex->query_tables;
-+
-+    if ((res= create_table_precheck(thd, select_tables, create_table)))
-+      goto end_with_restore_list;
-+
-+#ifndef HAVE_READLINK
-+    lex->create_info.data_file_name=lex->create_info.index_file_name=0;
-+#else
-+    /* Fix names if symlinked tables */
-+    if (append_file_to_dir(thd, &lex->create_info.data_file_name,
-+			   create_table->table_name) ||
-+	append_file_to_dir(thd, &lex->create_info.index_file_name,
-+			   create_table->table_name))
-+      goto end_with_restore_list;
-+#endif
-+    /*
-+      If we are using SET CHARSET without DEFAULT, add an implicit
-+      DEFAULT to not confuse old users. (This may change).
-+    */
-+    if ((lex->create_info.used_fields & 
-+	 (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
-+	HA_CREATE_USED_CHARSET)
-+    {
-+      lex->create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
-+      lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
-+      lex->create_info.default_table_charset= lex->create_info.table_charset;
-+      lex->create_info.table_charset= 0;
-+    }
-+    /*
-+      The create-select command will open and read-lock the select table
-+      and then create, open and write-lock the new table. If a global
-+      read lock steps in, we get a deadlock. The write lock waits for
-+      the global read lock, while the global read lock waits for the
-+      select table to be closed. So we wait until the global readlock is
-+      gone before starting both steps. Note that
-+      wait_if_global_read_lock() sets a protection against a new global
-+      read lock when it succeeds. This needs to be released by
-+      start_waiting_global_read_lock(). We protect the normal CREATE
-+      TABLE in the same way. That way we avoid that a new table is
-+      created during a gobal read lock.
-+    */
-+    if (!thd->locked_tables &&
-+        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+    {
-+      res= 1;
-+      goto end_with_restore_list;
-+    }
-+    if (select_lex->item_list.elements)		// With select
-+    {
-+      select_result *result;
-+
-+      select_lex->options|= SELECT_NO_UNLOCK;
-+      unit->set_limit(select_lex);
-+
-+      if (!(res= open_and_lock_tables(thd, select_tables)))
-+      {
-+        /*
-+          Is table which we are changing used somewhere in other parts
-+          of query
-+        */
-+        if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+        {
-+          TABLE_LIST *duplicate;
-+          if ((duplicate= unique_table(thd, create_table, select_tables)))
-+          {
-+            update_non_unique_table_error(create_table, "CREATE", duplicate);
-+            res= 1;
-+            goto end_with_restore_list;
-+          }
-+        }
-+        /* If we create merge table, we have to test tables in merge, too */
-+        if (lex->create_info.used_fields & HA_CREATE_USED_UNION)
-+        {
-+          TABLE_LIST *tab;
-+          for (tab= (TABLE_LIST*) lex->create_info.merge_list.first;
-+               tab;
-+               tab= tab->next_local)
-+          {
-+            TABLE_LIST *duplicate;
-+            if ((duplicate= unique_table(thd, tab, select_tables)))
-+            {
-+              update_non_unique_table_error(tab, "CREATE", duplicate);
-+              res= 1;
-+              goto end_with_restore_list;
-+            }
-+          }
-+        }
-+
-+        if ((result= new select_create(create_table,
-+				       &lex->create_info,
-+				       lex->create_list,
-+				       lex->key_list,
-+				       select_lex->item_list,
-+				       lex->duplicates,
-+				       lex->ignore)))
-+        {
-+          /*
-+            CREATE from SELECT give its SELECT_LEX for SELECT,
-+            and item_list belong to SELECT
-+          */
-+          res= handle_select(thd, lex, result, 0);
-+          delete result;
-+        }
-+	/* reset for PS */
-+	lex->create_list.empty();
-+	lex->key_list.empty();
-+      }
-+    }
-+    else
-+    {
-+      /* regular create */
-+      if (lex->name)
-+        res= mysql_create_like_table(thd, create_table, &lex->create_info, 
-+                                     (Table_ident *)lex->name); 
-+      else
-+      {
-+        res= mysql_create_table(thd, create_table->db,
-+				create_table->table_name, &lex->create_info,
-+				lex->create_list,
-+				lex->key_list, 0, 0);
-+      }
-+      if (!res)
-+	send_ok(thd);
-+    }
-+
-+    /* put tables back for PS rexecuting */
-+end_with_restore_list:
-+    lex->link_first_table_back(create_table, link_to_local);
-+    break;
-+  }
-+  case SQLCOM_CREATE_INDEX:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_one_table_access(thd, INDEX_ACL, all_tables))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    if (end_active_trans(thd))
-+      goto error;
-+    else
-+      res = mysql_create_index(thd, first_table, lex->key_list);
-+    break;
-+
-+#ifdef HAVE_REPLICATION
-+  case SQLCOM_SLAVE_START:
-+  {
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    start_slave(thd,active_mi,1 /* net report*/);
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+    break;
-+  }
-+  case SQLCOM_SLAVE_STOP:
-+  /*
-+    If the client thread has locked tables, a deadlock is possible.
-+    Assume that
-+    - the client thread does LOCK TABLE t READ.
-+    - then the master updates t.
-+    - then the SQL slave thread wants to update t,
-+      so it waits for the client thread because t is locked by it.
-+    - then the client thread does SLAVE STOP.
-+      SLAVE STOP waits for the SQL slave thread to terminate its
-+      update t, which waits for the client thread because t is locked by it.
-+    To prevent that, refuse SLAVE STOP if the
-+    client thread has locked tables
-+  */
-+  if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
-+  {
-+    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+    goto error;
-+  }
-+  {
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    stop_slave(thd,active_mi,1/* net report*/);
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+    break;
-+  }
-+#endif /* HAVE_REPLICATION */
-+
-+  case SQLCOM_ALTER_TABLE:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    {
-+      ulong priv=0;
-+      if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
-+      {
-+	my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
-+        goto error;
-+      }
-+      /* Must be set in the parser */
-+      DBUG_ASSERT(select_lex->db);
-+      if (check_access(thd, ALTER_ACL, first_table->db,
-+		       &first_table->grant.privilege, 0, 0,
-+                       test(first_table->schema_table)) ||
-+	  check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
-+                       is_schema_db(select_lex->db))||
-+	  check_merge_table_access(thd, first_table->db,
-+				   (TABLE_LIST *)
-+				   lex->create_info.merge_list.first))
-+	goto error;				/* purecov: inspected */
-+      if (grant_option)
-+      {
-+	if (check_grant(thd, ALTER_ACL, all_tables, 0, UINT_MAX, 0))
-+	  goto error;
-+	if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
-+	{					// Rename of table
-+	  TABLE_LIST tmp_table;
-+	  bzero((char*) &tmp_table,sizeof(tmp_table));
-+	  tmp_table.table_name=lex->name;
-+	  tmp_table.db=select_lex->db;
-+	  tmp_table.grant.privilege=priv;
-+	  if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
-+			  UINT_MAX, 0))
-+	    goto error;
-+	}
-+      }
-+      /* Don't yet allow changing of symlinks with ALTER TABLE */
-+      if (lex->create_info.data_file_name)
-+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
-+                     "DATA DIRECTORY option ignored");
-+      if (lex->create_info.index_file_name)
-+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
-+                     "INDEX DIRECTORY option ignored");
-+      lex->create_info.data_file_name=lex->create_info.index_file_name=0;
-+      /* ALTER TABLE ends previous transaction */
-+      if (end_active_trans(thd))
-+	goto error;
-+      else
-+      {
-+        if (!thd->locked_tables &&
-+            !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+        {
-+          res= 1;
-+          break;
-+        }
-+
-+        thd->enable_slow_log= opt_log_slow_admin_statements;
-+	res= mysql_alter_table(thd, select_lex->db, lex->name,
-+			       &lex->create_info,
-+			       first_table, lex->create_list,
-+			       lex->key_list,
-+			       select_lex->order_list.elements,
-+                               (ORDER *) select_lex->order_list.first,
-+			       lex->ignore, &lex->alter_info, 1);
-+      }
-+      break;
-+    }
-+  case SQLCOM_RENAME_TABLE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    TABLE_LIST *table;
-+    if (check_db_used(thd, all_tables))
-+      goto error;
-+    for (table= first_table; table; table= table->next_local->next_local)
-+    {
-+      if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
-+		       &table->grant.privilege,0,0, test(table->schema_table)) ||
-+	  check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
-+		       &table->next_local->grant.privilege, 0, 0,
-+                       test(table->next_local->schema_table)))
-+	goto error;
-+      if (grant_option)
-+      {
-+	TABLE_LIST old_list, new_list;
-+	/*
-+	  we do not need initialize old_list and new_list because we will
-+	  come table[0] and table->next[0] there
-+	*/
-+	old_list= table[0];
-+	new_list= table->next_local[0];
-+	if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
-+	    (!test_all_bits(table->next_local->grant.privilege,
-+			    INSERT_ACL | CREATE_ACL) &&
-+	     check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
-+	  goto error;
-+      }
-+    }
-+    query_cache_invalidate3(thd, first_table, 0);
-+    if (end_active_trans(thd) || mysql_rename_tables(thd, first_table))
-+      goto error;
-+    break;
-+  }
-+#ifndef EMBEDDED_LIBRARY
-+  case SQLCOM_SHOW_BINLOGS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+               MYF(0)); /* purecov: inspected */
-+    goto error;
-+#else
-+    {
-+      if (check_global_access(thd, SUPER_ACL))
-+	goto error;
-+      res = show_binlogs(thd);
-+      break;
-+    }
-+#endif
-+#endif /* EMBEDDED_LIBRARY */
-+  case SQLCOM_SHOW_CREATE:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+               MYF(0)); /* purecov: inspected */
-+    goto error;
-+#else
-+    {
-+      /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
-+      if (lex->only_view)
-+        first_table->skip_temporary= 1;
-+
-+      if (check_db_used(thd, all_tables) ||
-+	  check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db,
-+		       &first_table->grant.privilege, 0, 0, 
-+                       test(first_table->schema_table)))
-+	goto error;
-+      if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0))
-+	goto error;
-+      res= mysqld_show_create(thd, first_table);
-+      break;
-+    }
-+#endif
-+  case SQLCOM_CHECKSUM:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, 0))
-+      goto error; /* purecov: inspected */
-+    res = mysql_checksum_table(thd, first_table, &lex->check_opt);
-+    break;
-+  }
-+  case SQLCOM_REPAIR:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res= mysql_repair_table(thd, first_table, &lex->check_opt);
-+    /* ! we write after unlocking the table */
-+    if (!res && !lex->no_write_to_binlog)
-+    {
-+      /* Presumably, REPAIR and binlog writing doesn't require synchronization */
-+      if (mysql_bin_log.is_open())
-+      {
-+	thd->clear_error(); // No binlog error generated
-+        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-+        mysql_bin_log.write(&qinfo);
-+      }
-+    }
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+  case SQLCOM_CHECK:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, 0))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res = mysql_check_table(thd, first_table, &lex->check_opt);
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+  case SQLCOM_ANALYZE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res = mysql_analyze_table(thd, first_table, &lex->check_opt);
-+    /* ! we write after unlocking the table */
-+    if (!res && !lex->no_write_to_binlog)
-+    {
-+      /* Presumably, ANALYZE and binlog writing doesn't require synchronization */
-+      if (mysql_bin_log.is_open())
-+      {
-+	thd->clear_error(); // No binlog error generated
-+        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-+        mysql_bin_log.write(&qinfo);
-+      }
-+    }
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+
-+  case SQLCOM_OPTIMIZE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
-+      goto error; /* purecov: inspected */
-+    thd->enable_slow_log= opt_log_slow_admin_statements;
-+    res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
-+      mysql_recreate_table(thd, first_table, 1) :
-+      mysql_optimize_table(thd, first_table, &lex->check_opt);
-+    /* ! we write after unlocking the table */
-+    if (!res && !lex->no_write_to_binlog)
-+    {
-+      /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */
-+      if (mysql_bin_log.is_open())
-+      {
-+	thd->clear_error(); // No binlog error generated
-+        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-+        mysql_bin_log.write(&qinfo);
-+      }
-+    }
-+    select_lex->table_list.first= (byte*) first_table;
-+    lex->query_tables=all_tables;
-+    break;
-+  }
-+  case SQLCOM_UPDATE:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (update_precheck(thd, all_tables))
-+      break;
-+    DBUG_ASSERT(select_lex->offset_limit == 0);
-+    unit->set_limit(select_lex);
-+    res= (result= mysql_update(thd, all_tables,
-+                               select_lex->item_list,
-+                               lex->value_list,
-+                               select_lex->where,
-+                               select_lex->order_list.elements,
-+                               (ORDER *) select_lex->order_list.first,
-+                               unit->select_limit_cnt,
-+                               lex->duplicates, lex->ignore));
-+    /* mysql_update return 2 if we need to switch to multi-update */
-+    if (result != 2)
-+      break;
-+  case SQLCOM_UPDATE_MULTI:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    /* if we switched from normal update, rights are checked */
-+    if (result != 2)
-+    {
-+      if ((res= multi_update_precheck(thd, all_tables)))
-+        break;
-+    }
-+    else
-+      res= 0;
-+
-+    res= mysql_multi_update_prepare(thd);
-+
-+#ifdef HAVE_REPLICATION
-+    /* Check slave filtering rules */
-+    if (unlikely(thd->slave_thread))
-+    {
-+      if (all_tables_not_ok(thd, all_tables))
-+      {
-+        if (res!= 0)
-+        {
-+          res= 0;             /* don't care of prev failure  */
-+          thd->clear_error(); /* filters are of highest prior */
-+        }
-+        /* we warn the slave SQL thread */
-+        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
-+        break;
-+      }
-+      if (res)
-+        break;
-+    }
-+    else
-+    {
-+#endif /* HAVE_REPLICATION */
-+      if (res)
-+        break;
-+      if (opt_readonly &&
-+	  !(thd->security_ctx->master_access & SUPER_ACL) &&
-+	  some_non_temp_table_to_be_updated(thd, all_tables))
-+      {
-+	my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-+	break;
-+      }
-+#ifdef HAVE_REPLICATION
-+    }  /* unlikely */
-+#endif
-+
-+    res= mysql_multi_update(thd, all_tables,
-+                            &select_lex->item_list,
-+                            &lex->value_list,
-+                            select_lex->where,
-+                            select_lex->options,
-+                            lex->duplicates, lex->ignore, unit, select_lex);
-+    break;
-+  }
-+  case SQLCOM_REPLACE:
-+  case SQLCOM_INSERT:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if ((res= insert_precheck(thd, all_tables)))
-+      break;
-+
-+    if (!thd->locked_tables &&
-+        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+    {
-+      res= 1;
-+      break;
-+    }
-+
-+    res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
-+		      lex->update_list, lex->value_list,
-+                      lex->duplicates, lex->ignore);
-+
-+    /*
-+      If we have inserted into a VIEW, and the base table has
-+      AUTO_INCREMENT column, but this column is not accessible through
-+      a view, then we should restore LAST_INSERT_ID to the value it
-+      had before the statement.
-+    */
-+    if (first_table->view && !first_table->contain_auto_increment)
-+      thd->last_insert_id= thd->current_insert_id;
-+
-+    break;
-+  }
-+  case SQLCOM_REPLACE_SELECT:
-+  case SQLCOM_INSERT_SELECT:
-+  {
-+    select_result *result;
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if ((res= insert_precheck(thd, all_tables)))
-+      break;
-+
-+    /* Fix lock for first table */
-+    if (first_table->lock_type == TL_WRITE_DELAYED)
-+      first_table->lock_type= TL_WRITE;
-+
-+    /* Don't unlock tables until command is written to binary log */
-+    select_lex->options|= SELECT_NO_UNLOCK;
-+
-+    unit->set_limit(select_lex);
-+
-+    if (! thd->locked_tables &&
-+        ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
-+    {
-+      res= 1;
-+      break;
-+    }
-+
-+    if (!(res= open_and_lock_tables(thd, all_tables)))
-+    {
-+      /* Skip first table, which is the table we are inserting in */
-+      TABLE_LIST *second_table= first_table->next_local;
-+      select_lex->table_list.first= (byte*) second_table;
-+      select_lex->context.table_list= 
-+        select_lex->context.first_name_resolution_table= second_table;
-+      res= mysql_insert_select_prepare(thd);
-+      if (!res && (result= new select_insert(first_table, first_table->table,
-+                                             &lex->field_list,
-+                                             &lex->update_list,
-+                                             &lex->value_list,
-+                                             lex->duplicates, lex->ignore)))
-+      {
-+	res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
-+        /*
-+          Invalidate the table in the query cache if something changed
-+          after unlocking when changes become visible.
-+          TODO: this is workaround. right way will be move invalidating in
-+          the unlock procedure.
-+        */
-+        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
-+            thd->lock)
-+        {
-+          /* INSERT ... SELECT should invalidate only the very first table */
-+          TABLE_LIST *save_table= first_table->next_local;
-+          first_table->next_local= 0;
-+          mysql_unlock_tables(thd, thd->lock);
-+          query_cache_invalidate3(thd, first_table, 1);
-+          first_table->next_local= save_table;
-+          thd->lock=0;
-+        }
-+        delete result;
-+      }
-+      /* revert changes for SP */
-+      select_lex->table_list.first= (byte*) first_table;
-+    }
-+
-+    /*
-+      If we have inserted into a VIEW, and the base table has
-+      AUTO_INCREMENT column, but this column is not accessible through
-+      a view, then we should restore LAST_INSERT_ID to the value it
-+      had before the statement.
-+    */
-+    if (first_table->view && !first_table->contain_auto_increment)
-+      thd->last_insert_id= thd->current_insert_id;
-+
-+    break;
-+  }
-+  case SQLCOM_TRUNCATE:
-+    if (end_active_trans(thd))
-+    {
-+      res= -1;
-+      break;
-+    }
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_one_table_access(thd, DELETE_ACL, all_tables))
-+      goto error;
-+    /*
-+      Don't allow this within a transaction because we want to use
-+      re-generate table
-+    */
-+    if (thd->locked_tables || thd->active_transaction())
-+    {
-+      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+      goto error;
-+    }
-+
-+    res= mysql_truncate(thd, first_table, 0);
-+    break;
-+  case SQLCOM_DELETE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if ((res= delete_precheck(thd, all_tables)))
-+      break;
-+    DBUG_ASSERT(select_lex->offset_limit == 0);
-+    unit->set_limit(select_lex);
-+
-+    if (!thd->locked_tables &&
-+        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+    {
-+      res= 1;
-+      break;
-+    }
-+
-+    res = mysql_delete(thd, all_tables, select_lex->where,
-+                       &select_lex->order_list,
-+                       unit->select_limit_cnt, select_lex->options,
-+                       FALSE);
-+    break;
-+  }
-+  case SQLCOM_DELETE_MULTI:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    TABLE_LIST *aux_tables=
-+      (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
-+    multi_delete *result;
-+
-+    if (!thd->locked_tables &&
-+        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+    {
-+      res= 1;
-+      break;
-+    }
-+
-+    if ((res= multi_delete_precheck(thd, all_tables)))
-+      break;
-+
-+    /* condition will be TRUE on SP re-excuting */
-+    if (select_lex->item_list.elements != 0)
-+      select_lex->item_list.empty();
-+    if (add_item_to_list(thd, new Item_null()))
-+      goto error;
-+
-+    thd->proc_info="init";
-+    if ((res= open_and_lock_tables(thd, all_tables)))
-+      break;
-+
-+    if ((res= mysql_multi_delete_prepare(thd)))
-+      goto error;
-+
-+    if (!thd->is_fatal_error && (result= new multi_delete(aux_tables,
-+							  lex->table_count)))
-+    {
-+      res= mysql_select(thd, &select_lex->ref_pointer_array,
-+			select_lex->get_table_list(),
-+			select_lex->with_wild,
-+			select_lex->item_list,
-+			select_lex->where,
-+			0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
-+			(ORDER *)NULL,
-+			select_lex->options | thd->options |
-+			SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
-+                        OPTION_SETUP_TABLES_DONE,
-+			result, unit, select_lex);
-+      delete result;
-+    }
-+    else
-+      res= TRUE;                                // Error
-+    break;
-+  }
-+  case SQLCOM_DROP_TABLE:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (!lex->drop_temporary)
-+    {
-+      if (check_table_access(thd, DROP_ACL, all_tables, 0))
-+	goto error;				/* purecov: inspected */
-+      if (end_active_trans(thd))
-+        goto error;
-+    }
-+    else
-+    {
-+      /*
-+	If this is a slave thread, we may sometimes execute some 
-+	DROP / * 40005 TEMPORARY * / TABLE
-+	that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
-+	MASTER TO), while the temporary table has already been dropped.
-+	To not generate such irrelevant "table does not exist errors",
-+	we silently add IF EXISTS if TEMPORARY was used.
-+      */
-+      if (thd->slave_thread)
-+	lex->drop_if_exists= 1;
-+
-+      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
-+      thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
-+    }
-+    /* DDL and binlog write order protected by LOCK_open */
-+    res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
-+			lex->drop_temporary);
-+  }
-+  break;
-+  case SQLCOM_DROP_INDEX:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_one_table_access(thd, INDEX_ACL, all_tables))
-+      goto error;				/* purecov: inspected */
-+    if (end_active_trans(thd))
-+      goto error;
-+    else
-+      res = mysql_drop_index(thd, first_table, &lex->alter_info);
-+    break;
-+  case SQLCOM_SHOW_PROCESSLIST:
-+    if (!thd->security_ctx->priv_user[0] &&
-+        check_global_access(thd,PROCESS_ACL))
-+      break;
-+    mysqld_list_processes(thd,
-+			  (thd->security_ctx->master_access & PROCESS_ACL ?
-+                           NullS :
-+                           thd->security_ctx->priv_user),
-+                          lex->verbose);
-+    break;
-+  case SQLCOM_SHOW_STORAGE_ENGINES:
-+    res= mysqld_show_storage_engines(thd);
-+    break;
-+  case SQLCOM_SHOW_PRIVILEGES:
-+    res= mysqld_show_privileges(thd);
-+    break;
-+  case SQLCOM_SHOW_COLUMN_TYPES:
-+    res= mysqld_show_column_types(thd);
-+    break;
-+  case SQLCOM_SHOW_LOGS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+               MYF(0));	/* purecov: inspected */
-+    goto error;
-+#else
-+    {
-+      if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0,0))
-+	goto error;
-+      res= mysqld_show_logs(thd);
-+      break;
-+    }
-+#endif
-+  case SQLCOM_CHANGE_DB:
-+    if (!mysql_change_db(thd,select_lex->db,FALSE))
-+      send_ok(thd);
-+    break;
-+
-+  case SQLCOM_LOAD:
-+  {
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    uint privilege= (lex->duplicates == DUP_REPLACE ?
-+		     INSERT_ACL | DELETE_ACL : INSERT_ACL) |
-+                    (lex->local_file ? 0 : FILE_ACL);
-+
-+    if (lex->local_file)
-+    {
-+      if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
-+          !opt_local_infile)
-+      {
-+	my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
-+	goto error;
-+      }
-+    }
-+
-+    if (check_one_table_access(thd, privilege, all_tables))
-+      goto error;
-+
-+    res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
-+                    lex->update_list, lex->value_list, lex->duplicates,
-+                    lex->ignore, (bool) lex->local_file);
-+    break;
-+  }
-+
-+  case SQLCOM_SET_OPTION:
-+  {
-+    List<set_var_base> *lex_var_list= &lex->var_list;
-+    if ((check_table_access(thd, SELECT_ACL, all_tables, 0) ||
-+	 open_and_lock_tables(thd, all_tables)))
-+      goto error;
-+    if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
-+    {
-+      my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
-+      goto error;
-+    }
-+    if (!(res= sql_set_variables(thd, lex_var_list)))
-+    {
-+      /*
-+        If the previous command was a SET ONE_SHOT, we don't want to forget
-+        about the ONE_SHOT property of that SET. So we use a |= instead of = .
-+      */
-+      thd->one_shot_set|= lex->one_shot_set;
-+      send_ok(thd);
-+    }
-+    break;
-+  }
-+
-+  case SQLCOM_UNLOCK_TABLES:
-+    /*
-+      It is critical for mysqldump --single-transaction --master-data that
-+      UNLOCK TABLES does not implicitely commit a connection which has only
-+      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
-+      false, mysqldump will not work.
-+    */
-+    unlock_locked_tables(thd);
-+    if (thd->options & OPTION_TABLE_LOCK)
-+    {
-+      end_active_trans(thd);
-+      thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
-+    }
-+    if (thd->global_read_lock)
-+      unlock_global_read_lock(thd);
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_LOCK_TABLES:
-+    unlock_locked_tables(thd);
-+    if (check_db_used(thd, all_tables) || end_active_trans(thd))
-+      goto error;
-+    if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0))
-+      goto error;
-+    thd->in_lock_tables=1;
-+    thd->options|= OPTION_TABLE_LOCK;
-+
-+    if (!(res= simple_open_n_lock_tables(thd, all_tables)))
-+    {
-+#ifdef HAVE_QUERY_CACHE
-+      if (thd->variables.query_cache_wlock_invalidate)
-+	query_cache.invalidate_locked_for_write(first_table);
-+#endif /*HAVE_QUERY_CACHE*/
-+      thd->locked_tables=thd->lock;
-+      thd->lock=0;
-+      send_ok(thd);
-+    }
-+    else
-+      thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
-+    thd->in_lock_tables=0;
-+    break;
-+  case SQLCOM_CREATE_DB:
-+  {
-+    if (end_active_trans(thd))
-+    {
-+      res= -1;
-+      break;
-+    }
-+    char *alias;
-+    if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
-+      break;
-+    }
-+    /*
-+      If in a slave thread :
-+      CREATE DATABASE DB was certainly not preceded by USE DB.
-+      For that reason, db_ok() in sql/slave.cc did not check the
-+      do_db/ignore_db. And as this query involves no tables, tables_ok()
-+      above was not called. So we have to check rules again here.
-+    */
-+#ifdef HAVE_REPLICATION
-+    if (thd->slave_thread &&
-+	(!db_ok(lex->name, replicate_do_db, replicate_ignore_db) ||
-+	 !db_ok_with_wild_table(lex->name)))
-+    {
-+      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+      break;
-+    }
-+#endif
-+    if (check_access(thd,CREATE_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
-+      break;
-+    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
-+			 &lex->create_info, 0);
-+    break;
-+  }
-+  case SQLCOM_DROP_DB:
-+  {
-+    if (end_active_trans(thd))
-+    {
-+      res= -1;
-+      break;
-+    }
-+    if (check_db_name(lex->name))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
-+      break;
-+    }
-+    /*
-+      If in a slave thread :
-+      DROP DATABASE DB may not be preceded by USE DB.
-+      For that reason, maybe db_ok() in sql/slave.cc did not check the 
-+      do_db/ignore_db. And as this query involves no tables, tables_ok()
-+      above was not called. So we have to check rules again here.
-+    */
-+#ifdef HAVE_REPLICATION
-+    if (thd->slave_thread && 
-+	(!db_ok(lex->name, replicate_do_db, replicate_ignore_db) ||
-+	 !db_ok_with_wild_table(lex->name)))
-+    {
-+      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+      break;
-+    }
-+#endif
-+    if (check_access(thd,DROP_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
-+      break;
-+    if (thd->locked_tables || thd->active_transaction())
-+    {
-+      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+      goto error;
-+    }
-+    res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
-+    break;
-+  }
-+  case SQLCOM_ALTER_DB:
-+  {
-+    char *db= lex->name;
-+    DBUG_ASSERT(db); /* Must be set in the parser */
-+    if (!strip_sp(db) || check_db_name(db))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
-+      break;
-+    }
-+    /*
-+      If in a slave thread :
-+      ALTER DATABASE DB may not be preceded by USE DB.
-+      For that reason, maybe db_ok() in sql/slave.cc did not check the
-+      do_db/ignore_db. And as this query involves no tables, tables_ok()
-+      above was not called. So we have to check rules again here.
-+    */
-+#ifdef HAVE_REPLICATION
-+    if (thd->slave_thread &&
-+	(!db_ok(db, replicate_do_db, replicate_ignore_db) ||
-+	 !db_ok_with_wild_table(db)))
-+    {
-+      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+      break;
-+    }
-+#endif
-+    if (check_access(thd, ALTER_ACL, db, 0, 1, 0, is_schema_db(db)))
-+      break;
-+    if (thd->locked_tables || thd->active_transaction())
-+    {
-+      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+      goto error;
-+    }
-+    res= mysql_alter_db(thd, db, &lex->create_info);
-+    break;
-+  }
-+  case SQLCOM_SHOW_CREATE_DB:
-+  {
-+    if (!strip_sp(lex->name) || check_db_name(lex->name))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
-+      break;
-+    }
-+    if (check_access(thd,SELECT_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
-+      break;
-+    res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
-+    break;
-+  }
-+  case SQLCOM_CREATE_FUNCTION:                  // UDF function
-+  {
-+    if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
-+      break;
-+#ifdef HAVE_DLOPEN
-+    if (sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-+                        &thd->sp_func_cache, FALSE))
-+    {
-+      my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str);
-+      goto error;
-+    }
-+    if (!(res = mysql_create_function(thd, &lex->udf)))
-+      send_ok(thd);
-+#else
-+    my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
-+    res= TRUE;
-+#endif
-+    break;
-+  }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  case SQLCOM_CREATE_USER:
-+  {
-+    if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
-+        check_global_access(thd,CREATE_USER_ACL))
-+      break;
-+    if (end_active_trans(thd))
-+      goto error;
-+    /* Conditionally writes to binlog */
-+    if (!(res= mysql_create_user(thd, lex->users_list)))
-+      send_ok(thd);
-+    break;
-+  }
-+  case SQLCOM_DROP_USER:
-+  {
-+    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
-+        check_global_access(thd,CREATE_USER_ACL))
-+      break;
-+    if (end_active_trans(thd))
-+      goto error;
-+    /* Conditionally writes to binlog */
-+    if (!(res= mysql_drop_user(thd, lex->users_list)))
-+      send_ok(thd);
-+    break;
-+  }
-+  case SQLCOM_RENAME_USER:
-+  {
-+    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
-+        check_global_access(thd,CREATE_USER_ACL))
-+      break;
-+    if (end_active_trans(thd))
-+      goto error;
-+    /* Conditionally writes to binlog */
-+    if (!(res= mysql_rename_user(thd, lex->users_list)))
-+      send_ok(thd);
-+    break;
-+  }
-+  case SQLCOM_REVOKE_ALL:
-+  {
-+    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
-+        check_global_access(thd,CREATE_USER_ACL))
-+      break;
-+    /* Conditionally writes to binlog */
-+    if (!(res = mysql_revoke_all(thd, lex->users_list)))
-+      send_ok(thd);
-+    break;
-+  }
-+  case SQLCOM_REVOKE:
-+  case SQLCOM_GRANT:
-+  {
-+    if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
-+		     first_table ?  first_table->db : select_lex->db,
-+		     first_table ? &first_table->grant.privilege : 0,
-+		     first_table ? 0 : 1, 0,
-+                     first_table ? (bool) first_table->schema_table :
-+                     select_lex->db ? is_schema_db(select_lex->db) : 0))
-+      goto error;
-+
-+    if (thd->security_ctx->user)              // If not replication
-+    {
-+      LEX_USER *user, *tmp_user;
-+
-+      List_iterator <LEX_USER> user_list(lex->users_list);
-+      while ((tmp_user= user_list++))
-+      {
-+        if (!(user= get_current_user(thd, tmp_user)))
-+          goto error;
-+        if (specialflag & SPECIAL_NO_RESOLVE &&
-+            hostname_requires_resolving(user->host.str))
-+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                              ER_WARN_HOSTNAME_WONT_WORK,
-+                              ER(ER_WARN_HOSTNAME_WONT_WORK),
-+                              user->host.str);
-+        // Are we trying to change a password of another user
-+        DBUG_ASSERT(user->host.str != 0);
-+        if (strcmp(thd->security_ctx->user, user->user.str) ||
-+            my_strcasecmp(system_charset_info,
-+                          user->host.str, thd->security_ctx->host_or_ip))
-+        {
-+          // TODO: use check_change_password()
-+          if (is_acl_user(user->host.str, user->user.str) &&
-+              user->password.str &&
-+              check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
-+          {
-+            my_message(ER_PASSWORD_NOT_ALLOWED,
-+                       ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
-+            goto error;
-+          }
-+        }
-+      }
-+    }
-+    if (first_table)
-+    {
-+      if (lex->type == TYPE_ENUM_PROCEDURE ||
-+          lex->type == TYPE_ENUM_FUNCTION)
-+      {
-+        uint grants= lex->all_privileges 
-+		   ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
-+		   : lex->grant;
-+        if (grant_option && 
-+	    check_grant_routine(thd, grants | GRANT_ACL, all_tables,
-+                                lex->type == TYPE_ENUM_PROCEDURE, 0))
-+	  goto error;
-+        /* Conditionally writes to binlog */
-+        res= mysql_routine_grant(thd, all_tables,
-+                                 lex->type == TYPE_ENUM_PROCEDURE, 
-+                                 lex->users_list, grants,
-+                                 lex->sql_command == SQLCOM_REVOKE, 0);
-+      }
-+      else
-+      {
-+	if (grant_option && check_grant(thd,
-+					(lex->grant | lex->grant_tot_col |
-+					 GRANT_ACL),
-+					all_tables, 0, UINT_MAX, 0))
-+	  goto error;
-+        /* Conditionally writes to binlog */
-+        res= mysql_table_grant(thd, all_tables, lex->users_list,
-+			       lex->columns, lex->grant,
-+			       lex->sql_command == SQLCOM_REVOKE);
-+      }
-+    }
-+    else
-+    {
-+      if (lex->columns.elements || lex->type)
-+      {
-+	my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
-+                   MYF(0));
-+        goto error;
-+      }
-+      else
-+	/* Conditionally writes to binlog */
-+	res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
-+			  lex->sql_command == SQLCOM_REVOKE);
-+      if (!res)
-+      {
-+	if (lex->sql_command == SQLCOM_GRANT)
-+	{
-+	  List_iterator <LEX_USER> str_list(lex->users_list);
-+	  LEX_USER *user, *tmp_user;
-+	  while ((tmp_user=str_list++))
-+          {
-+            if (!(user= get_current_user(thd, tmp_user)))
-+              goto error;
-+	    reset_mqh(user);
-+          }
-+	}
-+      }
-+    }
-+    break;
-+  }
-+#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
-+  case SQLCOM_RESET:
-+    /*
-+      RESET commands are never written to the binary log, so we have to
-+      initialize this variable because RESET shares the same code as FLUSH
-+    */
-+    lex->no_write_to_binlog= 1;
-+  case SQLCOM_FLUSH:
-+  {
-+    bool write_to_binlog;
-+    if (check_global_access(thd,RELOAD_ACL))
-+      goto error;
-+
-+    /*
-+      reload_acl_and_cache() will tell us if we are allowed to write to the
-+      binlog or not.
-+    */
-+    if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
-+    {
-+      /*
-+        We WANT to write and we CAN write.
-+        ! we write after unlocking the table.
-+      */
-+      /* Presumably, RESET and binlog writing doesn't require synchronization */
-+      if (!lex->no_write_to_binlog && write_to_binlog)
-+      {
-+        if (mysql_bin_log.is_open())
-+        {
-+          Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-+          mysql_bin_log.write(&qinfo);
-+        }
-+      }
-+      send_ok(thd);
-+    } 
-+    
-+    break;
-+  }
-+  case SQLCOM_KILL:
-+  {
-+    Item *it= (Item *)lex->value_list.head();
-+
-+    if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
-+    {
-+      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
-+		 MYF(0));
-+      goto error;
-+    }
-+    kill_one_thread(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
-+    break;
-+  }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  case SQLCOM_SHOW_GRANTS:
-+  {
-+    LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
-+    if (!grant_user)
-+      goto error;
-+    if ((thd->security_ctx->priv_user &&
-+	 !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
-+	!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
-+    {
-+      res = mysql_show_grants(thd, grant_user);
-+    }
-+    break;
-+  }
-+#endif
-+  case SQLCOM_HA_OPEN:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables) ||
-+	check_table_access(thd, SELECT_ACL, all_tables, 0))
-+      goto error;
-+    res= mysql_ha_open(thd, first_table, 0);
-+    break;
-+  case SQLCOM_HA_CLOSE:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    if (check_db_used(thd, all_tables))
-+      goto error;
-+    res= mysql_ha_close(thd, first_table);
-+    break;
-+  case SQLCOM_HA_READ:
-+    DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+    /*
-+      There is no need to check for table permissions here, because
-+      if a user has no permissions to read a table, he won't be
-+      able to open it (with SQLCOM_HA_OPEN) in the first place.
-+    */
-+    if (check_db_used(thd, all_tables))
-+      goto error;
-+    unit->set_limit(select_lex);
-+    res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
-+                       lex->insert_list, lex->ha_rkey_mode, select_lex->where,
-+                       unit->select_limit_cnt, unit->offset_limit_cnt);
-+    break;
-+
-+  case SQLCOM_BEGIN:
-+    if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    if (begin_trans(thd))
-+      goto error;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_COMMIT:
-+    if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
-+                              lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
-+      goto error;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_ROLLBACK:
-+    if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
-+                              lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
-+      goto error;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_RELEASE_SAVEPOINT:
-+  {
-+    SAVEPOINT *sv;
-+    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
-+    {
-+      if (my_strnncoll(system_charset_info,
-+                       (uchar *)lex->ident.str, lex->ident.length,
-+                       (uchar *)sv->name, sv->length) == 0)
-+        break;
-+    }
-+    if (sv)
-+    {
-+      if (ha_release_savepoint(thd, sv))
-+        res= TRUE; // cannot happen
-+      else
-+        send_ok(thd);
-+      thd->transaction.savepoints=sv->prev;
-+    }
-+    else
-+      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
-+    break;
-+  }
-+  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
-+  {
-+    SAVEPOINT *sv;
-+    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
-+    {
-+      if (my_strnncoll(system_charset_info,
-+                       (uchar *)lex->ident.str, lex->ident.length,
-+                       (uchar *)sv->name, sv->length) == 0)
-+        break;
-+    }
-+    if (sv)
-+    {
-+      if (ha_rollback_to_savepoint(thd, sv))
-+        res= TRUE; // cannot happen
-+      else
-+      {
-+        if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
-+            !thd->slave_thread)
-+          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
-+                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
-+        send_ok(thd);
-+      }
-+      thd->transaction.savepoints=sv;
-+    }
-+    else
-+      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
-+    break;
-+  }
-+  case SQLCOM_SAVEPOINT:
-+    if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
-+          thd->in_sub_stmt) || !opt_using_transactions)
-+      send_ok(thd);
-+    else
-+    {
-+      SAVEPOINT **sv, *newsv;
-+      for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
-+      {
-+        if (my_strnncoll(system_charset_info,
-+                         (uchar *)lex->ident.str, lex->ident.length,
-+                         (uchar *)(*sv)->name, (*sv)->length) == 0)
-+          break;
-+      }
-+      if (*sv) /* old savepoint of the same name exists */
-+      {
-+        newsv=*sv;
-+        ha_release_savepoint(thd, *sv); // it cannot fail
-+        *sv=(*sv)->prev;
-+      }
-+      else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
-+                                               savepoint_alloc_size)) == 0)
-+      {
-+        my_error(ER_OUT_OF_RESOURCES, MYF(0));
-+        break;
-+      }
-+      newsv->name=strmake_root(&thd->transaction.mem_root,
-+                               lex->ident.str, lex->ident.length);
-+      newsv->length=lex->ident.length;
-+      /*
-+        if we'll get an error here, don't add new savepoint to the list.
-+        we'll lose a little bit of memory in transaction mem_root, but it'll
-+        be free'd when transaction ends anyway
-+      */
-+      if (ha_savepoint(thd, newsv))
-+        res= TRUE;
-+      else
-+      {
-+        newsv->prev=thd->transaction.savepoints;
-+        thd->transaction.savepoints=newsv;
-+        send_ok(thd);
-+      }
-+    }
-+    break;
-+  case SQLCOM_CREATE_PROCEDURE:
-+  case SQLCOM_CREATE_SPFUNCTION:
-+  {
-+    uint namelen;
-+    char *name;
-+    int result= SP_INTERNAL_ERROR;
-+
-+    DBUG_ASSERT(lex->sphead != 0);
-+    DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
-+    /*
-+      Verify that the database name is allowed, optionally
-+      lowercase it.
-+    */
-+    if (check_db_name(lex->sphead->m_db.str))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
-+      goto create_sp_error;
-+    }
-+
-+    /*
-+      Check that a database directory with this name
-+      exists. Design note: This won't work on virtual databases
-+      like information_schema.
-+    */
-+    if (check_db_dir_existence(lex->sphead->m_db.str))
-+    {
-+      my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
-+      goto create_sp_error;
-+    }
-+
-+    if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
-+                     is_schema_db(lex->sphead->m_db.str)))
-+      goto create_sp_error;
-+
-+    if (end_active_trans(thd))
-+      goto create_sp_error;
-+
-+    name= lex->sphead->name(&namelen);
-+#ifdef HAVE_DLOPEN
-+    if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
-+    {
-+      udf_func *udf = find_udf(name, namelen);
-+
-+      if (udf)
-+      {
-+        my_error(ER_UDF_EXISTS, MYF(0), name);
-+        goto create_sp_error;
-+      }
-+    }
-+#endif
-+
-+    /*
-+      If the definer is not specified, this means that CREATE-statement missed
-+      DEFINER-clause. DEFINER-clause can be missed in two cases:
-+
-+        - The user submitted a statement w/o the clause. This is a normal
-+          case, we should assign CURRENT_USER as definer.
-+
-+        - Our slave received an updated from the master, that does not
-+          replicate definer for stored rountines. We should also assign
-+          CURRENT_USER as definer here, but also we should mark this routine
-+          as NON-SUID. This is essential for the sake of backward
-+          compatibility.
-+
-+          The problem is the slave thread is running under "special" user (@),
-+          that actually does not exist. In the older versions we do not fail
-+          execution of a stored routine if its definer does not exist and
-+          continue the execution under the authorization of the invoker
-+          (BUG#13198). And now if we try to switch to slave-current-user (@),
-+          we will fail.
-+
-+          Actually, this leads to the inconsistent state of master and
-+          slave (different definers, different SUID behaviour), but it seems,
-+          this is the best we can do.
-+    */
-+
-+    if (!lex->definer)
-+    {
-+      bool res= FALSE;
-+      Query_arena original_arena;
-+      Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
-+
-+      if (!(lex->definer= create_default_definer(thd)))
-+        res= TRUE;
-+
-+      if (ps_arena)
-+        thd->restore_active_arena(ps_arena, &original_arena);
-+
-+      /* Error has been already reported. */
-+      if (res)
-+        goto create_sp_error;
-+
-+      if (thd->slave_thread)
-+        lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
-+    }
-+
-+    /*
-+      If the specified definer differs from the current user, we should check
-+      that the current user has SUPER privilege (in order to create a stored
-+      routine under another user one must have SUPER privilege).
-+    */
-+
-+    else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
-+        my_strcasecmp(system_charset_info,
-+                      lex->definer->host.str,
-+                      thd->security_ctx->priv_host))
-+    {
-+      if (check_global_access(thd, SUPER_ACL))
-+      {
-+        my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-+        goto create_sp_error;
-+      }
-+    }
-+
-+    /* Check that the specified definer exists. Emit a warning if not. */
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+    if (!is_acl_user(lex->definer->host.str,
-+                     lex->definer->user.str))
-+    {
-+      push_warning_printf(thd,
-+                          MYSQL_ERROR::WARN_LEVEL_NOTE,
-+                          ER_NO_SUCH_USER,
-+                          ER(ER_NO_SUCH_USER),
-+                          lex->definer->user.str,
-+                          lex->definer->host.str);
-+    }
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+
-+    res= (result= lex->sphead->create(thd));
-+    switch (result) {
-+    case SP_OK:
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+      /* only add privileges if really neccessary */
-+      if (sp_automatic_privileges && !opt_noacl &&
-+          check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
-+                               lex->sphead->m_db.str, name,
-+                               lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
-+      {
-+        if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
-+                                lex->sql_command == SQLCOM_CREATE_PROCEDURE))
-+          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                       ER_PROC_AUTO_GRANT_FAIL,
-+                       ER(ER_PROC_AUTO_GRANT_FAIL));
-+        close_thread_tables(thd);
-+      }
-+#endif
-+    break;
-+    case SP_WRITE_ROW_FAILED:
-+      my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
-+    break;
-+    case SP_BAD_IDENTIFIER:
-+      my_error(ER_TOO_LONG_IDENT, MYF(0), name);
-+    break;
-+    case SP_BODY_TOO_LONG:
-+      my_error(ER_TOO_LONG_BODY, MYF(0), name);
-+    break;
-+    default:
-+      my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
-+    break;
-+    } /* end switch */
-+
-+    /*
-+      Capture all errors within this CASE and
-+      clean up the environment.
-+    */
-+create_sp_error:
-+    lex->unit.cleanup();
-+    delete lex->sphead;
-+    lex->sphead= 0;
-+    if (result != SP_OK )
-+      goto error;
-+    send_ok(thd);
-+    break; /* break super switch */
-+  } /* end case group bracket */
-+  case SQLCOM_CALL:
-+    {
-+      sp_head *sp;
-+
-+      /*
-+        This will cache all SP and SF and open and lock all tables
-+        required for execution.
-+      */
-+      if (check_table_access(thd, SELECT_ACL, all_tables, 0) ||
-+	  open_and_lock_tables(thd, all_tables))
-+       goto error;
-+
-+      /*
-+        By this moment all needed SPs should be in cache so no need to look 
-+        into DB. 
-+      */
-+      if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+                                &thd->sp_proc_cache, TRUE)))
-+      {
-+	my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
-+                 lex->spname->m_qname.str);
-+	goto error;
-+      }
-+      else
-+      {
-+	ha_rows select_limit;
-+        /* bits that should be cleared in thd->server_status */
-+	uint bits_to_be_cleared= 0;
-+        /*
-+          Check that the stored procedure doesn't contain Dynamic SQL
-+          and doesn't return result sets: such stored procedures can't
-+          be called from a function or trigger.
-+        */
-+        if (thd->in_sub_stmt)
-+        {
-+          const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
-+                              "trigger" : "function");
-+          if (sp->is_not_allowed_in_function(where))
-+            goto error;
-+        }
-+
-+	my_bool nsok= thd->net.no_send_ok;
-+	thd->net.no_send_ok= TRUE;
-+	if (sp->m_flags & sp_head::MULTI_RESULTS)
-+	{
-+	  if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
-+	  {
-+            /*
-+              The client does not support multiple result sets being sent
-+              back
-+            */
-+	    my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
-+	    thd->net.no_send_ok= nsok;
-+	    goto error;
-+	  }
-+          /*
-+            If SERVER_MORE_RESULTS_EXISTS is not set,
-+            then remember that it should be cleared
-+          */
-+	  bits_to_be_cleared= (~thd->server_status &
-+                               SERVER_MORE_RESULTS_EXISTS);
-+	  thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
-+	}
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+	if (check_routine_access(thd, EXECUTE_ACL,
-+				 sp->m_db.str, sp->m_name.str, TRUE, FALSE))
-+	{
-+	  thd->net.no_send_ok= nsok;
-+	  goto error;
-+	}
-+#endif
-+	select_limit= thd->variables.select_limit;
-+	thd->variables.select_limit= HA_POS_ERROR;
-+
-+        /* 
-+          We never write CALL statements into binlog:
-+           - If the mode is non-prelocked, each statement will be logged
-+             separately.
-+           - If the mode is prelocked, the invoking statement will care
-+             about writing into binlog.
-+          So just execute the statement.
-+        */
-+	res= sp->execute_procedure(thd, &lex->value_list);
-+	/*
-+          If warnings have been cleared, we have to clear total_warn_count
-+          too, otherwise the clients get confused.
-+	 */
-+	if (thd->warn_list.is_empty())
-+	  thd->total_warn_count= 0;
-+
-+	thd->variables.select_limit= select_limit;
-+
-+	thd->net.no_send_ok= nsok;
-+        thd->server_status&= ~bits_to_be_cleared;
-+
-+	if (!res)
-+	  send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
-+                                thd->row_count_func));
-+	else
-+	  goto error;		// Substatement should already have sent error
-+      }
-+      break;
-+    }
-+  case SQLCOM_ALTER_PROCEDURE:
-+  case SQLCOM_ALTER_FUNCTION:
-+    {
-+      int result;
-+      sp_head *sp;
-+      st_sp_chistics chistics;
-+
-+      memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
-+      if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
-+        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+                            &thd->sp_proc_cache, FALSE);
-+      else
-+        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-+                            &thd->sp_func_cache, FALSE);
-+      mysql_reset_errors(thd, 0);
-+      if (! sp)
-+      {
-+	if (lex->spname->m_db.str)
-+	  result= SP_KEY_NOT_FOUND;
-+	else
-+	{
-+	  my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
-+	  goto error;
-+	}
-+      }
-+      else
-+      {
-+        if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str, 
-+				 sp->m_name.str,
-+                                 lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
-+	  goto error;
-+
-+        if (end_active_trans(thd)) 
-+          goto error;
-+	memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
-+        if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
-+            !trust_function_creators &&  mysql_bin_log.is_open() &&
-+            !sp->m_chistics->detistic &&
-+            (chistics.daccess == SP_CONTAINS_SQL ||
-+             chistics.daccess == SP_MODIFIES_SQL_DATA))
-+        {
-+          my_message(ER_BINLOG_UNSAFE_ROUTINE,
-+		     ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
-+          result= SP_INTERNAL_ERROR;
-+        }
-+        else
-+        {
-+          /*
-+            Note that if you implement the capability of ALTER FUNCTION to
-+            alter the body of the function, this command should be made to
-+            follow the restrictions that log-bin-trust-function-creators=0
-+            already puts on CREATE FUNCTION.
-+          */
-+          if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
-+            /* Conditionally writes to binlog */
-+            result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
-+          else
-+            /* Conditionally writes to binlog */
-+            result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
-+        }
-+      }
-+      switch (result)
-+      {
-+      case SP_OK:
-+	send_ok(thd);
-+	break;
-+      case SP_KEY_NOT_FOUND:
-+	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_qname.str);
-+	goto error;
-+      default:
-+	my_error(ER_SP_CANT_ALTER, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_qname.str);
-+	goto error;
-+      }
-+      break;
-+    }
-+  case SQLCOM_DROP_PROCEDURE:
-+  case SQLCOM_DROP_FUNCTION:
-+    {
-+      int result;
-+      int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
-+                 TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
-+
-+      result= sp_routine_exists_in_table(thd, type, lex->spname);
-+      mysql_reset_errors(thd, 0);
-+      if (result == SP_OK)
-+      {
-+        char *db= lex->spname->m_db.str;
-+	char *name= lex->spname->m_name.str;
-+
-+	if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
-+                                 lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
-+          goto error;
-+
-+        if (end_active_trans(thd)) 
-+          goto error;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+	if (sp_automatic_privileges && !opt_noacl &&
-+	    sp_revoke_privileges(thd, db, name, 
-+                                 lex->sql_command == SQLCOM_DROP_PROCEDURE))
-+	{
-+	  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
-+		       ER_PROC_AUTO_REVOKE_FAIL,
-+		       ER(ER_PROC_AUTO_REVOKE_FAIL));
-+	}
-+#endif
-+	if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-+          /* Conditionally writes to binlog */
-+	  result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
-+	else
-+          /* Conditionally writes to binlog */
-+	  result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
-+      }
-+      else
-+      {
-+#ifdef HAVE_DLOPEN
-+	if (lex->sql_command == SQLCOM_DROP_FUNCTION)
-+	{
-+          udf_func *udf = find_udf(lex->spname->m_name.str,
-+                                   lex->spname->m_name.length);
-+          if (udf)
-+          {
-+	    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
-+	      goto error;
-+
-+	    /* Does NOT write to binlog */
-+	    if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
-+	    {
-+	      send_ok(thd);
-+	      break;
-+	    }
-+	  }
-+	}
-+#endif
-+	if (lex->spname->m_db.str)
-+	  result= SP_KEY_NOT_FOUND;
-+	else
-+	{
-+	  my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
-+	  goto error;
-+	}
-+      }
-+      res= result;
-+      switch (result)
-+      {
-+      case SP_OK:
-+	send_ok(thd);
-+	break;
-+      case SP_KEY_NOT_FOUND:
-+	if (lex->drop_if_exists)
-+	{
-+	  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+			      ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
-+			      SP_COM_STRING(lex), lex->spname->m_name.str);
-+	  res= FALSE;
-+	  send_ok(thd);
-+	  break;
-+	}
-+	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_qname.str);
-+	goto error;
-+      default:
-+	my_error(ER_SP_DROP_FAILED, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_qname.str);
-+	goto error;
-+      }
-+      break;
-+    }
-+  case SQLCOM_SHOW_CREATE_PROC:
-+    {
-+      if (lex->spname->m_name.length > NAME_LEN)
-+      {
-+	my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
-+	goto error;
-+      }
-+      if (sp_show_create_procedure(thd, lex->spname) != SP_OK)
-+      {			/* We don't distinguish between errors for now */
-+	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_name.str);
-+	goto error;
-+      }
-+      break;
-+    }
-+  case SQLCOM_SHOW_CREATE_FUNC:
-+    {
-+      if (lex->spname->m_name.length > NAME_LEN)
-+      {
-+	my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
-+	goto error;
-+      }
-+      if (sp_show_create_function(thd, lex->spname) != SP_OK)
-+      {			/* We don't distinguish between errors for now */
-+	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_name.str);
-+	goto error;
-+      }
-+      break;
-+    }
-+  case SQLCOM_SHOW_STATUS_PROC:
-+    {
-+      res= sp_show_status_procedure(thd, (lex->wild ?
-+					  lex->wild->ptr() : NullS));
-+      break;
-+    }
-+  case SQLCOM_SHOW_STATUS_FUNC:
-+    {
-+      res= sp_show_status_function(thd, (lex->wild ? 
-+					 lex->wild->ptr() : NullS));
-+      break;
-+    }
-+#ifndef DBUG_OFF
-+  case SQLCOM_SHOW_PROC_CODE:
-+  case SQLCOM_SHOW_FUNC_CODE:
-+    {
-+      sp_head *sp;
-+
-+      if (lex->spname->m_name.length > NAME_LEN)
-+      {
-+	my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
-+	goto error;
-+      }
-+      if (lex->sql_command == SQLCOM_SHOW_PROC_CODE)
-+        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+                            &thd->sp_proc_cache, FALSE);
-+      else
-+        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-+                            &thd->sp_func_cache, FALSE);
-+      if (!sp || sp->show_routine_code(thd))
-+      {
-+        /* We don't distinguish between errors for now */
-+        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+                 SP_COM_STRING(lex), lex->spname->m_name.str);
-+        goto error;
-+      }
-+      break;
-+    }
-+#endif // ifndef DBUG_OFF
-+  case SQLCOM_CREATE_VIEW:
-+    {
-+      if (end_active_trans(thd))
-+        goto error;
-+
-+      res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
-+      break;
-+    }
-+  case SQLCOM_DROP_VIEW:
-+    {
-+      if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
-+          end_active_trans(thd))
-+        goto error;
-+      /* Conditionally writes to binlog. */
-+      res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
-+      break;
-+    }
-+  case SQLCOM_CREATE_TRIGGER:
-+  {
-+    if (end_active_trans(thd))
-+      goto error;
-+
-+    /* Conditionally writes to binlog. */
-+    res= mysql_create_or_drop_trigger(thd, all_tables, 1);
-+
-+    /* We don't care about trigger body after this point */
-+    delete lex->sphead;
-+    lex->sphead= 0;
-+    break;
-+  }
-+  case SQLCOM_DROP_TRIGGER:
-+  {
-+    if (end_active_trans(thd))
-+      goto error;
-+
-+    /* Conditionally writes to binlog. */
-+    res= mysql_create_or_drop_trigger(thd, all_tables, 0);
-+    break;
-+  }
-+  case SQLCOM_XA_START:
-+    if (thd->transaction.xid_state.xa_state == XA_IDLE &&
-+        thd->lex->xa_opt == XA_RESUME)
-+    {
-+      if (! thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+      {
-+        my_error(ER_XAER_NOTA, MYF(0));
-+        break;
-+      }
-+      thd->transaction.xid_state.xa_state=XA_ACTIVE;
-+      send_ok(thd);
-+      break;
-+    }
-+    if (thd->lex->xa_opt != XA_NONE)
-+    { // JOIN is not supported yet. TODO
-+      my_error(ER_XAER_INVAL, MYF(0));
-+      break;
-+    }
-+    if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    if (thd->active_transaction() || thd->locked_tables)
-+    {
-+      my_error(ER_XAER_OUTSIDE, MYF(0));
-+      break;
-+    }
-+    if (xid_cache_search(thd->lex->xid))
-+    {
-+      my_error(ER_XAER_DUPID, MYF(0));
-+      break;
-+    }
-+    DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
-+    thd->transaction.xid_state.xa_state=XA_ACTIVE;
-+    thd->transaction.xid_state.xid.set(thd->lex->xid);
-+    xid_cache_insert(&thd->transaction.xid_state);
-+    thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
-+                   OPTION_BEGIN);
-+    thd->server_status|= SERVER_STATUS_IN_TRANS;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_XA_END:
-+    /* fake it */
-+    if (thd->lex->xa_opt != XA_NONE)
-+    { // SUSPEND and FOR MIGRATE are not supported yet. TODO
-+      my_error(ER_XAER_INVAL, MYF(0));
-+      break;
-+    }
-+    if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+    {
-+      my_error(ER_XAER_NOTA, MYF(0));
-+      break;
-+    }
-+    thd->transaction.xid_state.xa_state=XA_IDLE;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_XA_PREPARE:
-+    if (thd->transaction.xid_state.xa_state != XA_IDLE)
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+    {
-+      my_error(ER_XAER_NOTA, MYF(0));
-+      break;
-+    }
-+    if (ha_prepare(thd))
-+    {
-+      my_error(ER_XA_RBROLLBACK, MYF(0));
-+      xid_cache_delete(&thd->transaction.xid_state);
-+      thd->transaction.xid_state.xa_state=XA_NOTR;
-+      break;
-+    }
-+    thd->transaction.xid_state.xa_state=XA_PREPARED;
-+    send_ok(thd);
-+    break;
-+  case SQLCOM_XA_COMMIT:
-+    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+    {
-+      XID_STATE *xs=xid_cache_search(thd->lex->xid);
-+      if (!xs || xs->in_thd)
-+        my_error(ER_XAER_NOTA, MYF(0));
-+      else
-+      {
-+        ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
-+        xid_cache_delete(xs);
-+        send_ok(thd);
-+      }
-+      break;
-+    }
-+    if (thd->transaction.xid_state.xa_state == XA_IDLE &&
-+        thd->lex->xa_opt == XA_ONE_PHASE)
-+    {
-+      int r;
-+      if ((r= ha_commit(thd)))
-+        my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
-+      else
-+        send_ok(thd);
-+    }
-+    else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
-+             thd->lex->xa_opt == XA_NONE)
-+    {
-+      if (wait_if_global_read_lock(thd, 0, 0))
-+      {
-+        ha_rollback(thd);
-+        my_error(ER_XAER_RMERR, MYF(0));
-+      }
-+      else
-+      {
-+        if (ha_commit_one_phase(thd, 1))
-+          my_error(ER_XAER_RMERR, MYF(0));
-+        else
-+          send_ok(thd);
-+        start_waiting_global_read_lock(thd);
-+      }
-+    }
-+    else
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
-+    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+    xid_cache_delete(&thd->transaction.xid_state);
-+    thd->transaction.xid_state.xa_state=XA_NOTR;
-+    break;
-+  case SQLCOM_XA_ROLLBACK:
-+    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+    {
-+      XID_STATE *xs=xid_cache_search(thd->lex->xid);
-+      if (!xs || xs->in_thd)
-+        my_error(ER_XAER_NOTA, MYF(0));
-+      else
-+      {
-+        ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
-+        xid_cache_delete(xs);
-+        send_ok(thd);
-+      }
-+      break;
-+    }
-+    if (thd->transaction.xid_state.xa_state != XA_IDLE &&
-+        thd->transaction.xid_state.xa_state != XA_PREPARED)
-+    {
-+      my_error(ER_XAER_RMFAIL, MYF(0),
-+               xa_state_names[thd->transaction.xid_state.xa_state]);
-+      break;
-+    }
-+    if (ha_rollback(thd))
-+      my_error(ER_XAER_RMERR, MYF(0));
-+    else
-+      send_ok(thd);
-+    thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
-+    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+    xid_cache_delete(&thd->transaction.xid_state);
-+    thd->transaction.xid_state.xa_state=XA_NOTR;
-+    break;
-+  case SQLCOM_XA_RECOVER:
-+    res= mysql_xa_recover(thd);
-+    break;
-+  default:
-+#ifndef EMBEDDED_LIBRARY
-+    DBUG_ASSERT(0);                             /* Impossible */
-+#endif
-+    send_ok(thd);
-+    break;
-+  }
-+  thd->proc_info="query end";
-+  /* Two binlog-related cleanups: */
-+
-+  /*
-+    Reset system variables temporarily modified by SET ONE SHOT.
-+
-+    Exception: If this is a SET, do nothing. This is to allow
-+    mysqlbinlog to print many SET commands (in this case we want the
-+    charset temp setting to live until the real query). This is also
-+    needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
-+    immediately.
-+  */
-+  if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
-+    reset_one_shot_variables(thd);
-+
-+  /*
-+    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)
-+    thd->row_count_func= -1;
-+
-+  goto end;
-+
-+error:
-+  res= TRUE;
-+
-+end:
-+  if (need_start_waiting)
-+  {
-+    /*
-+      Release the protection against the global read lock and wake
-+      everyone, who might want to set a global read lock.
-+    */
-+    start_waiting_global_read_lock(thd);
-+  }
-+  DBUG_RETURN(res || thd->net.report_error);
-+}
-+
-+
-+/*
-+  Check grants for commands which work only with one table.
-+
-+  SYNOPSIS
-+    check_single_table_access()
-+    thd			Thread handler
-+    privilege		requested privilege
-+    all_tables		global table list of query
-+
-+  RETURN
-+    0 - OK
-+    1 - access denied, error is sent to client
-+*/
-+
-+bool check_single_table_access(THD *thd, ulong privilege, 
-+                               TABLE_LIST *all_tables)
-+{
-+  Security_context * backup_ctx= thd->security_ctx;
-+
-+  /* we need to switch to the saved context (if any) */
-+  if (all_tables->security_ctx)
-+    thd->security_ctx= all_tables->security_ctx;
-+
-+  const char *db_name;
-+  if ((all_tables->view || all_tables->field_translation) &&
-+      !all_tables->schema_table)
-+    db_name= all_tables->view_db.str;
-+  else
-+    db_name= all_tables->db;
-+
-+  if (check_access(thd, privilege, db_name,
-+		   &all_tables->grant.privilege, 0, 0,
-+                   test(all_tables->schema_table)))
-+    goto deny;
-+
-+  /* Show only 1 table for check_grant */
-+  if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
-+    goto deny;
-+
-+  thd->security_ctx= backup_ctx;
-+  return 0;
-+
-+deny:
-+  thd->security_ctx= backup_ctx;
-+  return 1;
-+}
-+
-+/*
-+  Check grants for commands which work only with one table and all other
-+  tables belonging to subselects or implicitly opened tables.
-+
-+  SYNOPSIS
-+    check_one_table_access()
-+    thd			Thread handler
-+    privilege		requested privilege
-+    all_tables		global table list of query
-+
-+  RETURN
-+    0 - OK
-+    1 - access denied, error is sent to client
-+*/
-+
-+bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
-+{
-+  if (check_single_table_access (thd,privilege,all_tables))
-+    return 1;
-+
-+  /* Check rights on tables of subselects and implictly opened tables */
-+  TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
-+  if ((subselects_tables= all_tables->next_global))
-+  {
-+    /*
-+      Access rights asked for the first table of a view should be the same
-+      as for the view
-+    */
-+    if (view && subselects_tables->belong_to_view == view)
-+    {
-+      if (check_single_table_access (thd, privilege, subselects_tables))
-+        return 1;
-+      subselects_tables= subselects_tables->next_global;
-+    }
-+    if (subselects_tables &&
-+        (check_table_access(thd, SELECT_ACL, subselects_tables, 0)))
-+      return 1;
-+  }
-+  return 0;
-+}
-+
-+
-+/****************************************************************************
-+  Get the user (global) and database privileges for all used tables
-+
-+  NOTES
-+    The idea of EXTRA_ACL is that one will be granted access to the table if
-+    one has the asked privilege on any column combination of the table; For
-+    example to be able to check a table one needs to have SELECT privilege on
-+    any column of the table.
-+
-+  RETURN
-+    0  ok
-+    1  If we can't get the privileges and we don't use table/column grants.
-+
-+    save_priv	In this we store global and db level grants for the table
-+		Note that we don't store db level grants if the global grants
-+                is enough to satisfy the request and the global grants contains
-+                a SELECT grant.
-+****************************************************************************/
-+
-+bool
-+check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
-+	     bool dont_check_global_grants, bool no_errors, bool schema_db)
-+{
-+  Security_context *sctx= thd->security_ctx;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  ulong db_access;
-+  bool  db_is_pattern= test(want_access & GRANT_ACL);
-+#endif
-+  ulong dummy;
-+  DBUG_ENTER("check_access");
-+  DBUG_PRINT("enter",("db: %s  want_access: %lu  master_access: %lu",
-+                      db ? db : "", want_access, sctx->master_access));
-+  if (save_priv)
-+    *save_priv=0;
-+  else
-+    save_priv= &dummy;
-+
-+  if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
-+  {
-+    DBUG_PRINT("error",("No database"));
-+    if (!no_errors)
-+      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
-+                 MYF(0));                       /* purecov: tested */
-+    DBUG_RETURN(TRUE);				/* purecov: tested */
-+  }
-+
-+  if (schema_db)
-+  {
-+    if (want_access & ~(SELECT_ACL | EXTRA_ACL))
-+    {
-+      if (!no_errors)
-+      {
-+        const char *db_name= db ? db : thd->db;
-+        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+                 sctx->priv_user, sctx->priv_host, db_name);
-+      }
-+      DBUG_RETURN(TRUE);
-+    }
-+    else
-+    {
-+      *save_priv= SELECT_ACL;
-+      DBUG_RETURN(FALSE);
-+    }
-+  }
-+
-+#ifdef NO_EMBEDDED_ACCESS_CHECKS
-+  DBUG_RETURN(0);
-+#else
-+  if ((sctx->master_access & want_access) == want_access)
-+  {
-+    /*
-+      If we don't have a global SELECT privilege, we have to get the database
-+      specific access rights to be able to handle queries of type
-+      UPDATE t1 SET a=1 WHERE b > 0
-+    */
-+    db_access= sctx->db_access;
-+    if (!(sctx->master_access & SELECT_ACL) &&
-+	(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
-+      db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
-+                        db_is_pattern);
-+    *save_priv=sctx->master_access | db_access;
-+    DBUG_RETURN(FALSE);
-+  }
-+  if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
-+      ! db && dont_check_global_grants)
-+  {						// We can never grant this
-+    DBUG_PRINT("error",("No possible access"));
-+    if (!no_errors)
-+      my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-+               sctx->priv_user,
-+               sctx->priv_host,
-+               (thd->password ?
-+                ER(ER_YES) :
-+                ER(ER_NO)));                    /* purecov: tested */
-+    DBUG_RETURN(TRUE);				/* purecov: tested */
-+  }
-+
-+  if (db == any_db)
-+    DBUG_RETURN(FALSE);				// Allow select on anything
-+
-+  if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
-+    db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
-+                       db_is_pattern);
-+  else
-+    db_access= sctx->db_access;
-+  DBUG_PRINT("info",("db_access: %lu", db_access));
-+  /* Remove SHOW attribute and access rights we already have */
-+  want_access &= ~(sctx->master_access | EXTRA_ACL);
-+  DBUG_PRINT("info",("db_access: %lu  want_access: %lu",
-+                     db_access, want_access));
-+  db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
-+
-+  /* grant_option is set if there exists a single table or column grant */
-+  if (db_access == want_access ||
-+      (grant_option && !dont_check_global_grants &&
-+       !(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS))))
-+    DBUG_RETURN(FALSE);				/* Ok */
-+
-+  DBUG_PRINT("error",("Access denied"));
-+  if (!no_errors)
-+    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+             sctx->priv_user, sctx->priv_host,
-+             (db ? db : (thd->db ?
-+                         thd->db :
-+                         "unknown")));          /* purecov: tested */
-+  DBUG_RETURN(TRUE);				/* purecov: tested */
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+/*
-+  check for global access and give descriptive error message if it fails
-+
-+  SYNOPSIS
-+    check_global_access()
-+    thd			Thread handler
-+    want_access		Use should have any of these global rights
-+
-+  WARNING
-+    One gets access right if one has ANY of the rights in want_access
-+    This is useful as one in most cases only need one global right,
-+    but in some case we want to check if the user has SUPER or
-+    REPL_CLIENT_ACL rights.
-+
-+  RETURN
-+    0	ok
-+    1	Access denied.  In this case an error is sent to the client
-+*/
-+
-+bool check_global_access(THD *thd, ulong want_access)
-+{
-+#ifdef NO_EMBEDDED_ACCESS_CHECKS
-+  return 0;
-+#else
-+  char command[128];
-+  if ((thd->security_ctx->master_access & want_access))
-+    return 0;
-+  get_privilege_desc(command, sizeof(command), want_access);
-+  my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
-+  return 1;
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+/*
-+  Check the privilege for all used tables.
-+
-+  SYNOPSYS
-+    check_table_access()
-+      thd          Thread context
-+      want_access  Privileges requested
-+      tables       List of tables to be checked
-+      no_errors    FALSE/TRUE - report/don't report error to
-+                   the client (using my_error() call).
-+
-+  NOTES
-+    Table privileges are cached in the table list for GRANT checking.
-+    This functions assumes that table list used and
-+    thd->lex->query_tables_own_last value correspond to each other
-+    (the latter should be either 0 or point to next_global member
-+    of one of elements of this table list).
-+
-+  RETURN VALUE
-+    FALSE - OK
-+    TRUE  - Access denied
-+*/
-+
-+bool
-+check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
-+		   bool no_errors)
-+{
-+  uint found=0;
-+  ulong found_access=0;
-+  TABLE_LIST *org_tables= tables;
-+  TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
-+  Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
-+  /*
-+    The check that first_not_own_table is not reached is for the case when
-+    the given table list refers to the list for prelocking (contains tables
-+    of other queries). For simple queries first_not_own_table is 0.
-+  */
-+  for (; tables != first_not_own_table; tables= tables->next_global)
-+  {
-+    if (tables->security_ctx)
-+      sctx= tables->security_ctx;
-+    else
-+      sctx= backup_ctx;
-+
-+    if (tables->schema_table && 
-+        (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
-+    {
-+      if (!no_errors)
-+        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+                 sctx->priv_user, sctx->priv_host,
-+                 information_schema_name.str);
-+      return TRUE;
-+    }
-+    /*
-+       Register access for view underlying table.
-+       Remove SHOW_VIEW_ACL, because it will be checked during making view
-+     */
-+    tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
-+    if (tables->derived || tables->schema_table ||
-+        (tables->table && (int)tables->table->s->tmp_table) ||
-+        my_tz_check_n_skip_implicit_tables(&tables,
-+                                           thd->lex->time_zone_tables_used))
-+      continue;
-+    thd->security_ctx= sctx;
-+    if ((sctx->master_access & want_access) ==
-+        (want_access & ~EXTRA_ACL) &&
-+	thd->db)
-+      tables->grant.privilege= want_access;
-+    else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
-+    {
-+      if (found && !grant_option)		// db already checked
-+	tables->grant.privilege=found_access;
-+      else
-+      {
-+	if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
-+			 0, no_errors, test(tables->schema_table)))
-+	  goto deny;                            // Access denied
-+	found_access=tables->grant.privilege;
-+	found=1;
-+      }
-+    }
-+    else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
-+			  0, no_errors, test(tables->schema_table)))
-+      goto deny;
-+  }
-+  thd->security_ctx= backup_ctx;
-+  if (grant_option)
-+    return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
-+		       test(want_access & EXTRA_ACL), UINT_MAX, no_errors);
-+  return FALSE;
-+deny:
-+  thd->security_ctx= backup_ctx;
-+  return TRUE;
-+}
-+
-+
-+bool
-+check_routine_access(THD *thd, ulong want_access,char *db, char *name,
-+		     bool is_proc, bool no_errors)
-+{
-+  TABLE_LIST tables[1];
-+  
-+  bzero((char *)tables, sizeof(TABLE_LIST));
-+  tables->db= db;
-+  tables->table_name= tables->alias= name;
-+  
-+  /*
-+    The following test is just a shortcut for check_access() (to avoid
-+    calculating db_access) under the assumption that it's common to
-+    give persons global right to execute all stored SP (but not
-+    necessary to create them).
-+  */
-+  if ((thd->security_ctx->master_access & want_access) == want_access)
-+    tables->grant.privilege= want_access;
-+  else if (check_access(thd,want_access,db,&tables->grant.privilege,
-+			0, no_errors, 0))
-+    return TRUE;
-+  
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  if (grant_option)
-+    return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
-+#endif
-+
-+  return FALSE;
-+}
-+
-+
-+/*
-+  Check if the routine has any of the routine privileges
-+
-+  SYNOPSIS
-+    check_some_routine_access()
-+    thd		 Thread handler
-+    db           Database name
-+    name         Routine name
-+
-+  RETURN
-+    0            ok
-+    1            error
-+*/
-+
-+bool check_some_routine_access(THD *thd, const char *db, const char *name,
-+                               bool is_proc)
-+{
-+  ulong save_priv;
-+  if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
-+    return FALSE;
-+  /*
-+    There are no routines in information_schema db. So we can safely
-+    pass zero to last paramter of check_access function
-+  */
-+  if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
-+      (save_priv & SHOW_PROC_ACLS))
-+    return FALSE;
-+  return check_routine_level_acl(thd, db, name, is_proc);
-+}
-+
-+
-+/*
-+  Check if the given table has any of the asked privileges
-+
-+  SYNOPSIS
-+    check_some_access()
-+    thd		 Thread handler
-+    want_access	 Bitmap of possible privileges to check for
-+
-+  RETURN
-+    0  ok
-+    1  error
-+*/
-+
-+
-+bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
-+{
-+  ulong access;
-+  DBUG_ENTER("check_some_access");
-+
-+  /* This loop will work as long as we have less than 32 privileges */
-+  for (access= 1; access < want_access ; access<<= 1)
-+  {
-+    if (access & want_access)
-+    {
-+      if (!check_access(thd, access, table->db,
-+                        &table->grant.privilege, 0, 1,
-+                        test(table->schema_table)) &&
-+          !grant_option || !check_grant(thd, access, table, 0, 1, 1))
-+        DBUG_RETURN(0);
-+    }
-+  }
-+  DBUG_PRINT("exit",("no matching access rights"));
-+  DBUG_RETURN(1);
-+}
-+
-+
-+bool check_merge_table_access(THD *thd, char *db,
-+			      TABLE_LIST *table_list)
-+{
-+  int error=0;
-+  if (table_list)
-+  {
-+    /* Check that all tables use the current database */
-+    TABLE_LIST *tmp;
-+    for (tmp= table_list; tmp; tmp= tmp->next_local)
-+    {
-+      if (!tmp->db || !tmp->db[0])
-+	tmp->db=db;
-+    }
-+    error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
-+			     table_list,0);
-+  }
-+  return error;
-+}
-+
-+
-+static bool check_db_used(THD *thd,TABLE_LIST *tables)
-+{
-+  char *current_db= NULL;
-+  for (; tables; tables= tables->next_global)
-+  {
-+    if (tables->db == NULL)
-+    {
-+      /*
-+        This code never works and should be removed in 5.1.  All tables
-+        that are added to the list of tables should already have its
-+        database field initialized properly (see st_lex::add_table_to_list).
-+      */
-+      DBUG_ASSERT(0);
-+      if (thd->copy_db_to(&current_db, 0))
-+        return TRUE;
-+      tables->db= current_db;
-+    }
-+  }
-+  return FALSE;
-+}
-+
-+/****************************************************************************
-+	Check stack size; Send error if there isn't enough stack to continue
-+****************************************************************************/
-+
-+#if STACK_DIRECTION < 0
-+#define used_stack(A,B) (long) (A - B)
-+#else
-+#define used_stack(A,B) (long) (B - A)
-+#endif
-+
-+#ifndef DBUG_OFF
-+long max_stack_used;
-+#endif
-+
-+#ifndef EMBEDDED_LIBRARY
-+/*
-+  Note: The 'buf' parameter is necessary, even if it is unused here.
-+  - fix_fields functions has a "dummy" buffer large enough for the
-+    corresponding exec. (Thus we only have to check in fix_fields.)
-+  - Passing to check_stack_overrun() prevents the compiler from removing it.
-+ */
-+bool check_stack_overrun(THD *thd, long margin,
-+			 char *buf __attribute__((unused)))
-+{
-+  long stack_used;
-+  DBUG_ASSERT(thd == current_thd);
-+  if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
-+      (long) (thread_stack - margin))
-+  {
-+    sprintf(errbuff[0],ER(ER_STACK_OVERRUN_NEED_MORE),
-+            stack_used,thread_stack,margin);
-+    my_message(ER_STACK_OVERRUN_NEED_MORE,errbuff[0],MYF(0));
-+    thd->fatal_error();
-+    return 1;
-+  }
-+#ifndef DBUG_OFF
-+  max_stack_used= max(max_stack_used, stack_used);
-+#endif
-+  return 0;
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+#define MY_YACC_INIT 1000			// Start with big alloc
-+#define MY_YACC_MAX  32000			// Because of 'short'
-+
-+bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
-+{
-+  LEX	*lex= current_thd->lex;
-+  ulong old_info=0;
-+  if ((uint) *yystacksize >= MY_YACC_MAX)
-+    return 1;
-+  if (!lex->yacc_yyvs)
-+    old_info= *yystacksize;
-+  *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
-+  if (!(lex->yacc_yyvs= (char*)
-+	my_realloc((gptr) lex->yacc_yyvs,
-+		   *yystacksize*sizeof(**yyvs),
-+		   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
-+      !(lex->yacc_yyss= (char*)
-+	my_realloc((gptr) lex->yacc_yyss,
-+		   *yystacksize*sizeof(**yyss),
-+		   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
-+    return 1;
-+  if (old_info)
-+  {						// Copy old info from stack
-+    memcpy(lex->yacc_yyss, (gptr) *yyss, old_info*sizeof(**yyss));
-+    memcpy(lex->yacc_yyvs, (gptr) *yyvs, old_info*sizeof(**yyvs));
-+  }
-+  *yyss=(short*) lex->yacc_yyss;
-+  *yyvs=(YYSTYPE*) lex->yacc_yyvs;
-+  return 0;
-+}
-+
-+
-+/****************************************************************************
-+  Initialize global thd variables needed for query
-+****************************************************************************/
-+
-+void
-+mysql_init_query(THD *thd, uchar *buf, uint length)
-+{
-+  DBUG_ENTER("mysql_init_query");
-+  lex_start(thd, buf, length);
-+  mysql_reset_thd_for_next_command(thd);
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Reset THD part responsible for command processing state.
-+
-+ DESCRIPTION
-+   This needs to be called before execution of every statement
-+   (prepared or conventional).
-+
-+ TODO
-+   Make it a method of THD and align its name with the rest of
-+   reset/end/start/init methods.
-+   Call it after we use THD for queries, not before.
-+*/
-+
-+void mysql_reset_thd_for_next_command(THD *thd)
-+{
-+  DBUG_ENTER("mysql_reset_thd_for_next_command");
-+  thd->free_list= 0;
-+  thd->select_number= 1;
-+  thd->query_start_used= thd->insert_id_used=0;
-+  thd->last_insert_id_used_bin_log= FALSE;
-+  thd->is_fatal_error= thd->time_zone_used= 0;
-+  thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | 
-+                          SERVER_QUERY_NO_INDEX_USED |
-+                          SERVER_QUERY_NO_GOOD_INDEX_USED);
-+  DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
-+  thd->tmp_table_used= 0;
-+  if (!thd->in_sub_stmt)
-+  {
-+    if (opt_bin_log)
-+    {
-+      reset_dynamic(&thd->user_var_events);
-+      thd->user_var_events_alloc= thd->mem_root;
-+    }
-+    thd->clear_error();
-+    thd->total_warn_count=0;			// Warnings for this query
-+    thd->rand_used= 0;
-+    thd->sent_row_count= thd->examined_row_count= 0;
-+  }
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+void
-+mysql_init_select(LEX *lex)
-+{
-+  SELECT_LEX *select_lex= lex->current_select;
-+  select_lex->init_select();
-+  lex->wild= 0;
-+  if (select_lex == &lex->select_lex)
-+  {
-+    DBUG_ASSERT(lex->result == 0);
-+    lex->exchange= 0;
-+  }
-+}
-+
-+
-+bool
-+mysql_new_select(LEX *lex, bool move_down)
-+{
-+  SELECT_LEX *select_lex;
-+  THD *thd= lex->thd;
-+  DBUG_ENTER("mysql_new_select");
-+
-+  if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
-+    DBUG_RETURN(1);
-+  select_lex->select_number= ++thd->select_number;
-+  select_lex->parent_lex= lex; /* Used in init_query. */
-+  select_lex->init_query();
-+  select_lex->init_select();
-+  lex->nest_level++;
-+  select_lex->nest_level= lex->nest_level;
-+  /*
-+    Don't evaluate this subquery during statement prepare even if
-+    it's a constant one. The flag is switched off in the end of
-+    mysql_stmt_prepare.
-+  */
-+  if (thd->stmt_arena->is_stmt_prepare())
-+    select_lex->uncacheable|= UNCACHEABLE_PREPARE;
-+  if (move_down)
-+  {
-+    SELECT_LEX_UNIT *unit;
-+    lex->subqueries= TRUE;
-+    /* first select_lex of subselect or derived table */
-+    if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
-+      DBUG_RETURN(1);
-+
-+    unit->init_query();
-+    unit->init_select();
-+    unit->thd= thd;
-+    unit->include_down(lex->current_select);
-+    unit->link_next= 0;
-+    unit->link_prev= 0;
-+    unit->return_to= lex->current_select;
-+    select_lex->include_down(unit);
-+    /*
-+      By default we assume that it is usual subselect and we have outer name
-+      resolution context, if no we will assign it to 0 later
-+    */
-+    select_lex->context.outer_context= &select_lex->outer_select()->context;
-+  }
-+  else
-+  {
-+    if (lex->current_select->order_list.first && !lex->current_select->braces)
-+    {
-+      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
-+      DBUG_RETURN(1);
-+    }
-+    select_lex->include_neighbour(lex->current_select);
-+    SELECT_LEX_UNIT *unit= select_lex->master_unit();                              
-+    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
-+      DBUG_RETURN(1);
-+    select_lex->context.outer_context= 
-+                unit->first_select()->context.outer_context;
-+  }
-+
-+  select_lex->master_unit()->global_parameters= select_lex;
-+  select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
-+  lex->current_select= select_lex;
-+  /*
-+    in subquery is SELECT query and we allow resolution of names in SELECT
-+    list
-+  */
-+  select_lex->context.resolve_in_select_list= TRUE;
-+  DBUG_RETURN(0);
-+}
-+
-+/*
-+  Create a select to return the same output as 'SELECT @@var_name'.
-+
-+  SYNOPSIS
-+    create_select_for_variable()
-+    var_name		Variable name
-+
-+  DESCRIPTION
-+    Used for SHOW COUNT(*) [ WARNINGS | ERROR]
-+
-+    This will crash with a core dump if the variable doesn't exists
-+*/
-+
-+void create_select_for_variable(const char *var_name)
-+{
-+  THD *thd;
-+  LEX *lex;
-+  LEX_STRING tmp, null_lex_string;
-+  Item *var;
-+  char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
-+  DBUG_ENTER("create_select_for_variable");
-+
-+  thd= current_thd;
-+  lex= thd->lex;
-+  mysql_init_select(lex);
-+  lex->sql_command= SQLCOM_SELECT;
-+  tmp.str= (char*) var_name;
-+  tmp.length=strlen(var_name);
-+  bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
-+  /*
-+    We set the name of Item to @@session.var_name because that then is used
-+    as the column name in the output.
-+  */
-+  if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
-+  {
-+    end= strxmov(buff, "@@session.", var_name, NullS);
-+    var->set_name(buff, end-buff, system_charset_info);
-+    add_item_to_list(thd, var);
-+  }
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+void mysql_init_multi_delete(LEX *lex)
-+{
-+  lex->sql_command=  SQLCOM_DELETE_MULTI;
-+  mysql_init_select(lex);
-+  lex->select_lex.select_limit= 0;
-+  lex->unit.select_limit_cnt= HA_POS_ERROR;
-+  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
-+  lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ;
-+  lex->query_tables= 0;
-+  lex->query_tables_last= &lex->query_tables;
-+}
-+
-+/*
-+  When you modify mysql_parse(), you may need to mofify
-+  mysql_test_parse_for_slave() in this same file.
-+*/
-+
-+void mysql_parse(THD *thd, char *inBuf, uint length)
-+{
-+  DBUG_ENTER("mysql_parse");
-+
-+  DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
-+
-+  mysql_init_query(thd, (uchar*) inBuf, length);
-+  if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
-+  {
-+    LEX *lex= thd->lex;
-+    
-+    sp_cache_flush_obsolete(&thd->sp_proc_cache);
-+    sp_cache_flush_obsolete(&thd->sp_func_cache);
-+    
-+    if (!MYSQLparse((void *)thd) && ! thd->is_fatal_error)
-+    {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+      if (mqh_used && thd->user_connect &&
-+	  check_mqh(thd, lex->sql_command))
-+      {
-+	thd->net.error = 0;
-+      }
-+      else
-+#endif
-+      {
-+	if (thd->net.report_error)
-+	{
-+	  if (thd->lex->sphead)
-+	  {
-+	    delete thd->lex->sphead;
-+	    thd->lex->sphead= NULL;
-+	  }
-+	}
-+	else
-+	{
-+          /*
-+            Binlog logs a string starting from thd->query and having length
-+            thd->query_length; so we set thd->query_length correctly (to not
-+            log several statements in one event, when we executed only first).
-+            We set it to not see the ';' (otherwise it would get into binlog
-+            and Query_log_event::print() would give ';;' output).
-+            This also helps display only the current query in SHOW
-+            PROCESSLIST.
-+            Note that we don't need LOCK_thread_count to modify query_length.
-+          */
-+          if (lex->found_semicolon &&
-+              (thd->query_length= (ulong)(lex->found_semicolon - thd->query)))
-+            thd->query_length--;
-+          /* Actually execute the query */
-+	  mysql_execute_command(thd);
-+	  query_cache_end_of_result(thd);
-+	}
-+      }
-+      lex->unit.cleanup();
-+    }
-+    else
-+    {
-+      DBUG_ASSERT(thd->net.report_error);
-+      DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
-+			 thd->is_fatal_error));
-+
-+      /*
-+        The first thing we do after parse error is freeing sp_head to
-+        ensure that we have restored original memroot.
-+      */
-+      if (thd->lex->sphead)
-+      {
-+	/* Clean up after failed stored procedure/function */
-+	delete thd->lex->sphead;
-+	thd->lex->sphead= NULL;
-+      }
-+      query_cache_abort(&thd->net);
-+      lex->unit.cleanup();
-+    }
-+    thd->proc_info="freeing items";
-+    thd->end_statement();
-+    thd->cleanup_after_query();
-+    DBUG_ASSERT(thd->change_list.is_empty());
-+  }
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+#ifdef HAVE_REPLICATION
-+/*
-+  Usable by the replication SQL thread only: just parse a query to know if it
-+  can be ignored because of replicate-*-table rules.
-+
-+  RETURN VALUES
-+    0	cannot be ignored
-+    1	can be ignored
-+*/
-+
-+bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
-+{
-+  LEX *lex= thd->lex;
-+  bool error= 0;
-+  DBUG_ENTER("mysql_test_parse_for_slave");
-+
-+  mysql_init_query(thd, (uchar*) inBuf, length);
-+  if (!MYSQLparse((void*) thd) && ! thd->is_fatal_error &&
-+      all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
-+    error= 1;                  /* Ignore question */
-+  thd->end_statement();
-+  thd->cleanup_after_query();
-+  DBUG_RETURN(error);
-+}
-+#endif
-+
-+
-+
-+/*****************************************************************************
-+** Store field definition for create
-+** Return 0 if ok
-+******************************************************************************/
-+
-+bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
-+		       char *length, char *decimals,
-+		       uint type_modifier,
-+		       Item *default_value, Item *on_update_value,
-+                       LEX_STRING *comment,
-+		       char *change,
-+                       List<String> *interval_list, CHARSET_INFO *cs,
-+		       uint uint_geom_type)
-+{
-+  register create_field *new_field;
-+  LEX  *lex= thd->lex;
-+  DBUG_ENTER("add_field_to_list");
-+
-+  if (strlen(field_name) > NAME_LEN)
-+  {
-+    my_error(ER_TOO_LONG_IDENT, MYF(0), field_name); /* purecov: inspected */
-+    DBUG_RETURN(1);				/* purecov: inspected */
-+  }
-+  if (type_modifier & PRI_KEY_FLAG)
-+  {
-+    lex->col_list.push_back(new key_part_spec(field_name,0));
-+    lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF,
-+				    0, lex->col_list));
-+    lex->col_list.empty();
-+  }
-+  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
-+  {
-+    lex->col_list.push_back(new key_part_spec(field_name,0));
-+    lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0,
-+				    lex->col_list));
-+    lex->col_list.empty();
-+  }
-+
-+  if (default_value)
-+  {
-+    /* 
-+      Default value should be literal => basic constants =>
-+      no need fix_fields()
-+      
-+      We allow only one function as part of default value - 
-+      NOW() as default for TIMESTAMP type.
-+    */
-+    if (default_value->type() == Item::FUNC_ITEM && 
-+        !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
-+         type == FIELD_TYPE_TIMESTAMP))
-+    {
-+      my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
-+      DBUG_RETURN(1);
-+    }
-+    else if (default_value->type() == Item::NULL_ITEM)
-+    {
-+      default_value= 0;
-+      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
-+	  NOT_NULL_FLAG)
-+      {
-+	my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
-+	DBUG_RETURN(1);
-+      }
-+    }
-+    else if (type_modifier & AUTO_INCREMENT_FLAG)
-+    {
-+      my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
-+      DBUG_RETURN(1);
-+    }
-+  }
-+
-+  if (on_update_value && type != FIELD_TYPE_TIMESTAMP)
-+  {
-+    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
-+    DBUG_RETURN(1);
-+  }
-+
-+  if (type == FIELD_TYPE_TIMESTAMP && length)
-+  {
-+    /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
-+       In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
-+       and so on, the display width is ignored.
-+    */
-+    char buf[32];
-+    my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
-+    push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
-+                        ER_WARN_DEPRECATED_SYNTAX,
-+                        ER(ER_WARN_DEPRECATED_SYNTAX),
-+                        buf, "TIMESTAMP");
-+  }
-+
-+  if (!(new_field= new create_field()) ||
-+      new_field->init(thd, field_name, type, length, decimals, type_modifier,
-+                      default_value, on_update_value, comment, change,
-+                      interval_list, cs, uint_geom_type))
-+    DBUG_RETURN(1);
-+
-+  lex->create_list.push_back(new_field);
-+  lex->last_field=new_field;
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/* Store position for column in ALTER TABLE .. ADD column */
-+
-+void store_position_for_column(const char *name)
-+{
-+  current_thd->lex->last_field->after=my_const_cast(char*) (name);
-+}
-+
-+bool
-+add_proc_to_list(THD* thd, Item *item)
-+{
-+  ORDER *order;
-+  Item	**item_ptr;
-+
-+  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
-+    return 1;
-+  item_ptr = (Item**) (order+1);
-+  *item_ptr= item;
-+  order->item=item_ptr;
-+  order->free_me=0;
-+  thd->lex->proc_list.link_in_list((byte*) order,(byte**) &order->next);
-+  return 0;
-+}
-+
-+
-+/* Fix escaping of _, % and \ in database and table names (for ODBC) */
-+
-+static void remove_escape(char *name)
-+{
-+  if (!*name)					// For empty DB names
-+    return;
-+  char *to;
-+#ifdef USE_MB
-+  char *strend=name+(uint) strlen(name);
-+#endif
-+  for (to=name; *name ; name++)
-+  {
-+#ifdef USE_MB
-+    int l;
-+    if (use_mb(system_charset_info) &&
-+        (l = my_ismbchar(system_charset_info, name, strend)))
-+    {
-+	while (l--)
-+	    *to++ = *name++;
-+	name--;
-+	continue;
-+    }
-+#endif
-+    if (*name == '\\' && name[1])
-+      name++;					// Skip '\\'
-+    *to++= *name;
-+  }
-+  *to=0;
-+}
-+
-+/****************************************************************************
-+** save order by and tables in own lists
-+****************************************************************************/
-+
-+
-+bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
-+{
-+  ORDER *order;
-+  DBUG_ENTER("add_to_list");
-+  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
-+    DBUG_RETURN(1);
-+  order->item_ptr= item;
-+  order->item= &order->item_ptr;
-+  order->asc = asc;
-+  order->free_me=0;
-+  order->used=0;
-+  order->counter_used= 0;
-+  list.link_in_list((byte*) order,(byte**) &order->next);
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+  Add a table to list of used tables
-+
-+  SYNOPSIS
-+    add_table_to_list()
-+    table		Table to add
-+    alias		alias for table (or null if no alias)
-+    table_options	A set of the following bits:
-+			TL_OPTION_UPDATING	Table will be updated
-+			TL_OPTION_FORCE_INDEX	Force usage of index
-+			TL_OPTION_ALIAS	        an alias in multi table DELETE
-+    lock_type		How table should be locked
-+    use_index		List of indexed used in USE INDEX
-+    ignore_index	List of indexed used in IGNORE INDEX
-+
-+    RETURN
-+      0		Error
-+      #		Pointer to TABLE_LIST element added to the total table list
-+*/
-+
-+TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
-+					     Table_ident *table,
-+					     LEX_STRING *alias,
-+					     ulong table_options,
-+					     thr_lock_type lock_type,
-+					     List<String> *use_index_arg,
-+					     List<String> *ignore_index_arg,
-+                                             LEX_STRING *option)
-+{
-+  register TABLE_LIST *ptr;
-+  TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
-+  char *alias_str;
-+  LEX *lex= thd->lex;
-+  DBUG_ENTER("add_table_to_list");
-+  LINT_INIT(previous_table_ref);
-+
-+  if (!table)
-+    DBUG_RETURN(0);				// End of memory
-+  alias_str= alias ? alias->str : table->table.str;
-+  if (!test(table_options & TL_OPTION_ALIAS) && 
-+      check_table_name(table->table.str, table->table.length))
-+  {
-+    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
-+    DBUG_RETURN(0);
-+  }
-+
-+  if (!alias)					/* Alias is case sensitive */
-+  {
-+    if (table->sel)
-+    {
-+      my_message(ER_DERIVED_MUST_HAVE_ALIAS,
-+                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
-+      DBUG_RETURN(0);
-+    }
-+    if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
-+      DBUG_RETURN(0);
-+  }
-+  if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
-+    DBUG_RETURN(0);				/* purecov: inspected */
-+  if (table->db.str)
-+  {
-+    if (table->is_derived_table() == FALSE && check_db_name(table->db.str))
-+    {
-+      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
-+      DBUG_RETURN(0);
-+    }
-+    ptr->db= table->db.str;
-+    ptr->db_length= table->db.length;
-+  }
-+  else if (thd->copy_db_to(&ptr->db, &ptr->db_length))
-+    DBUG_RETURN(0);
-+
-+  ptr->alias= alias_str;
-+  if (lower_case_table_names && table->table.length)
-+    table->table.length= my_casedn_str(files_charset_info, table->table.str);
-+  ptr->table_name=table->table.str;
-+  ptr->table_name_length=table->table.length;
-+  ptr->lock_type=   lock_type;
-+  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
-+  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
-+  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
-+  ptr->derived=	    table->sel;
-+  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
-+                                      information_schema_name.str))
-+  {
-+    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
-+    {
-+      my_error(ER_UNKNOWN_TABLE, MYF(0),
-+               ptr->table_name, information_schema_name.str);
-+      DBUG_RETURN(0);
-+    }
-+    ptr->schema_table_name= ptr->table_name;
-+    ptr->schema_table= schema_table;
-+  }
-+  ptr->select_lex=  lex->current_select;
-+  ptr->cacheable_table= 1;
-+  if (use_index_arg)
-+    ptr->use_index=(List<String> *) thd->memdup((gptr) use_index_arg,
-+						sizeof(*use_index_arg));
-+  if (ignore_index_arg)
-+    ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index_arg,
-+						   sizeof(*ignore_index_arg));
-+  ptr->option= option ? option->str : 0;
-+  /* check that used name is unique */
-+  if (lock_type != TL_IGNORE)
-+  {
-+    TABLE_LIST *first_table= (TABLE_LIST*) table_list.first;
-+    if (lex->sql_command == SQLCOM_CREATE_VIEW)
-+      first_table= first_table ? first_table->next_local : NULL;
-+    for (TABLE_LIST *tables= first_table ;
-+	 tables ;
-+	 tables=tables->next_local)
-+    {
-+      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
-+	  !strcmp(ptr->db, tables->db))
-+      {
-+	my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
-+	DBUG_RETURN(0);				/* purecov: tested */
-+      }
-+    }
-+  }
-+  /* Store the table reference preceding the current one. */
-+  if (table_list.elements > 0)
-+  {
-+    /*
-+      table_list.next points to the last inserted TABLE_LIST->next_local'
-+      element
-+      We don't use the offsetof() macro here to avoid warnings from gcc
-+    */
-+    previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
-+                                       ((char*) &(ptr->next_local) -
-+                                        (char*) ptr));
-+    /*
-+      Set next_name_resolution_table of the previous table reference to point
-+      to the current table reference. In effect the list
-+      TABLE_LIST::next_name_resolution_table coincides with
-+      TABLE_LIST::next_local. Later this may be changed in
-+      store_top_level_join_columns() for NATURAL/USING joins.
-+    */
-+    previous_table_ref->next_name_resolution_table= ptr;
-+  }
-+
-+  /*
-+    Link the current table reference in a local list (list for current select).
-+    Notice that as a side effect here we set the next_local field of the
-+    previous table reference to 'ptr'. Here we also add one element to the
-+    list 'table_list'.
-+  */
-+  table_list.link_in_list((byte*) ptr, (byte**) &ptr->next_local);
-+  ptr->next_name_resolution_table= NULL;
-+  /* Link table in global list (all used tables) */
-+  lex->add_to_query_tables(ptr);
-+  DBUG_RETURN(ptr);
-+}
-+
-+
-+/*
-+  Initialize a new table list for a nested join
-+
-+  SYNOPSIS
-+    init_nested_join()
-+    thd         current thread
-+
-+  DESCRIPTION
-+    The function initializes a structure of the TABLE_LIST type
-+    for a nested join. It sets up its nested join list as empty.
-+    The created structure is added to the front of the current
-+    join list in the st_select_lex object. Then the function
-+    changes the current nest level for joins to refer to the newly
-+    created empty list after having saved the info on the old level
-+    in the initialized structure.
-+
-+  RETURN VALUE
-+    0,  if success
-+    1,  otherwise
-+*/
-+
-+bool st_select_lex::init_nested_join(THD *thd)
-+{
-+  TABLE_LIST *ptr;
-+  NESTED_JOIN *nested_join;
-+  DBUG_ENTER("init_nested_join");
-+
-+  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
-+                                       sizeof(NESTED_JOIN))))
-+    DBUG_RETURN(1);
-+  nested_join= ptr->nested_join=
-+    ((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
-+
-+  join_list->push_front(ptr);
-+  ptr->embedding= embedding;
-+  ptr->join_list= join_list;
-+  embedding= ptr;
-+  join_list= &nested_join->join_list;
-+  join_list->empty();
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+  End a nested join table list
-+
-+  SYNOPSIS
-+    end_nested_join()
-+    thd         current thread
-+
-+  DESCRIPTION
-+    The function returns to the previous join nest level.
-+    If the current level contains only one member, the function
-+    moves it one level up, eliminating the nest.
-+
-+  RETURN VALUE
-+    Pointer to TABLE_LIST element added to the total table list, if success
-+    0, otherwise
-+*/
-+
-+TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
-+{
-+  TABLE_LIST *ptr;
-+  NESTED_JOIN *nested_join;
-+  DBUG_ENTER("end_nested_join");
-+
-+  DBUG_ASSERT(embedding);
-+  ptr= embedding;
-+  join_list= ptr->join_list;
-+  embedding= ptr->embedding;
-+  nested_join= ptr->nested_join;
-+  if (nested_join->join_list.elements == 1)
-+  {
-+    TABLE_LIST *embedded= nested_join->join_list.head();
-+    join_list->pop();
-+    embedded->join_list= join_list;
-+    embedded->embedding= embedding;
-+    join_list->push_front(embedded);
-+    ptr= embedded;
-+  }
-+  else if (nested_join->join_list.elements == 0)
-+  {
-+    join_list->pop();
-+    ptr= 0;                                     // return value
-+  }
-+  DBUG_RETURN(ptr);
-+}
-+
-+
-+/*
-+  Nest last join operation
-+
-+  SYNOPSIS
-+    nest_last_join()
-+    thd         current thread
-+
-+  DESCRIPTION
-+    The function nest last join operation as if it was enclosed in braces.
-+
-+  RETURN VALUE
-+    0  Error
-+    #  Pointer to TABLE_LIST element created for the new nested join
-+
-+*/
-+
-+TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
-+{
-+  TABLE_LIST *ptr;
-+  NESTED_JOIN *nested_join;
-+  List<TABLE_LIST> *embedded_list;
-+  DBUG_ENTER("nest_last_join");
-+
-+  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
-+                                       sizeof(NESTED_JOIN))))
-+    DBUG_RETURN(0);
-+  nested_join= ptr->nested_join=
-+    ((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
-+
-+  ptr->embedding= embedding;
-+  ptr->join_list= join_list;
-+  embedded_list= &nested_join->join_list;
-+  embedded_list->empty();
-+
-+  for (uint i=0; i < 2; i++)
-+  {
-+    TABLE_LIST *table= join_list->pop();
-+    table->join_list= embedded_list;
-+    table->embedding= ptr;
-+    embedded_list->push_back(table);
-+    if (table->natural_join)
-+    {
-+      ptr->is_natural_join= TRUE;
-+      /*
-+        If this is a JOIN ... USING, move the list of joined fields to the
-+        table reference that describes the join.
-+      */
-+      if (table->join_using_fields)
-+      {
-+        ptr->join_using_fields= table->join_using_fields;
-+        table->join_using_fields= NULL;
-+      }
-+    }
-+  }
-+  join_list->push_front(ptr);
-+  nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
-+  DBUG_RETURN(ptr);
-+}
-+
-+
-+/*
-+  Add a table to the current join list
-+
-+  SYNOPSIS
-+    add_joined_table()
-+    table       the table to add
-+
-+  DESCRIPTION
-+    The function puts a table in front of the current join list
-+    of st_select_lex object.
-+    Thus, joined tables are put into this list in the reverse order
-+    (the most outer join operation follows first).
-+
-+  RETURN VALUE
-+    None
-+*/
-+
-+void st_select_lex::add_joined_table(TABLE_LIST *table)
-+{
-+  DBUG_ENTER("add_joined_table");
-+  join_list->push_front(table);
-+  table->join_list= join_list;
-+  table->embedding= embedding;
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+  Convert a right join into equivalent left join
-+
-+  SYNOPSIS
-+    convert_right_join()
-+    thd         current thread
-+
-+  DESCRIPTION
-+    The function takes the current join list t[0],t[1] ... and
-+    effectively converts it into the list t[1],t[0] ...
-+    Although the outer_join flag for the new nested table contains
-+    JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
-+    operation.
-+
-+  EXAMPLES
-+    SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
-+      SELECT * FROM t2 LEFT JOIN t1 ON on_expr
-+
-+    SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
-+      SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
-+
-+    SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
-+      SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
-+
-+    SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3  ON on_expr2 =>
-+      SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
-+
-+  RETURN
-+    Pointer to the table representing the inner table, if success
-+    0, otherwise
-+*/
-+
-+TABLE_LIST *st_select_lex::convert_right_join()
-+{
-+  TABLE_LIST *tab2= join_list->pop();
-+  TABLE_LIST *tab1= join_list->pop();
-+  DBUG_ENTER("convert_right_join");
-+
-+  join_list->push_front(tab2);
-+  join_list->push_front(tab1);
-+  tab1->outer_join|= JOIN_TYPE_RIGHT;
-+
-+  DBUG_RETURN(tab1);
-+}
-+
-+/*
-+  Set lock for all tables in current select level
-+
-+  SYNOPSIS:
-+    set_lock_for_tables()
-+    lock_type			Lock to set for tables
-+
-+  NOTE:
-+    If lock is a write lock, then tables->updating is set 1
-+    This is to get tables_ok to know that the table is updated by the
-+    query
-+*/
-+
-+void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
-+{
-+  bool for_update= lock_type >= TL_READ_NO_INSERT;
-+  DBUG_ENTER("set_lock_for_tables");
-+  DBUG_PRINT("enter", ("lock_type: %d  for_update: %d", lock_type,
-+		       for_update));
-+
-+  for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
-+       tables;
-+       tables= tables->next_local)
-+  {
-+    tables->lock_type= lock_type;
-+    tables->updating=  for_update;
-+  }
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+  Create a fake SELECT_LEX for a unit
-+
-+  SYNOPSIS:
-+    add_fake_select_lex()
-+    thd			   thread handle
-+
-+  DESCRIPTION
-+    The method create a fake SELECT_LEX object for a unit.
-+    This object is created for any union construct containing a union
-+    operation and also for any single select union construct of the form
-+    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... 
-+    or of the form
-+    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
-+  
-+  NOTES
-+    The object is used to retrieve rows from the temporary table
-+    where the result on the union is obtained.
-+
-+  RETURN VALUES
-+    1     on failure to create the object
-+    0     on success
-+*/
-+
-+bool st_select_lex_unit::add_fake_select_lex(THD *thd)
-+{
-+  SELECT_LEX *first_sl= first_select();
-+  DBUG_ENTER("add_fake_select_lex");
-+  DBUG_ASSERT(!fake_select_lex);
-+
-+  if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
-+      DBUG_RETURN(1);
-+  fake_select_lex->include_standalone(this, 
-+                                      (SELECT_LEX_NODE**)&fake_select_lex);
-+  fake_select_lex->select_number= INT_MAX;
-+  fake_select_lex->parent_lex= thd->lex; /* Used in init_query. */
-+  fake_select_lex->make_empty_select();
-+  fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
-+  fake_select_lex->select_limit= 0;
-+
-+  fake_select_lex->context.outer_context=first_sl->context.outer_context;
-+  /* allow item list resolving in fake select for ORDER BY */
-+  fake_select_lex->context.resolve_in_select_list= TRUE;
-+  fake_select_lex->context.select_lex= fake_select_lex;
-+
-+  if (!first_sl->next_select())
-+  {
-+    /* 
-+      This works only for 
-+      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
-+      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
-+      just before the parser starts processing order_list
-+    */ 
-+    global_parameters= fake_select_lex;
-+    fake_select_lex->no_table_names_allowed= 1;
-+    thd->lex->current_select= fake_select_lex;
-+  }
-+  thd->lex->pop_context();
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+  Push a new name resolution context for a JOIN ... ON clause to the
-+  context stack of a query block.
-+
-+  SYNOPSIS
-+    push_new_name_resolution_context()
-+    thd       pointer to current thread
-+    left_op   left  operand of the JOIN
-+    right_op  rigth operand of the JOIN
-+
-+  DESCRIPTION
-+    Create a new name resolution context for a JOIN ... ON clause,
-+    set the first and last leaves of the list of table references
-+    to be used for name resolution, and push the newly created
-+    context to the stack of contexts of the query.
-+
-+  RETURN
-+    FALSE  if all is OK
-+    TRUE   if a memory allocation error occured
-+*/
-+
-+bool
-+push_new_name_resolution_context(THD *thd,
-+                                 TABLE_LIST *left_op, TABLE_LIST *right_op)
-+{
-+  Name_resolution_context *on_context;
-+  if (!(on_context= new (thd->mem_root) Name_resolution_context))
-+    return TRUE;
-+  on_context->init();
-+  on_context->first_name_resolution_table=
-+    left_op->first_leaf_for_name_resolution();
-+  on_context->last_name_resolution_table=
-+    right_op->last_leaf_for_name_resolution();
-+  return thd->lex->push_context(on_context);
-+}
-+
-+
-+/*
-+  Add an ON condition to the second operand of a JOIN ... ON.
-+
-+  SYNOPSIS
-+    add_join_on
-+    b     the second operand of a JOIN ... ON
-+    expr  the condition to be added to the ON clause
-+
-+  DESCRIPTION
-+    Add an ON condition to the right operand of a JOIN ... ON clause.
-+
-+  RETURN
-+    FALSE  if there was some error
-+    TRUE   if all is OK
-+*/
-+
-+void add_join_on(TABLE_LIST *b, Item *expr)
-+{
-+  if (expr)
-+  {
-+    if (!b->on_expr)
-+      b->on_expr= expr;
-+    else
-+    {
-+      /*
-+        If called from the parser, this happens if you have both a
-+        right and left join. If called later, it happens if we add more
-+        than one condition to the ON clause.
-+      */
-+      b->on_expr= new Item_cond_and(b->on_expr,expr);
-+    }
-+    b->on_expr->top_level_item();
-+  }
-+}
-+
-+
-+/*
-+  Mark that there is a NATURAL JOIN or JOIN ... USING between two
-+  tables.
-+
-+  SYNOPSIS
-+    add_join_natural()
-+    a			Left join argument
-+    b			Right join argument
-+    using_fields        Field names from USING clause
-+  
-+  IMPLEMENTATION
-+    This function marks that table b should be joined with a either via
-+    a NATURAL JOIN or via JOIN ... USING. Both join types are special
-+    cases of each other, so we treat them together. The function
-+    setup_conds() creates a list of equal condition between all fields
-+    of the same name for NATURAL JOIN or the fields in 'using_fields'
-+    for JOIN ... USING. The list of equality conditions is stored
-+    either in b->on_expr, or in JOIN::conds, depending on whether there
-+    was an outer join.
-+
-+  EXAMPLE
-+    SELECT * FROM t1 NATURAL LEFT JOIN t2
-+     <=>
-+    SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
-+
-+    SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
-+     <=>
-+    SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
-+
-+    SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
-+     <=>
-+    SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
-+
-+  RETURN
-+    None
-+*/
-+
-+void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields)
-+{
-+  b->natural_join= a;
-+  b->join_using_fields= using_fields;
-+}
-+
-+
-+/*
-+  Reload/resets privileges and the different caches.
-+
-+  SYNOPSIS
-+    reload_acl_and_cache()
-+    thd			Thread handler (can be NULL!)
-+    options             What should be reset/reloaded (tables, privileges,
-+    slave...)
-+    tables              Tables to flush (if any)
-+    write_to_binlog     Depending on 'options', it may be very bad to write the
-+                        query to the binlog (e.g. FLUSH SLAVE); this is a
-+                        pointer where reload_acl_and_cache() will put 0 if
-+                        it thinks we really should not write to the binlog.
-+                        Otherwise it will put 1.
-+
-+  RETURN
-+    0	 ok
-+    !=0  error.  thd->killed or thd->net.report_error is set
-+*/
-+
-+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
-+                          bool *write_to_binlog)
-+{
-+  bool result=0;
-+  select_errors=0;				/* Write if more errors */
-+  bool tmp_write_to_binlog= 1;
-+
-+  DBUG_ASSERT(!thd || !thd->in_sub_stmt);
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  if (options & REFRESH_GRANT)
-+  {
-+    THD *tmp_thd= 0;
-+    /*
-+      If reload_acl_and_cache() is called from SIGHUP handler we have to
-+      allocate temporary THD for execution of acl_reload()/grant_reload().
-+    */
-+    if (!thd && (thd= (tmp_thd= new THD)))
-+    {
-+      thd->thread_stack= (char*) &tmp_thd;
-+      thd->store_globals();
-+    }
-+    if (thd)
-+    {
-+      (void)acl_reload(thd);
-+      (void)grant_reload(thd);
-+    }
-+    if (tmp_thd)
-+    {
-+      delete tmp_thd;
-+      /* Remember that we don't have a THD */
-+      my_pthread_setspecific_ptr(THR_THD,  0);
-+      thd= 0;
-+    }
-+    reset_mqh((LEX_USER *)NULL, TRUE);
-+  }
-+#endif
-+  if (options & REFRESH_LOG)
-+  {
-+    /*
-+      Flush the normal query log, the update log, the binary log,
-+      the slow query log, and the relay log (if it exists).
-+    */
-+
-+    /*
-+      Writing this command to the binlog may result in infinite loops
-+      when doing mysqlbinlog|mysql, and anyway it does not really make
-+      sense to log it automatically (would cause more trouble to users
-+      than it would help them)
-+    */
-+    tmp_write_to_binlog= 0;
-+    mysql_log.new_file(1);
-+    mysql_slow_log.new_file(1);
-+    if( mysql_bin_log.is_open() )
-+    {
-+      mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
-+    }
-+#ifdef HAVE_REPLICATION
-+    pthread_mutex_lock(&LOCK_active_mi);
-+    rotate_relay_log(active_mi);
-+    pthread_mutex_unlock(&LOCK_active_mi);
-+#endif
-+    if (ha_flush_logs())
-+      result=1;
-+    if (flush_error_log())
-+      result=1;
-+  }
-+#ifdef HAVE_QUERY_CACHE
-+  if (options & REFRESH_QUERY_CACHE_FREE)
-+  {
-+    query_cache.pack();				// FLUSH QUERY CACHE
-+    options &= ~REFRESH_QUERY_CACHE;    // Don't flush cache, just free memory
-+  }
-+  if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
-+  {
-+    query_cache.flush();			// RESET QUERY CACHE
-+  }
-+#endif /*HAVE_QUERY_CACHE*/
-+  /*
-+    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
-+    (see sql_yacc.yy)
-+  */
-+  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK)) 
-+  {
-+    if ((options & REFRESH_READ_LOCK) && thd)
-+    {
-+      /*
-+        We must not try to aspire a global read lock if we have a write
-+        locked table. This would lead to a deadlock when trying to
-+        reopen (and re-lock) the table after the flush.
-+      */
-+      if (thd->locked_tables)
-+      {
-+        THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
-+        THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
-+
-+        for (; lock_p < end_p; lock_p++)
-+        {
-+          if ((*lock_p)->type == TL_WRITE)
-+          {
-+            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
-+            return 1;
-+          }
-+        }
-+      }
-+      /*
-+	Writing to the binlog could cause deadlocks, as we don't log
-+	UNLOCK TABLES
-+      */
-+      tmp_write_to_binlog= 0;
-+      if (lock_global_read_lock(thd))
-+	return 1;                               // Killed
-+      result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
-+                                 tables);
-+      if (make_global_read_lock_block_commit(thd)) // Killed
-+      {
-+        /* Don't leave things in a half-locked state */
-+        unlock_global_read_lock(thd);
-+        return 1;
-+      }
-+    }
-+    else
-+      result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
-+    my_dbopt_cleanup();
-+  }
-+  if (options & REFRESH_HOSTS)
-+    hostname_cache_refresh();
-+  if (thd && (options & REFRESH_STATUS))
-+    refresh_status(thd);
-+  if (options & REFRESH_THREADS)
-+    flush_thread_cache();
-+#ifdef HAVE_REPLICATION
-+  if (options & REFRESH_MASTER)
-+  {
-+    DBUG_ASSERT(thd);
-+    tmp_write_to_binlog= 0;
-+    if (reset_master(thd))
-+    {
-+      result=1;
-+      thd->fatal_error();                       // Ensure client get error
-+    }
-+  }
-+#endif
-+#ifdef OPENSSL
-+   if (options & REFRESH_DES_KEY_FILE)
-+   {
-+     if (des_key_file)
-+       result=load_des_key_file(des_key_file);
-+   }
-+#endif
-+#ifdef HAVE_REPLICATION
-+ if (options & REFRESH_SLAVE)
-+ {
-+   tmp_write_to_binlog= 0;
-+   pthread_mutex_lock(&LOCK_active_mi);
-+   if (reset_slave(thd, active_mi))
-+     result=1;
-+   pthread_mutex_unlock(&LOCK_active_mi);
-+ }
-+#endif
-+ if (options & REFRESH_USER_RESOURCES)
-+   reset_mqh((LEX_USER *) NULL);
-+ *write_to_binlog= tmp_write_to_binlog;
-+ return result;
-+}
-+
-+/*
-+  kill on thread
-+
-+  SYNOPSIS
-+    kill_one_thread()
-+    thd			Thread class
-+    id			Thread id
-+
-+  NOTES
-+    This is written such that we have a short lock on LOCK_thread_count
-+*/
-+
-+void kill_one_thread(THD *thd, ulong id, bool only_kill_query)
-+{
-+  THD *tmp;
-+  uint error=ER_NO_SUCH_THREAD;
-+  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+  I_List_iterator<THD> it(threads);
-+  while ((tmp=it++))
-+  {
-+    if (tmp->thread_id == id)
-+    {
-+      pthread_mutex_lock(&tmp->LOCK_delete);	// Lock from delete
-+      break;
-+    }
-+  }
-+  VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+  if (tmp)
-+  {
-+    if ((thd->security_ctx->master_access & SUPER_ACL) ||
-+	!strcmp(thd->security_ctx->user, tmp->security_ctx->user))
-+    {
-+      tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
-+      error=0;
-+    }
-+    else
-+      error=ER_KILL_DENIED_ERROR;
-+    pthread_mutex_unlock(&tmp->LOCK_delete);
-+  }
-+
-+  if (!error)
-+    send_ok(thd);
-+  else
-+    my_error(error, MYF(0), id);
-+}
-+
-+
-+	/* If pointer is not a null pointer, append filename to it */
-+
-+static bool append_file_to_dir(THD *thd, const char **filename_ptr,
-+			       const char *table_name)
-+{
-+  char buff[FN_REFLEN],*ptr, *end;
-+  if (!*filename_ptr)
-+    return 0;					// nothing to do
-+
-+  /* Check that the filename is not too long and it's a hard path */
-+  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
-+      !test_if_hard_path(*filename_ptr))
-+  {
-+    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
-+    return 1;
-+  }
-+  /* Fix is using unix filename format on dos */
-+  strmov(buff,*filename_ptr);
-+  end=convert_dirname(buff, *filename_ptr, NullS);
-+  if (!(ptr=thd->alloc((uint) (end-buff)+(uint) strlen(table_name)+1)))
-+    return 1;					// End of memory
-+  *filename_ptr=ptr;
-+  strxmov(ptr,buff,table_name,NullS);
-+  return 0;
-+}
-+
-+
-+/*
-+  Check if the select is a simple select (not an union)
-+
-+  SYNOPSIS
-+    check_simple_select()
-+
-+  RETURN VALUES
-+    0	ok
-+    1	error	; In this case the error messege is sent to the client
-+*/
-+
-+bool check_simple_select()
-+{
-+  THD *thd= current_thd;
-+  LEX *lex= thd->lex;
-+  if (lex->current_select != &lex->select_lex)
-+  {
-+    char command[80];
-+    strmake(command, lex->yylval->symbol.str,
-+	    min(lex->yylval->symbol.length, sizeof(command)-1));
-+    my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
-+    return 1;
-+  }
-+  return 0;
-+}
-+
-+
-+Comp_creator *comp_eq_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
-+}
-+
-+
-+Comp_creator *comp_ge_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&lt_creator:(Comp_creator *)&ge_creator;
-+}
-+
-+
-+Comp_creator *comp_gt_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&le_creator:(Comp_creator *)&gt_creator;
-+}
-+
-+
-+Comp_creator *comp_le_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&gt_creator:(Comp_creator *)&le_creator;
-+}
-+
-+
-+Comp_creator *comp_lt_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&ge_creator:(Comp_creator *)&lt_creator;
-+}
-+
-+
-+Comp_creator *comp_ne_creator(bool invert)
-+{
-+  return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
-+}
-+
-+
-+/*
-+  Construct ALL/ANY/SOME subquery Item
-+
-+  SYNOPSIS
-+    all_any_subquery_creator()
-+    left_expr - pointer to left expression
-+    cmp - compare function creator
-+    all - true if we create ALL subquery
-+    select_lex - pointer on parsed subquery structure
-+
-+  RETURN VALUE
-+    constructed Item (or 0 if out of memory)
-+*/
-+Item * all_any_subquery_creator(Item *left_expr,
-+				chooser_compare_func_creator cmp,
-+				bool all,
-+				SELECT_LEX *select_lex)
-+{
-+  if ((cmp == &comp_eq_creator) && !all)       //  = ANY <=> IN
-+    return new Item_in_subselect(left_expr, select_lex);
-+
-+  if ((cmp == &comp_ne_creator) && all)        // <> ALL <=> NOT IN
-+    return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
-+
-+  Item_allany_subselect *it=
-+    new Item_allany_subselect(left_expr, cmp, select_lex, all);
-+  if (all)
-+    return it->upper_item= new Item_func_not_all(it);	/* ALL */
-+
-+  return it->upper_item= new Item_func_nop_all(it);      /* ANY/SOME */
-+}
-+
-+
-+/*
-+  CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
-+  the proper arguments.  This isn't very fast but it should work for most
-+  cases.
-+
-+  In the future ALTER TABLE will notice that only added indexes
-+  and create these one by one for the existing table without having to do
-+  a full rebuild.
-+
-+  One should normally create all indexes with CREATE TABLE or ALTER TABLE.
-+*/
-+
-+bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
-+{
-+  List<create_field> fields;
-+  ALTER_INFO alter_info;
-+  alter_info.flags= ALTER_ADD_INDEX;
-+  HA_CREATE_INFO create_info;
-+  DBUG_ENTER("mysql_create_index");
-+  bzero((char*) &create_info,sizeof(create_info));
-+  create_info.db_type=DB_TYPE_DEFAULT;
-+  create_info.default_table_charset= thd->variables.collation_database;
-+  DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
-+				&create_info, table_list,
-+				fields, keys, 0, (ORDER*)0,
-+                                0, &alter_info, 1));
-+}
-+
-+
-+bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
-+{
-+  List<create_field> fields;
-+  List<Key> keys;
-+  HA_CREATE_INFO create_info;
-+  DBUG_ENTER("mysql_drop_index");
-+  bzero((char*) &create_info,sizeof(create_info));
-+  create_info.db_type=DB_TYPE_DEFAULT;
-+  create_info.default_table_charset= thd->variables.collation_database;
-+  alter_info->clear();
-+  alter_info->flags= ALTER_DROP_INDEX;
-+  DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
-+				&create_info, table_list,
-+				fields, keys, 0, (ORDER*)0,
-+                                0, alter_info, 1));
-+}
-+
-+
-+/*
-+  Multi update query pre-check
-+
-+  SYNOPSIS
-+    multi_update_precheck()
-+    thd		Thread handler
-+    tables	Global/local table list (have to be the same)
-+
-+  RETURN VALUE
-+    FALSE OK
-+    TRUE  Error
-+*/
-+
-+bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+  const char *msg= 0;
-+  TABLE_LIST *table;
-+  LEX *lex= thd->lex;
-+  SELECT_LEX *select_lex= &lex->select_lex;
-+  DBUG_ENTER("multi_update_precheck");
-+
-+  if (select_lex->item_list.elements != lex->value_list.elements)
-+  {
-+    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+    DBUG_RETURN(TRUE);
-+  }
-+  /*
-+    Ensure that we have UPDATE or SELECT privilege for each table
-+    The exact privilege is checked in mysql_multi_update()
-+  */
-+  for (table= tables; table; table= table->next_local)
-+  {
-+    if (table->derived)
-+      table->grant.privilege= SELECT_ACL;
-+    else if ((check_access(thd, UPDATE_ACL, table->db,
-+                           &table->grant.privilege, 0, 1,
-+                           test(table->schema_table)) ||
-+              grant_option &&
-+              check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
-+             (check_access(thd, SELECT_ACL, table->db,
-+                           &table->grant.privilege, 0, 0,
-+                           test(table->schema_table)) ||
-+              grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
-+      DBUG_RETURN(TRUE);
-+
-+    table->table_in_first_from_clause= 1;
-+  }
-+  /*
-+    Is there tables of subqueries?
-+  */
-+  if (&lex->select_lex != lex->all_selects_list || lex->time_zone_tables_used)
-+  {
-+    DBUG_PRINT("info",("Checking sub query list"));
-+    for (table= tables; table; table= table->next_global)
-+    {
-+      if (!my_tz_check_n_skip_implicit_tables(&table,
-+                                              lex->time_zone_tables_used) &&
-+          !table->table_in_first_from_clause)
-+      {
-+	if (check_access(thd, SELECT_ACL, table->db,
-+			 &table->grant.privilege, 0, 0,
-+                         test(table->schema_table)) ||
-+	    grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))
-+	  DBUG_RETURN(TRUE);
-+      }
-+    }
-+  }
-+
-+  if (select_lex->order_list.elements)
-+    msg= "ORDER BY";
-+  else if (select_lex->select_limit)
-+    msg= "LIMIT";
-+  if (msg)
-+  {
-+    my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
-+    DBUG_RETURN(TRUE);
-+  }
-+  DBUG_RETURN(FALSE);
-+}
-+
-+/*
-+  Multi delete query pre-check
-+
-+  SYNOPSIS
-+    multi_delete_precheck()
-+    thd			Thread handler
-+    tables		Global/local table list
-+
-+  RETURN VALUE
-+    FALSE OK
-+    TRUE  error
-+*/
-+
-+bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+  SELECT_LEX *select_lex= &thd->lex->select_lex;
-+  TABLE_LIST *aux_tables=
-+    (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
-+  TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
-+  DBUG_ENTER("multi_delete_precheck");
-+
-+  /* sql_yacc guarantees that tables and aux_tables are not zero */
-+  DBUG_ASSERT(aux_tables != 0);
-+  if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
-+      check_table_access(thd, SELECT_ACL, tables, 0))
-+    DBUG_RETURN(TRUE);
-+
-+  /*
-+    Since aux_tables list is not part of LEX::query_tables list we
-+    have to juggle with LEX::query_tables_own_last value to be able
-+    call check_table_access() safely.
-+  */
-+  thd->lex->query_tables_own_last= 0;
-+  if (check_table_access(thd, DELETE_ACL, aux_tables, 0))
-+  {
-+    thd->lex->query_tables_own_last= save_query_tables_own_last;
-+    DBUG_RETURN(TRUE);
-+  }
-+  thd->lex->query_tables_own_last= save_query_tables_own_last;
-+
-+  if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
-+  {
-+    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
-+               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
-+    DBUG_RETURN(TRUE);
-+  }
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+  Link tables in auxilary table list of multi-delete with corresponding
-+  elements in main table list, and set proper locks for them.
-+
-+  SYNOPSIS
-+    multi_delete_set_locks_and_link_aux_tables()
-+      lex - pointer to LEX representing multi-delete
-+
-+  RETURN VALUE
-+    FALSE - success
-+    TRUE  - error
-+*/
-+
-+bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
-+{
-+  TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
-+  TABLE_LIST *target_tbl;
-+  DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
-+
-+  lex->table_count= 0;
-+
-+  for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
-+       target_tbl; target_tbl= target_tbl->next_local)
-+  {
-+    lex->table_count++;
-+    /* All tables in aux_tables must be found in FROM PART */
-+    TABLE_LIST *walk;
-+    for (walk= tables; walk; walk= walk->next_local)
-+    {
-+      if (!my_strcasecmp(table_alias_charset,
-+			 target_tbl->alias, walk->alias) &&
-+	  !strcmp(walk->db, target_tbl->db))
-+	break;
-+    }
-+    if (!walk)
-+    {
-+      my_error(ER_UNKNOWN_TABLE, MYF(0),
-+               target_tbl->table_name, "MULTI DELETE");
-+      DBUG_RETURN(TRUE);
-+    }
-+    if (!walk->derived)
-+    {
-+      target_tbl->table_name= walk->table_name;
-+      target_tbl->table_name_length= walk->table_name_length;
-+    }
-+    walk->updating= target_tbl->updating;
-+    walk->lock_type= target_tbl->lock_type;
-+    target_tbl->correspondent_table= walk;	// Remember corresponding table
-+  }
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+  simple UPDATE query pre-check
-+
-+  SYNOPSIS
-+    update_precheck()
-+    thd		Thread handler
-+    tables	Global table list
-+
-+  RETURN VALUE
-+    FALSE OK
-+    TRUE  Error
-+*/
-+
-+bool update_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+  DBUG_ENTER("update_precheck");
-+  if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
-+  {
-+    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+    DBUG_RETURN(TRUE);
-+  }
-+  DBUG_RETURN(check_db_used(thd, tables) ||
-+	       check_one_table_access(thd, UPDATE_ACL, tables));
-+}
-+
-+
-+/*
-+  simple DELETE query pre-check
-+
-+  SYNOPSIS
-+    delete_precheck()
-+    thd		Thread handler
-+    tables	Global table list
-+
-+  RETURN VALUE
-+    FALSE  OK
-+    TRUE   error
-+*/
-+
-+bool delete_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+  DBUG_ENTER("delete_precheck");
-+  if (check_one_table_access(thd, DELETE_ACL, tables))
-+    DBUG_RETURN(TRUE);
-+  /* Set privilege for the WHERE clause */
-+  tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+  simple INSERT query pre-check
-+
-+  SYNOPSIS
-+    insert_precheck()
-+    thd		Thread handler
-+    tables	Global table list
-+
-+  RETURN VALUE
-+    FALSE  OK
-+    TRUE   error
-+*/
-+
-+bool insert_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+  LEX *lex= thd->lex;
-+  DBUG_ENTER("insert_precheck");
-+
-+  /*
-+    Check that we have modify privileges for the first table and
-+    select privileges for the rest
-+  */
-+  ulong privilege= (INSERT_ACL |
-+                    (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
-+                    (lex->value_list.elements ? UPDATE_ACL : 0));
-+
-+  if (check_one_table_access(thd, privilege, tables))
-+    DBUG_RETURN(TRUE);
-+
-+  if (lex->update_list.elements != lex->value_list.elements)
-+  {
-+    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+    DBUG_RETURN(TRUE);
-+  }
-+  if (check_db_used(thd, tables))
-+    DBUG_RETURN(TRUE);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+  CREATE TABLE query pre-check
-+
-+  SYNOPSIS
-+    create_table_precheck()
-+    thd			Thread handler
-+    tables		Global table list
-+    create_table	Table which will be created
-+
-+  RETURN VALUE
-+    FALSE   OK
-+    TRUE   Error
-+*/
-+
-+bool create_table_precheck(THD *thd, TABLE_LIST *tables,
-+                           TABLE_LIST *create_table)
-+{
-+  LEX *lex= thd->lex;
-+  SELECT_LEX *select_lex= &lex->select_lex;
-+  ulong want_priv;
-+  bool error= TRUE;                                 // Error message is given
-+  DBUG_ENTER("create_table_precheck");
-+
-+  want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
-+              CREATE_TMP_ACL : CREATE_ACL);
-+  lex->create_info.alias= create_table->alias;
-+  if (check_access(thd, want_priv, create_table->db,
-+		   &create_table->grant.privilege, 0, 0,
-+                   test(create_table->schema_table)) ||
-+      check_merge_table_access(thd, create_table->db,
-+			       (TABLE_LIST *)
-+			       lex->create_info.merge_list.first))
-+    goto err;
-+  if (grant_option && want_priv != CREATE_TMP_ACL &&
-+      check_grant(thd, want_priv, create_table, 0, 1, 0))
-+    goto err;
-+
-+  if (select_lex->item_list.elements)
-+  {
-+    /* Check permissions for used tables in CREATE TABLE ... SELECT */
-+
-+#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
-+    /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
-+    /*
-+      Only do the check for PS, becasue we on execute we have to check that
-+      against the opened tables to ensure we don't use a table that is part
-+      of the view (which can only be done after the table has been opened).
-+    */
-+    if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
-+    {
-+      /*
-+        For temporary tables we don't have to check if the created table exists
-+      */
-+      if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
-+          find_table_in_global_list(tables, create_table->db,
-+                                    create_table->table_name))
-+      {
-+	error= FALSE;
-+        goto err;
-+      }
-+    }
-+#endif
-+    if (tables && check_table_access(thd, SELECT_ACL, tables,0))
-+      goto err;
-+  }
-+  error= FALSE;
-+
-+err:
-+  DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+  negate given expression
-+
-+  SYNOPSIS
-+    negate_expression()
-+    thd  thread handler
-+    expr expression for negation
-+
-+  RETURN
-+    negated expression
-+*/
-+
-+Item *negate_expression(THD *thd, Item *expr)
-+{
-+  Item *negated;
-+  if (expr->type() == Item::FUNC_ITEM &&
-+      ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
-+  {
-+    /* it is NOT(NOT( ... )) */
-+    Item *arg= ((Item_func *) expr)->arguments()[0];
-+    enum_parsing_place place= thd->lex->current_select->parsing_place;
-+    if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
-+      return arg;
-+    /*
-+      if it is not boolean function then we have to emulate value of
-+      not(not(a)), it will be a != 0
-+    */
-+    return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
-+  }
-+
-+  if ((negated= expr->neg_transformer(thd)) != 0)
-+    return negated;
-+  return new Item_func_not(expr);
-+}
-+
-+/*
-+  Set the specified definer to the default value, which is the current user in
-+  the thread.
-+ 
-+  SYNOPSIS
-+    get_default_definer()
-+    thd       [in] thread handler
-+    definer   [out] definer
-+*/
-+ 
-+void get_default_definer(THD *thd, LEX_USER *definer)
-+{
-+  const Security_context *sctx= thd->security_ctx;
-+
-+  definer->user.str= (char *) sctx->priv_user;
-+  definer->user.length= strlen(definer->user.str);
-+
-+  definer->host.str= (char *) sctx->priv_host;
-+  definer->host.length= strlen(definer->host.str);
-+}
-+
-+
-+/*
-+  Create default definer for the specified THD.
-+
-+  SYNOPSIS
-+    create_default_definer()
-+    thd         [in] thread handler
-+
-+  RETURN
-+    On success, return a valid pointer to the created and initialized
-+    LEX_USER, which contains definer information.
-+    On error, return 0.
-+*/
-+
-+LEX_USER *create_default_definer(THD *thd)
-+{
-+  LEX_USER *definer;
-+
-+  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
-+    return 0;
-+
-+  get_default_definer(thd, definer);
-+
-+  return definer;
-+}
-+
-+
-+/*
-+  Create definer with the given user and host names.
-+
-+  SYNOPSIS
-+    create_definer()
-+    thd         [in] thread handler
-+    user_name   [in] user name
-+    host_name   [in] host name
-+
-+  RETURN
-+    On success, return a valid pointer to the created and initialized
-+    LEX_USER, which contains definer information.
-+    On error, return 0.
-+*/
-+
-+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
-+{
-+  LEX_USER *definer;
-+
-+  /* Create and initialize. */
-+
-+  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
-+    return 0;
-+
-+  definer->user= *user_name;
-+  definer->host= *host_name;
-+
-+  return definer;
-+}
-+
-+
-+/*
-+  Retuns information about user or current user.
-+
-+  SYNOPSIS
-+    get_current_user()
-+    thd         [in] thread handler
-+    user        [in] user
-+
-+  RETURN
-+    On success, return a valid pointer to initialized
-+    LEX_USER, which contains user information.
-+    On error, return 0.
-+*/
-+
-+LEX_USER *get_current_user(THD *thd, LEX_USER *user)
-+{
-+  if (!user->user.str)  // current_user
-+    return create_default_definer(thd);
-+
-+  return user;
-+}
-+
-+
-+/*
-+  Check that length of a string does not exceed some limit.
-+
-+  SYNOPSIS
-+    check_string_length()
-+      str         string to be checked
-+      err_msg     error message to be displayed if the string is too long
-+      max_length  max length
-+
-+  RETURN
-+    FALSE   the passed string is not longer than max_length
-+    TRUE    the passed string is longer than max_length
-+*/
-+
-+bool check_string_length(LEX_STRING *str, const char *err_msg,
-+                         uint max_length)
-+{
-+  if (str->length <= max_length)
-+    return FALSE;
-+
-+  my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length);
-+
-+  return TRUE;
-+}
 diff -urNad mysql-5.0-etch~/sql/sql_show.cc mysql-5.0-etch/sql/sql_show.cc
 --- mysql-5.0-etch~/sql/sql_show.cc	2007-05-28 18:56:15.000000000 +0200
 +++ mysql-5.0-etch/sql/sql_show.cc	2007-05-28 19:12:52.000000000 +0200
@@ -9522,4357 +257,3 @@
    {
      TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
      bool res;
-diff -urNad mysql-5.0-etch~/sql/sql_show.cc.orig mysql-5.0-etch/sql/sql_show.cc.orig
---- mysql-5.0-etch~/sql/sql_show.cc.orig	1970-01-01 01:00:00.000000000 +0100
-+++ mysql-5.0-etch/sql/sql_show.cc.orig	2007-05-28 18:56:15.000000000 +0200
-@@ -0,0 +1,4350 @@
-+/* Copyright (C) 2000-2004 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2 of the License, or
-+   (at your option) any later version.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+
-+/* Function with list databases, tables or fields */
-+
-+#include "mysql_priv.h"
-+#include "sql_select.h"                         // For select_describe
-+#include "repl_failsafe.h"
-+#include "sp.h"
-+#include "sp_head.h"
-+#include "sql_trigger.h"
-+#include <my_dir.h>
-+
-+#ifdef HAVE_BERKELEY_DB
-+#include "ha_berkeley.h"			// For berkeley_show_logs
-+#endif
-+
-+static const char *grant_names[]={
-+  "select","insert","update","delete","create","drop","reload","shutdown",
-+  "process","file","grant","references","index","alter"};
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
-+                               "grant_types",
-+                               grant_names, NULL};
-+#endif
-+
-+static int
-+store_create_info(THD *thd, TABLE_LIST *table_list, String *packet);
-+static void
-+append_algorithm(TABLE_LIST *table, String *buff);
-+static int
-+view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
-+static bool schema_table_store_record(THD *thd, TABLE *table);
-+
-+
-+/***************************************************************************
-+** List all table types supported 
-+***************************************************************************/
-+
-+bool mysqld_show_storage_engines(THD *thd)
-+{
-+  List<Item> field_list;
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_show_storage_engines");
-+
-+  field_list.push_back(new Item_empty_string("Engine",10));
-+  field_list.push_back(new Item_empty_string("Support",10));
-+  field_list.push_back(new Item_empty_string("Comment",80));
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+  const char *default_type_name= 
-+    ha_get_storage_engine((enum db_type)thd->variables.table_type);
-+
-+  handlerton **types;
-+  for (types= sys_table_types; *types; types++)
-+  {
-+    if (!((*types)->flags & HTON_HIDDEN))
-+    {
-+      protocol->prepare_for_resend();
-+      protocol->store((*types)->name, system_charset_info);
-+      const char *option_name= show_comp_option_name[(int) (*types)->state];
-+
-+      if ((*types)->state == SHOW_OPTION_YES &&
-+          !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
-+        option_name= "DEFAULT";
-+      protocol->store(option_name, system_charset_info);
-+      protocol->store((*types)->comment, system_charset_info);
-+      if (protocol->write())
-+        DBUG_RETURN(TRUE);
-+    }
-+  }
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/***************************************************************************
-+ List all privileges supported
-+***************************************************************************/
-+
-+struct show_privileges_st {
-+  const char *privilege;
-+  const char *context;
-+  const char *comment;
-+};
-+
-+static struct show_privileges_st sys_privileges[]=
-+{
-+  {"Alter", "Tables",  "To alter the table"},
-+  {"Alter routine", "Functions,Procedures",  "To alter or drop stored functions/procedures"},
-+  {"Create", "Databases,Tables,Indexes",  "To create new databases and tables"},
-+  {"Create routine","Functions,Procedures","To use CREATE FUNCTION/PROCEDURE"},
-+  {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
-+  {"Create view", "Tables",  "To create new views"},
-+  {"Create user", "Server Admin",  "To create new users"},
-+  {"Delete", "Tables",  "To delete existing rows"},
-+  {"Drop", "Databases,Tables", "To drop databases, tables, and views"},
-+  {"Execute", "Functions,Procedures", "To execute stored routines"},
-+  {"File", "File access on server",   "To read and write files on the server"},
-+  {"Grant option",  "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
-+  {"Index", "Tables",  "To create or drop indexes"},
-+  {"Insert", "Tables",  "To insert data into tables"},
-+  {"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
-+  {"Process", "Server Admin", "To view the plain text of currently executing queries"},
-+  {"References", "Databases,Tables", "To have references on tables"},
-+  {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
-+  {"Replication client","Server Admin","To ask where the slave or master servers are"},
-+  {"Replication slave","Server Admin","To read binary log events from the master"},
-+  {"Select", "Tables",  "To retrieve rows from table"},
-+  {"Show databases","Server Admin","To see all databases with SHOW DATABASES"},
-+  {"Show view","Tables","To see views with SHOW CREATE VIEW"},
-+  {"Shutdown","Server Admin", "To shut down the server"},
-+  {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
-+  {"Update", "Tables",  "To update existing rows"},
-+  {"Usage","Server Admin","No privileges - allow connect only"},
-+  {NullS, NullS, NullS}
-+};
-+
-+bool mysqld_show_privileges(THD *thd)
-+{
-+  List<Item> field_list;
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_show_privileges");
-+
-+  field_list.push_back(new Item_empty_string("Privilege",10));
-+  field_list.push_back(new Item_empty_string("Context",15));
-+  field_list.push_back(new Item_empty_string("Comment",NAME_LEN));
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+  show_privileges_st *privilege= sys_privileges;
-+  for (privilege= sys_privileges; privilege->privilege ; privilege++)
-+  {
-+    protocol->prepare_for_resend();
-+    protocol->store(privilege->privilege, system_charset_info);
-+    protocol->store(privilege->context, system_charset_info);
-+    protocol->store(privilege->comment, system_charset_info);
-+    if (protocol->write())
-+      DBUG_RETURN(TRUE);
-+  }
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/***************************************************************************
-+  List all column types
-+***************************************************************************/
-+
-+struct show_column_type_st
-+{
-+  const char *type;
-+  uint size;
-+  const char *min_value;
-+  const char *max_value;
-+  uint precision;
-+  uint scale;
-+  const char *nullable;
-+  const char *auto_increment;
-+  const char *unsigned_attr;
-+  const char *zerofill;
-+  const char *searchable;
-+  const char *case_sensitivity;
-+  const char *default_value;
-+  const char *comment;
-+};
-+
-+/* TODO: Add remaning types */
-+
-+static struct show_column_type_st sys_column_types[]=
-+{
-+  {"tinyint",
-+    1,  "-128",  "127",  0,  0,  "YES",  "YES",
-+    "NO",   "YES", "YES",  "NO",  "NULL,0",
-+    "A very small integer"},
-+  {"tinyint unsigned",
-+    1,  "0"   ,  "255",  0,  0,  "YES",  "YES",
-+    "YES",  "YES",  "YES",  "NO",  "NULL,0",
-+    "A very small integer"},
-+};
-+
-+bool mysqld_show_column_types(THD *thd)
-+{
-+  List<Item> field_list;
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_show_column_types");
-+
-+  field_list.push_back(new Item_empty_string("Type",30));
-+  field_list.push_back(new Item_int("Size",(longlong) 1,21));
-+  field_list.push_back(new Item_empty_string("Min_Value",20));
-+  field_list.push_back(new Item_empty_string("Max_Value",20));
-+  field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT));
-+  field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT));
-+  field_list.push_back(new Item_empty_string("Nullable",4));
-+  field_list.push_back(new Item_empty_string("Auto_Increment",4));
-+  field_list.push_back(new Item_empty_string("Unsigned",4));
-+  field_list.push_back(new Item_empty_string("Zerofill",4));
-+  field_list.push_back(new Item_empty_string("Searchable",4));
-+  field_list.push_back(new Item_empty_string("Case_Sensitive",4));
-+  field_list.push_back(new Item_empty_string("Default",NAME_LEN));
-+  field_list.push_back(new Item_empty_string("Comment",NAME_LEN));
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+  /* TODO: Change the loop to not use 'i' */
-+  for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
-+  {
-+    protocol->prepare_for_resend();
-+    protocol->store(sys_column_types[i].type, system_charset_info);
-+    protocol->store((ulonglong) sys_column_types[i].size);
-+    protocol->store(sys_column_types[i].min_value, system_charset_info);
-+    protocol->store(sys_column_types[i].max_value, system_charset_info);
-+    protocol->store_short((longlong) sys_column_types[i].precision);
-+    protocol->store_short((longlong) sys_column_types[i].scale);
-+    protocol->store(sys_column_types[i].nullable, system_charset_info);
-+    protocol->store(sys_column_types[i].auto_increment, system_charset_info);
-+    protocol->store(sys_column_types[i].unsigned_attr, system_charset_info);
-+    protocol->store(sys_column_types[i].zerofill, system_charset_info);
-+    protocol->store(sys_column_types[i].searchable, system_charset_info);
-+    protocol->store(sys_column_types[i].case_sensitivity, system_charset_info);
-+    protocol->store(sys_column_types[i].default_value, system_charset_info);
-+    protocol->store(sys_column_types[i].comment, system_charset_info);
-+    if (protocol->write())
-+      DBUG_RETURN(TRUE);
-+  }
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+  find_files() - find files in a given directory.
-+
-+  SYNOPSIS
-+    find_files()
-+    thd                 thread handler
-+    files               put found files in this list
-+    db                  database name to set in TABLE_LIST structure
-+    path                path to database
-+    wild                filter for found files
-+    dir                 read databases in path if TRUE, read .frm files in
-+                        database otherwise
-+
-+  RETURN
-+    FIND_FILES_OK       success
-+    FIND_FILES_OOM      out of memory error
-+    FIND_FILES_DIR      no such directory, or directory can't be read
-+*/
-+
-+enum find_files_result {
-+  FIND_FILES_OK,
-+  FIND_FILES_OOM,
-+  FIND_FILES_DIR
-+};
-+
-+static
-+find_files_result
-+find_files(THD *thd, List<char> *files, const char *db,
-+           const char *path, const char *wild, bool dir)
-+{
-+  uint i;
-+  char *ext;
-+  MY_DIR *dirp;
-+  FILEINFO *file;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  uint col_access=thd->col_access;
-+#endif
-+  TABLE_LIST table_list;
-+  DBUG_ENTER("find_files");
-+
-+  if (wild && !wild[0])
-+    wild=0;
-+
-+  bzero((char*) &table_list,sizeof(table_list));
-+
-+  if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
-+  {
-+    if (my_errno == ENOENT)
-+      my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
-+    else
-+      my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
-+    DBUG_RETURN(FIND_FILES_DIR);
-+  }
-+
-+  for (i=0 ; i < (uint) dirp->number_off_files  ; i++)
-+  {
-+    file=dirp->dir_entry+i;
-+    if (dir)
-+    {                                           /* Return databases */
-+#ifdef USE_SYMDIR
-+      char *ext;
-+      char buff[FN_REFLEN];
-+      if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
-+      {
-+	/* Only show the sym file if it points to a directory */
-+	char *end;
-+        *ext=0;                                 /* Remove extension */
-+	unpack_dirname(buff, file->name);
-+	end= strend(buff);
-+	if (end != buff && end[-1] == FN_LIBCHAR)
-+	  end[-1]= 0;				// Remove end FN_LIBCHAR
-+        if (!my_stat(buff, file->mystat, MYF(0)))
-+               continue;
-+       }
-+#endif
-+        if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) ||
-+            (wild && wild_compare(file->name,wild,0)))
-+          continue;
-+    }
-+    else
-+    {
-+        // Return only .frm files which aren't temp files.
-+      if (my_strcasecmp(system_charset_info, ext=fn_ext(file->name),reg_ext) ||
-+          is_prefix(file->name,tmp_file_prefix))
-+        continue;
-+      *ext=0;
-+      if (wild)
-+      {
-+	if (lower_case_table_names)
-+	{
-+	  if (wild_case_compare(files_charset_info, file->name, wild))
-+	    continue;
-+	}
-+	else if (wild_compare(file->name,wild,0))
-+	  continue;
-+      }
-+    }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+    /* Don't show tables where we don't have any privileges */
-+    if (db && !(col_access & TABLE_ACLS))
-+    {
-+      table_list.db= (char*) db;
-+      table_list.db_length= strlen(db);
-+      table_list.table_name= file->name;
-+      table_list.table_name_length= strlen(file->name);
-+      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)))
-+    {
-+      my_dirend(dirp);
-+      DBUG_RETURN(FIND_FILES_OOM);
-+    }
-+  }
-+  DBUG_PRINT("info",("found: %d files", files->elements));
-+  my_dirend(dirp);
-+
-+  VOID(ha_find_files(thd,db,path,wild,dir,files));
-+
-+  DBUG_RETURN(FIND_FILES_OK);
-+}
-+
-+
-+bool
-+mysqld_show_create(THD *thd, TABLE_LIST *table_list)
-+{
-+  Protocol *protocol= thd->protocol;
-+  char buff[2048];
-+  String buffer(buff, sizeof(buff), system_charset_info);
-+  DBUG_ENTER("mysqld_show_create");
-+  DBUG_PRINT("enter",("db: %s  table: %s",table_list->db,
-+                      table_list->table_name));
-+
-+  /* We want to preserve the tree for views. */
-+  thd->lex->view_prepare_mode= TRUE;
-+
-+  /* Only one table for now, but VIEW can involve several tables */
-+  if (open_normal_and_derived_tables(thd, table_list, 0))
-+  {
-+    if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
-+      DBUG_RETURN(TRUE);
-+
-+    /*
-+      Clear all messages with 'error' level status and
-+      issue a warning with 'warning' level status in 
-+      case of invalid view and last error is ER_VIEW_INVALID
-+    */
-+    mysql_reset_errors(thd, true);
-+    thd->clear_error();
-+
-+    push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
-+                        ER_VIEW_INVALID,
-+                        ER(ER_VIEW_INVALID),
-+                        table_list->view_db.str,
-+                        table_list->view_name.str);
-+  }
-+
-+  /* TODO: add environment variables show when it become possible */
-+  if (thd->lex->only_view && !table_list->view)
-+  {
-+    my_error(ER_WRONG_OBJECT, MYF(0),
-+             table_list->db, table_list->table_name, "VIEW");
-+    DBUG_RETURN(TRUE);
-+  }
-+
-+  buffer.length(0);
-+  if ((table_list->view ?
-+       view_store_create_info(thd, table_list, &buffer) :
-+       store_create_info(thd, table_list, &buffer)))
-+    DBUG_RETURN(TRUE);
-+
-+  List<Item> field_list;
-+  if (table_list->view)
-+  {
-+    field_list.push_back(new Item_empty_string("View",NAME_LEN));
-+    field_list.push_back(new Item_empty_string("Create View",
-+                                               max(buffer.length(),1024)));
-+  }
-+  else
-+  {
-+    field_list.push_back(new Item_empty_string("Table",NAME_LEN));
-+    // 1024 is for not to confuse old clients
-+    field_list.push_back(new Item_empty_string("Create Table",
-+                                               max(buffer.length(),1024)));
-+  }
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+  protocol->prepare_for_resend();
-+  if (table_list->view)
-+    protocol->store(table_list->view_name.str, system_charset_info);
-+  else
-+  {
-+    if (table_list->schema_table)
-+      protocol->store(table_list->schema_table->table_name,
-+                      system_charset_info);
-+    else
-+      protocol->store(table_list->table->alias, system_charset_info);
-+  }
-+  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
-+
-+  if (protocol->write())
-+    DBUG_RETURN(TRUE);
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+bool mysqld_show_create_db(THD *thd, char *dbname,
-+                           HA_CREATE_INFO *create_info)
-+{
-+  Security_context *sctx= thd->security_ctx;
-+  char buff[2048];
-+  String buffer(buff, sizeof(buff), system_charset_info);
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  uint db_access;
-+#endif
-+  HA_CREATE_INFO create;
-+  uint create_options = create_info ? create_info->options : 0;
-+  Protocol *protocol=thd->protocol;
-+  DBUG_ENTER("mysql_show_create_db");
-+
-+  if (check_db_name(dbname))
-+  {
-+    my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
-+    DBUG_RETURN(TRUE);
-+  }
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  if (test_all_bits(sctx->master_access, DB_ACLS))
-+    db_access=DB_ACLS;
-+  else
-+    db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
-+		sctx->master_access);
-+  if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
-+  {
-+    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+             sctx->priv_user, sctx->host_or_ip, dbname);
-+    mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-+		    sctx->priv_user, sctx->host_or_ip, dbname);
-+    DBUG_RETURN(TRUE);
-+  }
-+#endif
-+  if (!my_strcasecmp(system_charset_info, dbname,
-+                     information_schema_name.str))
-+  {
-+    dbname= information_schema_name.str;
-+    create.default_table_charset= system_charset_info;
-+  }
-+  else
-+  {
-+    if (check_db_dir_existence(dbname))
-+    {
-+      my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
-+      DBUG_RETURN(TRUE);
-+    }
-+
-+    load_db_opt_by_name(thd, dbname, &create);
-+  }
-+  List<Item> field_list;
-+  field_list.push_back(new Item_empty_string("Database",NAME_LEN));
-+  field_list.push_back(new Item_empty_string("Create Database",1024));
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+  protocol->prepare_for_resend();
-+  protocol->store(dbname, strlen(dbname), system_charset_info);
-+  buffer.length(0);
-+  buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
-+  if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+    buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
-+  append_identifier(thd, &buffer, dbname, strlen(dbname));
-+
-+  if (create.default_table_charset)
-+  {
-+    buffer.append(STRING_WITH_LEN(" /*!40100"));
-+    buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
-+    buffer.append(create.default_table_charset->csname);
-+    if (!(create.default_table_charset->state & MY_CS_PRIMARY))
-+    {
-+      buffer.append(STRING_WITH_LEN(" COLLATE "));
-+      buffer.append(create.default_table_charset->name);
-+    }
-+    buffer.append(STRING_WITH_LEN(" */"));
-+  }
-+  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
-+
-+  if (protocol->write())
-+    DBUG_RETURN(TRUE);
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+bool
-+mysqld_show_logs(THD *thd)
-+{
-+  List<Item> field_list;
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_show_logs");
-+
-+  field_list.push_back(new Item_empty_string("File",FN_REFLEN));
-+  field_list.push_back(new Item_empty_string("Type",10));
-+  field_list.push_back(new Item_empty_string("Status",10));
-+
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+#ifdef HAVE_BERKELEY_DB
-+  if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_show_logs(protocol))
-+    DBUG_RETURN(TRUE);
-+#endif
-+
-+  send_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/****************************************************************************
-+  Return only fields for API mysql_list_fields
-+  Use "show table wildcard" in mysql instead of this
-+****************************************************************************/
-+
-+void
-+mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
-+{
-+  TABLE *table;
-+  DBUG_ENTER("mysqld_list_fields");
-+  DBUG_PRINT("enter",("table: %s",table_list->table_name));
-+
-+  if (open_normal_and_derived_tables(thd, table_list, 0))
-+    DBUG_VOID_RETURN;
-+  table= table_list->table;
-+
-+  List<Item> field_list;
-+
-+  Field **ptr,*field;
-+  for (ptr=table->field ; (field= *ptr); ptr++)
-+  {
-+    if (!wild || !wild[0] || 
-+        !wild_case_compare(system_charset_info, field->field_name,wild))
-+    {
-+      if (table_list->view)
-+        field_list.push_back(new Item_ident_for_show(field,
-+                                                     table_list->view_db.str,
-+                                                     table_list->view_name.str));
-+      else
-+        field_list.push_back(new Item_field(field));
-+    }
-+  }
-+  restore_record(table, s->default_values);              // Get empty record
-+  if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
-+                                              Protocol::SEND_EOF))
-+    DBUG_VOID_RETURN;
-+  thd->protocol->flush();
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+int
-+mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
-+{
-+  Protocol *protocol= thd->protocol;
-+  String *packet= protocol->storage_packet();
-+  DBUG_ENTER("mysqld_dump_create_info");
-+  DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name));
-+
-+  protocol->prepare_for_resend();
-+  if (store_create_info(thd, table_list, packet))
-+    DBUG_RETURN(-1);
-+
-+  if (fd < 0)
-+  {
-+    if (protocol->write())
-+      DBUG_RETURN(-1);
-+    protocol->flush();
-+  }
-+  else
-+  {
-+    if (my_write(fd, (const byte*) packet->ptr(), packet->length(),
-+		 MYF(MY_WME)))
-+      DBUG_RETURN(-1);
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+/*
-+  Go through all character combinations and ensure that sql_lex.cc can
-+  parse it as an identifier.
-+
-+  SYNOPSIS
-+  require_quotes()
-+  name			attribute name
-+  name_length		length of name
-+
-+  RETURN
-+    #	Pointer to conflicting character
-+    0	No conflicting character
-+*/
-+
-+static const char *require_quotes(const char *name, uint name_length)
-+{
-+  uint length;
-+  const char *end= name + name_length;
-+
-+  for (; name < end ; name++)
-+  {
-+    uchar chr= (uchar) *name;
-+    length= my_mbcharlen(system_charset_info, chr);
-+    if (length == 1 && !system_charset_info->ident_map[chr])
-+      return name;
-+  }
-+  return 0;
-+}
-+
-+
-+/*
-+  Quote the given identifier if needed and append it to the target string.
-+  If the given identifier is empty, it will be quoted.
-+
-+  SYNOPSIS
-+  append_identifier()
-+  thd                   thread handler
-+  packet                target string
-+  name                  the identifier to be appended
-+  name_length           length of the appending identifier
-+*/
-+
-+void
-+append_identifier(THD *thd, String *packet, const char *name, uint length)
-+{
-+  const char *name_end;
-+  char quote_char;
-+  int q= get_quote_char_for_identifier(thd, name, length);
-+
-+  if (q == EOF)
-+  {
-+    packet->append(name, length, system_charset_info);
-+    return;
-+  }
-+
-+  /*
-+    The identifier must be quoted as it includes a quote character or
-+   it's a keyword
-+  */
-+
-+  VOID(packet->reserve(length*2 + 2));
-+  quote_char= (char) q;
-+  packet->append(&quote_char, 1, system_charset_info);
-+
-+  for (name_end= name+length ; name < name_end ; name+= length)
-+  {
-+    uchar chr= (uchar) *name;
-+    length= my_mbcharlen(system_charset_info, chr);
-+    /*
-+      my_mbcharlen can retur 0 on a wrong multibyte
-+      sequence. It is possible when upgrading from 4.0,
-+      and identifier contains some accented characters.
-+      The manual says it does not work. So we'll just
-+      change length to 1 not to hang in the endless loop.
-+    */
-+    if (!length)
-+      length= 1;
-+    if (length == 1 && chr == (uchar) quote_char)
-+      packet->append(&quote_char, 1, system_charset_info);
-+    packet->append(name, length, packet->charset());
-+  }
-+  packet->append(&quote_char, 1, system_charset_info);
-+}
-+
-+
-+/*
-+  Get the quote character for displaying an identifier.
-+
-+  SYNOPSIS
-+    get_quote_char_for_identifier()
-+    thd		Thread handler
-+    name	name to quote
-+    length	length of name
-+
-+  IMPLEMENTATION
-+    Force quoting in the following cases:
-+      - name is empty (for one, it is possible when we use this function for
-+        quoting user and host names for DEFINER clause);
-+      - name is a keyword;
-+      - name includes a special character;
-+    Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
-+    is set.
-+
-+  RETURN
-+    EOF	  No quote character is needed
-+    #	  Quote character
-+*/
-+
-+int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
-+{
-+  if (length &&
-+      !is_keyword(name,length) &&
-+      !require_quotes(name, length) &&
-+      !(thd->options & OPTION_QUOTE_SHOW_CREATE))
-+    return EOF;
-+  if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
-+    return '"';
-+  return '`';
-+}
-+
-+
-+/* Append directory name (if exists) to CREATE INFO */
-+
-+static void append_directory(THD *thd, String *packet, const char *dir_type,
-+			     const char *filename)
-+{
-+  if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
-+  {
-+    uint length= dirname_length(filename);
-+    packet->append(' ');
-+    packet->append(dir_type);
-+    packet->append(STRING_WITH_LEN(" DIRECTORY='"));
-+#ifdef __WIN__
-+    /* Convert \ to / to be able to create table on unix */
-+    char *winfilename= (char*) thd->memdup(filename, length);
-+    char *pos, *end;
-+    for (pos= winfilename, end= pos+length ; pos < end ; pos++)
-+    {
-+      if (*pos == '\\')
-+        *pos = '/';
-+    }
-+    filename= winfilename;
-+#endif
-+    packet->append(filename, length);
-+    packet->append('\'');
-+  }
-+}
-+
-+
-+#define LIST_PROCESS_HOST_LEN 64
-+
-+static int
-+store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
-+{
-+  List<Item> field_list;
-+  char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end;
-+  const char *alias;
-+  String type(tmp, sizeof(tmp), system_charset_info);
-+  Field **ptr,*field;
-+  uint primary_key;
-+  KEY *key_info;
-+  TABLE *table= table_list->table;
-+  handler *file= table->file;
-+  TABLE_SHARE *share= table->s;
-+  HA_CREATE_INFO create_info;
-+  my_bool foreign_db_mode=    (thd->variables.sql_mode & (MODE_POSTGRESQL |
-+							  MODE_ORACLE |
-+							  MODE_MSSQL |
-+							  MODE_DB2 |
-+							  MODE_MAXDB |
-+							  MODE_ANSI)) != 0;
-+  my_bool limited_mysql_mode= (thd->variables.sql_mode &
-+			       (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
-+				MODE_MYSQL40)) != 0;
-+  DBUG_ENTER("store_create_info");
-+  DBUG_PRINT("enter",("table: %s", table->s->table_name));
-+
-+  restore_record(table, s->default_values); // Get empty record
-+
-+  if (share->tmp_table)
-+    packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
-+  else
-+    packet->append(STRING_WITH_LEN("CREATE TABLE "));
-+  if (table_list->schema_table)
-+    alias= table_list->schema_table->table_name;
-+  else
-+    alias= (lower_case_table_names == 2 ? table->alias :
-+            share->table_name);
-+  append_identifier(thd, packet, alias, strlen(alias));
-+  packet->append(STRING_WITH_LEN(" (\n"));
-+
-+  for (ptr=table->field ; (field= *ptr); ptr++)
-+  {
-+    bool has_default;
-+    bool has_now_default;
-+    uint flags = field->flags;
-+
-+    if (ptr != table->field)
-+      packet->append(STRING_WITH_LEN(",\n"));
-+
-+    packet->append(STRING_WITH_LEN("  "));
-+    append_identifier(thd,packet,field->field_name, strlen(field->field_name));
-+    packet->append(' ');
-+    // check for surprises from the previous call to Field::sql_type()
-+    if (type.ptr() != tmp)
-+      type.set(tmp, sizeof(tmp), system_charset_info);
-+    else
-+      type.set_charset(system_charset_info);
-+
-+    field->sql_type(type);
-+    packet->append(type.ptr(), type.length(), system_charset_info);
-+
-+    if (field->has_charset() && 
-+        !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
-+    {
-+      if (field->charset() != share->table_charset)
-+      {
-+	packet->append(STRING_WITH_LEN(" character set "));
-+	packet->append(field->charset()->csname);
-+      }
-+      /* 
-+	For string types dump collation name only if 
-+	collation is not primary for the given charset
-+      */
-+      if (!(field->charset()->state & MY_CS_PRIMARY))
-+      {
-+	packet->append(STRING_WITH_LEN(" collate "));
-+	packet->append(field->charset()->name);
-+      }
-+    }
-+
-+    if (flags & NOT_NULL_FLAG)
-+      packet->append(STRING_WITH_LEN(" NOT NULL"));
-+    else if (field->type() == FIELD_TYPE_TIMESTAMP)
-+    {
-+      /*
-+        TIMESTAMP field require explicit NULL flag, because unlike
-+        all other fields they are treated as NOT NULL by default.
-+      */
-+      packet->append(STRING_WITH_LEN(" NULL"));
-+    }
-+
-+    /* 
-+      Again we are using CURRENT_TIMESTAMP instead of NOW because it is
-+      more standard 
-+    */
-+    has_now_default= table->timestamp_field == field && 
-+                     field->unireg_check != Field::TIMESTAMP_UN_FIELD;
-+    
-+    has_default= (field->type() != FIELD_TYPE_BLOB &&
-+                  !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
-+		  field->unireg_check != Field::NEXT_NUMBER &&
-+                  !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
-+		    && has_now_default));
-+
-+    if (has_default)
-+    {
-+      packet->append(STRING_WITH_LEN(" default "));
-+      if (has_now_default)
-+        packet->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
-+      else if (!field->is_null())
-+      {                                             // Not null by default
-+        type.set(tmp, sizeof(tmp), field->charset());
-+        field->val_str(&type);
-+	if (type.length())
-+	{
-+	  String def_val;
-+          uint dummy_errors;
-+	  /* convert to system_charset_info == utf8 */
-+	  def_val.copy(type.ptr(), type.length(), field->charset(),
-+		       system_charset_info, &dummy_errors);
-+          append_unescaped(packet, def_val.ptr(), def_val.length());
-+	}
-+        else
-+	  packet->append(STRING_WITH_LEN("''"));
-+      }
-+      else if (field->maybe_null())
-+        packet->append(STRING_WITH_LEN("NULL"));    // Null as default
-+      else
-+        packet->append(tmp);
-+    }
-+
-+    if (!limited_mysql_mode && table->timestamp_field == field && 
-+        field->unireg_check != Field::TIMESTAMP_DN_FIELD)
-+      packet->append(STRING_WITH_LEN(" on update CURRENT_TIMESTAMP"));
-+
-+    if (field->unireg_check == Field::NEXT_NUMBER && 
-+        !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
-+      packet->append(STRING_WITH_LEN(" auto_increment"));
-+
-+    if (field->comment.length)
-+    {
-+      packet->append(STRING_WITH_LEN(" COMMENT "));
-+      append_unescaped(packet, field->comment.str, field->comment.length);
-+    }
-+  }
-+
-+  key_info= table->key_info;
-+  bzero((char*) &create_info, sizeof(create_info));
-+  file->update_create_info(&create_info);
-+  primary_key= share->primary_key;
-+
-+  for (uint i=0 ; i < share->keys ; i++,key_info++)
-+  {
-+    KEY_PART_INFO *key_part= key_info->key_part;
-+    bool found_primary=0;
-+    packet->append(STRING_WITH_LEN(",\n  "));
-+
-+    if (i == primary_key && !strcmp(key_info->name, primary_key_name))
-+    {
-+      found_primary=1;
-+      packet->append(STRING_WITH_LEN("PRIMARY "));
-+    }
-+    else if (key_info->flags & HA_NOSAME)
-+      packet->append(STRING_WITH_LEN("UNIQUE "));
-+    else if (key_info->flags & HA_FULLTEXT)
-+      packet->append(STRING_WITH_LEN("FULLTEXT "));
-+    else if (key_info->flags & HA_SPATIAL)
-+      packet->append(STRING_WITH_LEN("SPATIAL "));
-+    packet->append(STRING_WITH_LEN("KEY "));
-+
-+    if (!found_primary)
-+     append_identifier(thd, packet, key_info->name, strlen(key_info->name));
-+
-+    if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
-+	!limited_mysql_mode && !foreign_db_mode)
-+    {
-+      if (key_info->algorithm == HA_KEY_ALG_BTREE)
-+        packet->append(STRING_WITH_LEN(" USING BTREE"));
-+
-+      if (key_info->algorithm == HA_KEY_ALG_HASH)
-+        packet->append(STRING_WITH_LEN(" USING HASH"));
-+
-+      // +BAR: send USING only in non-default case: non-spatial rtree
-+      if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
-+	  !(key_info->flags & HA_SPATIAL))
-+        packet->append(STRING_WITH_LEN(" USING RTREE"));
-+
-+      // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
-+    }
-+    packet->append(STRING_WITH_LEN(" ("));
-+
-+    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+    {
-+      if (j)
-+        packet->append(',');
-+
-+      if (key_part->field)
-+        append_identifier(thd,packet,key_part->field->field_name,
-+			  strlen(key_part->field->field_name));
-+      if (key_part->field &&
-+          (key_part->length !=
-+           table->field[key_part->fieldnr-1]->key_length() &&
-+           !(key_info->flags & HA_FULLTEXT)))
-+      {
-+        buff[0] = '(';
-+        char* end=int10_to_str((long) key_part->length /
-+			       key_part->field->charset()->mbmaxlen,
-+			       buff + 1,10);
-+        *end++ = ')';
-+        packet->append(buff,(uint) (end-buff));
-+      }
-+    }
-+    packet->append(')');
-+  }
-+
-+  /*
-+    Get possible foreign key definitions stored in InnoDB and append them
-+    to the CREATE TABLE statement
-+  */
-+
-+  if ((for_str= file->get_foreign_key_create_info()))
-+  {
-+    packet->append(for_str, strlen(for_str));
-+    file->free_foreign_key_create_info(for_str);
-+  }
-+
-+  packet->append(STRING_WITH_LEN("\n)"));
-+  if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
-+  {
-+    if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
-+      packet->append(STRING_WITH_LEN(" TYPE="));
-+    else
-+      packet->append(STRING_WITH_LEN(" ENGINE="));
-+    packet->append(file->table_type());
-+
-+    /*
-+      Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
-+      and NEXT_ID > 1 (the default).  We must not print the clause
-+      for engines that do not support this as it would break the
-+      import of dumps, but as of this writing, the test for whether
-+      AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
-+      is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
-+      Because of that, we do not explicitly test for the feature,
-+      but may extrapolate its existence from that of an AUTO_INCREMENT column.
-+    */
-+
-+    if(create_info.auto_increment_value > 1)
-+    {
-+      packet->append(" AUTO_INCREMENT=", 16);
-+      end= longlong10_to_str(create_info.auto_increment_value, buff,10);
-+      packet->append(buff, (uint) (end - buff));
-+    }
-+
-+    
-+    if (share->table_charset &&
-+	!(thd->variables.sql_mode & MODE_MYSQL323) &&
-+	!(thd->variables.sql_mode & MODE_MYSQL40))
-+    {
-+      packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
-+      packet->append(share->table_charset->csname);
-+      if (!(share->table_charset->state & MY_CS_PRIMARY))
-+      {
-+	packet->append(STRING_WITH_LEN(" COLLATE="));
-+	packet->append(table->s->table_charset->name);
-+      }
-+    }
-+
-+    if (share->min_rows)
-+    {
-+      packet->append(STRING_WITH_LEN(" MIN_ROWS="));
-+      end= longlong10_to_str(share->min_rows, buff, 10);
-+      packet->append(buff, (uint) (end- buff));
-+    }
-+
-+    if (share->max_rows && !table_list->schema_table)
-+    {
-+      packet->append(STRING_WITH_LEN(" MAX_ROWS="));
-+      end= longlong10_to_str(share->max_rows, buff, 10);
-+      packet->append(buff, (uint) (end - buff));
-+    }
-+
-+    if (share->avg_row_length)
-+    {
-+      packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
-+      end= longlong10_to_str(share->avg_row_length, buff,10);
-+      packet->append(buff, (uint) (end - buff));
-+    }
-+
-+    if (share->db_create_options & HA_OPTION_PACK_KEYS)
-+      packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
-+    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
-+      packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
-+    if (share->db_create_options & HA_OPTION_CHECKSUM)
-+      packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
-+    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
-+      packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
-+    if (share->row_type != ROW_TYPE_DEFAULT)
-+    {
-+      packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
-+      packet->append(ha_row_type[(uint) share->row_type]);
-+    }
-+    table->file->append_create_info(packet);
-+    if (share->comment.length)
-+    {
-+      packet->append(STRING_WITH_LEN(" COMMENT="));
-+      append_unescaped(packet, share->comment.str, share->comment.length);
-+    }
-+    if (share->connect_string.length)
-+    {
-+      packet->append(STRING_WITH_LEN(" CONNECTION="));
-+      append_unescaped(packet, share->connect_string.str, share->connect_string.length);
-+    }
-+    if (file->raid_type)
-+    {
-+      uint length;
-+      length= my_snprintf(buff,sizeof(buff),
-+			  " RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
-+			  my_raid_type(file->raid_type), file->raid_chunks,
-+			  file->raid_chunksize/RAID_BLOCK_SIZE);
-+      packet->append(buff, length);
-+    }
-+    append_directory(thd, packet, "DATA",  create_info.data_file_name);
-+    append_directory(thd, packet, "INDEX", create_info.index_file_name);
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+void
-+view_store_options(THD *thd, TABLE_LIST *table, String *buff)
-+{
-+  append_algorithm(table, buff);
-+  append_definer(thd, buff, &table->definer.user, &table->definer.host);
-+  if (table->view_suid)
-+    buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER "));
-+  else
-+    buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
-+}
-+
-+
-+/*
-+  Append DEFINER clause to the given buffer.
-+  
-+  SYNOPSIS
-+    append_definer()
-+    thd           [in] thread handle
-+    buffer        [inout] buffer to hold DEFINER clause
-+    definer_user  [in] user name part of definer
-+    definer_host  [in] host name part of definer
-+*/
-+
-+static void append_algorithm(TABLE_LIST *table, String *buff)
-+{
-+  buff->append(STRING_WITH_LEN("ALGORITHM="));
-+  switch ((int8)table->algorithm) {
-+  case VIEW_ALGORITHM_UNDEFINED:
-+    buff->append(STRING_WITH_LEN("UNDEFINED "));
-+    break;
-+  case VIEW_ALGORITHM_TMPTABLE:
-+    buff->append(STRING_WITH_LEN("TEMPTABLE "));
-+    break;
-+  case VIEW_ALGORITHM_MERGE:
-+    buff->append(STRING_WITH_LEN("MERGE "));
-+    break;
-+  default:
-+    DBUG_ASSERT(0); // never should happen
-+  }
-+}
-+
-+
-+/*
-+  Append DEFINER clause to the given buffer.
-+  
-+  SYNOPSIS
-+    append_definer()
-+    thd           [in] thread handle
-+    buffer        [inout] buffer to hold DEFINER clause
-+    definer_user  [in] user name part of definer
-+    definer_host  [in] host name part of definer
-+*/
-+
-+void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
-+                    const LEX_STRING *definer_host)
-+{
-+  buffer->append(STRING_WITH_LEN("DEFINER="));
-+  append_identifier(thd, buffer, definer_user->str, definer_user->length);
-+  buffer->append('@');
-+  append_identifier(thd, buffer, definer_host->str, definer_host->length);
-+  buffer->append(' ');
-+}
-+
-+
-+static int
-+view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
-+{
-+  my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
-+                                                       MODE_ORACLE |
-+                                                       MODE_MSSQL |
-+                                                       MODE_DB2 |
-+                                                       MODE_MAXDB |
-+                                                       MODE_ANSI)) != 0;
-+  /*
-+     Compact output format for view can be used
-+     - if user has db of this view as current db
-+     - if this view only references table inside it's own db
-+  */
-+  if (!thd->db || strcmp(thd->db, table->view_db.str))
-+    table->compact_view_format= FALSE;
-+  else
-+  {
-+    TABLE_LIST *tbl;
-+    table->compact_view_format= TRUE;
-+    for (tbl= thd->lex->query_tables;
-+         tbl;
-+         tbl= tbl->next_global)
-+    {
-+      if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
-+      {
-+        table->compact_view_format= FALSE;
-+        break;
-+      }
-+    }
-+  }
-+
-+  buff->append(STRING_WITH_LEN("CREATE "));
-+  if (!foreign_db_mode)
-+  {
-+    view_store_options(thd, table, buff);
-+  }
-+  buff->append(STRING_WITH_LEN("VIEW "));
-+  if (!table->compact_view_format)
-+  {
-+    append_identifier(thd, buff, table->view_db.str, table->view_db.length);
-+    buff->append('.');
-+  }
-+  append_identifier(thd, buff, table->view_name.str, table->view_name.length);
-+  buff->append(STRING_WITH_LEN(" AS "));
-+
-+  /*
-+    We can't just use table->query, because our SQL_MODE may trigger
-+    a different syntax, like when ANSI_QUOTES is defined.
-+  */
-+  table->view->unit.print(buff);
-+
-+  if (table->with_check != VIEW_CHECK_NONE)
-+  {
-+    if (table->with_check == VIEW_CHECK_LOCAL)
-+      buff->append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
-+    else
-+      buff->append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
-+  }
-+  return 0;
-+}
-+
-+
-+/****************************************************************************
-+  Return info about all processes
-+  returns for each thread: thread id, user, host, db, command, info
-+****************************************************************************/
-+
-+class thread_info :public ilink {
-+public:
-+  static void *operator new(size_t size)
-+  {
-+    return (void*) sql_alloc((uint) size);
-+  }
-+  static void operator delete(void *ptr __attribute__((unused)),
-+                              size_t size __attribute__((unused)))
-+  { TRASH(ptr, size); }
-+
-+  ulong thread_id;
-+  time_t start_time;
-+  uint   command;
-+  const char *user,*host,*db,*proc_info,*state_info;
-+  char *query;
-+};
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class I_List<thread_info>;
-+#endif
-+
-+void mysqld_list_processes(THD *thd,const char *user, bool verbose)
-+{
-+  Item *field;
-+  List<Item> field_list;
-+  I_List<thread_info> thread_infos;
-+  ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
-+			   PROCESS_LIST_WIDTH);
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_list_processes");
-+
-+  field_list.push_back(new Item_int("Id",0,11));
-+  field_list.push_back(new Item_empty_string("User",16));
-+  field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
-+  field_list.push_back(field=new Item_empty_string("db",NAME_LEN));
-+  field->maybe_null=1;
-+  field_list.push_back(new Item_empty_string("Command",16));
-+  field_list.push_back(new Item_return_int("Time",7, FIELD_TYPE_LONG));
-+  field_list.push_back(field=new Item_empty_string("State",30));
-+  field->maybe_null=1;
-+  field_list.push_back(field=new Item_empty_string("Info",max_query_length));
-+  field->maybe_null=1;
-+  if (protocol->send_fields(&field_list,
-+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_VOID_RETURN;
-+
-+  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+  if (!thd->killed)
-+  {
-+    I_List_iterator<THD> it(threads);
-+    THD *tmp;
-+    while ((tmp=it++))
-+    {
-+      Security_context *tmp_sctx= tmp->security_ctx;
-+      struct st_my_thread_var *mysys_var;
-+      if ((tmp->vio_ok() || tmp->system_thread) &&
-+          (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
-+      {
-+        thread_info *thd_info= new thread_info;
-+
-+        thd_info->thread_id=tmp->thread_id;
-+        thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
-+                                    (tmp->system_thread ?
-+                                     "system user" : "unauthenticated user"));
-+	if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
-+            thd->security_ctx->host_or_ip[0])
-+	{
-+	  if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
-+	    my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
-+			"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
-+	}
-+	else
-+	  thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ? 
-+                                      tmp_sctx->host_or_ip : 
-+                                      tmp_sctx->host ? tmp_sctx->host : "");
-+        if ((thd_info->db=tmp->db))             // Safe test
-+          thd_info->db=thd->strdup(thd_info->db);
-+        thd_info->command=(int) tmp->command;
-+        if ((mysys_var= tmp->mysys_var))
-+          pthread_mutex_lock(&mysys_var->mutex);
-+        thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
-+#ifndef EMBEDDED_LIBRARY
-+        thd_info->state_info= (char*) (tmp->locked ? "Locked" :
-+                                       tmp->net.reading_or_writing ?
-+                                       (tmp->net.reading_or_writing == 2 ?
-+                                        "Writing to net" :
-+                                        thd_info->command == COM_SLEEP ? "" :
-+                                        "Reading from net") :
-+                                       tmp->proc_info ? tmp->proc_info :
-+                                       tmp->mysys_var &&
-+                                       tmp->mysys_var->current_cond ?
-+                                       "Waiting on cond" : NullS);
-+#else
-+        thd_info->state_info= (char*)"Writing to net";
-+#endif
-+        if (mysys_var)
-+          pthread_mutex_unlock(&mysys_var->mutex);
-+
-+#if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
-+        if (pthread_kill(tmp->real_id,0))
-+          tmp->proc_info="*** DEAD ***";        // This shouldn't happen
-+#endif
-+#ifdef EXTRA_DEBUG
-+        thd_info->start_time= tmp->time_after_lock;
-+#else
-+        thd_info->start_time= tmp->start_time;
-+#endif
-+        thd_info->query=0;
-+        if (tmp->query)
-+        {
-+	  /* 
-+            query_length is always set to 0 when we set query = NULL; see
-+	    the comment in sql_class.h why this prevents crashes in possible
-+            races with query_length
-+          */
-+          uint length= min(max_query_length, tmp->query_length);
-+          thd_info->query=(char*) thd->strmake(tmp->query,length);
-+        }
-+        thread_infos.append(thd_info);
-+      }
-+    }
-+  }
-+  VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+
-+  thread_info *thd_info;
-+  time_t now= time(0);
-+  while ((thd_info=thread_infos.get()))
-+  {
-+    protocol->prepare_for_resend();
-+    protocol->store((ulonglong) thd_info->thread_id);
-+    protocol->store(thd_info->user, system_charset_info);
-+    protocol->store(thd_info->host, system_charset_info);
-+    protocol->store(thd_info->db, system_charset_info);
-+    if (thd_info->proc_info)
-+      protocol->store(thd_info->proc_info, system_charset_info);
-+    else
-+      protocol->store(command_name[thd_info->command], system_charset_info);
-+    if (thd_info->start_time)
-+      protocol->store((uint32) (now - thd_info->start_time));
-+    else
-+      protocol->store_null();
-+    protocol->store(thd_info->state_info, system_charset_info);
-+    protocol->store(thd_info->query, system_charset_info);
-+    if (protocol->write())
-+      break; /* purecov: inspected */
-+  }
-+  send_eof(thd);
-+  DBUG_VOID_RETURN;
-+}
-+
-+/*****************************************************************************
-+  Status functions
-+*****************************************************************************/
-+
-+
-+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, TABLE *table)
-+{
-+  char buff[1024], *prefix_end;
-+  /* the variable name should not be longer then 80 characters */
-+  char name_buffer[80];
-+  int len;
-+  LEX_STRING null_lex_str;
-+  DBUG_ENTER("show_status_array");
-+
-+  null_lex_str.str= 0;				// For sys_var->value_ptr()
-+  null_lex_str.length= 0;
-+
-+  prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
-+  len=name_buffer + sizeof(name_buffer) - prefix_end;
-+
-+  for (; variables->name; variables++)
-+  {
-+    strnmov(prefix_end, variables->name, len);
-+    name_buffer[sizeof(name_buffer)-1]=0;       /* Safety */
-+    SHOW_TYPE show_type=variables->type;
-+    if (show_type == SHOW_VARS)
-+    {
-+      show_status_array(thd, wild, (show_var_st *) variables->value,
-+                        value_type, status_var, variables->name, table);
-+    }
-+    else
-+    {
-+      if (!(wild && wild[0] && wild_case_compare(system_charset_info,
-+                                                 name_buffer, wild)))
-+      {
-+        char *value=variables->value;
-+        const char *pos, *end;                  // We assign a lot of const's
-+        long nr;
-+        if (show_type == SHOW_SYS)
-+        {
-+          show_type= ((sys_var*) value)->type();
-+          value=     (char*) ((sys_var*) value)->value_ptr(thd, value_type,
-+                                                           &null_lex_str);
-+        }
-+
-+        pos= end= buff;
-+        switch (show_type) {
-+        case SHOW_LONG_STATUS:
-+        case SHOW_LONG_CONST_STATUS:
-+          value= ((char *) status_var + (ulong) value);
-+          /* fall through */
-+        case SHOW_LONG:
-+        case SHOW_LONG_CONST:
-+          end= int10_to_str(*(long*) value, buff, 10);
-+          break;
-+        case SHOW_LONGLONG:
-+          end= longlong10_to_str(*(longlong*) value, buff, 10);
-+          break;
-+        case SHOW_HA_ROWS:
-+          end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
-+          break;
-+        case SHOW_BOOL:
-+          end= strmov(buff, *(bool*) value ? "ON" : "OFF");
-+          break;
-+        case SHOW_MY_BOOL:
-+          end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
-+          break;
-+        case SHOW_INT_CONST:
-+        case SHOW_INT:
-+          end= int10_to_str((long) *(uint32*) value, buff, 10);
-+          break;
-+        case SHOW_HAVE:
-+        {
-+          SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
-+          pos= show_comp_option_name[(int) tmp];
-+          end= strend(pos);
-+          break;
-+        }
-+        case SHOW_CHAR:
-+        {
-+          if (!(pos= value))
-+            pos= "";
-+          end= strend(pos);
-+          break;
-+        }
-+        case SHOW_STARTTIME:
-+          nr= (long) (thd->query_start() - start_time);
-+          end= int10_to_str(nr, buff, 10);
-+          break;
-+        case SHOW_QUESTION:
-+          end= int10_to_str((long) thd->query_id, buff, 10);
-+          break;
-+#ifdef HAVE_REPLICATION
-+        case SHOW_RPL_STATUS:
-+          end= strmov(buff, rpl_status_type[(int)rpl_status]);
-+          break;
-+        case SHOW_SLAVE_RUNNING:
-+        {
-+          pthread_mutex_lock(&LOCK_active_mi);
-+          end= strmov(buff, (active_mi && active_mi->slave_running &&
-+                             active_mi->rli.slave_running) ? "ON" : "OFF");
-+          pthread_mutex_unlock(&LOCK_active_mi);
-+          break;
-+        }
-+        case SHOW_SLAVE_RETRIED_TRANS:
-+        {
-+          /*
-+            TODO: in 5.1 with multimaster, have one such counter per line in
-+            SHOW SLAVE STATUS, and have the sum over all lines here.
-+          */
-+          pthread_mutex_lock(&LOCK_active_mi);
-+          if (active_mi)
-+          {
-+            pthread_mutex_lock(&active_mi->rli.data_lock);
-+            end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
-+            pthread_mutex_unlock(&active_mi->rli.data_lock);
-+          }
-+          pthread_mutex_unlock(&LOCK_active_mi);
-+          break;
-+        }
-+        case SHOW_SLAVE_SKIP_ERRORS:
-+        {
-+          MY_BITMAP *bitmap= (MY_BITMAP *)value;
-+          if (!use_slave_mask || bitmap_is_clear_all(bitmap))
-+          {
-+            end= strmov(buff, "OFF");
-+          }
-+          else if (bitmap_is_set_all(bitmap))
-+          {
-+            end= strmov(buff, "ALL");
-+          }
-+          else
-+          {
-+            /* 10 is enough assuming errors are max 4 digits */
-+            int i;
-+            for (i= 1;
-+                 i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10;
-+                 i++)
-+            {
-+              if (bitmap_is_set(bitmap, i))
-+              {
-+                end= int10_to_str(i, (char*) end, 10);
-+                *(char*) end++= ',';
-+              }
-+            }
-+            if (end != buff)
-+              end--;				// Remove last ','
-+            if (i < MAX_SLAVE_ERROR)
-+              end= strmov((char*) end, "...");  // Couldn't show all errors
-+          }
-+          break;
-+        }
-+#endif /* HAVE_REPLICATION */
-+        case SHOW_OPENTABLES:
-+          end= int10_to_str((long) cached_tables(), buff, 10);
-+          break;
-+        case SHOW_CHAR_PTR:
-+        {
-+          if (!(pos= *(char**) value))
-+            pos= "";
-+          end= strend(pos);
-+          break;
-+        }
-+        case SHOW_DOUBLE_STATUS:
-+        {
-+          value= ((char *) status_var + (ulong) value);
-+          end= buff + sprintf(buff, "%f", *(double*) value);
-+          break;
-+        }
-+#ifdef HAVE_OPENSSL
-+          /* First group - functions relying on CTX */
-+        case SHOW_SSL_CTX_SESS_ACCEPT:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_accept(ssl_acceptor_fd->
-+                                                        ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_ACCEPT_GOOD:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_accept_good(ssl_acceptor_fd->
-+                                                             ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_connect_good(ssl_acceptor_fd->
-+                                                              ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd-> ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_CB_HITS:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_cb_hits(ssl_acceptor_fd->
-+                                                         ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_HITS:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_hits(ssl_acceptor_fd->
-+                                                      ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_CACHE_FULL:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_cache_full(ssl_acceptor_fd->
-+                                                            ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_MISSES:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_misses(ssl_acceptor_fd->
-+                                                        ssl_context)),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_TIMEOUTS:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_NUMBER:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_CONNECT:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_GET_VERIFY_MODE:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_GET_VERIFY_DEPTH:
-+          end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
-+                                    SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)),
-+                            buff,10);
-+          break;
-+        case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE:
-+          if (!ssl_acceptor_fd)
-+          {
-+            pos= "NONE";
-+            end= pos+4;
-+            break;
-+          }
-+          switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
-+          {
-+          case SSL_SESS_CACHE_OFF:
-+            pos= "OFF";
-+            break;
-+          case SSL_SESS_CACHE_CLIENT:
-+            pos= "CLIENT";
-+            break;
-+          case SSL_SESS_CACHE_SERVER:
-+            pos= "SERVER";
-+            break;
-+          case SSL_SESS_CACHE_BOTH:
-+            pos= "BOTH";
-+            break;
-+          case SSL_SESS_CACHE_NO_AUTO_CLEAR:
-+            pos= "NO_AUTO_CLEAR";
-+            break;
-+          case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
-+            pos= "NO_INTERNAL_LOOKUP";
-+            break;
-+          default:
-+            pos= "Unknown";
-+            break;
-+          }
-+          end= strend(pos);
-+          break;
-+          /* First group - functions relying on SSL */
-+        case SHOW_SSL_GET_VERSION:
-+          pos= (thd->net.vio->ssl_arg ?
-+                SSL_get_version((SSL*) thd->net.vio->ssl_arg) : "");
-+          end= strend(pos);
-+          break;
-+        case SHOW_SSL_SESSION_REUSED:
-+          end= int10_to_str((long) (thd->net.vio->ssl_arg ?
-+                                    SSL_session_reused((SSL*) thd->net.vio->
-+                                                       ssl_arg) :
-+                                    0),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_GET_DEFAULT_TIMEOUT:
-+          end= int10_to_str((long) (thd->net.vio->ssl_arg ?
-+                                    SSL_get_default_timeout((SSL*) thd->net.vio->
-+                                                            ssl_arg) :
-+                                    0),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_GET_VERIFY_MODE:
-+          end= int10_to_str((long) (thd->net.vio->ssl_arg ?
-+                                    SSL_get_verify_mode((SSL*) thd->net.vio->
-+                                                        ssl_arg):
-+                                    0),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_GET_VERIFY_DEPTH:
-+          end= int10_to_str((long) (thd->net.vio->ssl_arg ?
-+                                    SSL_get_verify_depth((SSL*) thd->net.vio->
-+                                                         ssl_arg):
-+                                    0),
-+                            buff, 10);
-+          break;
-+        case SHOW_SSL_GET_CIPHER:
-+          pos= (thd->net.vio->ssl_arg ?
-+                SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : "" );
-+          end= strend(pos);
-+          break;
-+        case SHOW_SSL_GET_CIPHER_LIST:
-+          if (thd->net.vio->ssl_arg)
-+          {
-+            char *to= buff;
-+            for (int i=0 ; i++ ;)
-+            {
-+              const char *p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i);
-+              if (p == NULL)
-+                break;
-+              to= strmov(to, p);
-+              *to++= ':';
-+            }
-+            if (to != buff)
-+              to--;				// Remove last ':'
-+            end= to;
-+          }
-+          break;
-+
-+#endif /* HAVE_OPENSSL */
-+        case SHOW_KEY_CACHE_LONG:
-+        case SHOW_KEY_CACHE_CONST_LONG:
-+          value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
-+          end= int10_to_str(*(long*) value, buff, 10);
-+          break;
-+        case SHOW_KEY_CACHE_LONGLONG:
-+	  value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
-+	  end= longlong10_to_str(*(longlong*) value, buff, 10);
-+	  break;
-+        case SHOW_NET_COMPRESSION:
-+          end= strmov(buff, thd->net.compress ? "ON" : "OFF");
-+          break;
-+        case SHOW_UNDEF:				// Show never happen
-+        case SHOW_SYS:
-+          break;					// Return empty string
-+        default:
-+          break;
-+        }
-+        restore_record(table, s->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);
-+        if (schema_table_store_record(thd, table))
-+          DBUG_RETURN(TRUE);
-+      }
-+    }
-+  }
-+
-+  DBUG_RETURN(FALSE);
-+}
-+
-+
-+/* collect status for all running threads */
-+
-+void calc_sum_of_all_status(STATUS_VAR *to)
-+{
-+  DBUG_ENTER("calc_sum_of_all_status");
-+
-+  /* Ensure that thread id not killed during loop */
-+  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+
-+  I_List_iterator<THD> it(threads);
-+  THD *tmp;
-+  
-+  /* Get global values as base */
-+  *to= global_status_var;
-+  
-+  /* Add to this status from existing threads */
-+  while ((tmp= it++))
-+    add_to_status(to, &tmp->status_var);
-+  
-+  VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+  DBUG_VOID_RETURN;
-+}
-+
-+
-+LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
-+                            const char* str, uint length,
-+                            bool allocate_lex_string)
-+{
-+  MEM_ROOT *mem= thd->mem_root;
-+  if (allocate_lex_string)
-+    if (!(lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING))))
-+      return 0;
-+  lex_str->str= strmake_root(mem, str, length);
-+  lex_str->length= length;
-+  return lex_str;
-+}
-+
-+
-+/* INFORMATION_SCHEMA name */
-+LEX_STRING information_schema_name= {(char*)"information_schema", 18};
-+
-+/* 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
-+{
-+  const char *db_value, *table_value;
-+} INDEX_FIELD_VALUES;
-+
-+
-+/*
-+  Store record to I_S table, convert HEAP table
-+  to MyISAM if necessary
-+
-+  SYNOPSIS
-+    schema_table_store_record()
-+    thd                   thread handler
-+    table                 Information schema table to be updated
-+
-+  RETURN
-+    0	                  success
-+    1	                  error
-+*/
-+
-+static bool schema_table_store_record(THD *thd, TABLE *table)
-+{
-+  int error;
-+  if ((error= table->file->write_row(table->record[0])))
-+  {
-+    if (create_myisam_from_heap(thd, table, 
-+                                table->pos_in_table_list->schema_table_param,
-+                                error, 0))
-+      return 1;
-+  }
-+  return 0;
-+}
-+
-+
-+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) {
-+  case SQLCOM_SHOW_DATABASES:
-+    index_field_values->db_value= wild;
-+    break;
-+  case SQLCOM_SHOW_TABLES:
-+  case SQLCOM_SHOW_TABLE_STATUS:
-+  case SQLCOM_SHOW_TRIGGERS:
-+    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)
-+{
-+  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);
-+  sel->init_query();
-+  if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
-+                             (List<String> *) 0, (List<String> *) 0))
-+    return 1;
-+  return 0;
-+}
-+
-+
-+bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
-+{
-+  if (item->type() == Item::FUNC_ITEM)
-+  {
-+    Item_func *item_func= (Item_func*)item;
-+    Item **child;
-+    Item **item_end= (item_func->arguments()) + item_func->argument_count();
-+    for (child= item_func->arguments(); child != item_end; child++)
-+    {
-+      if (!uses_only_table_name_fields(*child, table))
-+        return 0;
-+    }
-+  }
-+  else if (item->type() == Item::FIELD_ITEM)
-+  {
-+    Item_field *item_field= (Item_field*)item;
-+    CHARSET_INFO *cs= system_charset_info;
-+    ST_SCHEMA_TABLE *schema_table= table->schema_table;
-+    ST_FIELD_INFO *field_info= schema_table->fields_info;
-+    const char *field_name1= schema_table->idx_field1 >= 0 ? field_info[schema_table->idx_field1].field_name : "";
-+    const char *field_name2= schema_table->idx_field2 >= 0 ? field_info[schema_table->idx_field2].field_name : "";
-+    if (table->table != item_field->field->table ||
-+        (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
-+                               (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, 
-+                               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())
-+    return 0;
-+
-+  return 1;
-+}
-+
-+
-+static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
-+{
-+  if (!cond)
-+    return (COND*) 0;
-+  if (cond->type() == Item::COND_ITEM)
-+  {
-+    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+    {
-+      /* Create new top level AND item */
-+      Item_cond_and *new_cond=new Item_cond_and;
-+      if (!new_cond)
-+	return (COND*) 0;
-+      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+      Item *item;
-+      while ((item=li++))
-+      {
-+	Item *fix= make_cond_for_info_schema(item, table);
-+	if (fix)
-+	  new_cond->argument_list()->push_back(fix);
-+      }
-+      switch (new_cond->argument_list()->elements) {
-+      case 0:
-+	return (COND*) 0;
-+      case 1:
-+	return new_cond->argument_list()->head();
-+      default:
-+	new_cond->quick_fix_field();
-+	return new_cond;
-+      }
-+    }
-+    else
-+    {						// Or list
-+      Item_cond_or *new_cond=new Item_cond_or;
-+      if (!new_cond)
-+	return (COND*) 0;
-+      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+      Item *item;
-+      while ((item=li++))
-+      {
-+	Item *fix=make_cond_for_info_schema(item, table);
-+	if (!fix)
-+	  return (COND*) 0;
-+	new_cond->argument_list()->push_back(fix);
-+      }
-+      new_cond->quick_fix_field();
-+      new_cond->top_level_item();
-+      return new_cond;
-+    }
-+  }
-+
-+  if (!uses_only_table_name_fields(cond, table))
-+    return (COND*) 0;
-+  return cond;
-+}
-+
-+
-+enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
-+{
-+  return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
-+}
-+
-+
-+/*
-+  Create db names list. Information schema name always is first in list
-+
-+  SYNOPSIS
-+    make_db_list()
-+    thd                   thread handler
-+    files                 list of db names
-+    wild                  wild string
-+    idx_field_vals        idx_field_vals->db_name contains db name or
-+                          wild string
-+    with_i_schema         returns 1 if we added 'IS' name to list
-+                          otherwise returns 0
-+    is_wild_value         if value is 1 then idx_field_vals->db_name is
-+                          wild string otherwise it's db name; 
-+
-+  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)
-+{
-+  LEX *lex= thd->lex;
-+  *with_i_schema= 0;
-+  get_index_field_values(lex, idx_field_vals);
-+  if (is_wild_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 ||
-+        !wild_case_compare(system_charset_info, 
-+                           information_schema_name.str,
-+                           idx_field_vals->db_value))
-+    {
-+      *with_i_schema= 1;
-+      if (files->push_back(thd->strdup(information_schema_name.str)))
-+        return 1;
-+    }
-+    return (find_files(thd, files, NullS, mysql_data_home,
-+                       idx_field_vals->db_value, 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). lex->orig_sql_command can be not equal to SQLCOM_END
-+    only in case of executing of SHOW commands.
-+  */
-+  if (lex->orig_sql_command != SQLCOM_END)
-+  {
-+    if (!my_strcasecmp(system_charset_info, information_schema_name.str,
-+                       idx_field_vals->db_value))
-+    {
-+      *with_i_schema= 1;
-+      return files->push_back(thd->strdup(information_schema_name.str));
-+    }
-+    return files->push_back(thd->strdup(idx_field_vals->db_value));
-+  }
-+
-+  /*
-+    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)))
-+    return 1;
-+  *with_i_schema= 1;
-+  return (find_files(thd, files, NullS,
-+                     mysql_data_home, NullS, 1) != FIND_FILES_OK);
-+}
-+
-+
-+int schema_tables_add(THD *thd, List<char> *files, const char *wild)
-+{
-+  ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
-+  for (; tmp_schema_table->table_name; tmp_schema_table++)
-+  {
-+    if (tmp_schema_table->hidden)
-+      continue;
-+    if (wild)
-+    {
-+      if (lower_case_table_names)
-+      {
-+        if (wild_case_compare(files_charset_info,
-+                              tmp_schema_table->table_name,
-+                              wild))
-+          continue;
-+      }
-+      else if (wild_compare(tmp_schema_table->table_name, wild, 0))
-+        continue;
-+    }
-+    if (files->push_back(thd->strdup(tmp_schema_table->table_name)))
-+      return 1;
-+  }
-+  return 0;
-+}
-+
-+
-+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], *end, *base_name, *orig_base_name, *file_name;
-+  uint len;
-+  bool with_i_schema;
-+  enum enum_schema_tables schema_table_idx;
-+  List<char> bases;
-+  List_iterator_fast<char> it(bases);
-+  COND *partial_cond;
-+  Security_context *sctx= thd->security_ctx;
-+  uint derived_tables= lex->derived_tables; 
-+  int error= 1;
-+  db_type not_used;
-+  Open_tables_state open_tables_state_backup;
-+  bool save_view_prepare_mode= lex->view_prepare_mode;
-+  Query_tables_list query_tables_list_backup;
-+  lex->view_prepare_mode= TRUE;
-+  DBUG_ENTER("get_all_tables");
-+
-+  LINT_INIT(end);
-+  LINT_INIT(len);
-+
-+  lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
-+
-+  /*
-+    We should not introduce deadlocks even if we already have some
-+    tables open and locked, since we won't lock tables which we will
-+    open and will ignore possible name-locks for these tables.
-+  */
-+  thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
-+
-+  if (lsel)
-+  {
-+    TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
-+    bool res;
-+
-+    lex->all_selects_list= lsel;
-+    /*
-+      Restore thd->temporary_tables to be able to process
-+      temporary tables(only for 'show index' & 'show columns').
-+      This should be changed when processing of temporary tables for
-+      I_S tables will be done.
-+    */
-+    thd->temporary_tables= open_tables_state_backup.temporary_tables;
-+    /*
-+      Let us set fake sql_command so views won't try to merge
-+      themselves into main statement. If we don't do this,
-+      SELECT * from information_schema.xxxx will cause problems.
-+      SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
-+    */
-+    lex->sql_command= SQLCOM_SHOW_FIELDS;
-+    res= open_normal_and_derived_tables(thd, show_table_list,
-+                                        MYSQL_LOCK_IGNORE_FLUSH);
-+    lex->sql_command= save_sql_command;
-+    /*
-+      get_all_tables() returns 1 on failure and 0 on success thus
-+      return only these and not the result code of ::process_table()
-+
-+      We should use show_table_list->alias instead of 
-+      show_table_list->table_name because table_name
-+      could be changed during opening of I_S tables. It's safe
-+      to use alias because alias contains original table name 
-+      in this case(this part of code is used only for 
-+      'show columns' & 'show statistics' commands).
-+    */
-+    error= test(schema_table->process_table(thd, show_table_list,
-+                                            table, res, 
-+                                            (show_table_list->view ?
-+                                             show_table_list->view_db.str :
-+                                             show_table_list->db),
-+                                            show_table_list->alias));
-+    thd->temporary_tables= 0;
-+    close_tables_for_reopen(thd, &show_table_list);
-+    goto err;
-+  }
-+
-+  schema_table_idx= get_schema_table_idx(schema_table);
-+
-+  if (make_db_list(thd, &bases, &idx_field_vals,
-+                   &with_i_schema, 0))
-+    goto err;
-+
-+  partial_cond= make_cond_for_info_schema(cond, tables);
-+  it.rewind(); /* To get access to new elements in basis list */
-+  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) &&
-+	  (base_name= select_lex->db) && !bases.elements))
-+  {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+    if (!check_access(thd,SELECT_ACL, base_name, 
-+                      &thd->col_access, 0, 1, with_i_schema) ||
-+        sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-+	acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) ||
-+	(grant_option && !check_grant_db(thd, base_name)))
-+#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
-+      {
-+        strxmov(path, mysql_data_home, "/", base_name, NullS);
-+        end= path + (len= unpack_dirname(path,path));
-+        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)
-+        {
-+          /*
-+            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 && lex->orig_sql_command == SQLCOM_END)
-+          {
-+            push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                         thd->net.last_errno, thd->net.last_error);
-+            thd->clear_error();
-+            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())
-+        {
-+          if (schema_table_idx == SCH_TABLE_NAMES)
-+          {
-+            if (lex->verbose || lex->orig_sql_command == SQLCOM_END)
-+            {
-+              if (with_i_schema)
-+              {
-+                table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
-+                                       system_charset_info);
-+              }
-+              else
-+              {
-+                my_snprintf(end, len, "/%s%s", file_name, reg_ext);
-+                switch (mysql_frm_type(thd, path, &not_used)) {
-+                case FRMTYPE_ERROR:
-+                  table->field[3]->store(STRING_WITH_LEN("ERROR"),
-+                                         system_charset_info);
-+                  break;
-+                case FRMTYPE_TABLE:
-+                  table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
-+                                         system_charset_info);
-+                  break;
-+                case FRMTYPE_VIEW:
-+                  table->field[3]->store(STRING_WITH_LEN("VIEW"),
-+                                         system_charset_info);
-+                  break;
-+                default:
-+                  DBUG_ASSERT(0);
-+                }
-+              }
-+            }
-+            if (schema_table_store_record(thd, table))
-+              goto err;
-+          }
-+          else
-+          {
-+            int res;
-+            /*
-+              Set the parent lex of 'sel' because it is needed by sel.init_query()
-+              which is called inside make_table_list.
-+            */
-+            sel.parent_lex= lex;
-+            if (make_table_list(thd, &sel, base_name, file_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;
-+            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
-+              could be changed during opening of I_S tables. It's safe
-+              to use alias because alias contains original table name 
-+              in this case.
-+            */
-+            res= schema_table->process_table(thd, show_table_list, table,
-+                                             res, orig_base_name,
-+                                             show_table_list->alias);
-+            close_tables_for_reopen(thd, &show_table_list);
-+            DBUG_ASSERT(!lex->query_tables_own_last);
-+            if (res)
-+              goto err;
-+          }
-+        }
-+      }
-+      /*
-+        If we have information schema its always the first table and only
-+        the first table. Reset for other tables.
-+      */
-+      with_i_schema= 0;
-+    }
-+  }
-+
-+  error= 0;
-+err:
-+  thd->restore_backup_open_tables_state(&open_tables_state_backup);
-+  lex->restore_backup_query_tables_list(&query_tables_list_backup);
-+  lex->derived_tables= derived_tables;
-+  lex->all_selects_list= old_all_select_lex;
-+  lex->view_prepare_mode= save_view_prepare_mode;
-+  lex->sql_command= save_sql_command;
-+  DBUG_RETURN(error);
-+}
-+
-+
-+bool store_schema_shemata(THD* thd, TABLE *table, const char *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[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);
-+}
-+
-+
-+int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  /*
-+    TODO: fill_schema_shemata() is called when new client is connected.
-+    Returning error status in this case leads to client hangup.
-+  */
-+
-+  INDEX_FIELD_VALUES idx_field_vals;
-+  List<char> files;
-+  char *file_name;
-+  bool with_i_schema;
-+  HA_CREATE_INFO create;
-+  TABLE *table= tables->table;
-+  Security_context *sctx= thd->security_ctx;
-+  DBUG_ENTER("fill_schema_shemata");
-+
-+  if (make_db_list(thd, &files, &idx_field_vals,
-+                   &with_i_schema, 1))
-+    DBUG_RETURN(1);
-+
-+  List_iterator_fast<char> it(files);
-+  while ((file_name=it++))
-+  {
-+    if (with_i_schema)       // information schema name is always first in list
-+    {
-+      if (store_schema_shemata(thd, table, file_name,
-+                               system_charset_info))
-+        DBUG_RETURN(1);
-+      with_i_schema= 0;
-+      continue;
-+    }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+    if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-+	acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
-+	(grant_option && !check_grant_db(thd, file_name)))
-+#endif
-+    {
-+      load_db_opt_by_name(thd, file_name, &create);
-+
-+      if (store_schema_shemata(thd, table, file_name,
-+                               create.default_table_charset))
-+        DBUG_RETURN(1);
-+    }
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+
-+static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
-+				    TABLE *table, bool res,
-+				    const char *base_name,
-+				    const char *file_name)
-+{
-+  const char *tmp_buff;
-+  TIME time;
-+  CHARSET_INFO *cs= system_charset_info;
-+  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);
-+  if (res)
-+  {
-+    /*
-+      there was errors during opening tables
-+    */
-+    const char *error= thd->net.last_error;
-+    if (tables->view)
-+      table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
-+    else if (tables->schema_table)
-+      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
-+    else
-+      table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
-+    table->field[20]->store(error, strlen(error), cs);
-+    thd->clear_error();
-+  }
-+  else if (tables->view)
-+  {
-+    table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
-+    table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
-+  }
-+  else
-+  {
-+    TABLE *show_table= tables->table;
-+    TABLE_SHARE *share= show_table->s;
-+    handler *file= show_table->file;
-+
-+    file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
-+               HA_STATUS_NO_LOCK);
-+    if (share->tmp_table == SYSTEM_TMP_TABLE)
-+      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
-+    else if (share->tmp_table)
-+      table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
-+    else
-+      table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
-+
-+    for (int i= 4; i < 20; i++)
-+    {
-+      if (i == 7 || (i > 12 && i < 17) || i == 18)
-+        continue;
-+      table->field[i]->set_notnull();
-+    }
-+    tmp_buff= file->table_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;
-+    }
-+    table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
-+    if (!tables->schema_table)
-+    {
-+      table->field[7]->store((longlong) file->records, TRUE);
-+      table->field[7]->set_notnull();
-+    }
-+    table->field[8]->store((longlong) file->mean_rec_length, TRUE);
-+    table->field[9]->store((longlong) file->data_file_length, TRUE);
-+    if (file->max_data_file_length)
-+    {
-+      table->field[10]->store((longlong) file->max_data_file_length, TRUE);
-+    }
-+    table->field[11]->store((longlong) file->index_file_length, TRUE);
-+    table->field[12]->store((longlong) file->delete_length, TRUE);
-+    if (show_table->found_next_number_field)
-+    {
-+      table->field[13]->store((longlong) file->auto_increment_value, TRUE);
-+      table->field[13]->set_notnull();
-+    }
-+    if (file->create_time)
-+    {
-+      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+                                                file->create_time);
-+      table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      table->field[14]->set_notnull();
-+    }
-+    if (file->update_time)
-+    {
-+      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+                                                file->update_time);
-+      table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      table->field[15]->set_notnull();
-+    }
-+    if (file->check_time)
-+    {
-+      thd->variables.time_zone->gmt_sec_to_TIME(&time, file->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->table_flags() & (ulong) HA_HAS_CHECKSUM)
-+    {
-+      table->field[18]->store((longlong) file->checksum(), TRUE);
-+      table->field[18]->set_notnull();
-+    }
-+
-+    char option_buff[350],*ptr;
-+    ptr=option_buff;
-+    if (share->min_rows)
-+    {
-+      ptr=strmov(ptr," min_rows=");
-+      ptr=longlong10_to_str(share->min_rows,ptr,10);
-+    }
-+    if (share->max_rows)
-+    {
-+      ptr=strmov(ptr," max_rows=");
-+      ptr=longlong10_to_str(share->max_rows,ptr,10);
-+    }
-+    if (share->avg_row_length)
-+    {
-+      ptr=strmov(ptr," avg_row_length=");
-+      ptr=longlong10_to_str(share->avg_row_length,ptr,10);
-+    }
-+    if (share->db_create_options & HA_OPTION_PACK_KEYS)
-+      ptr=strmov(ptr," pack_keys=1");
-+    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
-+      ptr=strmov(ptr," pack_keys=0");
-+    if (share->db_create_options & HA_OPTION_CHECKSUM)
-+      ptr=strmov(ptr," checksum=1");
-+    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
-+      ptr=strmov(ptr," delay_key_write=1");
-+    if (share->row_type != ROW_TYPE_DEFAULT)
-+      ptr=strxmov(ptr, " row_format=", 
-+                  ha_row_type[(uint) share->row_type],
-+                  NullS);
-+    if (file->raid_type)
-+    {
-+      char buff[100];
-+      my_snprintf(buff,sizeof(buff),
-+                  " raid_type=%s raid_chunks=%d raid_chunksize=%ld",
-+                  my_raid_type(file->raid_type), file->raid_chunks,
-+                  file->raid_chunksize/RAID_BLOCK_SIZE);
-+      ptr=strmov(ptr,buff);
-+    }
-+    table->field[19]->store(option_buff+1,
-+                            (ptr == option_buff ? 0 : 
-+                             (uint) (ptr-option_buff)-1), cs);
-+    {
-+      char *comment;
-+      comment= show_table->file->update_table_comment(share->comment.str);
-+      if (comment)
-+      {
-+        table->field[20]->store(comment,
-+                                (comment == share->comment.str ?
-+                                 share->comment.length : 
-+                                 strlen(comment)), cs);
-+        if (comment != share->comment.str)
-+          my_free(comment, MYF(0));
-+      }
-+    }
-+  }
-+  DBUG_RETURN(schema_table_store_record(thd, table));
-+}
-+
-+
-+static int get_schema_column_record(THD *thd, struct st_table_list *tables,
-+				    TABLE *table, bool res,
-+				    const char *base_name,
-+				    const char *file_name)
-+{
-+  LEX *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)
-+  {
-+    if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS)
-+    {
-+      /*
-+        I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
-+        rather than in SHOW COLUMNS
-+      */ 
-+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                   thd->net.last_errno, thd->net.last_error);
-+      thd->clear_error();
-+      res= 0;
-+    }
-+    DBUG_RETURN(res);
-+  }
-+
-+  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);
-+
-+  for (ptr=show_table->field; (field= *ptr) ; ptr++)
-+  {
-+    const char *tmp_buff;
-+    byte *pos;
-+    bool is_blob;
-+    uint flags=field->flags;
-+    char tmp[MAX_FIELD_WIDTH];
-+    char tmp1[MAX_FIELD_WIDTH];
-+    String type(tmp,sizeof(tmp), system_charset_info);
-+    char *end;
-+    int decimals, field_length;
-+
-+    if (wild && wild[0] &&
-+        wild_case_compare(system_charset_info, field->field_name,wild))
-+      continue;
-+
-+    flags= field->flags;
-+    count++;
-+    /* Get default row, with all NULL fields set to NULL */
-+    restore_record(table, s->default_values);
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+    uint col_access;
-+    check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
-+                 &tables->grant.privilege, 0, 0, test(tables->schema_table));
-+    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  && 
-+        !tables->schema_table && !col_access)
-+      continue;
-+    end= tmp;
-+    for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
-+    {
-+      if (col_access & 1)
-+      {
-+        *end++=',';
-+        end=strmov(end,grant_types.type_names[bitnr]);
-+      }
-+    }
-+    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[3]->store(field->field_name, strlen(field->field_name),
-+                           cs);
-+    table->field[4]->store((longlong) count, TRUE);
-+    field->sql_type(type);
-+    table->field[14]->store(type.ptr(), type.length(), cs);		
-+    tmp_buff= strchr(type.ptr(), '(');
-+    table->field[7]->store(type.ptr(),
-+                           (tmp_buff ? tmp_buff - type.ptr() :
-+                            type.length()), cs);
-+    if (show_table->timestamp_field == field &&
-+        field->unireg_check != Field::TIMESTAMP_UN_FIELD)
-+    {
-+      table->field[5]->store(STRING_WITH_LEN("CURRENT_TIMESTAMP"), cs);
-+      table->field[5]->set_notnull();
-+    }
-+    else if (field->unireg_check != Field::NEXT_NUMBER &&
-+             !field->is_null() &&
-+             !(field->flags & NO_DEFAULT_VALUE_FLAG))
-+    {
-+      String def(tmp1,sizeof(tmp1), cs);
-+      type.set(tmp, sizeof(tmp), field->charset());
-+      field->val_str(&type);
-+      uint dummy_errors;
-+      def.copy(type.ptr(), type.length(), type.charset(), cs, &dummy_errors);
-+      table->field[5]->store(def.ptr(), def.length(), def.charset());
-+      table->field[5]->set_notnull();
-+    }
-+    else if (field->unireg_check == Field::NEXT_NUMBER ||
-+             lex->orig_sql_command != SQLCOM_SHOW_FIELDS ||
-+             field->maybe_null())
-+      table->field[5]->set_null();                // Null as default
-+    else
-+    {
-+      table->field[5]->store("",0, cs);
-+      table->field[5]->set_notnull();
-+    }
-+    pos=(byte*) ((flags & NOT_NULL_FLAG) ?  "NO" : "YES");
-+    table->field[6]->store((const char*) pos,
-+                           strlen((const char*) pos), cs);
-+    is_blob= (field->type() == FIELD_TYPE_BLOB);
-+    if (field->has_charset() || is_blob ||
-+        field->real_type() == MYSQL_TYPE_VARCHAR ||  // For varbinary type
-+        field->real_type() == MYSQL_TYPE_STRING)     // For binary type
-+    {
-+      uint32 octet_max_length= field->max_length();
-+      if (is_blob && octet_max_length != (uint32) 4294967295U)
-+        octet_max_length /= field->charset()->mbmaxlen;
-+      longlong char_max_len= is_blob ? 
-+        (longlong) octet_max_length / field->charset()->mbminlen :
-+        (longlong) octet_max_length / field->charset()->mbmaxlen;
-+      table->field[8]->store(char_max_len, TRUE);
-+      table->field[8]->set_notnull();
-+      table->field[9]->store((longlong) octet_max_length, TRUE);
-+      table->field[9]->set_notnull();
-+    }
-+
-+    /*
-+      Calculate field_length and decimals.
-+      They are set to -1 if they should not be set (we should return NULL)
-+    */
-+
-+    decimals= field->decimals();
-+    switch (field->type()) {
-+    case FIELD_TYPE_NEWDECIMAL:
-+      field_length= ((Field_new_decimal*) field)->precision;
-+      break;
-+    case FIELD_TYPE_DECIMAL:
-+      field_length= field->field_length - (decimals  ? 2 : 1);
-+      break;
-+    case FIELD_TYPE_TINY:
-+    case FIELD_TYPE_SHORT:
-+    case FIELD_TYPE_LONG:
-+    case FIELD_TYPE_LONGLONG:
-+    case FIELD_TYPE_INT24:
-+      field_length= field->max_length() - 1;
-+      break;
-+    case FIELD_TYPE_BIT:
-+      field_length= field->max_length();
-+      decimals= -1;                             // return NULL
-+      break;
-+    case FIELD_TYPE_FLOAT:  
-+    case FIELD_TYPE_DOUBLE:
-+      field_length= field->field_length;
-+      if (decimals == NOT_FIXED_DEC)
-+        decimals= -1;                           // return NULL
-+    break;
-+    default:
-+      field_length= decimals= -1;
-+      break;
-+    }
-+
-+    if (field_length >= 0)
-+    {
-+      table->field[10]->store((longlong) field_length, TRUE);
-+      table->field[10]->set_notnull();
-+    }
-+    if (decimals >= 0)
-+    {
-+      table->field[11]->store((longlong) decimals, TRUE);
-+      table->field[11]->set_notnull();
-+    }
-+
-+    if (field->has_charset())
-+    {
-+      pos=(byte*) field->charset()->csname;
-+      table->field[12]->store((const char*) pos,
-+                              strlen((const char*) pos), cs);
-+      table->field[12]->set_notnull();
-+      pos=(byte*) field->charset()->name;
-+      table->field[13]->store((const char*) pos,
-+                              strlen((const char*) pos), cs);
-+      table->field[13]->set_notnull();
-+    }
-+    pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
-+                 (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
-+                 (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
-+    table->field[15]->store((const char*) pos,
-+                            strlen((const char*) pos), cs);
-+
-+    end= tmp;
-+    if (field->unireg_check == Field::NEXT_NUMBER)
-+      end=strmov(tmp,"auto_increment");
-+    table->field[16]->store(tmp, (uint) (end-tmp), cs);
-+
-+    table->field[18]->store(field->comment.str, field->comment.length, cs);
-+    if (schema_table_store_record(thd, table))
-+      DBUG_RETURN(1);
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+
-+
-+int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  CHARSET_INFO **cs;
-+  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+  TABLE *table= tables->table;
-+  CHARSET_INFO *scs= system_charset_info;
-+
-+  for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
-+  {
-+    CHARSET_INFO *tmp_cs= cs[0];
-+    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && 
-+        (tmp_cs->state & MY_CS_AVAILABLE) &&
-+        !(wild && wild[0] &&
-+	  wild_case_compare(scs, tmp_cs->csname,wild)))
-+    {
-+      const char *comment;
-+      restore_record(table, s->default_values);
-+      table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
-+      table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
-+      comment= tmp_cs->comment ? tmp_cs->comment : "";
-+      table->field[2]->store(comment, strlen(comment), scs);
-+      table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
-+      if (schema_table_store_record(thd, table))
-+        return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  CHARSET_INFO **cs;
-+  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+  TABLE *table= tables->table;
-+  CHARSET_INFO *scs= system_charset_info;
-+  for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
-+  {
-+    CHARSET_INFO **cl;
-+    CHARSET_INFO *tmp_cs= cs[0];
-+    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
-+        !(tmp_cs->state & MY_CS_PRIMARY))
-+      continue;
-+    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
-+    {
-+      CHARSET_INFO *tmp_cl= cl[0];
-+      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
-+          !my_charset_same(tmp_cs, tmp_cl))
-+	continue;
-+      if (!(wild && wild[0] &&
-+	  wild_case_compare(scs, tmp_cl->name,wild)))
-+      {
-+	const char *tmp_buff;
-+	restore_record(table, s->default_values);
-+	table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
-+        table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
-+        table->field[2]->store((longlong) tmp_cl->number, TRUE);
-+        tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
-+	table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
-+        tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
-+	table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
-+        table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
-+        if (schema_table_store_record(thd, table))
-+          return 1;
-+      }
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  CHARSET_INFO **cs;
-+  TABLE *table= tables->table;
-+  CHARSET_INFO *scs= system_charset_info;
-+  for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
-+  {
-+    CHARSET_INFO **cl;
-+    CHARSET_INFO *tmp_cs= cs[0];
-+    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
-+        !(tmp_cs->state & MY_CS_PRIMARY))
-+      continue;
-+    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
-+    {
-+      CHARSET_INFO *tmp_cl= cl[0];
-+      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
-+          !my_charset_same(tmp_cs,tmp_cl))
-+	continue;
-+      restore_record(table, s->default_values);
-+      table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
-+      table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
-+      if (schema_table_store_record(thd, table))
-+        return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
-+                       const char *wild, bool full_access, const char *sp_user)
-+{
-+  String tmp_string;
-+  String sp_db, sp_name, definer;
-+  TIME time;
-+  LEX *lex= thd->lex;
-+  CHARSET_INFO *cs= system_charset_info;
-+  get_field(thd->mem_root, proc_table->field[0], &sp_db);
-+  get_field(thd->mem_root, proc_table->field[1], &sp_name);
-+  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() ==
-+                                                TYPE_ENUM_PROCEDURE))
-+    return 0;
-+
-+  if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
-+      proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
-+      lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC &&
-+      proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION ||
-+      lex->orig_sql_command == SQLCOM_END)
-+  {
-+    restore_record(table, s->default_values);
-+    if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
-+    {
-+      int enum_idx= (int) proc_table->field[5]->val_int();
-+      table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
-+      get_field(thd->mem_root, proc_table->field[3], &tmp_string);
-+      table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
-+      get_field(thd->mem_root, proc_table->field[2], &tmp_string);
-+      table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
-+      {
-+        get_field(thd->mem_root, proc_table->field[9], &tmp_string);
-+        table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+        table->field[5]->set_notnull();
-+      }
-+      if (full_access)
-+      {
-+        get_field(thd->mem_root, proc_table->field[10], &tmp_string);
-+        table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+        table->field[7]->set_notnull();
-+      }
-+      table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
-+      table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
-+      get_field(thd->mem_root, proc_table->field[6], &tmp_string);
-+      table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      table->field[12]->store(sp_data_access_name[enum_idx].str, 
-+                              sp_data_access_name[enum_idx].length , cs);
-+      get_field(thd->mem_root, proc_table->field[7], &tmp_string);
-+      table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      bzero((char *)&time, sizeof(time));
-+      ((Field_timestamp *) proc_table->field[12])->get_time(&time);
-+      table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      bzero((char *)&time, sizeof(time));
-+      ((Field_timestamp *) proc_table->field[13])->get_time(&time);
-+      table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      get_field(thd->mem_root, proc_table->field[14], &tmp_string);
-+      table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      get_field(thd->mem_root, proc_table->field[15], &tmp_string);
-+      table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
-+      table->field[19]->store(definer.ptr(), definer.length(), cs);
-+      return schema_table_store_record(thd, table);
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  TABLE *proc_table;
-+  TABLE_LIST proc_tables;
-+  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+  int res= 0;
-+  TABLE *table= tables->table;
-+  bool full_access;
-+  char definer[USER_HOST_BUFF_SIZE];
-+  Open_tables_state open_tables_state_backup;
-+  DBUG_ENTER("fill_schema_proc");
-+
-+  strxmov(definer, thd->security_ctx->priv_user, "@",
-+          thd->security_ctx->priv_host, NullS);
-+  /* We use this TABLE_LIST instance only for checking of privileges. */
-+  bzero((char*) &proc_tables,sizeof(proc_tables));
-+  proc_tables.db= (char*) "mysql";
-+  proc_tables.db_length= 5;
-+  proc_tables.table_name= proc_tables.alias= (char*) "proc";
-+  proc_tables.table_name_length= 4;
-+  proc_tables.lock_type= TL_READ;
-+  full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
-+  if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
-+  {
-+    DBUG_RETURN(1);
-+  }
-+  proc_table->file->ha_index_init(0);
-+  if ((res= proc_table->file->index_first(proc_table->record[0])))
-+  {
-+    res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
-+    goto err;
-+  }
-+  if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
-+  {
-+    res= 1;
-+    goto err;
-+  }
-+  while (!proc_table->file->index_next(proc_table->record[0]))
-+  {
-+    if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
-+    {
-+      res= 1;
-+      goto err;
-+    }
-+  }
-+
-+err:
-+  proc_table->file->ha_index_end();
-+  close_proc_table(thd, &open_tables_state_backup);
-+  DBUG_RETURN(res);
-+}
-+
-+
-+static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
-+				  TABLE *table, bool res,
-+				  const char *base_name,
-+				  const char *file_name)
-+{
-+  CHARSET_INFO *cs= system_charset_info;
-+  DBUG_ENTER("get_schema_stat_record");
-+  if (res)
-+  {
-+    if (thd->lex->orig_sql_command != SQLCOM_SHOW_KEYS)
-+    {
-+      /*
-+        I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
-+        rather than in SHOW KEYS
-+      */
-+      if (!tables->view)
-+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                     thd->net.last_errno, thd->net.last_error);
-+      thd->clear_error();
-+      res= 0;
-+    }
-+    DBUG_RETURN(res);
-+  }
-+  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);
-+    for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
-+    {
-+      KEY_PART_INFO *key_part= key_info->key_part;
-+      const char *str;
-+      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[3]->store((longlong) ((key_info->flags &
-+                                            HA_NOSAME) ? 0 : 1), TRUE);
-+        table->field[4]->store(base_name, strlen(base_name), 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)
-+        {
-+          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->records /
-+                           key->rec_per_key[j]);
-+          table->field[9]->store((longlong) records, TRUE);
-+          table->field[9]->set_notnull();
-+        }
-+        if (!(key_info->flags & HA_FULLTEXT) &&
-+            (key_part->field &&
-+             key_part->length !=
-+             show_table->field[key_part->fieldnr-1]->key_length()))
-+        {
-+          table->field[10]->store((longlong) key_part->length /
-+                                  key_part->field->charset()->mbmaxlen, 1);
-+          table->field[10]->set_notnull();
-+        }
-+        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
-+          table->field[14]->store("", 0, cs);
-+        table->field[14]->set_notnull();
-+        if (schema_table_store_record(thd, table))
-+          DBUG_RETURN(1);
-+      }
-+    }
-+  }
-+  DBUG_RETURN(res);
-+}
-+
-+
-+static int get_schema_views_record(THD *thd, struct st_table_list *tables,
-+				   TABLE *table, bool res,
-+				   const char *base_name,
-+				   const char *file_name)
-+{
-+  CHARSET_INFO *cs= system_charset_info;
-+  DBUG_ENTER("get_schema_views_record");
-+  char definer[USER_HOST_BUFF_SIZE];
-+  uint definer_len;
-+
-+  if (tables->view)
-+  {
-+    Security_context *sctx= thd->security_ctx;
-+    if (!tables->allowed_show)
-+    {
-+      if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
-+                         sctx->priv_user) &&
-+          !my_strcasecmp(system_charset_info, tables->definer.host.str,
-+                         sctx->priv_host))
-+        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)
-+    {
-+      char buff[2048];
-+      String qwe_str(buff, sizeof(buff), cs);
-+      qwe_str.length(0);
-+      qwe_str.append(STRING_WITH_LEN("/* "));
-+      append_algorithm(tables, &qwe_str);
-+      qwe_str.append(STRING_WITH_LEN("*/ "));
-+      qwe_str.append(tables->query.str, tables->query.length);
-+      table->field[3]->store(qwe_str.ptr(), qwe_str.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("NONE"), cs);
-+
-+    if (tables->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);
-+    if (schema_table_store_record(thd, table))
-+      DBUG_RETURN(1);
-+    if (res)
-+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
-+                   thd->net.last_errno, thd->net.last_error);
-+  }
-+  if (res) 
-+    thd->clear_error();
-+  DBUG_RETURN(0);
-+}
-+
-+
-+bool store_constraints(THD *thd, TABLE *table, const char *db,
-+                       const char *tname, 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[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[5]->store(con_type, con_len, cs);
-+  return schema_table_store_record(thd, table);
-+}
-+
-+
-+static int get_schema_constraints_record(THD *thd, struct st_table_list *tables,
-+					 TABLE *table, bool res,
-+					 const char *base_name,
-+					 const char *file_name)
-+{
-+  DBUG_ENTER("get_schema_constraints_record");
-+  if (res)
-+  {
-+    if (!tables->view)
-+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                   thd->net.last_errno, thd->net.last_error);
-+    thd->clear_error();
-+    DBUG_RETURN(0);
-+  }
-+  else if (!tables->view)
-+  {
-+    List<FOREIGN_KEY_INFO> f_key_list;
-+    TABLE *show_table= tables->table;
-+    KEY *key_info=show_table->key_info;
-+    uint primary_key= show_table->s->primary_key;
-+    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++)
-+    {
-+      if (i != primary_key && !(key_info->flags & HA_NOSAME))
-+        continue;
-+
-+      if (i == primary_key && !strcmp(key_info->name, primary_key_name))
-+      {
-+        if (store_constraints(thd, table, base_name, file_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,
-+                              strlen(key_info->name),
-+                              STRING_WITH_LEN("UNIQUE")))
-+          DBUG_RETURN(1);
-+      }
-+    }
-+
-+    show_table->file->get_foreign_key_list(thd, &f_key_list);
-+    FOREIGN_KEY_INFO *f_key_info;
-+    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
-+    while ((f_key_info=it++))
-+    {
-+      if (store_constraints(thd, table, base_name, file_name, 
-+                            f_key_info->forein_id->str,
-+                            strlen(f_key_info->forein_id->str),
-+                            "FOREIGN KEY", 11))
-+        DBUG_RETURN(1);
-+    }
-+  }
-+  DBUG_RETURN(res);
-+}
-+
-+
-+static bool store_trigger(THD *thd, TABLE *table, const char *db,
-+                          const char *tname, LEX_STRING *trigger_name,
-+                          enum trg_event_type event,
-+                          enum trg_action_time_type timing,
-+                          LEX_STRING *trigger_stmt,
-+                          ulong sql_mode,
-+                          LEX_STRING *definer_buffer)
-+{
-+  CHARSET_INFO *cs= system_charset_info;
-+  byte *sql_mode_str;
-+  ulong sql_mode_len;
-+
-+  restore_record(table, s->default_values);
-+  table->field[1]->store(db, strlen(db), 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[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,
-+                          trg_action_time_type_names[timing].length, cs);
-+  table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
-+  table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
-+
-+  sql_mode_str=
-+    sys_var_thd_sql_mode::symbolic_mode_representation(thd,
-+                                                       sql_mode,
-+                                                       &sql_mode_len);
-+  table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
-+  table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
-+  return schema_table_store_record(thd, table);
-+}
-+
-+
-+static int get_schema_triggers_record(THD *thd, struct st_table_list *tables,
-+				      TABLE *table, bool res,
-+				      const char *base_name,
-+				      const char *file_name)
-+{
-+  DBUG_ENTER("get_schema_triggers_record");
-+  /*
-+    res can be non zero value when processed table is a view or
-+    error happened during opening of processed table.
-+  */
-+  if (res)
-+  {
-+    if (!tables->view)
-+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                   thd->net.last_errno, thd->net.last_error);
-+    thd->clear_error();
-+    DBUG_RETURN(0);
-+  }
-+  if (!tables->view && tables->table->triggers)
-+  {
-+    Table_triggers_list *triggers= tables->table->triggers;
-+    int event, timing;
-+    for (event= 0; event < (int)TRG_EVENT_MAX; event++)
-+    {
-+      for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
-+      {
-+        LEX_STRING trigger_name;
-+        LEX_STRING trigger_stmt;
-+        ulong sql_mode;
-+        char definer_holder[USER_HOST_BUFF_SIZE];
-+        LEX_STRING definer_buffer;
-+        definer_buffer.str= definer_holder;
-+        if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
-+                                       (enum trg_action_time_type)timing,
-+                                       &trigger_name, &trigger_stmt,
-+                                       &sql_mode,
-+                                       &definer_buffer))
-+          continue;
-+
-+        if (store_trigger(thd, table, base_name, file_name, &trigger_name,
-+                         (enum trg_event_type) event,
-+                         (enum trg_action_time_type) timing, &trigger_stmt,
-+                         sql_mode,
-+                         &definer_buffer))
-+          DBUG_RETURN(1);
-+      }
-+    }
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+
-+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)
-+{
-+  CHARSET_INFO *cs= system_charset_info;
-+  table->field[1]->store(db, strlen(db), 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[6]->store(con_type, con_len, cs);
-+  table->field[7]->store((longlong) idx, TRUE);
-+}
-+
-+
-+static int get_schema_key_column_usage_record(THD *thd,
-+					      struct st_table_list *tables,
-+					      TABLE *table, bool res,
-+					      const char *base_name,
-+					      const char *file_name)
-+{
-+  DBUG_ENTER("get_schema_key_column_usage_record");
-+  if (res)
-+  {
-+    if (!tables->view)
-+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+                   thd->net.last_errno, thd->net.last_error);
-+    thd->clear_error();
-+    DBUG_RETURN(0);
-+  }
-+  else if (!tables->view)
-+  {
-+    List<FOREIGN_KEY_INFO> f_key_list;
-+    TABLE *show_table= tables->table;
-+    KEY *key_info=show_table->key_info;
-+    uint primary_key= show_table->s->primary_key;
-+    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++)
-+    {
-+      if (i != primary_key && !(key_info->flags & HA_NOSAME))
-+        continue;
-+      uint f_idx= 0;
-+      KEY_PART_INFO *key_part= key_info->key_part;
-+      for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+      {
-+        if (key_part->field)
-+        {
-+          f_idx++;
-+          restore_record(table, s->default_values);
-+          store_key_column_usage(table, base_name, file_name,
-+                                 key_info->name,
-+                                 strlen(key_info->name), 
-+                                 key_part->field->field_name, 
-+                                 strlen(key_part->field->field_name),
-+                                 (longlong) f_idx);
-+          if (schema_table_store_record(thd, table))
-+            DBUG_RETURN(1);
-+        }
-+      }
-+    }
-+
-+    show_table->file->get_foreign_key_list(thd, &f_key_list);
-+    FOREIGN_KEY_INFO *f_key_info;
-+    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
-+    while ((f_key_info= it++))
-+    {
-+      LEX_STRING *f_info;
-+      LEX_STRING *r_info;
-+      List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
-+        it1(f_key_info->referenced_fields);
-+      uint f_idx= 0;
-+      while ((f_info= it++))
-+      {
-+        r_info= it1++;
-+        f_idx++;
-+        restore_record(table, s->default_values);
-+        store_key_column_usage(table, base_name, file_name,
-+                               f_key_info->forein_id->str,
-+                               f_key_info->forein_id->length,
-+                               f_info->str, f_info->length,
-+                               (longlong) f_idx);
-+        table->field[8]->store((longlong) f_idx, TRUE);
-+        table->field[8]->set_notnull();
-+        table->field[9]->store(f_key_info->referenced_db->str,
-+                               f_key_info->referenced_db->length,
-+                               system_charset_info);
-+        table->field[9]->set_notnull();
-+        table->field[10]->store(f_key_info->referenced_table->str,
-+                                f_key_info->referenced_table->length, 
-+                                system_charset_info);
-+        table->field[10]->set_notnull();
-+        table->field[11]->store(r_info->str, r_info->length,
-+                                system_charset_info);
-+        table->field[11]->set_notnull();
-+        if (schema_table_store_record(thd, table))
-+          DBUG_RETURN(1);
-+      }
-+    }
-+  }
-+  DBUG_RETURN(res);
-+}
-+
-+
-+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,thd->lex->select_lex.db, wild))
-+            && thd->is_fatal_error)
-+    DBUG_RETURN(1);
-+
-+  for (; open_list ; open_list=open_list->next)
-+  {
-+    restore_record(table, s->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, TRUE);
-+    table->field[3]->store((longlong) open_list->locked, TRUE);
-+    if (schema_table_store_record(thd, table))
-+      DBUG_RETURN(1);
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+
-+int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  DBUG_ENTER("fill_variables");
-+  int res= 0;
-+  LEX *lex= thd->lex;
-+  const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-+  pthread_mutex_lock(&LOCK_global_system_variables);
-+  res= show_status_array(thd, wild, init_vars, 
-+                         lex->option_type, 0, "", tables->table);
-+  pthread_mutex_unlock(&LOCK_global_system_variables);
-+  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;
-+  ha_update_statistics();                    /* Export engines statistics */
-+  pthread_mutex_lock(&LOCK_status);
-+  if (lex->option_type == OPT_GLOBAL)
-+    calc_sum_of_all_status(&tmp);
-+  res= show_status_array(thd, wild, status_vars, OPT_GLOBAL,
-+                         (lex->option_type == OPT_GLOBAL ? 
-+                          &tmp: &thd->status_var), "",tables->table);
-+  pthread_mutex_unlock(&LOCK_status);
-+  DBUG_RETURN(res);
-+}
-+
-+
-+/*
-+  Find schema_tables elment by name
-+
-+  SYNOPSIS
-+    find_schema_table()
-+    thd                 thread handler
-+    table_name          table name
-+
-+  RETURN
-+    0	table not found
-+    #   pointer to 'shema_tables' element
-+*/
-+
-+ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
-+{
-+  ST_SCHEMA_TABLE *schema_table= schema_tables;
-+  for (; schema_table->table_name; schema_table++)
-+  {
-+    if (!my_strcasecmp(system_charset_info,
-+                       schema_table->table_name,
-+                       table_name))
-+      return schema_table;
-+  }
-+  return 0;
-+}
-+
-+
-+ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
-+{
-+  return &schema_tables[schema_table_idx];
-+}
-+
-+
-+/*
-+  Create information_schema table using schema_table data
-+
-+  SYNOPSIS
-+    create_schema_table()
-+    thd	       	          thread handler
-+    schema_table          pointer to 'shema_tables' element
-+
-+  RETURN
-+    #	                  Pointer to created table
-+    0	                  Can't create table
-+*/
-+
-+TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
-+{
-+  int field_count= 0;
-+  Item *item;
-+  TABLE *table;
-+  List<Item> field_list;
-+  ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
-+  ST_FIELD_INFO *fields_info= schema_table->fields_info;
-+  CHARSET_INFO *cs= system_charset_info;
-+  DBUG_ENTER("create_schema_table");
-+
-+  for (; fields_info->field_name; fields_info++)
-+  {
-+    switch (fields_info->field_type) {
-+    case MYSQL_TYPE_LONG:
-+      if (!(item= new Item_int(fields_info->field_name,
-+                               fields_info->value,
-+                               fields_info->field_length)))
-+      {
-+        DBUG_RETURN(0);
-+      }
-+      break;
-+    case MYSQL_TYPE_TIMESTAMP:
-+      if (!(item=new Item_datetime(fields_info->field_name)))
-+      {
-+        DBUG_RETURN(0);
-+      }
-+      break;
-+    default:
-+      /* this should be changed when Item_empty_string is fixed(in 4.1) */
-+      if (!(item= new Item_empty_string("", 0, cs)))
-+      {
-+        DBUG_RETURN(0);
-+      }
-+      item->max_length= fields_info->field_length * cs->mbmaxlen;
-+      item->set_name(fields_info->field_name,
-+                     strlen(fields_info->field_name), cs);
-+      break;
-+    }
-+    field_list.push_back(item);
-+    item->maybe_null= fields_info->maybe_null;
-+    field_count++;
-+  }
-+  TMP_TABLE_PARAM *tmp_table_param =
-+    (TMP_TABLE_PARAM*) (thd->calloc(sizeof(TMP_TABLE_PARAM)));
-+  tmp_table_param->init();
-+  tmp_table_param->table_charset= cs;
-+  tmp_table_param->field_count= field_count;
-+  tmp_table_param->schema_table= 1;
-+  SELECT_LEX *select_lex= thd->lex->current_select;
-+  if (!(table= create_tmp_table(thd, tmp_table_param,
-+                                field_list, (ORDER*) 0, 0, 0, 
-+                                (select_lex->options | thd->options |
-+                                 TMP_TABLE_ALL_COLUMNS),
-+                                HA_POS_ERROR, table_list->alias)))
-+    DBUG_RETURN(0);
-+  table_list->schema_table_param= tmp_table_param;
-+  DBUG_RETURN(table);
-+}
-+
-+
-+/*
-+  For old SHOW compatibility. It is used when
-+  old SHOW doesn't have generated column names
-+  Make list of fields for SHOW
-+
-+  SYNOPSIS
-+    make_old_format()
-+    thd			thread handler
-+    schema_table        pointer to 'schema_tables' element
-+
-+  RETURN
-+   -1	errror
-+    0	success
-+*/
-+
-+int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  ST_FIELD_INFO *field_info= schema_table->fields_info;
-+  Name_resolution_context *context= &thd->lex->select_lex.context;
-+  for (; field_info->field_name; field_info++)
-+  {
-+    if (field_info->old_name)
-+    {
-+      Item_field *field= new Item_field(context,
-+                                        NullS, NullS, field_info->field_name);
-+      if (field)
-+      {
-+        field->set_name(field_info->old_name,
-+                        strlen(field_info->old_name),
-+                        system_charset_info);
-+        if (add_item_to_list(thd, field))
-+          return 1;
-+      }
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  char tmp[128];
-+  LEX *lex= thd->lex;
-+  SELECT_LEX *sel= lex->current_select;
-+  Name_resolution_context *context= &sel->context;
-+
-+  if (!sel->item_list.elements)
-+  {
-+    ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
-+    String buffer(tmp,sizeof(tmp), system_charset_info);
-+    Item_field *field= new Item_field(context,
-+                                      NullS, NullS, field_info->field_name);
-+    if (!field || add_item_to_list(thd, field))
-+      return 1;
-+    buffer.length(0);
-+    buffer.append(field_info->old_name);
-+    if (lex->wild && lex->wild->ptr())
-+    {
-+      buffer.append(STRING_WITH_LEN(" ("));
-+      buffer.append(lex->wild->ptr());
-+      buffer.append(')');
-+    }
-+    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+  }
-+  return 0;
-+}
-+
-+
-+int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  char tmp[128];
-+  String buffer(tmp,sizeof(tmp), thd->charset());
-+  LEX *lex= thd->lex;
-+  Name_resolution_context *context= &lex->select_lex.context;
-+
-+  ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
-+  buffer.length(0);
-+  buffer.append(field_info->old_name);
-+  buffer.append(lex->select_lex.db);
-+  if (lex->wild && lex->wild->ptr())
-+  {
-+    buffer.append(STRING_WITH_LEN(" ("));
-+    buffer.append(lex->wild->ptr());
-+    buffer.append(')');
-+  }
-+  Item_field *field= new Item_field(context,
-+                                    NullS, NullS, field_info->field_name);
-+  if (add_item_to_list(thd, field))
-+    return 1;
-+  field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+  if (thd->lex->verbose)
-+  {
-+    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+    field_info= &schema_table->fields_info[3];
-+    field= new Item_field(context, NullS, NullS, field_info->field_name);
-+    if (add_item_to_list(thd, field))
-+      return 1;
-+    field->set_name(field_info->old_name, strlen(field_info->old_name),
-+                    system_charset_info);
-+  }
-+  return 0;
-+}
-+
-+
-+int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
-+  int *field_num= fields_arr;
-+  ST_FIELD_INFO *field_info;
-+  Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+  for (; *field_num >= 0; field_num++)
-+  {
-+    field_info= &schema_table->fields_info[*field_num];
-+    if (!thd->lex->verbose && (*field_num == 13 ||
-+                               *field_num == 17 ||
-+                               *field_num == 18))
-+      continue;
-+    Item_field *field= new Item_field(context,
-+                                      NullS, NullS, field_info->field_name);
-+    if (field)
-+    {
-+      field->set_name(field_info->old_name,
-+                      strlen(field_info->old_name),
-+                      system_charset_info);
-+      if (add_item_to_list(thd, field))
-+        return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  int fields_arr[]= {0, 2, 1, 3, -1};
-+  int *field_num= fields_arr;
-+  ST_FIELD_INFO *field_info;
-+  Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+  for (; *field_num >= 0; field_num++)
-+  {
-+    field_info= &schema_table->fields_info[*field_num];
-+    Item_field *field= new Item_field(context,
-+                                      NullS, NullS, field_info->field_name);
-+    if (field)
-+    {
-+      field->set_name(field_info->old_name,
-+                      strlen(field_info->old_name),
-+                      system_charset_info);
-+      if (add_item_to_list(thd, field))
-+        return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, -1};
-+  int *field_num= fields_arr;
-+  ST_FIELD_INFO *field_info;
-+  Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+  for (; *field_num >= 0; field_num++)
-+  {
-+    field_info= &schema_table->fields_info[*field_num];
-+    Item_field *field= new Item_field(context,
-+                                      NullS, NullS, field_info->field_name);
-+    if (field)
-+    {
-+      field->set_name(field_info->old_name,
-+                      strlen(field_info->old_name),
-+                      system_charset_info);
-+      if (add_item_to_list(thd, field))
-+        return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+
-+/*
-+  Create information_schema table
-+
-+  SYNOPSIS
-+  mysql_schema_table()
-+    thd                thread handler
-+    lex                pointer to LEX
-+    table_list         pointer to table_list
-+
-+  RETURN
-+    0	success
-+    1   error
-+*/
-+
-+int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
-+{
-+  TABLE *table;
-+  DBUG_ENTER("mysql_schema_table");
-+  if (!(table= table_list->schema_table->create_table(thd, table_list)))
-+  {
-+    DBUG_RETURN(1);
-+  }
-+  table->s->tmp_table= SYSTEM_TMP_TABLE;
-+  table->grant.privilege= SELECT_ACL;
-+  /*
-+    This test is necessary to make
-+    case insensitive file systems +
-+    upper case table names(information schema tables) +
-+    views
-+    working correctly
-+  */
-+  if (table_list->schema_table_name)
-+    table->alias_name_used= my_strcasecmp(table_alias_charset,
-+                                          table_list->schema_table_name,
-+                                          table_list->alias);
-+  table_list->table_name= (char*) table->s->table_name;
-+  table_list->table_name_length= strlen(table->s->table_name);
-+  table_list->table= table;
-+  table->next= thd->derived_tables;
-+  thd->derived_tables= table;
-+  table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
-+  lex->safe_to_cache_query= 0;
-+
-+  if (table_list->schema_table_reformed) // show command
-+  {
-+    SELECT_LEX *sel= lex->current_select;
-+    Item *item;
-+    Field_translator *transl, *org_transl;
-+
-+    if (table_list->field_translation)
-+    {
-+      Field_translator *end= table_list->field_translation_end;
-+      for (transl= table_list->field_translation; transl < end; transl++)
-+      {
-+        if (!transl->item->fixed &&
-+            transl->item->fix_fields(thd, &transl->item))
-+          DBUG_RETURN(1);
-+      }
-+      DBUG_RETURN(0);
-+    }
-+    List_iterator_fast<Item> it(sel->item_list);
-+    if (!(transl=
-+          (Field_translator*)(thd->stmt_arena->
-+                              alloc(sel->item_list.elements *
-+                                    sizeof(Field_translator)))))
-+    {
-+      DBUG_RETURN(1);
-+    }
-+    for (org_transl= transl; (item= it++); transl++)
-+    {
-+      transl->item= item;
-+      transl->name= item->name;
-+      if (!item->fixed && item->fix_fields(thd, &transl->item))
-+      {
-+        DBUG_RETURN(1);
-+      }
-+    }
-+    table_list->field_translation= org_transl;
-+    table_list->field_translation_end= transl;
-+  }
-+
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+  Generate select from information_schema table
-+
-+  SYNOPSIS
-+    make_schema_select()
-+    thd                  thread handler
-+    sel                  pointer to SELECT_LEX
-+    schema_table_idx     index of 'schema_tables' element
-+
-+  RETURN
-+    0	success
-+    1   error
-+*/
-+
-+int make_schema_select(THD *thd, SELECT_LEX *sel,
-+		       enum enum_schema_tables schema_table_idx)
-+{
-+  ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
-+  LEX_STRING db, table;
-+  DBUG_ENTER("mysql_schema_select");
-+  /*
-+     We have to make non const db_name & table_name
-+     because of lower_case_table_names
-+  */
-+  make_lex_string(thd, &db, information_schema_name.str,
-+                  information_schema_name.length, 0);
-+  make_lex_string(thd, &table, schema_table->table_name,
-+                  strlen(schema_table->table_name), 0);
-+  if (schema_table->old_format(thd, schema_table) ||   /* Handle old syntax */
-+      !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
-+                              0, 0, TL_READ, (List<String> *) 0,
-+                              (List<String> *) 0))
-+  {
-+    DBUG_RETURN(1);
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+  Fill temporary schema tables before SELECT
-+
-+  SYNOPSIS
-+    get_schema_tables_result()
-+    join  join which use schema tables
-+    executed_place place where I_S table processed
-+
-+  RETURN
-+    FALSE success
-+    TRUE  error
-+*/
-+
-+bool get_schema_tables_result(JOIN *join,
-+                              enum enum_schema_table_state executed_place)
-+{
-+  JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
-+  THD *thd= join->thd;
-+  LEX *lex= thd->lex;
-+  bool result= 0;
-+  DBUG_ENTER("get_schema_tables_result");
-+
-+  thd->no_warnings_for_error= 1;
-+  for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
-+  {  
-+    if (!tab->table || !tab->table->pos_in_table_list)
-+      break;
-+
-+    TABLE_LIST *table_list= tab->table->pos_in_table_list;
-+    if (table_list->schema_table && thd->fill_derived_tables())
-+    {
-+      bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
-+                          lex->current_select->master_unit()->item);
-+      /*
-+        If schema table is already processed and
-+        the statement is not a subselect then
-+        we don't need to fill this table again.
-+        If schema table is already processed and
-+        schema_table_state != executed_place then
-+        table is already processed and
-+        we should skip second data processing.
-+      */
-+      if (table_list->schema_table_state &&
-+          (!is_subselect || table_list->schema_table_state != executed_place))
-+        continue;
-+
-+      /*
-+        if table is used in a subselect and
-+        table has been processed earlier with the same
-+        'executed_place' value then we should refresh the table.
-+      */
-+      if (table_list->schema_table_state && is_subselect)
-+      {
-+        table_list->table->file->extra(HA_EXTRA_RESET_STATE);
-+        table_list->table->file->delete_all_rows();
-+        free_io_cache(table_list->table);
-+        filesort_free_buffers(table_list->table,1);
-+        table_list->table->null_row= 0;
-+      }
-+      else
-+        table_list->table->file->records= 0;
-+
-+      if (table_list->schema_table->fill_table(thd, table_list,
-+                                               tab->select_cond))
-+      {
-+        result= 1;
-+        join->error= 1;
-+        table_list->schema_table_state= executed_place;
-+        break;
-+      }
-+      table_list->schema_table_state= executed_place;
-+    }
-+  }
-+  thd->no_warnings_for_error= 0;
-+  DBUG_RETURN(result);
-+}
-+
-+
-+ST_FIELD_INFO schema_fields_info[]=
-+{
-+  {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
-+  {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO tables_fields_info[]=
-+{
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-+  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"},
-+  {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
-+  {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
-+  {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
-+  {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
-+  {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
-+  {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
-+  {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
-+  {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
-+  {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, "Auto_increment"},
-+  {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
-+  {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
-+  {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
-+  {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-+  {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
-+  {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options"},
-+  {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO columns_fields_info[]=
-+{
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"},
-+  {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-+  {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1, "Default"},
-+  {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
-+  {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-+  {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-+  {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-+  {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
-+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-+  {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type"},
-+  {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"},
-+  {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra"},
-+  {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges"},
-+  {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO charsets_fields_info[]=
-+{
-+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
-+  {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation"},
-+  {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description"},
-+  {"MAXLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO collation_fields_info[]=
-+{
-+  {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation"},
-+  {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
-+  {"ID", 11, MYSQL_TYPE_LONG, 0, 0, "Id"},
-+  {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default"},
-+  {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled"},
-+  {"SORTLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+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}
-+};
-+
-+
-+ST_FIELD_INFO proc_fields_info[]=
-+{
-+  {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
-+  {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
-+  {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
-+  {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"EXTERNAL_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"EXTERNAL_LANGUAGE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"},
-+  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created"},
-+  {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified"},
-+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"},
-+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO stat_fields_info[]=
-+{
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-+  {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, "Non_unique"},
-+  {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name"},
-+  {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, "Seq_in_index"},
-+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name"},
-+  {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation"},
-+  {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, "Cardinality"},
-+  {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, "Sub_part"},
-+  {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed"},
-+  {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
-+  {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type"},
-+  {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO view_fields_info[]=
-+{
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO user_privileges_fields_info[]=
-+{
-+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO schema_privileges_fields_info[]=
-+{
-+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO table_privileges_fields_info[]=
-+{
-+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO column_privileges_fields_info[]=
-+{
-+  {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO table_constraints_fields_info[]=
-+{
-+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO key_column_usage_fields_info[]=
-+{
-+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0},
-+  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0},
-+  {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO table_names_fields_info[]=
-+{
-+  {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_"},
-+  {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+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 triggers_fields_info[]=
-+{
-+  {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"TRIGGER_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"TRIGGER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger"},
-+  {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event"},
-+  {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"EVENT_OBJECT_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"EVENT_OBJECT_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
-+  {"ACTION_ORDER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
-+  {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement"},
-+  {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing"},
-+  {"ACTION_REFERENCE_OLD_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"ACTION_REFERENCE_NEW_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
-+  {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
-+  {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
-+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
-+  {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+ST_FIELD_INFO variables_fields_info[]=
-+{
-+  {"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
-+  {"Value", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, "Value"},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
-+
-+
-+/*
-+  Description of ST_FIELD_INFO in table.h
-+*/
-+
-+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},
-+  {"COLLATIONS", collation_fields_info, create_schema_table, 
-+   fill_schema_collation, make_old_format, 0, -1, -1, 0},
-+  {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
-+   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0},
-+  {"COLUMNS", columns_fields_info, create_schema_table, 
-+   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
-+  {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
-+    fill_schema_column_privileges, 0, 0, -1, -1, 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},
-+  {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
-+   fill_open_tables, make_old_format, 0, -1, -1, 1},
-+  {"ROUTINES", proc_fields_info, create_schema_table, 
-+    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
-+  {"SCHEMATA", schema_fields_info, create_schema_table,
-+   fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0},
-+  {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-+    fill_schema_schema_privileges, 0, 0, -1, -1, 0},
-+  {"STATISTICS", stat_fields_info, create_schema_table, 
-+    get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0},
-+  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
-+   make_old_format, 0, -1, -1, 1},
-+  {"TABLES", tables_fields_info, create_schema_table, 
-+   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
-+  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
-+    get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
-+  {"TABLE_NAMES", table_names_fields_info, create_schema_table,
-+   get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
-+  {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
-+    fill_schema_table_privileges, 0, 0, -1, -1, 0},
-+  {"TRIGGERS", triggers_fields_info, create_schema_table,
-+   get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
-+  {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-+    fill_schema_user_privileges, 0, 0, -1, -1, 0},
-+  {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-+   make_old_format, 0, -1, -1, 1},
-+  {"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}
-+};
-+
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class List_iterator_fast<char>;
-+template class List<char>;
-+#endif




More information about the Pkg-mysql-commits mailing list