List:Commits« Previous MessageNext Message »
From:Stewart Smith Date:December 22 2005 1:19am
Subject:bk commit into 5.1 tree (stewart:1.1979)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of stewart. When stewart does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1979 05/12/22 12:19:06 stewart@stripped +11 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.1-dd-new
  into  mysql.com:/home/stewart/Documents/MySQL/5.1/dd-new-merge

  sql/sql_yacc.yy
    1.422 05/12/22 12:19:02 stewart@stripped +0 -0
    merge

  sql/sql_lex.h
    1.206 05/12/22 12:19:02 stewart@stripped +0 -0
    merge

  sql/share/errmsg.txt
    1.54 05/12/22 12:19:02 stewart@stripped +14 -0
    merge errmsg codes from ndb-dd clone

  sql/sql_parse.cc
    1.483 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.344 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/lex.h
    1.148 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/handler.h
    1.167 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.h
    1.100 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.218 05/12/22 11:29:11 stewart@stripped +0 -0
    Auto merged

  sql/Makefile.am
    1.122 05/12/22 11:29:10 stewart@stripped +0 -0
    Auto merged

  libmysqld/Makefile.am
    1.72 05/12/22 11:29:10 stewart@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	stewart
# Host:	willster.(none)
# Root:	/home/stewart/Documents/MySQL/5.1/dd-new-merge/RESYNC

--- 1.121/sql/Makefile.am	2005-11-15 02:11:20 +11:00
+++ 1.122/sql/Makefile.am	2005-12-22 11:29:10 +11:00
@@ -46,6 +46,7 @@
                         @yassl_libs@ @openssl_libs@
 noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
 			item_strfunc.h item_timefunc.h item_uniq.h \
+			item_xmlfunc.h \
 			item_create.h item_subselect.h item_row.h \
 			mysql_priv.h item_geofunc.h sql_bitmap.h \
 			procedure.h sql_class.h sql_lex.h sql_list.h \
@@ -62,12 +63,12 @@
 			sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
 			parse_file.h sql_view.h	sql_trigger.h \
 			sql_array.h sql_cursor.h \
-			sql_plugin.h
+			sql_plugin.h authors.h
 mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			item.cc item_sum.cc item_buff.cc item_func.cc \
 			item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
 			thr_malloc.cc item_create.cc item_subselect.cc \
-			item_row.cc item_geofunc.cc \
+			item_row.cc item_geofunc.cc item_xmlfunc.cc \
 			field.cc strfunc.cc key.cc sql_class.cc sql_list.cc \
 			net_serv.cc protocol.cc sql_state.c \
 			lock.cc my_lock.c \
@@ -101,9 +102,7 @@
 			ha_innodb.h  ha_berkeley.h  ha_archive.h \
 			ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
 			ha_blackhole.h  ha_federated.h  ha_ndbcluster.h \
-			ha_partition.cc ha_partition.h \
-			examples/ha_tina.cc examples/ha_example.cc \
-			examples/ha_tina.h  examples/ha_example.h
+			ha_partition.cc ha_partition.h
 mysqld_DEPENDENCIES =	@mysql_se_objs@
 gen_lex_hash_SOURCES =	gen_lex_hash.cc
 gen_lex_hash_LDADD =	$(LDADD) $(CXXLDFLAGS)
@@ -118,23 +117,23 @@
 			@DEFS@
 
 BUILT_SOURCES =		sql_yacc.cc sql_yacc.h lex_hash.h
-EXTRA_DIST =		udf_example.cc $(BUILT_SOURCES)
+EXTRA_DIST =		udf_example.cc handlerton-win.cc $(BUILT_SOURCES)
 DISTCLEANFILES =        lex_hash.h
 AM_YFLAGS =		-d
 
 mysql_tzinfo_to_sql.cc:
 	rm -f mysql_tzinfo_to_sql.cc
-	@LN_CP_F@ tztime.cc mysql_tzinfo_to_sql.cc
+	@LN_CP_F@ $(srcdir)/tztime.cc mysql_tzinfo_to_sql.cc
 
 link_sources: mysql_tzinfo_to_sql.cc
 	rm -f mini_client_errors.c
-	@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
+	@LN_CP_F@ $(top_srcdir)/libmysql/errmsg.c mini_client_errors.c
 	rm -f pack.c
-	@LN_CP_F@ ../sql-common/pack.c pack.c
+	@LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c
 	rm -f client.c
-	@LN_CP_F@ ../sql-common/client.c client.c
+	@LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c
 	rm -f my_time.c
-	@LN_CP_F@ ../sql-common/my_time.c my_time.c
+	@LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c
 
 mysql_tzinfo_to_sql.o:	$(mysql_tzinfo_to_sql_SOURCES)
 			$(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $<

--- 1.166/sql/handler.h	2005-11-15 02:11:21 +11:00
+++ 1.167/sql/handler.h	2005-12-22 11:29:11 +11:00
@@ -42,6 +42,7 @@
 #define HA_ADMIN_REJECT          -6
 #define HA_ADMIN_TRY_ALTER       -7
 #define HA_ADMIN_WRONG_CHECKSUM  -8
+#define HA_ADMIN_NOT_BASE_TABLE  -9
 
 /* Bits in table_flags() to show what database can do */
 
@@ -85,6 +86,7 @@
 #define HA_CAN_BIT_FIELD       (1 << 28) /* supports bit fields */
 #define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
+#define HA_NO_COPY_ON_ALTER    (1 << 31)
 
 /* Flags for partition handlers */
 #define HA_CAN_PARTITION       (1 << 0) /* Partition support */
@@ -176,7 +178,7 @@
 /* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
 #define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
 
-enum db_type
+enum legacy_db_type
 {
   DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
   DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
@@ -189,7 +191,7 @@
   DB_TYPE_BLACKHOLE_DB,
   DB_TYPE_PARTITION_DB,
   DB_TYPE_BINLOG,
-  DB_TYPE_DEFAULT // Must be last
+  DB_TYPE_DEFAULT=127 // Must be last
 };
 
 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
@@ -310,10 +312,12 @@
 
 struct st_table;
 typedef struct st_table TABLE;
+typedef struct st_table_share TABLE_SHARE;
 struct st_foreign_key_info;
 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
-typedef bool (stat_print_fn)(THD *thd, const char *type, const char *file,
-                             const char *status);
+typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
+                             const char *file, uint file_len,
+                             const char *status, uint status_len);
 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
 
 /*
@@ -330,6 +334,13 @@
 typedef struct
 {
   /*
+    handlerton structure version
+   */
+  const int interface_version;
+#define MYSQL_HANDLERTON_INTERFACE_VERSION 0x0000
+
+
+  /*
     storage engine name as it should be printed to a user
   */
   const char *name;
@@ -348,7 +359,7 @@
     Historical number used for frm file to determine the correct storage engine.
     This is going away and new engines will just use "name" for this.
   */
-  enum db_type db_type;
+  enum legacy_db_type db_type;
   /* 
     Method that initizlizes a storage engine
   */
@@ -410,31 +421,30 @@
    void *(*create_cursor_read_view)();
    void (*set_cursor_read_view)(void *);
    void (*close_cursor_read_view)(void *);
-   handler *(*create)(TABLE *table);
+   handler *(*create)(TABLE_SHARE *table);
    void (*drop_database)(char* path);
    int (*panic)(enum ha_panic_function flag);
-   int (*release_temporary_latches)(THD *thd);
-   int (*update_statistics)();
    int (*start_consistent_snapshot)(THD *thd);
    bool (*flush_logs)();
    bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat);
-   int (*repl_report_sent_binlog)(THD *thd, char *log_file_name,
-                                  my_off_t end_offset);
    uint32 flags;                                /* global handler flags */
 } handlerton;
 
+extern const handlerton default_hton;
+
 struct show_table_alias_st {
   const char *alias;
-  const char *type;
+  enum legacy_db_type type;
 };
 
 /* Possible flags of a handlerton */
 #define HTON_NO_FLAGS                 0
 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
-#define HTON_ALTER_NOT_SUPPORTED     (1 << 1)
-#define HTON_CAN_RECREATE            (1 << 2)
-#define HTON_FLUSH_AFTER_RENAME      (1 << 3)
-#define HTON_NOT_USER_SELECTABLE     (1 << 4)
+#define HTON_ALTER_NOT_SUPPORTED     (1 << 1) //Engine does not support alter
+#define HTON_CAN_RECREATE            (1 << 2) //Delete all is used fro truncate
+#define HTON_HIDDEN                  (1 << 3) //Engine does not appear in lists
+#define HTON_FLUSH_AFTER_RENAME      (1 << 4)
+#define HTON_NOT_USER_SELECTABLE     (1 << 5)
 
 typedef struct st_thd_trans
 {
@@ -492,7 +502,7 @@
   char* part_comment;
   char* data_file_name;
   char* index_file_name;
-  enum db_type engine_type;
+  handlerton *engine_type;
   enum partition_state part_state;
   uint16 nodegroup_id;
   
@@ -500,7 +510,7 @@
   : part_max_rows(0), part_min_rows(0), partition_name(NULL),
     tablespace_name(NULL), range_value(0), part_comment(NULL),
     data_file_name(NULL), index_file_name(NULL),
-    engine_type(DB_TYPE_UNKNOWN),part_state(PART_NORMAL),
+    engine_type(NULL),part_state(PART_NORMAL),
     nodegroup_id(UNDEF_NODEGROUP)
   {
     subpartitions.empty();
@@ -563,7 +573,7 @@
   key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
   key_map some_fields_in_PF;
 
-  enum db_type default_engine_type;
+  handlerton *default_engine_type;
   Item_result part_result_type;
   partition_type part_type;
   partition_type subpart_type;
@@ -604,7 +614,7 @@
     part_info_string(NULL),
     part_func_string(NULL), subpart_func_string(NULL),
     curr_part_elem(NULL), current_partition(NULL),
-    default_engine_type(DB_TYPE_UNKNOWN),
+    default_engine_type(NULL),
     part_result_type(INT_RESULT),
     part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
     part_info_len(0), part_func_len(0), subpart_func_len(0),
@@ -679,7 +689,7 @@
   ulong raid_chunksize;
   ulong used_fields;
   SQL_LIST merge_list;
-  enum db_type db_type;
+  handlerton *db_type;
   enum row_type row_type;
   uint null_bits;                       /* NULL bits at start of record */
   uint options;				/* OR of HA_CREATE_ options */
@@ -714,6 +724,9 @@
 bool is_partition_in_list(char *part_name, List<char> list_part_names);
 bool is_partitions_in_table(partition_info *new_part_info,
                             partition_info *old_part_info);
+bool check_reorganise_list(partition_info *new_part_info,
+                           partition_info *old_part_info,
+                           List<char> list_part_names);
 bool set_up_defaults_for_partitioning(partition_info *part_info,
                                       handler *file,
                                       ulonglong max_rows,
@@ -724,7 +737,7 @@
                          uint32 *old_part_id, uint32 *new_part_id);
 int get_part_for_delete(const byte *buf, const byte *rec0,
                         partition_info *part_info, uint32 *part_id);
-bool check_partition_info(partition_info *part_info,enum db_type eng_type,
+bool check_partition_info(partition_info *part_info,handlerton *eng_type,
                           handler *file, ulonglong max_rows);
 bool fix_partition_func(THD *thd, const char *name, TABLE *table);
 char *generate_partition_syntax(partition_info *part_info,
@@ -738,8 +751,9 @@
                                KEY *key_info,
                                const key_range *key_spec,
                                part_id_range *part_spec);
-bool mysql_unpack_partition(THD *thd, uchar *part_buf, uint part_info_len,
-                            TABLE* table, enum db_type default_db_type);
+bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
+                            uint part_info_len, TABLE *table,
+                            handlerton *default_db_type);
 #endif
 
 
@@ -839,7 +853,8 @@
  friend class ha_partition;
 #endif
  protected:
-  struct st_table *table;		/* The table definition */
+  struct st_table_share *table_share;   /* The table definition */
+  struct st_table *table;               /* The current open table */
 
   virtual int index_init(uint idx, bool sorted) { active_index=idx; return 0; }
   virtual int index_end() { active_index=MAX_KEY; return 0; }
@@ -900,8 +915,8 @@
   MY_BITMAP *read_set;
   MY_BITMAP *write_set;
 
-  handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
-    ht(ht_arg),
+  handler(const handlerton *ht_arg, TABLE_SHARE *share_arg)
+    :table_share(share_arg), ht(ht_arg),
     ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
     delete_length(0), auto_increment_value(0),
     records(0), deleted(0), mean_rec_length(0),
@@ -913,16 +928,19 @@
     {}
   virtual ~handler(void)
   {
-    ha_deallocate_read_write_set();
     /* TODO: DBUG_ASSERT(inited == NONE); */
   }
   virtual int ha_initialise();
-  int ha_open(const char *name, int mode, int test_if_locked);
+  int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
   bool update_auto_increment();
   virtual void print_error(int error, myf errflag);
   virtual bool get_error_message(int error, String *buf);
   uint get_dup_key(int error);
-  void change_table_ptr(TABLE *table_arg) { table=table_arg; }
+  void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+  {
+    table= table_arg;
+    table_share= share;
+  }
   virtual double scan_time()
     { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
   virtual double read_time(uint index, uint ranges, ha_rows rows)
@@ -1108,7 +1126,6 @@
   }
   void ha_set_primary_key_in_read_set();
   int ha_allocate_read_write_set(ulong no_fields);
-  void ha_deallocate_read_write_set();
   void ha_clear_all_set();
   uint get_index(void) const { return active_index; }
   virtual int open(const char *name, int mode, uint test_if_locked)=0;
@@ -1242,7 +1259,7 @@
                                    key_range *max_key)
     { return (ha_rows) 10; }
   virtual void position(const byte *record)=0;
-  virtual void info(uint)=0;
+  virtual void info(uint)=0; // see my_base.h for full description
   virtual int extra(enum ha_extra_function operation)
   { return 0; }
   virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
@@ -1343,6 +1360,7 @@
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   virtual ulong partition_flags(void) const { return 0;}
   virtual int get_default_no_partitions(ulonglong max_rows) { return 1;}
+  virtual void set_part_info(partition_info *part_info) { return; }
 #endif
   virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
   virtual ulong index_ddl_flags(KEY *wanted_index) const
@@ -1482,29 +1500,56 @@
 #define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
 
 /* lookups */
-enum db_type ha_resolve_by_name(const char *name, uint namelen);
-const char *ha_get_storage_engine(enum db_type db_type);
-handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type);
-enum db_type ha_checktype(THD *thd, enum db_type database_type,
+handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name);
+handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
+const char *ha_get_storage_engine(enum legacy_db_type db_type);
+handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
+                         handlerton *db_type);
+handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
                           bool no_substitute, bool report_error);
-bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag);
+
+
+inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
+{
+  return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
+}
+
+inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
+{
+  return db_type == NULL ? "UNKNOWN" : db_type->name;
+}
+
+inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
+{
+  return db_type == NULL ? FALSE : test(db_type->flags & flag);
+}
+
+inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
+{
+  return (db_type && db_type->create) ? 
+         (db_type->state == SHOW_OPTION_YES) : FALSE;
+}
 
 /* basic stuff */
 int ha_init(void);
+int ha_register_builtin_plugins();
+int ha_initialize_handlerton(handlerton *hton);
+
 TYPELIB *ha_known_exts(void);
 int ha_panic(enum ha_panic_function flag);
 int ha_update_statistics();
 void ha_close_connection(THD* thd);
-my_bool ha_storage_engine_is_enabled(enum db_type database_type);
-bool ha_flush_logs(enum db_type db_type=DB_TYPE_DEFAULT);
+bool ha_flush_logs(handlerton *db_type);
 void ha_drop_database(char* path);
-int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
+int ha_create_table(THD *thd, const char *path,
+                    const char *db, const char *table_name,
+                    HA_CREATE_INFO *create_info,
 		    bool update_create_info);
-int ha_delete_table(THD *thd, enum db_type db_type, const char *path,
-                    const char *alias, bool generate_warning);
+int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
+                    const char *db, const char *alias, bool generate_warning);
 
 /* statistics and info */
-bool ha_show_status(THD *thd, enum db_type db_type, enum ha_stat_type stat);
+bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
 
 /* discovery */
 int ha_create_table_from_engine(THD* thd, const char *db, const char *name);

--- 1.147/sql/lex.h	2005-11-15 02:11:21 +11:00
+++ 1.148/sql/lex.h	2005-12-22 11:29:11 +11:00
@@ -114,6 +114,7 @@
   { "CLIENT",		SYM(CLIENT_SYM)},
   { "CLOSE",		SYM(CLOSE_SYM)},
   { "COALESCE",		SYM(COALESCE)},
+  { "CODE",             SYM(CODE_SYM)},
   { "COLLATE",		SYM(COLLATE_SYM)},
   { "COLLATION",	SYM(COLLATION_SYM)},
   { "COLUMN",		SYM(COLUMN_SYM)},
@@ -647,6 +648,7 @@
   { "EQUALS",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)},
   { "EXTERIORRING",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_exteriorring)},
   { "EXTRACT",		SYM(EXTRACT_SYM)},
+  { "EXTRACTVALUE",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_xml_extractvalue)},
   { "EXP",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)},
   { "EXPORT_SET",	SYM(EXPORT_SET)},
   { "FIELD",		SYM(FIELD_FUNC)},	/* For compability */
@@ -801,6 +803,7 @@
   { "UNHEX",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_unhex)},
   { "UNIQUE_USERS",	SYM(UNIQUE_USERS)},
   { "UNIX_TIMESTAMP",	SYM(UNIX_TIMESTAMP)},
+  { "UPDATEXML",	F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_xml_update)},
   { "UPPER",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
   { "UUID",		F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)},
   { "VARIANCE",		SYM(VARIANCE_SYM)},

--- 1.343/sql/mysql_priv.h	2005-11-15 02:11:21 +11:00
+++ 1.344/sql/mysql_priv.h	2005-12-22 11:29:11 +11:00
@@ -42,8 +42,19 @@
 
 /* TODO convert all these three maps to Bitmap classes */
 typedef ulonglong table_map;          /* Used for table bits in join */
-typedef Bitmap<64> key_map;           /* Used for finding keys */
+#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;
@@ -95,6 +106,7 @@
 #define MAX_FIELDS_BEFORE_HASH	32
 #define USER_VARS_HASH_SIZE     16
 #define STACK_MIN_SIZE		8192	// 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.
@@ -519,8 +531,9 @@
 bool insert_precheck(THD *thd, TABLE_LIST *tables);
 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
                            TABLE_LIST *create_table);
-bool default_view_definer(Security_context *sctx, st_lex_user *definer);
 
+bool get_default_definer(THD *thd, LEX_USER *definer);
+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
 
 enum enum_mysql_completiontype {
   ROLLBACK_RELEASE=-2, ROLLBACK=1,  ROLLBACK_AND_CHAIN=7,
@@ -594,8 +607,8 @@
 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);
+bool quick_rm_table(handlerton *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 mysql_change_db(THD *thd,const char *name,bool no_access_check);
@@ -626,7 +639,10 @@
 
 bool table_cache_init(void);
 void table_cache_free(void);
-uint cached_tables(void);
+bool table_def_init(void);
+void table_def_free(void);
+uint cached_open_tables(void);
+uint cached_table_definitions(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, 
@@ -671,6 +687,7 @@
 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);
 
@@ -738,7 +755,7 @@
 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,
+bool mysql_rename_table(handlerton *base,
 			const char *old_db,
 			const char * old_name,
 			const char *new_db,
@@ -774,15 +791,18 @@
                   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);
+uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
+                          bool tmp_table);
+TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
+                             uint key_length, uint db_flags, int *error);
+void release_table_share(TABLE_SHARE *share, enum release_type type);
+TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
 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);
@@ -803,18 +823,15 @@
                      bool check_privileges, bool register_tree_change);
 Field *
 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
-                        const char *name, const char *item_name,
-                        const char *table_name, const char *db_name,
-                        uint length, Item **ref,
-                        bool check_grants_table, bool check_grants_view,
-                        bool allow_rowid,
+                        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 check_grants, bool allow_rowid,
-                    uint *cached_field_index_ptr,
-                    Security_context *sctx);
+find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
+                    bool allow_rowid, uint *cached_field_index_ptr);
 Field *
 find_field_in_table_sef(TABLE *table, const char *name);
 
@@ -864,6 +881,10 @@
 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,
@@ -902,7 +923,8 @@
 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);
+int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
+                   bool is_locked);
 /* mysql_ha_flush mode_flags bits */
 #define MYSQL_HA_CLOSE_FINAL        0x00
 #define MYSQL_HA_REOPEN_ON_USAGE    0x01
@@ -928,8 +950,9 @@
 				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);
-Name_resolution_context *make_join_on_context(THD *thd, TABLE_LIST *left_op,
-                                              TABLE_LIST *right_op);
+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);
@@ -974,7 +997,8 @@
 		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);
+void wait_for_condition(THD *thd, pthread_mutex_t *mutex,
+                        pthread_cond_t *cond);
 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);
@@ -982,7 +1006,7 @@
 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);
+bool rm_temporary_table(handlerton *base, char *path);
 void free_io_cache(TABLE *entry);
 void intern_close_table(TABLE *entry);
 bool close_thread_table(THD *thd, TABLE **table_ptr);
@@ -993,9 +1017,12 @@
                                const char *db_name,
                                const char *table_name);
 TABLE_LIST *unique_table(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);
+TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
+TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list);
+bool close_temporary_table(THD *thd, TABLE_LIST *table_list);
+void close_temporary_table(THD *thd, TABLE *table, bool free_share,
+                           bool delete_table);
+void close_temporary(TABLE *table, bool free_share, 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);
@@ -1074,7 +1101,7 @@
 #endif
 void mysql_print_status();
 /* key.cc */
-int find_ref_key(TABLE *form,Field *field, uint *offset);
+int find_ref_key(KEY *key, uint key_count, Field *field, uint *key_length);
 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);
@@ -1114,8 +1141,8 @@
 uint check_word(TYPELIB *lib, const char *val, const char *end,
 		const char **end_of_word);
 
-bool is_keyword(const char *name, uint len);
 
+bool is_keyword(const char *name, uint len);
 
 #define MY_DB_OPT_FILE "db.opt"
 bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
@@ -1164,7 +1191,7 @@
 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 table_cache_size, table_def_size;
 extern ulong max_connections,max_connect_errors, connect_timeout;
 extern ulong slave_net_timeout, slave_trans_retries;
 extern uint max_user_connections;
@@ -1193,14 +1220,14 @@
 extern bool mysql_proc_table_exists;
 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_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
 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_routine_creators;
+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;
@@ -1307,6 +1334,10 @@
 extern SHOW_COMP_OPTION have_partition_db;
 #endif
 
+extern handlerton myisam_hton;
+extern handlerton myisammrg_hton;
+extern handlerton heap_hton;
+
 extern SHOW_COMP_OPTION have_isam;
 extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink;
 extern SHOW_COMP_OPTION have_query_cache;
@@ -1359,23 +1390,36 @@
 
 void unireg_init(ulong options);
 void unireg_end(void);
-bool mysql_create_frm(THD *thd, my_string file_name,
+bool mysql_create_frm(THD *thd, const char *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,
+int rea_create_table(THD *thd, const char *path,
+                     const char *db, const char *table_name,
                      HA_CREATE_INFO *create_info,
-		     List<create_field> &create_field,
-		     uint key_count,KEY *key_info, handler *file);
+  		     List<create_field> &create_field,
+                     uint key_count,KEY *key_info,
+                     handler *file);
 int format_number(uint inputflag,uint max_length,my_string pos,uint length,
 		  my_string *errpos);
+
+/* table.cc */
+TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
+                               uint key_length);
+void init_tmp_table_share(TABLE_SHARE *share, const char *key, uint key_length,
+                          const char *table_name, const char *path);
+void free_table_share(TABLE_SHARE *share);
+int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags);
+void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg);
+int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
+                          uint db_stat, uint prgflag, uint ha_open_flags,
+                          TABLE *outparam);
 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 closefrm(TABLE *table, bool free_share);
 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);
@@ -1428,14 +1472,14 @@
 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(List<String> &strings);
+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,
+int create_frm(THD *thd, const 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);

--- 1.205/sql/sql_lex.h	2005-11-15 02:11:22 +11:00
+++ 1.206/sql/sql_lex.h	2005-12-22 12:19:02 +11:00
@@ -92,9 +92,10 @@
   SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER,
   SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
   SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
+  SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
   SQLCOM_ALTER_TABLESPACE,
   SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
-  SQLCOM_SHOW_AUTHORS,
+  SQLCOM_SHOW_AUTHORS, SQLCOM_SHOW_PLUGINS,
   /* This should be the last !!! */
 
   SQLCOM_END
@@ -460,7 +461,7 @@
   void set_limit(st_select_lex *values);
   void set_thd(THD *thd_arg) { thd= thd_arg; }
 
-  friend void lex_start(THD *thd, uchar *buf, uint length);
+  friend void lex_start(THD *thd, const uchar *buf, uint length);
   friend int subselect_union_engine::exec();
 
   List<Item> *get_unit_column_types();
@@ -532,6 +533,8 @@
   ulong table_join_options;
   uint in_sum_expr;
   uint select_number; /* number of select (used for EXPLAIN) */
+  int nest_level;     /* nesting level of select */
+  Item_sum *inner_sum_func_list; /* list of sum func in nested selects */ 
   uint with_wild; /* item list contain '*' */
   bool  braces;   	/* SELECT ... UNION (SELECT ... ) <- this braces */
   /* TRUE when having fix field called in processing of this SELECT */
@@ -627,7 +630,7 @@
   void cut_subtree() { slave= 0; }
   bool test_limit();
 
-  friend void lex_start(THD *thd, uchar *buf, uint length);
+  friend void lex_start(THD *thd, const uchar *buf, uint length);
   st_select_lex() {}
   void make_empty_select()
   {
@@ -723,11 +726,11 @@
   SELECT_LEX *current_select;
   /* list of all SELECT_LEX */
   SELECT_LEX *all_selects_list;
-  uchar *buf;			/* The beginning of string, used by SPs */
-  uchar *ptr,*tok_start,*tok_end,*end_of_query;
+  const uchar *buf;		/* The beginning of string, used by SPs */
+  const uchar *ptr,*tok_start,*tok_end,*end_of_query;
   
   /* The values of tok_start/tok_end as they were one call of yylex before */
-  uchar *tok_start_prev, *tok_end_prev;
+  const uchar *tok_start_prev, *tok_end_prev;
 
   char *length,*dec,*change,*name;
   char *help_arg;
@@ -755,12 +758,17 @@
   TABLE_LIST **query_tables_last;
   /* store original leaf_tables for INSERT SELECT and PS/SP */
   TABLE_LIST *leaf_tables_insert;
-  st_lex_user *create_view_definer;
-  char *create_view_start;
-  char *create_view_select_start;
+  /* Position (first character index) of SELECT of CREATE VIEW statement */
+  uint create_view_select_start;
   /* Partition info structure filled in by PARTITION BY parse part */
   partition_info *part_info;
 
+  /*
+    The definer of the object being created (view, trigger, stored routine).
+    I.e. the value of DEFINER clause.
+  */
+  LEX_USER *definer;
+
   List<key_part_spec> col_list;
   List<key_part_spec> ref_list;
   List<String>	      interval_list;
@@ -790,12 +798,23 @@
 
   SQL_LIST	      proc_list, auxilliary_table_list, save_list;
   create_field	      *last_field;
+  Item_sum *in_sum_func;
   udf_func udf;
   HA_CHECK_OPT   check_opt;			// check/repair options
   HA_CREATE_INFO create_info;
   LEX_MASTER_INFO mi;				// used by CHANGE MASTER
   USER_RESOURCES mqh;
   ulong type;
+  /*
+    This variable is used in post-parse stage to declare that sum-functions,
+    or functions which have sense only if GROUP BY is present, are allowed.
+    For example in a query
+    SELECT ... FROM ...WHERE MIN(i) == 1 GROUP BY ... HAVING MIN(i) > 2
+    MIN(i) in the WHERE clause is not allowed in the opposite to MIN(i)
+    in the HAVING clause. Due to possible nesting of select construct
+    the variable can contain 0 or 1 for each nest level.
+  */
+  nesting_map allow_sum_func;
   enum_sql_command sql_command, orig_sql_command;
   thr_lock_type lock_option;
   enum SSL_type ssl_type;			/* defined in violite.h */
@@ -814,6 +833,7 @@
   uint grant, grant_tot_col, which_columns;
   uint fk_delete_opt, fk_update_opt, fk_match_option;
   uint slave_thd_opt, start_transaction_opt;
+  int nest_level;
   /*
     In LEX representing update which were transformed to multi-update
     stores total number of tables. For LEX representing multi-delete
@@ -908,6 +928,14 @@
   SQL_LIST trg_table_fields;
 
   /*
+    trigger_definition_begin points to the beginning of the word "TRIGGER" in
+    CREATE TRIGGER statement. This is used to add possibly omitted DEFINER
+    clause to the trigger definition statement before dumping it to the
+    binlog. 
+  */
+  const char *trigger_definition_begin;
+
+  /*
     If non-0 then indicates that query requires prelocking and points to
     next_global member of last own element in query table list (i.e. last
     table which was not added to it as part of preparation to prelocking).
@@ -919,7 +947,7 @@
     Pointers to part of LOAD DATA statement that should be rewritten
     during replication ("LOCAL 'filename' REPLACE INTO" part).
   */
-  uchar *fname_start, *fname_end;
+  const uchar *fname_start, *fname_end;
 
   /*
     Reference to a struct that contains information in various commands
@@ -1018,9 +1046,9 @@
   }
   void cleanup_after_one_table_open();
 
-  void push_context(Name_resolution_context *context)
+  bool push_context(Name_resolution_context *context)
   {
-    context_stack.push_front(context);
+    return context_stack.push_front(context);
   }
 
   void pop_context()
@@ -1052,7 +1080,7 @@
 
 extern void lex_init(void);
 extern void lex_free(void);
-extern void lex_start(THD *thd, uchar *buf,uint length);
+extern void lex_start(THD *thd, const uchar *buf, uint length);
 extern void lex_end(LEX *lex);
 extern int yylex(void *arg, void *yythd);
 

--- 1.482/sql/sql_parse.cc	2005-11-15 02:11:22 +11:00
+++ 1.483/sql/sql_parse.cc	2005-12-22 11:29:11 +11:00
@@ -182,12 +182,24 @@
 */
 inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
 {
-  return rpl_filter->is_on() && tables &&
+  return rpl_filter->is_on() && tables && !thd->spcont &&
          !rpl_filter->tables_ok(thd->db, 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;
+}
+
 static HASH hash_user_connections;
 
 static int get_or_create_user_conn(THD *thd, const char *user,
@@ -779,6 +791,9 @@
 
   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
   {
@@ -1079,6 +1094,7 @@
   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);
@@ -1092,7 +1108,6 @@
     int error;
     NET *net= &thd->net;
     Security_context *sctx= thd->security_ctx;
-    thd->thread_stack= (char*) &thd;
     net->no_send_error= 0;
 
     if ((error=check_connection(thd)))
@@ -1164,6 +1179,7 @@
       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 */
@@ -1183,6 +1199,7 @@
   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
@@ -1966,7 +1983,8 @@
 	    uptime,
 	    (int) thread_count, (ulong) thd->query_id,
             (ulong) thd->status_var.long_query_count,
-	    thd->status_var.opened_tables, refresh_version, cached_tables(),
+	    thd->status_var.opened_tables, refresh_version,
+            cached_open_tables(),
 	    (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) :
 	     (double) 0));
 #ifdef SAFEMALLOC
@@ -2360,7 +2378,7 @@
     mysql_reset_errors(thd, 0);
 
 #ifdef HAVE_REPLICATION
-  if (thd->slave_thread)
+  if (unlikely(thd->slave_thread))
   {
     /*
       Check if statment should be skipped because of slave filtering
@@ -2386,29 +2404,21 @@
       reset_one_shot_variables(thd);
       DBUG_RETURN(0);
     }
-#ifndef TO_BE_DELETED
-    /*
-      This is a workaround to deal with the shortcoming in 3.23.44-3.23.46
-      masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK()
-      as DO RELEASE_LOCK()
-    */
-    if (lex->sql_command == SQLCOM_SELECT)
-    {
-      lex->sql_command = SQLCOM_DO;
-      lex->insert_list = &select_lex->item_list;
-    }
-#endif
   }
+  else
 #endif /* HAVE_REPLICATION */
 
   /*
-    When option readonly is set deny operations which change tables.
-    Except for the replication thread and the 'super' users.
+    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->slave_thread ||
-        (thd->security_ctx->master_access & SUPER_ACL)) &&
-      uc_update_queries[lex->sql_command])
+      !(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_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);
@@ -2604,7 +2614,8 @@
       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:
@@ -2616,6 +2627,8 @@
       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:
@@ -3109,6 +3122,8 @@
         mysql_bin_log.write(&qinfo);
       }
     }
+    select_lex->table_list.first= (byte*) first_table;
+    lex->query_tables=all_tables;
     break;
   }
   case SQLCOM_CHECK:
@@ -3119,6 +3134,8 @@
       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:
@@ -3139,6 +3156,8 @@
         mysql_bin_log.write(&qinfo);
       }
     }
+    select_lex->table_list.first= (byte*) first_table;
+    lex->query_tables=all_tables;
     break;
   }
 
@@ -3162,6 +3181,8 @@
         mysql_bin_log.write(&qinfo);
       }
     }
+    select_lex->table_list.first= (byte*) first_table;
+    lex->query_tables=all_tables;
     break;
   }
   case SQLCOM_UPDATE:
@@ -3198,13 +3219,24 @@
 
 #ifdef HAVE_REPLICATION
     /* Check slave filtering rules */
-    if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
+    if (unlikely(thd->slave_thread))
     {
-      /* we warn the slave SQL thread */
-      my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
-      break;
+      if (all_tables_not_ok(thd, all_tables))
+      {
+        /* we warn the slave SQL thread */
+        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+        break;
+      }
     }
+    else
 #endif /* HAVE_REPLICATION */
+    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;
+    }
 
     res= mysql_multi_update(thd, all_tables,
                             &select_lex->item_list,
@@ -3646,8 +3678,6 @@
       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;
   }
@@ -3656,7 +3686,8 @@
     if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
       break;
 #ifdef HAVE_DLOPEN
-    if (sp_find_function(thd, lex->spname))
+    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;
@@ -4007,8 +4038,8 @@
     break;
   }
   case SQLCOM_SAVEPOINT:
-    if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
-        !opt_using_transactions)
+    if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+          thd->in_sub_stmt) || !opt_using_transactions)
       send_ok(thd);
     else
     {
@@ -4061,7 +4092,7 @@
 
     if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
     {
-      if (! thd->db)
+      if (!thd->db)
       {
         my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
         delete lex->sphead;
@@ -4102,14 +4133,6 @@
       }
     }
 #endif
-    if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
-	!(lex->sphead->m_flags & sp_head::HAS_RETURN))
-    {
-      my_error(ER_SP_NORETURN, MYF(0), name);
-      delete lex->sphead;
-      lex->sphead= 0;
-      goto error;
-    }
 
     /*
       We need to copy name and db in order to use them for
@@ -4190,7 +4213,8 @@
         By this moment all needed SPs should be in cache so no need to look 
         into DB. 
       */
-      if (!(sp= sp_find_procedure(thd, lex->spname, TRUE)))
+      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);
@@ -4280,18 +4304,6 @@
           So just execute the statement.
         */
 	res= sp->execute_procedure(thd, &lex->value_list);
-        if (mysql_bin_log.is_open() &&
-            (sp->m_chistics->daccess == SP_CONTAINS_SQL ||
-             sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
-        {
-          if (res)
-            push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                         ER_FAILED_ROUTINE_BREAK_BINLOG,
-			 ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
-          else
-            thd->clear_error();
-        }
-
 	/*
           If warnings have been cleared, we have to clear total_warn_count
           too, otherwise the clients get confused.
@@ -4326,9 +4338,11 @@
 
       memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
       if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
-	sp= sp_find_procedure(thd, lex->spname);
+        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
+                            &thd->sp_proc_cache, FALSE);
       else
-	sp= sp_find_function(thd, lex->spname);
+        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
+                            &thd->sp_func_cache, FALSE);
       mysql_reset_errors(thd, 0);
       if (! sp)
       {
@@ -4350,7 +4364,8 @@
         if (end_active_trans(thd)) 
           goto error;
 	memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
-        if (!trust_routine_creators &&  mysql_bin_log.is_open() &&
+        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))
@@ -4361,6 +4376,12 @@
         }
         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)
             result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
           else
@@ -4397,9 +4418,11 @@
       char *db, *name;
 
       if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-	sp= sp_find_procedure(thd, lex->spname);
+        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
+                            &thd->sp_proc_cache, FALSE);
       else
-	sp= sp_find_function(thd, lex->spname);
+        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
+                            &thd->sp_func_cache, FALSE);
       mysql_reset_errors(thd, 0);
       if (sp)
       {
@@ -4527,6 +4550,33 @@
 					 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))
@@ -4545,7 +4595,7 @@
         buff.append(command[thd->lex->create_view_mode].str,
                     command[thd->lex->create_view_mode].length);
         view_store_options(thd, first_table, &buff);
-        buff.append("VIEW ", 5);
+        buff.append(STRING_WITH_LEN("VIEW "));
         /* Test if user supplied a db (ie: we did not use thd->db) */
         if (first_table->db != thd->db && first_table->db[0])
         {
@@ -4555,7 +4605,7 @@
         }
         append_identifier(thd, &buff, first_table->table_name,
                           first_table->table_name_length);
-        buff.append(" AS ", 4);
+        buff.append(STRING_WITH_LEN(" AS "));
         buff.append(first_table->source.str, first_table->source.length);
 
         Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
@@ -4804,11 +4854,15 @@
 
 
   /*
-    The return value for ROW_COUNT() is "implementation dependent" if
-    the statement is not DELETE, INSERT or UPDATE (or a CALL executing
-    such a statement), but -1 is what JDBC and ODBC wants.
+    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 && uc_update_queries[lex->sql_command]<2)
+  if (lex->sql_command != SQLCOM_CALL && lex->sql_command != SQLCOM_EXECUTE &&
+      uc_update_queries[lex->sql_command]<2)
     thd->row_count_func= -1;
   goto cleanup;
 
@@ -5039,7 +5093,7 @@
     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)
+  for (; tables && tables != first_not_own_table; tables= tables->next_global)
   {
     if (tables->schema_table && 
         (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
@@ -5249,6 +5303,7 @@
 			 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))
   {
@@ -5379,6 +5434,8 @@
   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
@@ -5719,9 +5776,10 @@
                         buf, "TIMESTAMP");
   }
 
-  if (!(new_field= new_create_field(thd, field_name, type, length, decimals,
-		type_modifier, default_value, on_update_value,
-		comment, change, interval_list, cs, uint_geom_type)))
+  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);
@@ -5729,327 +5787,6 @@
   DBUG_RETURN(0);
 }
 
-/*****************************************************************************
-** Create field definition for create
-** Return 0 on failure, otherwise return create_field instance
-******************************************************************************/
-  
-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)
-{
-  register create_field *new_field;
-  uint sign_len, allowed_type_modifier=0;
-  ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
-  DBUG_ENTER("new_create_field");
-  
-  if (!(new_field=new create_field()))
-    DBUG_RETURN(NULL);
-  new_field->field=0;
-  new_field->field_name=field_name;
-  new_field->def= default_value;
-  new_field->flags= type_modifier;
-  new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
-			    Field::NEXT_NUMBER : Field::NONE);
-  new_field->decimals= decimals ? (uint)atoi(decimals) : 0;
-  if (new_field->decimals >= NOT_FIXED_DEC)
-  {
-    my_error(ER_TOO_BIG_SCALE, MYF(0), new_field->decimals, field_name,
-             NOT_FIXED_DEC-1);
-    DBUG_RETURN(NULL);
-  }
-
-  new_field->sql_type=type;
-  new_field->length=0;
-  new_field->change=change;
-  new_field->interval=0;
-  new_field->pack_length= new_field->key_length= 0;
-  new_field->charset=cs;
-  new_field->geom_type= (Field::geometry_type) uint_geom_type;
-
-  new_field->comment=*comment;
-  /*
-    Set flag if this field doesn't have a default value
-  */
-  if (!default_value && !(type_modifier & AUTO_INCREMENT_FLAG) &&
-      (type_modifier & NOT_NULL_FLAG) && type != FIELD_TYPE_TIMESTAMP)
-    new_field->flags|= NO_DEFAULT_VALUE_FLAG;
-
-  if (length && !(new_field->length= (uint) atoi(length)))
-    length=0; /* purecov: inspected */
-  sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
-
-  switch (type) {
-  case FIELD_TYPE_TINY:
-    if (!length) new_field->length=MAX_TINYINT_WIDTH+sign_len;
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    break;
-  case FIELD_TYPE_SHORT:
-    if (!length) new_field->length=MAX_SMALLINT_WIDTH+sign_len;
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    break;
-  case FIELD_TYPE_INT24:
-    if (!length) new_field->length=MAX_MEDIUMINT_WIDTH+sign_len;
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    break;
-  case FIELD_TYPE_LONG:
-    if (!length) new_field->length=MAX_INT_WIDTH+sign_len;
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    break;
-  case FIELD_TYPE_LONGLONG:
-    if (!length) new_field->length=MAX_BIGINT_WIDTH;
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    break;
-  case FIELD_TYPE_NULL:
-    break;
-  case FIELD_TYPE_NEWDECIMAL:
-    if (!length && !new_field->decimals)
-      new_field->length= 10;
-    if (new_field->length > DECIMAL_MAX_PRECISION)
-    {
-      my_error(ER_TOO_BIG_PRECISION, MYF(0), new_field->length, field_name,
-               DECIMAL_MAX_PRECISION);
-      DBUG_RETURN(NULL);
-    }
-    if (new_field->length < new_field->decimals)
-    {
-      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
-      DBUG_RETURN(NULL);
-    }
-    new_field->length=
-      my_decimal_precision_to_length(new_field->length, new_field->decimals,
-                                     type_modifier & UNSIGNED_FLAG);
-    new_field->pack_length=
-      my_decimal_get_binary_size(new_field->length, new_field->decimals);
-    break;
-  case MYSQL_TYPE_VARCHAR:
-    /*
-      Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
-      if they don't have a default value
-    */
-    max_field_charlength= MAX_FIELD_VARCHARLENGTH;
-    break;
-  case MYSQL_TYPE_STRING:
-    break;
-  case FIELD_TYPE_BLOB:
-  case FIELD_TYPE_TINY_BLOB:
-  case FIELD_TYPE_LONG_BLOB:
-  case FIELD_TYPE_MEDIUM_BLOB:
-  case FIELD_TYPE_GEOMETRY:
-    if (default_value)				// Allow empty as default value
-    {
-      String str,*res;
-      res=default_value->val_str(&str);
-      if (res->length())
-      {
-	my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
-                 field_name); /* purecov: inspected */
-	DBUG_RETURN(NULL);
-      }
-      new_field->def=0;
-    }
-    new_field->flags|=BLOB_FLAG;
-    break;
-  case FIELD_TYPE_YEAR:
-    if (!length || new_field->length != 2)
-      new_field->length=4;			// Default length
-    new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
-    break;
-  case FIELD_TYPE_FLOAT:
-    /* change FLOAT(precision) to FLOAT or DOUBLE */
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    if (length && !decimals)
-    {
-      uint tmp_length=new_field->length;
-      if (tmp_length > PRECISION_FOR_DOUBLE)
-      {
-	my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
-	DBUG_RETURN(NULL);
-      }
-      else if (tmp_length > PRECISION_FOR_FLOAT)
-      {
-	new_field->sql_type=FIELD_TYPE_DOUBLE;
-	new_field->length=DBL_DIG+7;			// -[digits].E+###
-      }
-      else
-	new_field->length=FLT_DIG+6;			// -[digits].E+##
-      new_field->decimals= NOT_FIXED_DEC;
-      break;
-    }
-    if (!length && !decimals)
-    {
-      new_field->length =  FLT_DIG+6;
-      new_field->decimals= NOT_FIXED_DEC;
-    }
-    if (new_field->length < new_field->decimals &&
-        new_field->decimals != NOT_FIXED_DEC)
-    {
-      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
-      DBUG_RETURN(NULL);
-    }
-    break;
-  case FIELD_TYPE_DOUBLE:
-    allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    if (!length && !decimals)
-    {
-      new_field->length = DBL_DIG+7;
-      new_field->decimals=NOT_FIXED_DEC;
-    }
-    if (new_field->length < new_field->decimals &&
-        new_field->decimals != NOT_FIXED_DEC)
-    {
-      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
-      DBUG_RETURN(NULL);
-    }
-    break;
-  case FIELD_TYPE_TIMESTAMP:
-    if (!length)
-      new_field->length= 14;			// Full date YYYYMMDDHHMMSS
-    else if (new_field->length != 19)
-    {
-      /*
-        We support only even TIMESTAMP lengths less or equal than 14
-        and 19 as length of 4.1 compatible representation.
-      */
-      new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */
-      new_field->length= min(new_field->length,14); /* purecov: inspected */
-    }
-    new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
-    if (default_value)
-    {
-      /* Grammar allows only NOW() value for ON UPDATE clause */
-      if (default_value->type() == Item::FUNC_ITEM && 
-          ((Item_func*)default_value)->functype() == Item_func::NOW_FUNC)
-      {
-        new_field->unireg_check= (on_update_value?Field::TIMESTAMP_DNUN_FIELD:
-                                                  Field::TIMESTAMP_DN_FIELD);
-        /*
-          We don't need default value any longer moreover it is dangerous.
-          Everything handled by unireg_check further.
-        */
-        new_field->def= 0;
-      }
-      else
-        new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD:
-                                                  Field::NONE);
-    }
-    else
-    {
-      /*
-        If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
-        or ON UPDATE values then for the sake of compatiblity we should treat
-        this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
-        have another TIMESTAMP column with auto-set option before this one)
-        or DEFAULT 0 (in other cases).
-        So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
-        replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
-        information about all TIMESTAMP fields in table will be availiable.
-
-        If we have TIMESTAMP NULL column without explicit DEFAULT value
-        we treat it as having DEFAULT NULL attribute.
-      */
-      new_field->unireg_check= (on_update_value ?
-                                Field::TIMESTAMP_UN_FIELD :
-                                (new_field->flags & NOT_NULL_FLAG ?
-                                 Field::TIMESTAMP_OLD_FIELD:
-                                 Field::NONE));
-    }
-    break;
-  case FIELD_TYPE_DATE:				// Old date type
-    if (protocol_version != PROTOCOL_VERSION-1)
-      new_field->sql_type=FIELD_TYPE_NEWDATE;
-    /* fall trough */
-  case FIELD_TYPE_NEWDATE:
-    new_field->length=10;
-    break;
-  case FIELD_TYPE_TIME:
-    new_field->length=10;
-    break;
-  case FIELD_TYPE_DATETIME:
-    new_field->length=19;
-    break;
-  case FIELD_TYPE_SET:
-    {
-      if (interval_list->elements > sizeof(longlong)*8)
-      {
-	my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
-	DBUG_RETURN(NULL);
-      }
-      new_field->pack_length= get_set_pack_length(interval_list->elements);
-
-      List_iterator<String> it(*interval_list);
-      String *tmp;
-      while ((tmp= it++))
-        new_field->interval_list.push_back(tmp);
-      /*
-        Set fake length to 1 to pass the below conditions.
-        Real length will be set in mysql_prepare_table()
-        when we know the character set of the column
-      */
-      new_field->length= 1;
-      break;
-    }
-  case FIELD_TYPE_ENUM:
-    {
-      // Should be safe
-      new_field->pack_length= get_enum_pack_length(interval_list->elements);
-
-      List_iterator<String> it(*interval_list);
-      String *tmp;
-      while ((tmp= it++))
-        new_field->interval_list.push_back(tmp);
-      new_field->length= 1; // See comment for FIELD_TYPE_SET above.
-      break;
-   }
-  case MYSQL_TYPE_VAR_STRING:
-    DBUG_ASSERT(0);                             // Impossible
-    break;
-  case MYSQL_TYPE_BIT:
-    {
-      if (!length)
-        new_field->length= 1;
-      if (new_field->length > MAX_BIT_FIELD_LENGTH)
-      {
-        my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
-                 MAX_BIT_FIELD_LENGTH);
-        DBUG_RETURN(NULL);
-      }
-      new_field->pack_length= (new_field->length + 7) / 8;
-      break;
-    }
-  case FIELD_TYPE_DECIMAL:
-    DBUG_ASSERT(0); /* Was obsolete */
-  }
-
-  if (!(new_field->flags & BLOB_FLAG) &&
-      ((new_field->length > max_field_charlength && type != FIELD_TYPE_SET && 
-        type != FIELD_TYPE_ENUM &&
-        (type != MYSQL_TYPE_VARCHAR || default_value)) ||
-       (!new_field->length &&
-        type != MYSQL_TYPE_STRING &&
-        type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY)))
-  {
-    my_error((type == MYSQL_TYPE_VAR_STRING || type == MYSQL_TYPE_VARCHAR ||
-              type == MYSQL_TYPE_STRING) ?  ER_TOO_BIG_FIELDLENGTH :
-             ER_TOO_BIG_DISPLAYWIDTH,
-             MYF(0),
-             field_name, max_field_charlength); /* purecov: inspected */
-    DBUG_RETURN(NULL);
-  }
-  type_modifier&= AUTO_INCREMENT_FLAG;
-  if ((~allowed_type_modifier) & type_modifier)
-  {
-    my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
-    DBUG_RETURN(NULL);
-  }
-  DBUG_RETURN(new_field);
-}
-
 
 /* Store position for column in ALTER TABLE .. ADD column */
 
@@ -6165,12 +5902,16 @@
   if (!table)
     DBUG_RETURN(0);				// End of memory
   alias_str= alias ? alias->str : table->table.str;
-  if (check_table_name(table->table.str,table->table.length) ||
-      table->db.str && check_db_name(table->db.str))
+  if (check_table_name(table->table.str,table->table.length))
   {
     my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
     DBUG_RETURN(0);
   }
+  if (table->db.str && check_db_name(table->db.str))
+  {
+    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
+    DBUG_RETURN(0);
+  }
 
   if (!alias)					/* Alias is case sensitive */
   {
@@ -6543,36 +6284,39 @@
 
 
 /*
-  Create a new name resolution context for a JOIN ... ON clause.
+  Push a new name resolution context for a JOIN ... ON clause to the
+  context stack of a query block.
 
   SYNOPSIS
-    make_join_on_context()
+    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,
-    and set the first and last leaves of the list of table references
-    to be used for name resolution.
+    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
-    A new context if all is OK
-    NULL - if a memory allocation error occured
+    FALSE  if all is OK
+    TRUE   if a memory allocation error occured
 */
 
-Name_resolution_context *
-make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
+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 NULL;
+    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 on_context;
+  return thd->lex->push_context(on_context);
 }
 
 
@@ -6698,7 +6442,10 @@
       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);
@@ -6736,7 +6483,7 @@
     rotate_relay_log(active_mi);
     pthread_mutex_unlock(&LOCK_active_mi);
 #endif
-    if (ha_flush_logs())
+    if (ha_flush_logs(NULL))
       result=1;
     if (flush_error_log())
       result=1;
@@ -7052,7 +6799,7 @@
   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.db_type= (handlerton*) &default_hton;
   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,
@@ -7068,7 +6815,7 @@
   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.db_type= (handlerton*) &default_hton;
   create_info.default_table_charset= thd->variables.collation_database;
   alter_info->clear();
   alter_info->flags= ALTER_DROP_INDEX;
@@ -7443,32 +7190,81 @@
   return new Item_func_not(expr);
 }
 
+/*
+  Set the specified definer to the default value, which is the current user in
+  the thread. Also check that the current user satisfies to the definers
+  requirements.
+ 
+  SYNOPSIS
+    get_default_definer()
+    thd       [in] thread handler
+    definer   [out] definer
+ 
+  RETURN
+    error status, that is:
+      - FALSE -- on success;
+      - TRUE -- on error (current user can not be a definer).
+*/
+ 
+bool get_default_definer(THD *thd, LEX_USER *definer)
+{
+  /* Check that current user has non-empty host name. */
+
+  const Security_context *sctx= thd->security_ctx;
+
+  if (sctx->priv_host[0] == 0)
+  {
+    my_error(ER_MALFORMED_DEFINER, MYF(0));
+    return TRUE;
+  }
+
+  /* Fill in. */
+
+  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);
+
+  return FALSE;
+}
+
 
 /*
-  Assign as view definer current user
+  Create definer with the given user and host names. Also check that the user
+  and host names satisfy definers requirements.
 
   SYNOPSIS
-    default_view_definer()
-    sctx		current security context
-    definer             structure where it should be assigned
+    create_definer()
+    thd         [in] thread handler
+    user_name   [in] user name
+    host_name   [in] host name
 
   RETURN
-    FALSE   OK
-    TRUE    Error
+    On success, return a valid pointer to the created and initialized
+    LEX_STRING, which contains definer information.
+    On error, return 0.
 */
 
-bool default_view_definer(Security_context *sctx, st_lex_user *definer)
+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
 {
-  definer->user.str= sctx->priv_user;
-  definer->user.length= strlen(sctx->priv_user);
+  LEX_USER *definer;
+
+  /* Check that specified host name is valid. */
 
-  if (!*sctx->priv_host)
+  if (host_name->length == 0)
   {
-    my_error(ER_NO_VIEW_USER, MYF(0));
-    return TRUE;
+    my_error(ER_MALFORMED_DEFINER, MYF(0));
+    return 0;
   }
 
-  definer->host.str= sctx->priv_host;
-  definer->host.length= strlen(sctx->priv_host);
-  return FALSE;
+  /* Create and initialize. */
+
+  if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
+    return 0;
+
+  definer->user= *user_name;
+  definer->host= *host_name;
+
+  return definer;
 }

--- 1.421/sql/sql_yacc.yy	2005-11-15 02:11:22 +11:00
+++ 1.422/sql/sql_yacc.yy	2005-12-22 12:19:02 +11:00
@@ -92,7 +92,7 @@
   enum enum_var_type var_type;
   Key::Keytype key_type;
   enum ha_key_alg key_alg;
-  enum db_type db_type;
+  handlerton *db_type;
   enum row_type row_type;
   enum ha_rkey_function ha_rkey_mode;
   enum enum_tx_isolation tx_isolation;
@@ -179,6 +179,7 @@
 %token  CLIENT_SYM
 %token  CLOSE_SYM
 %token  COALESCE
+%token  CODE_SYM
 %token  COLLATE_SYM
 %token  COLLATION_SYM
 %token  COLUMNS
@@ -812,7 +813,7 @@
 
 %type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp
 
-%type <lex_user> user grant_user
+%type <lex_user> user grant_user get_definer
 
 %type <charset>
 	opt_collate
@@ -863,11 +864,13 @@
 	subselect_end select_var_list select_var_list_init help opt_len
 	opt_extended_describe
         prepare prepare_src execute deallocate
-	statement sp_suid opt_view_list view_list or_replace algorithm
+	statement sp_suid
 	sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
         load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
-        install uninstall view_user view_suid
-        partition_entry
+        definer view_replace_or_algorithm view_replace view_algorithm_opt
+        view_algorithm view_or_trigger_tail view_suid view_tail view_list_opt
+        view_list view_select view_check_option trigger_tail
+        install uninstall partition_entry
 END_OF_INPUT
 
 %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1188,7 +1191,7 @@
 	  lex->change=NullS;
 	  bzero((char*) &lex->create_info,sizeof(lex->create_info));
 	  lex->create_info.options=$2 | $4;
-	  lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
+	  lex->create_info.db_type= lex->thd->variables.table_type;
 	  lex->create_info.default_table_charset= NULL;
 	  lex->name=0;
 	}
@@ -1197,11 +1200,6 @@
 	| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident
 	  {
 	    LEX *lex=Lex;
-            if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-            {
-              my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-              YYABORT;
-            }
 	    lex->sql_command= SQLCOM_CREATE_INDEX;
 	    if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
 							TL_OPTION_UPDATING))
@@ -1302,17 +1300,13 @@
 	      YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
 	    sp->restore_thd_mem_root(YYTHD);
 	  }
-	| CREATE or_replace algorithm view_user view_suid VIEW_SYM table_ident
+	| CREATE
 	  {
-	    THD *thd= YYTHD;
-	    LEX *lex= thd->lex;
-	    lex->sql_command= SQLCOM_CREATE_VIEW;
-            lex->create_view_start= thd->query;
-	    /* first table in list is target VIEW name */
-	    if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0))
-              YYABORT;
+            Lex->create_view_mode= VIEW_CREATE_NEW;
+            Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+            Lex->create_view_suid= TRUE;
 	  }
-	  opt_view_list AS select_view_init check_option
+	  view_or_trigger
 	  {}
         | CREATE LOGFILE_SYM GROUP logfile_group_info 
           {
@@ -1324,68 +1318,6 @@
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
           }
-        | CREATE TRIGGER_SYM sp_name trg_action_time trg_event 
-          ON table_ident FOR_SYM EACH_SYM ROW_SYM
-          {
-            LEX *lex= Lex;
-            sp_head *sp;
-           
-            if (lex->sphead)
-            {
-              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
-              YYABORT;
-            }
-
-            if (!(sp= new sp_head()))
-              YYABORT;
-            sp->reset_thd_mem_root(YYTHD);
-            sp->init(lex);
-            
-            sp->m_type= TYPE_ENUM_TRIGGER;
-            lex->sphead= sp;
-            lex->spname= $3;
-            /*
-              We have to turn of CLIENT_MULTI_QUERIES while parsing a
-              stored procedure, otherwise yylex will chop it into pieces
-              at each ';'.
-            */
-            sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
-            YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
-            
-            bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
-            lex->sphead->m_chistics= &lex->sp_chistics;
-            lex->sphead->m_body_begin= lex->ptr;
-          }
-          sp_proc_stmt
-          {
-            LEX *lex= Lex;
-            sp_head *sp= lex->sphead;
-            
-            lex->sql_command= SQLCOM_CREATE_TRIGGER;
-            sp->init_strings(YYTHD, lex, $3);
-            /* Restore flag if it was cleared above */
-            if (sp->m_old_cmq)
-              YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
-            sp->restore_thd_mem_root(YYTHD);
-
-            if (sp->is_not_allowed_in_function("trigger"))
-                YYABORT;
-
-            /*
-              We have to do it after parsing trigger body, because some of
-              sp_proc_stmt alternatives are not saving/restoring LEX, so
-              lex->query_tables can be wiped out.
-              
-              QQ: What are other consequences of this?
-              
-              QQ: Could we loosen lock type in certain cases ?
-            */
-            if (!lex->select_lex.add_table_to_list(YYTHD, $7, 
-                                                   (LEX_STRING*) 0,
-                                                   TL_OPTION_UPDATING,
-                                                   TL_WRITE))
-              YYABORT;
-          }
 	| CREATE USER clear_privileges grant_list
 	  {
 	    Lex->sql_command = SQLCOM_CREATE_USER;
@@ -1472,41 +1404,11 @@
 	  {
 	    LEX *lex= Lex;
 	    sp_head *sp= lex->sphead;
-            LEX_STRING cmt = { 0, 0 };
-	    create_field *new_field;
-	    uint unused1= 0;
-	    int unused2= 0;
-
-	    if (!(new_field= new_create_field(YYTHD, (char*) "",
-					      (enum enum_field_types)$8,
-			  		      lex->length, lex->dec, lex->type,
-			  		      (Item *)0, (Item *) 0, &cmt, 0,
-					      &lex->interval_list, 
-			  		      (lex->charset ? lex->charset :
-					       default_charset_info),
-					      lex->uint_geom_type)))
-	      YYABORT;
-
-	    sp->m_returns_cs= new_field->charset;
-
-            if (new_field->interval_list.elements)
-            {
-	      new_field->interval= 
-                sp->create_typelib(&new_field->interval_list);
-            }
-            sp_prepare_create_field(YYTHD, new_field);
 
-	    if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
-				     HA_CAN_GEOMETRY))
-	      YYABORT;
-
-	    sp->m_returns= new_field->sql_type;
-	    sp->m_returns_cs= new_field->charset;
-	    sp->m_returns_len= new_field->length;
-	    sp->m_returns_pack= new_field->pack_flag;
-            sp->m_returns_typelib= new_field->interval;
-            sp->m_geom_returns= new_field->geom_type;
-            new_field->interval= NULL;
+            if (sp->fill_field_definition(YYTHD, lex,
+                                          (enum enum_field_types) $8,
+                                          &sp->m_return_field_def))
+              YYABORT;
 
 	    bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
 	  }
@@ -1529,6 +1431,11 @@
 	      YYABORT;
 	    lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
 	    sp->init_strings(YYTHD, lex, lex->spname);
+            if (!(sp->m_flags & sp_head::HAS_RETURN))
+            {
+              my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
+              YYABORT;
+            }
 	    /* Restore flag if it was cleared above */
 	    if (sp->m_old_cmq)
 	      YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
@@ -1623,8 +1530,28 @@
 	| sp_fdparam
 	;
 
+sp_init_param:
+	  /* Empty */
+	  {
+	    LEX *lex= Lex;
+
+	    lex->length= 0;
+	    lex->dec= 0;
+	    lex->type= 0;
+	  
+	    lex->default_value= 0;
+	    lex->on_update_value= 0;
+	  
+	    lex->comment= null_lex_str;
+	    lex->charset= NULL;
+	  
+	    lex->interval_list.empty();
+	    lex->uint_geom_type= 0;
+	  }
+	;
+
 sp_fdparam:
-	  ident type
+	  ident sp_init_param type
 	  {
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
@@ -1634,7 +1561,17 @@
 	      my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
 	      YYABORT;
 	    }
-	    spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in);
+	    sp_pvar_t *pvar= spc->push_pvar(&$1, (enum enum_field_types)$3,
+                                            sp_param_in);
+
+            if (lex->sphead->fill_field_definition(YYTHD, lex,
+                                                   (enum enum_field_types) $3,
+                                                   &pvar->field_def))
+            {
+              YYABORT;
+            }
+            pvar->field_def.field_name= pvar->name.str;
+            pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
 	  }
 	;
 
@@ -1650,18 +1587,27 @@
 	;
 
 sp_pdparam:
-	  sp_opt_inout ident type
+	  sp_opt_inout sp_init_param ident type
 	  {
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
 
-	    if (spc->find_pvar(&$2, TRUE))
+	    if (spc->find_pvar(&$3, TRUE))
 	    {
-	      my_error(ER_SP_DUP_PARAM, MYF(0), $2.str);
+	      my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
 	      YYABORT;
 	    }
-	    spc->push_pvar(&$2, (enum enum_field_types)$3,
-			   (sp_param_mode_t)$1);
+	    sp_pvar_t *pvar= spc->push_pvar(&$3, (enum enum_field_types)$4,
+			                    (sp_param_mode_t)$1);
+
+            if (lex->sphead->fill_field_definition(YYTHD, lex,
+                                                   (enum enum_field_types) $4,
+                                                   &pvar->field_def))
+            {
+              YYABORT;
+            }
+            pvar->field_def.field_name= pvar->name.str;
+            pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
 	  }
 	;
 
@@ -1713,38 +1659,60 @@
 	;
 
 sp_decl:
-          DECLARE_SYM sp_decl_idents type 
-          { Lex->sphead->reset_lex(YYTHD); }
+          DECLARE_SYM sp_decl_idents
+          {
+            LEX *lex= Lex;
+
+            lex->sphead->reset_lex(YYTHD);
+            lex->spcont->declare_var_boundary($2);
+          }
+          type
           sp_opt_default
           {
             LEX *lex= Lex;
-            sp_pcontext *ctx= lex->spcont;
-            uint max= ctx->context_pvars();
-            enum enum_field_types type= (enum enum_field_types)$3;
-            Item *it= $5;
-            bool has_default= (it != NULL);
-
-            for (uint i = max-$2 ; i < max ; i++)
-            {
-              sp_instr_set *in;
-
-              ctx->set_type(i, type);
-              if (! has_default)
-                it= new Item_null();  /* QQ Set to the type with null_value? */
-              in = new sp_instr_set(lex->sphead->instructions(),
-                                    ctx,
-                                    ctx->pvar_context2index(i),
-                                    it, type, lex,
-                                    (i == max - 1));
+            sp_pcontext *pctx= lex->spcont;
+            uint num_vars= pctx->context_pvars();
+            enum enum_field_types var_type= (enum enum_field_types) $4;
+            Item *dflt_value_item= $5;
+            create_field *create_field_op;
+            
+            if (!dflt_value_item)
+            {
+              dflt_value_item= new Item_null();
+              /* QQ Set to the var_type with null_value? */
+            }
+            
+            for (uint i = num_vars-$2 ; i < num_vars ; i++)
+            {
+              uint var_idx= pctx->pvar_context2index(i);
+              sp_pvar_t *pvar= pctx->find_pvar(var_idx);
+            
+              if (!pvar)
+                YYABORT;
+            
+              pvar->type= var_type;
+              pvar->dflt= dflt_value_item;
+            
+              if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
+                                                     &pvar->field_def))
+              {
+                YYABORT;
+              }
+            
+              pvar->field_def.field_name= pvar->name.str;
+              pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
+            
+              /* The last instruction is responsible for freeing LEX. */
 
-              /*
-                The last instruction is assigned to be responsible for
-                freeing LEX.
-              */
-              lex->sphead->add_instr(in);
-              ctx->set_default(i, it);
+              lex->sphead->add_instr(
+                new sp_instr_set(lex->sphead->instructions(), pctx, var_idx,
+                                 dflt_value_item, var_type, lex,
+                                 (i == num_vars - 1)));
             }
+
+            pctx->declare_var_boundary(0);
             lex->sphead->restore_lex(YYTHD);
+
             $$.vars= $2;
             $$.conds= $$.hndlrs= $$.curs= 0;
           }
@@ -1816,7 +1784,8 @@
 	      delete $5;
 	      YYABORT;
 	    }
-            i= new sp_instr_cpush(sp->instructions(), ctx, $5);
+            i= new sp_instr_cpush(sp->instructions(), ctx, $5,
+                                  ctx->current_cursors());
 	    sp->add_instr(i);
 	    ctx->push_cursor(&$2);
 	    $$.vars= $$.conds= $$.hndlrs= 0;
@@ -1966,6 +1935,8 @@
 sp_decl_idents:
 	  ident
 	  {
+            /* NOTE: field definition is filled in sp_decl section. */
+
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
 
@@ -1979,6 +1950,8 @@
 	  }
 	| sp_decl_idents ',' ident
 	  {
+            /* NOTE: field definition is filled in sp_decl section. */
+
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
 
@@ -2056,8 +2029,8 @@
 	    {
 	      sp_instr_freturn *i;
 
-	      i= new sp_instr_freturn(sp->instructions(), lex->spcont,
-		                      $3, sp->m_returns, lex);
+	      i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
+                                      sp->m_return_field_def.sql_type, lex);
 	      sp->add_instr(i);
 	      sp->m_flags|= sp_head::HAS_RETURN;
 	    }
@@ -2073,25 +2046,27 @@
           { Lex->sphead->reset_lex(YYTHD); }
           expr WHEN_SYM
 	  {
-	    /* We "fake" this by using an anonymous variable which we
-	       set to the expression. Note that all WHENs are evaluate
-	       at the same frame level, so we then know that it's the
-	       top-most variable in the frame. */
-	    LEX *lex= Lex;
-	    uint offset= lex->spcont->current_pvars();
-	    sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
-                                               lex->spcont, offset, $3,
-                                               MYSQL_TYPE_STRING, lex, TRUE);
-	    LEX_STRING dummy={(char*)"", 0};
-
-	    lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in);
-	    lex->sphead->add_instr(i);
-	    lex->sphead->m_flags|= sp_head::IN_SIMPLE_CASE;
-            lex->sphead->restore_lex(YYTHD);
+	    LEX *lex= Lex;
+	    sp_head *sp= lex->sphead;
+	    sp_pcontext *parsing_ctx= lex->spcont;
+	    int case_expr_id= parsing_ctx->register_case_expr();
+	    
+	    if (parsing_ctx->push_case_expr_id(case_expr_id))
+              YYABORT;
+	    
+	    sp->add_instr(
+	      new sp_instr_set_case_expr(sp->instructions(),
+	                                 parsing_ctx,
+	                                 case_expr_id,
+	                                 $3,
+	                                 lex));
+	    
+	    sp->m_flags|= sp_head::IN_SIMPLE_CASE;
+	    sp->restore_lex(YYTHD);
 	  }
 	  sp_case END CASE_SYM
 	  {
-	    Lex->spcont->pop_pvar();
+	    Lex->spcont->pop_case_expr_id();
 	  }
 	| sp_labeled_control
 	  {}
@@ -2402,16 +2377,20 @@
 	      i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
 	    else
 	    { /* Simple case: <caseval> = <whenval> */
-	      LEX_STRING ivar;
 
-	      ivar.str= (char *)"_tmp_";
-	      ivar.length= 5;
-	      Item *var= (Item*) new Item_splocal(ivar, 
-						  ctx->current_pvars()-1);
-	      Item *expr= new Item_func_eq(var, $2);
+	      Item_case_expr *var;
+              Item *expr;
+
+              var= new Item_case_expr(ctx->get_current_case_expr_id());
+
+#ifndef DBUG_OFF
+              if (var)
+                var->m_sp= sp;
+#endif
+
+	      expr= new Item_func_eq(var, $2);
 
 	      i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
-              lex->variables_used= 1;
 	    }
 	    sp->push_backpatch(i, ctx->push_label((char *)"", 0));
             sp->add_instr(i);
@@ -3001,7 +2980,7 @@
 /*
  This part of the parser is about handling of the partition information.
 
+ It's first version was written by Mikael Ronström with lots of answers to
  questions provided by Antony Curtis.
 
  The partition grammar can be called from three places.
@@ -3246,7 +3225,7 @@
           part_info->current_partition= p_elem;
           part_info->use_default_partitions= FALSE;
           part_info->partitions.push_back(p_elem);
-          p_elem->engine_type= DB_TYPE_UNKNOWN;
+          p_elem->engine_type= NULL;
           part_info->count_curr_parts++;
         }
         part_name {}
@@ -3429,7 +3408,7 @@
           part_info->current_partition->subpartitions.push_back(p_elem);
           part_info->use_default_subpartitions= FALSE;
           part_info->count_curr_subparts++;
-          p_elem->engine_type= DB_TYPE_UNKNOWN;
+          p_elem->engine_type= NULL;
         }
         sub_name opt_part_options {}
         ;
@@ -3661,8 +3640,8 @@
 storage_engines:
 	ident_or_text
 	{
-	  $$ = ha_resolve_by_name($1.str,$1.length);
-	  if ($$ == DB_TYPE_UNKNOWN &&
+	  $$ = ha_resolve_by_name(YYTHD, &$1);
+	  if ($$ == NULL &&
 	      test(YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION))
 	  {
 	    my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
@@ -4301,11 +4280,6 @@
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
 	  lex->sql_command= SQLCOM_ALTER_TABLE;
 	  lex->name= 0;
 	  lex->duplicates= DUP_ERROR; 
@@ -4318,7 +4292,7 @@
           lex->select_lex.init_order();
 	  lex->select_lex.db=lex->name=0;
 	  bzero((char*) &lex->create_info,sizeof(lex->create_info));
-	  lex->create_info.db_type= DB_TYPE_DEFAULT;
+	  lex->create_info.db_type= (handlerton*) &default_hton;
 	  lex->create_info.default_table_charset= NULL;
 	  lex->create_info.row_type= ROW_TYPE_NOT_USED;
 	  lex->alter_info.reset();
@@ -4373,17 +4347,17 @@
 	    lex->sql_command= SQLCOM_ALTER_FUNCTION;
 	    lex->spname= $3;
 	  }
-	| ALTER algorithm view_user view_suid VIEW_SYM table_ident
+        | ALTER view_algorithm_opt definer view_suid
+          VIEW_SYM table_ident
 	  {
 	    THD *thd= YYTHD;
 	    LEX *lex= thd->lex;
 	    lex->sql_command= SQLCOM_CREATE_VIEW;
-            lex->create_view_start= thd->query;
 	    lex->create_view_mode= VIEW_ALTER;
 	    /* first table in list is target VIEW name */
 	    lex->select_lex.add_table_to_list(thd, $6, NULL, 0);
 	  }
-	  opt_view_list AS select_view_init check_option
+	  view_list_opt AS view_select view_check_option
 	  {}
         | ALTER TABLESPACE alter_tablespace_info
           {
@@ -4418,7 +4392,7 @@
         opt_partitioning
         | partitioning
 /*
+  This part was added for release 5.1 by Mikael Ronström.
   From here we insert a number of commands to manage the partitions of a
   partitioned table such as adding partitions, dropping partitions,
   reorganising partitions in various manners. In future releases the list
@@ -4726,11 +4700,6 @@
 	START_SYM TRANSACTION_SYM start_transaction_opts
         {
           LEX *lex= Lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
           lex->sql_command= SQLCOM_BEGIN;
           lex->start_transaction_opt= $3;
         }
@@ -4893,11 +4862,6 @@
 	OPTIMIZE opt_no_write_to_binlog table_or_tables
 	{
 	   LEX *lex=Lex;
-	   if (lex->sphead)
-	   {
-	     my_error(ER_SP_BADSTATEMENT, MYF(0), "OPTIMIZE TABLE");
-	     YYABORT;
-	   }
 	   lex->sql_command = SQLCOM_OPTIMIZE;
            lex->no_write_to_binlog= $2;
 	   lex->check_opt.init();
@@ -4915,13 +4879,7 @@
 rename:
 	RENAME table_or_tables
 	{
-          LEX *lex= Lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
-          lex->sql_command=SQLCOM_RENAME_TABLE;
+          Lex->sql_command= SQLCOM_RENAME_TABLE;
 	}
 	table_to_table_list
 	{}
@@ -5062,18 +5020,6 @@
 	|
 	'(' select_paren ')' union_opt;
 
-select_view_init:
-        SELECT_SYM remember_name select_init2
-          {
-            Lex->create_view_select_start= $2;
-          }
-        |
-        '(' remember_name select_paren ')' union_opt
-          {
-            Lex->create_view_select_start= $2;
-          }
-        ;
-
 select_paren:
 	SELECT_SYM select_part2
 	  {
@@ -5534,16 +5480,14 @@
 	  {
 	    if ($3->is_splocal())
 	    {
-	      LEX_STRING *name;
 	      Item_splocal *il= static_cast<Item_splocal *>($3);
 
-	      name= il->my_name(NULL);
-	      my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
+	      my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
 	      YYABORT;
 	    }
 	    $$= new Item_default_value(Lex->current_context(), $3);
 	  }
-	| VALUES '(' simple_ident ')'
+	| VALUES '(' simple_ident_nospvar ')'
 	  { $$= new Item_insert_value(Lex->current_context(), $3); }
 	| FUNC_ARG0 '(' ')'
 	  {
@@ -6313,10 +6257,8 @@
           {
             YYERROR_UNLESS($1 && ($$=$3));
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+            if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
 	  {
@@ -6328,10 +6270,8 @@
           {
             YYERROR_UNLESS($1 && ($$=$3));
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+            if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
           {
@@ -6358,10 +6298,8 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+            if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
 	  {
@@ -6391,10 +6329,8 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+            if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
           {
@@ -6455,10 +6391,9 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
+            if (push_new_name_resolution_context(YYTHD, $3, $7))
               YYABORT;
-            Lex->push_context(on_context);
+
           }
           expr '}'
 	  {
@@ -7010,7 +6945,13 @@
 	       YYABORT;
 	     else
 	     {
-	       ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset,t->type));
+               my_var *var;
+	       ((select_dumpvar *)lex->result)->
+                 var_list.push_back(var= new my_var($1,1,t->offset,t->type));
+#ifndef DBUG_OFF
+	       if (var)
+		 var->sp= lex->sphead;
+#endif
 	     }
 	   }
            ;
@@ -7070,21 +7011,10 @@
 	  lex->sql_command = SQLCOM_DROP_TABLE;
 	  lex->drop_temporary= $2;
 	  lex->drop_if_exists= $4;
-          if (!lex->drop_temporary && lex->sphead &&
-              lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
 	}
 	| DROP INDEX_SYM ident ON table_ident {}
 	  {
 	     LEX *lex=Lex;
-             if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-             {
-               my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-               YYABORT;
-             }
 	     lex->sql_command= SQLCOM_DROP_INDEX;
 	     lex->alter_info.drop_list.empty();
 	     lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
@@ -7130,13 +7060,7 @@
           }
 	| DROP VIEW_SYM if_exists table_list opt_restrict
 	  {
-	    THD *thd= YYTHD;
-	    LEX *lex= thd->lex;
-            if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-            {
-              my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-              YYABORT;
-            }
+	    LEX *lex= Lex;
 	    lex->sql_command= SQLCOM_DROP_VIEW;
 	    lex->drop_if_exists= $3;
 	  }
@@ -7546,11 +7470,19 @@
             if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
               YYABORT;
 	  }
+        | PLUGIN_SYM
+	  {
+	    LEX *lex= Lex;
+            lex->sql_command= SQLCOM_SELECT;
+            lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
+            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
+              YYABORT;
+	  }
 	| ENGINE_SYM storage_engines 
 	  { Lex->create_info.db_type= $2; }
 	  show_engine_param
 	| ENGINE_SYM ALL 
-	  { Lex->create_info.db_type= DB_TYPE_DEFAULT; }
+	  { Lex->create_info.db_type= NULL; }
 	  show_engine_param
 	| opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
 	  {
@@ -7642,14 +7574,24 @@
           {
             LEX *lex= Lex;
             lex->sql_command = SQLCOM_SHOW_ENGINE_STATUS;
-            lex->create_info.db_type= DB_TYPE_INNODB;
+            if (!(lex->create_info.db_type=
+                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB)))
+            {
+	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
+	      YYABORT;
+            }
             WARN_DEPRECATED("SHOW INNODB STATUS", "SHOW ENGINE INNODB STATUS");
 	  }
         | MUTEX_SYM STATUS_SYM
           {
 	    LEX *lex= Lex;
             lex->sql_command = SQLCOM_SHOW_ENGINE_MUTEX; 
-            lex->create_info.db_type= DB_TYPE_INNODB;
+            if (!(lex->create_info.db_type=
+                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB)))
+            {
+	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
+	      YYABORT;
+            }
             WARN_DEPRECATED("SHOW MUTEX STATUS", "SHOW ENGINE INNODB MUTEX");
 	  }
 	| opt_full PROCESSLIST_SYM
@@ -7683,14 +7625,24 @@
 	  {
 	    LEX *lex= Lex;
 	    lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS;
-	    lex->create_info.db_type= DB_TYPE_BERKELEY_DB;
+            if (!(lex->create_info.db_type=
+                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_BERKELEY_DB)))
+            {
+	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "BerkeleyDB");
+	      YYABORT;
+            }
 	    WARN_DEPRECATED("SHOW BDB LOGS", "SHOW ENGINE BDB LOGS");
 	  }
 	| LOGS_SYM
 	  {
 	    LEX *lex= Lex;
 	    lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS;
-	    lex->create_info.db_type= DB_TYPE_BERKELEY_DB;
+            if (!(lex->create_info.db_type=
+                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_BERKELEY_DB)))
+            {
+	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "BerkeleyDB");
+	      YYABORT;
+            }
 	    WARN_DEPRECATED("SHOW LOGS", "SHOW ENGINE BDB LOGS");
 	  }
 	| GRANTS
@@ -7787,7 +7739,28 @@
 	      YYABORT;
             if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
               YYABORT;
-	  };
+	  }
+        | PROCEDURE CODE_SYM sp_name
+          {
+#ifdef DBUG_OFF
+            yyerror(ER(ER_SYNTAX_ERROR));
+            YYABORT;
+#else
+            Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
+	    Lex->spname= $3;
+#endif
+          }
+        | FUNCTION_SYM CODE_SYM sp_name
+          {
+#ifdef DBUG_OFF
+            yyerror(ER(ER_SYNTAX_ERROR));
+            YYABORT;
+#else
+            Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
+	    Lex->spname= $3;
+#endif
+          }
+        ;
 
 show_engine_param:
 	STATUS_SYM
@@ -8326,8 +8299,13 @@
 	  {
             /* We're compiling a stored procedure and found a variable */
             Item_splocal *splocal;
-            splocal= new Item_splocal($1, spv->offset, lex->tok_start_prev - 
+            splocal= new Item_splocal($1, spv->offset, spv->type,
+                                      lex->tok_start_prev - 
                                       lex->sphead->m_tmp_query);
+#ifndef DBUG_OFF
+            if (splocal)
+              splocal->m_sp= lex->sphead;
+#endif
 	    $$ = (Item*) splocal;
             lex->variables_used= 1;
 	    lex->safe_to_cache_query=0;
@@ -8686,6 +8664,7 @@
 	| CIPHER_SYM		{}
 	| CLIENT_SYM		{}
 	| COALESCE		{}
+	| CODE_SYM              {}
 	| COLLATION_SYM		{}
         | COLUMNS               {}
 	| COMMITTED_SYM		{}
@@ -9137,6 +9116,9 @@
 	    names.length= 5;
 	    if (spc && spc->find_pvar(&names))
               my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
+            else
+              yyerror(ER(ER_SYNTAX_ERROR));
+
 	    YYABORT;
 	  }
 	| NAMES_SYM charset_name_or_default opt_collate
@@ -9826,11 +9808,6 @@
 	BEGIN_SYM  
         {
 	  LEX *lex=Lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
           lex->sql_command = SQLCOM_BEGIN;
           lex->start_transaction_opt= 0;
         }
@@ -9863,11 +9840,6 @@
 	COMMIT_SYM opt_work opt_chain opt_release
 	{
 	  LEX *lex=Lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
 	  lex->sql_command= SQLCOM_COMMIT;
 	  lex->tx_chain= $3; 
 	  lex->tx_release= $4;
@@ -9878,11 +9850,6 @@
 	ROLLBACK_SYM opt_work opt_chain opt_release
 	{
 	  LEX *lex=Lex;
-          if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
-          {
-            my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-            YYABORT;
-          }
 	  lex->sql_command= SQLCOM_ROLLBACK;
 	  lex->tx_chain= $3; 
 	  lex->tx_release= $4;
@@ -10060,10 +10027,121 @@
 	  LEX *lex=Lex;
           lex->pop_context();
 	  lex->current_select = lex->current_select->return_after_parsing();
+          lex->nest_level--;
 	};
 
-opt_view_list:
-	/* empty */ {}
+definer:
+	get_definer
+	{
+	  THD *thd= YYTHD;
+	  
+	  if (! (thd->lex->definer= create_definer(thd, &$1->user, &$1->host)))
+	    YYABORT;
+	}
+	;
+
+get_definer:
+	opt_current_definer
+	{
+	  THD *thd= YYTHD;
+          
+	  if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+	    YYABORT;
+
+	  if (get_default_definer(thd, $$))
+	    YYABORT;
+	}
+	| DEFINER_SYM EQ ident_or_text '@' ident_or_text
+	{
+	  if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
+	    YYABORT;
+
+	  $$->user= $3;
+	  $$->host= $5;
+	}
+	;
+
+opt_current_definer:
+	/* empty */
+	| DEFINER_SYM EQ CURRENT_USER optional_braces
+	;
+
+/**************************************************************************
+
+ CREATE VIEW statement options.
+
+**************************************************************************/
+
+view_replace_or_algorithm:
+	view_replace
+	{}
+	| view_replace view_algorithm
+	{}
+	| view_algorithm
+	{}
+	;
+
+view_replace:
+	OR_SYM REPLACE
+	{ Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
+	;
+
+view_algorithm:
+	ALGORITHM_SYM EQ UNDEFINED_SYM
+	{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
+	| ALGORITHM_SYM EQ MERGE_SYM
+	{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
+	| ALGORITHM_SYM EQ TEMPTABLE_SYM
+	{ Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; }
+	;
+
+view_algorithm_opt:
+	/* empty */
+	{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
+	| view_algorithm
+	{}
+	;
+
+view_or_trigger:
+	definer view_or_trigger_tail
+	{}
+	| view_replace_or_algorithm definer view_tail
+	{}
+	;
+
+view_or_trigger_tail:
+	view_tail
+	{}
+	| trigger_tail
+	{}
+	;
+
+view_suid:
+	/* empty */
+	{ Lex->create_view_suid= TRUE; }
+	| SQL_SYM SECURITY_SYM DEFINER_SYM
+	{ Lex->create_view_suid= TRUE; }
+	| SQL_SYM SECURITY_SYM INVOKER_SYM
+	{ Lex->create_view_suid= FALSE; }
+	;
+
+view_tail:
+	view_suid VIEW_SYM table_ident
+	{
+	  THD *thd= YYTHD;
+	  LEX *lex= thd->lex;
+	  lex->sql_command= SQLCOM_CREATE_VIEW;
+	  /* first table in list is target VIEW name */
+	  if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+	    YYABORT;
+	}
+	view_list_opt AS view_select view_check_option
+	{}
+	;
+
+view_list_opt:
+	/* empty */
+	{}
 	| '(' view_list ')'
 	;
 
@@ -10080,79 +10158,112 @@
 	  }
 	;
 
-or_replace:
-	/* empty */	 { Lex->create_view_mode= VIEW_CREATE_NEW; }
-	| OR_SYM REPLACE { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
+view_select:
+	SELECT_SYM remember_name select_init2
+	{
+          THD *thd=YYTHD;
+          LEX *lex= thd->lex;
+          char *stmt_beg= (lex->sphead ?
+                           (char *)lex->sphead->m_tmp_query :
+                           thd->query);
+	  lex->create_view_select_start= $2 - stmt_beg;
+	}
+	| '(' remember_name select_paren ')' union_opt
+	{
+          THD *thd=YYTHD;
+          LEX *lex= thd->lex;
+          char *stmt_beg= (lex->sphead ?
+                           (char *)lex->sphead->m_tmp_query :
+                           thd->query);
+	  lex->create_view_select_start= $2 - stmt_beg;
+	}
 	;
 
-algorithm:
+view_check_option:
 	/* empty */
-	  { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
-	| ALGORITHM_SYM EQ UNDEFINED_SYM
-	  { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
-	| ALGORITHM_SYM EQ MERGE_SYM
-	  { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
-	| ALGORITHM_SYM EQ TEMPTABLE_SYM
-	  { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; }
+	{ Lex->create_view_check= VIEW_CHECK_NONE; }
+	| WITH CHECK_SYM OPTION
+	{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
+	| WITH CASCADED CHECK_SYM OPTION
+	{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
+	| WITH LOCAL_SYM CHECK_SYM OPTION
+	{ Lex->create_view_check= VIEW_CHECK_LOCAL; }
 	;
 
-view_user:
-        /* empty */
-          {
-            THD *thd= YYTHD;
-            if (!(thd->lex->create_view_definer=
-                  (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
-              YYABORT;
-            if (default_view_definer(thd->security_ctx,
-                                     thd->lex->create_view_definer))
-              YYABORT;
-          }
-        | CURRENT_USER optional_braces
-          {
-            THD *thd= YYTHD;
-            if (!(thd->lex->create_view_definer=
-                  (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
-              YYABORT;
-            if (default_view_definer(thd->security_ctx,
-                                     thd->lex->create_view_definer))
-              YYABORT;
-          }
-	| DEFINER_SYM EQ ident_or_text '@' ident_or_text
+/**************************************************************************
+
+ CREATE TRIGGER statement parts.
+
+**************************************************************************/
+
+trigger_tail:
+	TRIGGER_SYM remember_name sp_name trg_action_time trg_event 
+	ON table_ident FOR_SYM EACH_SYM ROW_SYM
+	{
+	  LEX *lex= Lex;
+	  sp_head *sp;
+	 
+	  if (lex->sphead)
 	  {
-	    THD *thd= YYTHD;
-            st_lex_user *view_user;
-	    if (!(thd->lex->create_view_definer= view_user=
-                  (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
-	      YYABORT;
-	    view_user->user = $3; view_user->host=$5;
-            if (view_user->host.length == 0)
-            {
-              my_error(ER_NO_VIEW_USER, MYF(0));
-              YYABORT;
-            }
+	    my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
+	    YYABORT;
 	  }
-        ;
-
-view_suid:
-        /* empty */
-	  { Lex->create_view_suid= TRUE; }
-        |
-	  SQL_SYM SECURITY_SYM DEFINER_SYM
-	  { Lex->create_view_suid= TRUE; }
-	| SQL_SYM SECURITY_SYM INVOKER_SYM
-	  { Lex->create_view_suid= FALSE; }
+	
+	  if (!(sp= new sp_head()))
+	    YYABORT;
+	  sp->reset_thd_mem_root(YYTHD);
+	  sp->init(lex);
+	
+	  lex->trigger_definition_begin= $2;
+	  
+	  sp->m_type= TYPE_ENUM_TRIGGER;
+	  lex->sphead= sp;
+	  lex->spname= $3;
+	  /*
+	    We have to turn of CLIENT_MULTI_QUERIES while parsing a
+	    stored procedure, otherwise yylex will chop it into pieces
+	    at each ';'.
+	  */
+	  sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
+	  YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
+	  
+	  bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
+	  lex->sphead->m_chistics= &lex->sp_chistics;
+	  lex->sphead->m_body_begin= lex->ptr;
+	}
+	sp_proc_stmt
+	{
+	  LEX *lex= Lex;
+	  sp_head *sp= lex->sphead;
+	  
+	  lex->sql_command= SQLCOM_CREATE_TRIGGER;
+	  sp->init_strings(YYTHD, lex, $3);
+	  /* Restore flag if it was cleared above */
+	  if (sp->m_old_cmq)
+	    YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
+	  sp->restore_thd_mem_root(YYTHD);
+	
+	  if (sp->is_not_allowed_in_function("trigger"))
+	      YYABORT;
+	
+	  /*
+	    We have to do it after parsing trigger body, because some of
+	    sp_proc_stmt alternatives are not saving/restoring LEX, so
+	    lex->query_tables can be wiped out.
+	    
+	    QQ: What are other consequences of this?
+	    
+	    QQ: Could we loosen lock type in certain cases ?
+	  */
+	  if (!lex->select_lex.add_table_to_list(YYTHD, $7, 
+	                                         (LEX_STRING*) 0,
+	                                         TL_OPTION_UPDATING,
+	                                         TL_WRITE))
+	    YYABORT;
+	}
 	;
 
-check_option:
-        /* empty */
-          { Lex->create_view_check= VIEW_CHECK_NONE; }
-        | WITH CHECK_SYM OPTION
-          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
-        | WITH CASCADED CHECK_SYM OPTION
-          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
-        | WITH LOCAL_SYM CHECK_SYM OPTION
-          { Lex->create_view_check= VIEW_CHECK_LOCAL; }
-        ;
+/*************************************************************************/
 
 xa: XA_SYM begin_or_start xid opt_join_or_resume
       {
@@ -10230,7 +10341,7 @@
     ;
 
 install:
-  INSTALL_SYM PLUGIN_SYM IDENT_sys SONAME_SYM TEXT_STRING_sys
+  INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys
   {
     LEX *lex= Lex;
     lex->sql_command= SQLCOM_INSTALL_PLUGIN;
@@ -10239,7 +10350,7 @@
   };
 
 uninstall:
-  UNINSTALL_SYM PLUGIN_SYM IDENT_sys
+  UNINSTALL_SYM PLUGIN_SYM ident
   {
     LEX *lex= Lex;
     lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;

--- 1.53/sql/share/errmsg.txt	2005-11-15 02:11:22 +11:00
+++ 1.54/sql/share/errmsg.txt	2005-12-22 12:19:02 +11:00
@@ -132,7 +132,7 @@
 	est "Ei suuda luua andmebaasi '%-.64s': andmebaas juba eksisteerib"
-	ger "Kann Datenbank '%-.64s' nicht erzeugen. Datenbank '%-.64s' existiert bereits"
+	ger "Kann Datenbank '%-.64s' nicht erzeugen. Datenbank existiert bereits"
 	hun "Az '%-.64s' adatbazis nem hozhato letre Az adatbazis mar letezik"
 	ita "Impossibile creare il database '%-.64s'; il database esiste"
@@ -157,7 +157,7 @@
 	est "Ei suuda kustutada andmebaasi '%-.64s': andmebaasi ei eksisteeri"
 	fre "Ne peut effacer la base '%-.64s'; elle n'existe pas"
 	hun "A(z) '%-.64s' adatbazis nem szuntetheto meg. Az adatbazis nem letezik"
 	ita "Impossibile cancellare '%-.64s'; il database non esiste"
@@ -182,7 +182,7 @@
 	est "Viga andmebaasi kustutamisel (ei suuda kustutada faili '%-.64s', veakood: %d)"
 	fre "Ne peut effacer la base '%-.64s' (erreur %d)"
 	hun "Adatbazis megszuntetesi hiba ('%-.64s' nem torolheto, hibakod: %d)"
 	ita "Errore durante la cancellazione del database (impossibile cancellare '%-.64s', errno: %d)"
@@ -207,7 +207,7 @@
 	est "Viga andmebaasi kustutamisel (ei suuda kustutada kataloogi '%-.64s', veakood: %d)"
 	hun "Adatbazis megszuntetesi hiba ('%-.64s' nem szuntetheto meg, hibakod: %d)"
 	ita "Errore durante la cancellazione del database (impossibile rmdir '%-.64s', errno: %d)"
@@ -357,7 +357,7 @@
 	est "Ei suuda avada faili '%-.64s' (veakood: %d)"
 	fre "Ne peut ouvrir le fichier: '%-.64s' (Errcode: %d)"
 	hun "A '%-.64s' file nem nyithato meg (hibakod: %d)"
 	ita "Impossibile aprire il file: '%-.64s' (errno: %d)"
@@ -702,7 +702,7 @@
 	eng "Got error %d from storage engine"
 	est "Tabeli handler tagastas vea %d"
-	ger "Fehler %d (Tabellenhandler)"
+	ger "Fehler %d (Speicher-Engine)"
 	hun "%d hibajelzes a tablakezelotol"
 	ita "Rilevato l'errore %d dal gestore delle tabelle"
@@ -726,7 +726,7 @@
 	eng "Table storage engine for '%-.64s' doesn't have this option"
 	est "Tabeli '%-.64s' handler ei toeta antud operatsiooni"
 	fre "Le handler de la table '%-.64s' n'a pas cette option"
-	ger "Diese Option gibt es nicht (Tabellenhandler)"
 	hun "A(z) '%-.64s' tablakezelonek nincs ilyen opcioja"
 	ita "Il gestore delle tabelle per '%-.64s' non ha questa opzione"
@@ -751,7 +751,7 @@
 	est "Ei suuda leida kirjet '%-.64s'-s"
 	fre "Ne peut trouver l'enregistrement dans '%-.64s'"
-	ger "Kann Datensatz nicht finden"
+	ger "Kann Datensatz in '%-.64s' nicht finden"
 	hun "Nem talalhato a rekord '%-.64s'-ben"
 	ita "Impossibile trovare il record in '%-.64s'"
@@ -801,7 +801,7 @@
 	hun "Ervenytelen kulcsfile a tablahoz: '%-.64s'; probalja kijavitani!"
 	ita "File chiave errato per la tabella : '%-.64s'; prova a riparalo"
@@ -826,7 +826,7 @@
 	hun "Regi kulcsfile a '%-.64s'tablahoz; probalja kijavitani!"
 	ita "File chiave vecchio per la tabella '%-.64s'; riparalo!"
@@ -851,7 +851,7 @@
 	est "Tabel '%-.64s' on ainult lugemiseks"
 	fre "'%-.64s' est en lecture seulement"
-	ger "'%-.64s' ist nur lesbar"
+	ger "Tabelle '%-.64s' ist nur lesbar"
 	hun "'%-.64s' irasvedett"
 	ita "'%-.64s' e` di sola lettura"
@@ -901,7 +901,7 @@
 	hun "Nincs eleg memoria a rendezeshez. Novelje a rendezo demon puffermeretet"
 	ita "Memoria per gli ordinamenti esaurita. Incrementare il 'sort_buffer' al demone"
@@ -976,7 +976,7 @@
 	hun "Elfogyott a thread-memoria"
 	ita "Fine dello spazio/memoria per i thread"
@@ -1025,7 +1025,7 @@
 	eng "Bad handshake"
 	fre "Mauvais 'handshake'"
-	ger "Schlechter Handshake"
 	hun "A kapcsolatfelvetel nem sikerult (Bad handshake)"
 	ita "Negoziazione impossibile"
@@ -1245,7 +1245,7 @@
 	eng "Column '%-.64s' in %-.64s is ambiguous"
 	fre "Champ: '%-.64s' dans %s est ambigu"
-	ger "Spalte '%-.64s' in %-.64s ist nicht eindeutig"
+	ger "Feld '%-.64s' in %-.64s ist nicht eindeutig"
 	hun "A(z) '%-.64s' oszlop %-.64s-ben ketertelmu"
 	ita "Colonna: '%-.64s' di %-.64s e` ambigua"
@@ -1411,7 +1411,7 @@
 	est "Identifikaatori '%-.100s' nimi on liiga pikk"
 	fre "Le nom de l'identificateur '%-.64s' est trop long"
-	ger "Name des Bezeichners '%-.64s' ist zu lang"
+	ger "Name des Bezeichners '%-.100s' ist zu lang"
 	hun "A(z) '%-.100s' azonositonev tul hosszu."
 	ita "Il nome dell'identificatore '%-.100s' e` troppo lungo"
@@ -1436,7 +1436,7 @@
 	est "Kattuv tulba nimi '%-.64s'"
-	ger "Doppelter Spaltenname vorhanden: '%-.64s'"
+	ger "Doppelter Spaltenname: '%-.64s'"
 	hun "Duplikalt oszlopazonosito: '%-.64s'"
 	ita "Nome colonna duplicato '%-.64s'"
@@ -1461,7 +1461,7 @@
 	hun "Duplikalt kulcsazonosito: '%-.64s'"
 	ita "Nome chiave duplicato '%-.64s'"
@@ -1510,7 +1510,7 @@
 	eng "Incorrect column specifier for column '%-.64s'"
 	est "Vigane tulba kirjeldus tulbale '%-.64s'"
 	hun "Rossz oszlopazonosito: '%-.64s'"
 	ita "Specifica errata per la colonna '%-.64s'"
@@ -1608,7 +1608,7 @@
 	eng "Invalid default value for '%-.64s'"
-	ger "Fehlerhafter Vorgabewert (DEFAULT): '%-.64s'"
 	hun "Ervenytelen ertek: '%-.64s'"
 	ita "Valore di default non valido per '%-.64s'"
@@ -1632,7 +1632,7 @@
 	hun "Tobbszoros elsodleges kulcs definialas."
 	ita "Definite piu` chiave primarie"
@@ -1681,7 +1681,7 @@
 	eng "Too many key parts specified; max %d parts allowed"
 	hun "Tul sok kulcsdarabot definialt. Maximum %d resz engedelyezett"
 	ita "Troppe parti di chiave specificate. Sono ammesse max %d parti"
@@ -1730,7 +1730,7 @@
 	hun "A(z) '%-.64s'kulcsoszlop nem letezik a tablaban"
 	ita "La colonna chiave '%-.64s' non esiste nella tabella"
@@ -1778,7 +1778,7 @@
 	fre "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB"
 	hun "A(z) '%-.64s' oszlop tul hosszu. (maximum = %d). Hasznaljon BLOB tipust inkabb."
 	ita "La colonna '%-.64s' e` troppo grande (max=%d). Utilizza un BLOB."
@@ -1803,7 +1803,7 @@
 	hun "Csak egy auto mezo lehetseges, es azt kulcskent kell definialni."
 	ita "Puo` esserci solo un campo AUTO e deve essere definito come chiave"
@@ -1828,7 +1828,7 @@
 	hun "%s: kapcsolatra kesz"
 	ita "%s: Pronto per le connessioni\n"
@@ -1901,7 +1901,7 @@
-	ger "%-.64s: Heruntergefahren (shutdown)\n"
+	ger "%-.64s: Herunterfahren beendet\n"
 	hun "%s: A leallitas kesz\n"
 	ita "%s: Shutdown completato\n"
@@ -1976,7 +1976,7 @@
-	ger "Tabelle '%-.64s' besitzt keinen wie den in CREATE INDEX verwendeten Index. Index neu anlegen"
+	ger "Tabelle '%-.64s' besitzt keinen wie den in CREATE INDEX verwendeten Index. Tabelle neu anlegen"
 	hun "A(z) '%-.64s' tablahoz nincs meg a CREATE INDEX altal hasznalt index. Alakitsa at a tablat"
 	ita "La tabella '%-.64s' non ha nessun indice come quello specificatato dalla CREATE INDEX. Ricrea la tabella"
@@ -2048,7 +2048,7 @@
 	hun "A(z) '%-.64s'-nak az adatbazis konyvtarban kell lennie, vagy mindenki szamara olvashatonak"
 	ita "Il file '%-.64s' deve essere nella directory del database e deve essere leggibile da tutti"
@@ -2073,7 +2073,7 @@
 	est "Fail '%-.80s' juba eksisteerib"
-	ger "Datei '%-.64s' bereits vorhanden"
+	ger "Datei '%-.80s' bereits vorhanden"
 	hun "A '%-.64s' file mar letezik."
 	ita "Il file '%-.64s' esiste gia`"
@@ -2147,7 +2147,7 @@
 	eng "Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys"
 	hun "Rossz alkulcs. A hasznalt kulcsresz nem karaktersorozat vagy hosszabb, mint a kulcsresz"
 	ita "Sotto-parte della chiave errata. La parte di chiave utilizzata non e` una stringa o la lunghezza e` maggiore della parte di chiave."
@@ -2197,7 +2197,7 @@
 	hun "A DROP '%-.64s' nem lehetseges. Ellenorizze, hogy a mezo/kulcs letezik-e"
 	ita "Impossibile cancellare '%-.64s'. Controllare che il campo chiave esista"
@@ -2325,7 +2325,7 @@
 	eng "Too many strings for column %-.64s and SET"
 	hun "Tul sok karakter: %-.64s es SET"
 	ita "Troppe stringhe per la colonna %-.64s e la SET"
@@ -2348,7 +2348,7 @@
 	eng "Can't generate a unique log-filename %-.64s.(1-999)\n"
 	est "Ei suuda luua unikaalset logifaili nime %-.64s.(1-999)\n"
 	hun "Egyedi log-filenev nem generalhato: %-.64s.(1-999)\n"
 	ita "Impossibile generare un nome del file log unico %-.64s.(1-999)\n"
@@ -2421,7 +2421,7 @@
 	eng "BLOB/TEXT column '%-.64s' can't have a default value"
-	ger "BLOB-Feld '%-.64s' darf keinen Vorgabewert (DEFAULT) haben"
+	ger "BLOB/TEXT-Feld '%-.64s' darf keinen Vorgabewert (DEFAULT) haben"
 	hun "A(z) '%-.64s' blob objektumnak nem lehet alapertelmezett erteke"
 	ita "Il campo BLOB '%-.64s' non puo` avere un valore di default"
@@ -2446,7 +2446,7 @@
 	est "Vigane andmebaasi nimi '%-.100s'"
-	ger "Unerlaubter Datenbankname '%-.64s'"
+	ger "Unerlaubter Datenbankname '%-.100s'"
 	hun "Hibas adatbazisnev: '%-.100s'"
 	ita "Nome database errato '%-.100s'"
@@ -2471,7 +2471,7 @@
 	est "Vigane tabeli nimi '%-.100s'"
-	ger "Unerlaubter Tabellenname '%-.64s'"
+	ger "Unerlaubter Tabellenname '%-.100s'"
 	hun "Hibas tablanev: '%-.100s'"
 	ita "Nome tabella errato '%-.100s'"
@@ -2495,7 +2495,7 @@
 	eng "The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay"
 	hun "A SELECT tul sok rekordot fog megvizsgalni es nagyon sokaig fog tartani. Ellenorizze a WHERE-t es hasznalja a SET SQL_BIG_SELECTS=1 beallitast, ha a SELECT okay"
 	ita "La SELECT dovrebbe esaminare troppi record e usare troppo tempo. Controllare la WHERE e usa SET SQL_BIG_SELECTS=1 se e` tutto a posto."
@@ -2676,7 +2676,7 @@
 	eng "Table '%-.64s' uses an extension that doesn't exist in this MySQL version"
 	est "Tabel '%-.64s' kasutab laiendust, mis ei eksisteeri antud MySQL versioonis"
 	fre "Table '%-.64s' : utilise une extension invalide pour cette version de MySQL"
 	hun "A(z) '%-.64s' tabla olyan bovitest hasznal, amely nem letezik ebben a MySQL versioban."
 	ita "La tabella '%-.64s' usa un'estensione che non esiste in questa versione di MySQL"
@@ -2700,7 +2700,7 @@
 	fre "Une table doit comporter au moins une colonne"
+	ger "Eine Tabelle muss mindestens eine Spalte besitzen"
 	hun "A tablanak legalabb egy oszlopot tartalmazni kell"
 	ita "Una tabella deve avere almeno 1 colonna"
@@ -2788,7 +2788,7 @@
 	est "Liiga palju tulpasid"
 	fre "Trop de champs"
-	ger "Zu viele Spalten"
+	ger "Zu viele Felder"
 	hun "Tul sok mezo"
 	ita "Troppi campi"
@@ -2810,7 +2810,7 @@
 	fre "Ligne trop grande. Le taille maximale d'une ligne, sauf les BLOBs, est %d. Changez le type de quelques colonnes en BLOB"
 	hun "Tul nagy sormeret. A maximalis sormeret (nem szamolva a blob objektumokat) %d. Nehany mezot meg kell valtoztatnia"
 	ita "Riga troppo grande. La massima grandezza di una riga, non contando i BLOB, e` %d. Devi cambiare alcuni campi in BLOB"
@@ -2831,7 +2831,7 @@
 	eng "Thread stack overrun:  Used: %ld of a %ld stack.  Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed"
 	hun "Thread verem tullepes:  Used: %ld of a %ld stack. Hasznalja a 'mysqld -O thread_stack=#' nagyobb verem definialasahoz"
 	ita "Thread stack overrun:  Usati: %ld di uno stack di %ld.  Usa 'mysqld -O thread_stack=#' per specificare uno stack piu` grande."
@@ -3003,15 +3003,15 @@
 ER_CANT_FIND_DL_ENTRY  
-	dan "Kan ikke finde funktionen '%-.64s' i bibliotek'"
+	dan "Kan ikke finde funktionen '%-.64s' i bibliotek"
 	nla "Kan functie '%-.64s' niet in library vinden"
-	eng "Can't find symbol '%-.64s' in library'"
+	eng "Can't find symbol '%-.64s' in library"
 	est "Ei leia funktsiooni '%-.64s' antud teegis"
 	ger "Kann Funktion '%-.64s' in der Library nicht finden"
 	hun "A(z) '%-.64s' fuggveny nem talalhato a konyvtarban"
 	ita "Impossibile trovare la funzione '%-.64s' nella libreria"
@@ -3020,10 +3020,10 @@
 	rum "Nu pot gasi functia '%-.64s' in libraria"
 	serbian "Ne mogu da pronadjem funkciju '%-.64s' u biblioteci"
 	swe "Hittar inte funktionen '%-.64s' in det dynamiska biblioteket"
 ER_FUNCTION_NOT_DEFINED  
 	dan "Funktionen '%-.64s' er ikke defineret"
@@ -3198,7 +3198,7 @@
 	nla "Kolom aantal komt niet overeen met waarde aantal in rij %ld"
 	eng "Column count doesn't match value count at row %ld"
 	hun "Az oszlopban talalhato ertek nem egyezik meg a %ld sorban szamitott ertekkel"
 	ita "Il numero delle colonne non corrisponde al conteggio alla riga %ld"
@@ -3276,7 +3276,7 @@
 	eng "Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause"
 	est "GROUP tulpade (MIN(),MAX(),COUNT()...) kooskasutamine tavaliste tulpadega ilma GROUP BY klauslita ei ole lubatud"
 	hun "A GROUP mezok (MIN(),MAX(),COUNT()...) kevert hasznalata nem lehetseges GROUP BY hivatkozas nelkul"
 	ita "Il mescolare funzioni di aggregazione (MIN(),MAX(),COUNT()...) e non e` illegale se non c'e` una clausula GROUP BY"
@@ -3315,7 +3315,7 @@
 	hun "%-.16s parancs a '%-.32s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' tablaban"
 	ita "Comando %-.16s negato per l'utente: '%-.32s'@'%-.64s' sulla tabella '%-.64s'"
@@ -3335,7 +3335,7 @@
 	hun "%-.16s parancs a '%-.32s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban"
 	ita "Comando %-.16s negato per l'utente: '%-.32s'@'%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'"
@@ -3419,7 +3419,7 @@
 	eng "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'"
 	hun "A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett"
 	ita "GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'"
@@ -3455,7 +3455,7 @@
 	eng "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use"
 	fre "Erreur de syntaxe"
+	ger "Fehler in der SQL-Syntax. Bitte die korrekte Syntax im Handbuch nachschlagen"
 	greek "You have an error in your SQL syntax"
 	hun "Szintaktikai hiba"
 	ita "Errore di sintassi nella query SQL"
@@ -3538,7 +3538,7 @@
 	eng "Got a packet bigger than 'max_allowed_packet' bytes"
 	est "Saabus suurem pakett kui lubatud 'max_allowed_packet' muutujaga"
 	hun "A kapott csomag nagyobb, mint a maximalisan engedelyezett: 'max_allowed_packet'"
 	ita "Ricevuto un pacchetto piu` grande di 'max_allowed_packet'"
@@ -3556,7 +3556,7 @@
 	eng "Got a read error from the connection pipe"
-	ger "Lese-Fehler bei einer Kommunikations-Pipe"
+	ger "Lese-Fehler bei einer Verbindungs-Pipe"
 	hun "Olvasasi hiba a kapcsolat soran"
 	ita "Rilevato un errore di lettura dalla pipe di connessione"
@@ -3700,7 +3700,7 @@
 	eng "Result string is longer than 'max_allowed_packet' bytes"
 	est "Tulemus on pikem kui lubatud 'max_allowed_packet' muutujaga"
 	hun "Ez eredmeny sztring nagyobb, mint a lehetseges maximum: 'max_allowed_packet'"
 	ita "La stringa di risposta e` piu` lunga di 'max_allowed_packet'"
@@ -3717,7 +3717,7 @@
 	eng "The used table type doesn't support BLOB/TEXT columns"
 	fre "Ce type de table ne supporte pas les colonnes BLOB/TEXT"
 	hun "A hasznalt tabla tipus nem tamogatja a BLOB/TEXT mezoket"
 	ita "Il tipo di tabella usata non supporta colonne di tipo BLOB/TEXT"
@@ -3734,7 +3734,7 @@
 	eng "The used table type doesn't support AUTO_INCREMENT columns"
 	fre "Ce type de table ne supporte pas les colonnes AUTO_INCREMENT"
 	hun "A hasznalt tabla tipus nem tamogatja az AUTO_INCREMENT tipusu mezoket"
 	ita "Il tipo di tabella usata non supporta colonne di tipo AUTO_INCREMENT"
@@ -3751,7 +3751,7 @@
 	eng "INSERT DELAYED can't be used with table '%-.64s' because it is locked with LOCK TABLES"
-	ger "INSERT DELAYED kann nicht auf Tabelle '%-.64s' angewendet werden, da diese mit LOCK TABLES gesperrt ist"
 	greek "INSERT DELAYED can't be used with table '%-.64s', because it is locked with LOCK TABLES"
 	hun "Az INSERT DELAYED nem hasznalhato a '%-.64s' tablahoz, mert a tabla zarolt (LOCK TABLES)"
 	ita "L'inserimento ritardato (INSERT DELAYED) non puo` essere usato con la tabella '%-.64s', perche` soggetta a lock da 'LOCK TABLES'"
@@ -3792,7 +3792,7 @@
 	eng "The used storage engine can't index column '%-.64s'"
 	est "Tabelihandler ei oska indekseerida tulpa '%-.64s'"
-	ger "Der verwendete Tabellen-Handler kann die Spalte '%-.64s' nicht indizieren"
+	ger "Die verwendete Speicher-Engine kann die Spalte '%-.64s' nicht indizieren"
 	greek "The used table handler can't index column '%-.64s'"
 	hun "A hasznalt tablakezelo nem tudja a '%-.64s' mezot indexelni"
 	ita "Il gestore delle tabelle non puo` indicizzare la colonna '%-.64s'"
@@ -3839,7 +3839,7 @@
 	eng "Can't write, because of unique constraint, to table '%-.64s'"
 	hun "A '%-.64s' nem irhato, az egyedi mezok miatt"
 	ita "Impossibile scrivere nella tabella '%-.64s' per limitazione di unicita`"
@@ -3880,7 +3880,7 @@
 	eng "All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead"
 	hun "Az elsodleges kulcs teljes egeszeben csak NOT NULL tipusu lehet; Ha NULL mezot szeretne a kulcskent, hasznalja inkabb a UNIQUE-ot"
 	ita "Tutte le parti di una chiave primaria devono essere dichiarate NOT NULL; se necessitano valori NULL nelle chiavi utilizzare UNIQUE"
@@ -3914,7 +3914,7 @@
 	eng "This table type requires a primary key"
 	hun "Az adott tablatipushoz elsodleges kulcs hasznalata kotelezo"
 	ita "Questo tipo di tabella richiede una chiave primaria"
@@ -3948,7 +3948,7 @@
 	eng "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column"
 	est "Katse muuta tabelit turvalises rezhiimis ilma WHERE klauslita"
 	hun "On a biztonsagos update modot hasznalja, es        WHERE that uses a KEY column"
 	ita "In modalita` 'safe update' si e` cercato di aggiornare una tabella senza clausola WHERE su una chiave"
@@ -4100,7 +4100,7 @@
 	eng "Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: '%-.64s' (%-.64s)"
-	ger "Verbindungsabbruch  %ld zur Datenbank '%-.64s'. Benutzer: '%-.32s', Host: '%-.64s' (%-.64s)"
+	ger "Abbruch der Verbindung %ld zur Datenbank '%-.64s'. Benutzer: '%-.32s', Host: '%-.64s' (%-.64s)"
 	ita "Interrotta la connessione %ld al db: ''%-.64s' utente: '%-.32s' host: '%-.64s' (%-.64s)"
@@ -4137,7 +4137,7 @@
 	nla "Gefaald tijdens heropbouw index van gedumpte tabel '%-.64s'"
 	eng "Failed rebuilding the index of  dumped table '%-.64s'"
-	ger "Neuerstellung des Indizes der Dump-Tabelle '%-.64s' fehlgeschlagen"
+	ger "Neuerstellung des Index der Dump-Tabelle '%-.64s' fehlgeschlagen"
 	greek "Failed rebuilding the index of dumped table '%-.64s'"
 	hun "Failed rebuilding the index of dumped table '%-.64s'"
 	ita "Fallita la ricostruzione dell'indice della tabella copiata '%-.64s'"
@@ -4195,7 +4195,7 @@
 	eng "Can't find FULLTEXT index matching the column list"
 	est "Ei suutnud leida FULLTEXT indeksit, mis kattuks kasutatud tulpadega"
-	ger "Kann keinen FULLTEXT-Index finden, der der Spaltenliste entspricht"
+	ger "Kann keinen FULLTEXT-Index finden, der der Feldliste entspricht"
 	ita "Impossibile trovare un indice FULLTEXT che corrisponda all'elenco delle colonne"
@@ -4283,7 +4283,7 @@
 	eng "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again"
 	ita "La transazione a comandi multipli (multi-statement) ha richiesto piu` di 'max_binlog_cache_size' bytes di disco: aumentare questa variabile di mysqld e riprovare"
@@ -4295,7 +4295,7 @@
 	nla "Deze operatie kan niet worden uitgevoerd met een actieve slave, doe eerst STOP SLAVE"
 	eng "This operation cannot be performed with a running slave; run STOP SLAVE first"
 	ita "Questa operazione non puo' essere eseguita con un database 'slave' che gira, lanciare prima STOP SLAVE"
@@ -4332,6 +4332,7 @@
 ER_MASTER_INFO  
 	eng "Could not initialize master info structure; more error messages can be found in the MySQL error log"
 	serbian "Nisam mogao da inicijalizujem informacionu strukturu glavnog servera, proverite da li imam privilegije potrebne za pristup file-u 'master.info'"
 ER_SLAVE_THREAD  
@@ -4339,7 +4340,7 @@
 	nla "Kon slave thread niet aanmaken, controleer systeem resources"
 	eng "Could not create slave thread; check system resources"
 	ita "Impossibile creare il thread 'slave', controllare le risorse di sistema"
@@ -4353,7 +4354,7 @@
 	eng "User %-.64s already has more than 'max_user_connections' active connections"
-	ger "Benutzer '%-.64s' hat mehr als max_user_connections aktive Verbindungen"
+	ger "Benutzer '%-.64s' hat mehr als 'max_user_connections' aktive Verbindungen"
 	ita "L'utente %-.64s ha gia' piu' di 'max_user_connections' connessioni attive"
@@ -4409,7 +4410,7 @@
 	eng "Update locks cannot be acquired during a READ UNCOMMITTED transaction"
 	ita "I lock di aggiornamento non possono essere acquisiti durante una transazione 'READ UNCOMMITTED'"
@@ -4463,7 +4464,7 @@
 	eng "'%-.32s'@'%-.64s' is not allowed to create new users"
 	est "Kasutajal '%-.32s'@'%-.64s' ei ole lubatud luua uusi kasutajaid"
 	ita "A '%-.32s'@'%-.64s' non e' permesso creare nuovi utenti"
@@ -4488,7 +4489,7 @@
 	eng "Deadlock found when trying to get lock; try restarting transaction"
 	est "Lukustamisel tekkis tupik (deadlock); alusta transaktsiooni otsast"
-	ger "Beim Versuch, eine Sperre anzufordern, ist ein Deadlock aufgetreten. Versuchen Sie, die Transaktion erneut zu starten"
+	ger "Beim Versuch, eine Sperre anzufordern, ist ein Deadlock aufgetreten. Versuchen Sie, die Transaktion neu zu starten"
 	ita "Trovato deadlock durante il lock; Provare a far ripartire la transazione"
@@ -4512,7 +4513,7 @@
 	nla "Kan foreign key beperking niet toevoegen"
 	eng "Cannot add foreign key constraint"
 	fre "Impossible d'ajouter des contraintes d'index externe"
 	ita "Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)"
@@ -4523,7 +4524,7 @@
 	nla "Kan onderliggende rij niet toevoegen: foreign key beperking gefaald"
 	eng "Cannot add or update a child row: a foreign key constraint fails"
 	greek "Cannot add a child row: a foreign key constraint fails"
 	hun "Cannot add a child row: a foreign key constraint fails"
 	ita "Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto"
@@ -4535,7 +4536,7 @@
 ER_ROW_IS_REFERENCED 23000 
 	eng "Cannot delete or update a parent row: a foreign key constraint fails"
 	greek "Cannot delete a parent row: a foreign key constraint fails"
 	hun "Cannot delete a parent row: a foreign key constraint fails"
 	ita "Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto"
@@ -4589,7 +4590,7 @@
 	nla "De gebruikte SELECT commando's hebben een verschillend aantal kolommen"
 	eng "The used SELECT statements have a different number of columns"
 	est "Tulpade arv kasutatud SELECT lausetes ei kattu"
 	ita "La SELECT utilizzata ha un numero di colonne differente"
@@ -4600,7 +4601,7 @@
 	nla "Kan de query niet uitvoeren vanwege een conflicterende read lock"
 	eng "Can't execute the query because you have a conflicting read lock"
 	ita "Impossibile eseguire la query perche' c'e' un conflitto con in lock di lettura"
@@ -4640,7 +4641,7 @@
 ER_SPECIFIC_ACCESS_DENIED_ERROR 42000 
 	nla "Toegang geweigerd. U moet het %-.128s privilege hebben voor deze operatie"
 	eng "Access denied; you need the %-.128s privilege for this operation"
 	ita "Accesso non consentito. Serve il privilegio %-.128s per questa operazione"
@@ -4722,7 +4723,7 @@
 ER_MASTER_FATAL_ERROR_READING_BINLOG  
 	nla "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log"
 	eng "Got fatal error %d: '%-.128s' from master when reading data from binary log"
 	ita "Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario"
 	por "Obteve fatal erro %d: '%-.128s' do master quando lendo dados do binary log"
@@ -4737,11 +4738,12 @@
 ER_INCORRECT_GLOBAL_LOCAL_VAR  
 	eng "Variable '%-.64s' is a %s variable"
 	serbian "Incorrect foreign key definition for '%-.64s': %s"
+	ger "Variable '%-.64s' ist eine %s-Variable"
 	spa "Variable '%-.64s' es una %s variable"
 ER_WRONG_FK_DEF 42000 
 	eng "Incorrect foreign key definition for '%-.64s': %s"
@@ -4753,7 +4755,7 @@
 ER_OPERAND_COLUMNS 21000 
 	eng "Operand should contain %d column(s)"
-	ger "Operand solle %d Spalte(n) enthalten"
+	ger "Operand sollte %d Spalte(n) enthalten"
 	spa "Operando debe tener %d columna(s)"
@@ -4789,7 +4791,7 @@
 ER_AUTO_CONVERT  
 	eng "Converting column '%s' from %s to %s"
-	ger "Spalte '%s' wird von %s nach %s umgewandelt"
+	ger "Feld '%s' wird von %s nach %s umgewandelt"
 	por "Convertendo coluna '%s' de %s para %s"
 	spa "Convirtiendo columna '%s' de %s para %s"
@@ -4831,7 +4833,7 @@
 ER_SPATIAL_CANT_HAVE_NULL 42000 
 	eng "All parts of a SPATIAL index must be NOT NULL"
 	por "Todas as partes de uma SPATIAL index devem ser NOT NULL"
 	spa "Todas las partes de una SPATIAL index deben ser NOT NULL"
@@ -4855,12 +4857,12 @@
 	swe "Slaven har redan stoppat"
 ER_TOO_BIG_FOR_UNCOMPRESS  
 	eng "Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted)"
 ER_ZLIB_Z_MEM_ERROR  
 	eng "ZLIB: Not enough memory"
+	ger "ZLIB: Nicht genug Speicher"
 	spa "Z_MEM_ERROR: No suficiente memoria para zlib"
 ER_ZLIB_Z_BUF_ERROR  
@@ -4882,27 +4884,24 @@
 	ukr "%d line(s) was(were) cut by group_concat()"
 ER_WARN_TOO_FEW_RECORDS 01000 
 	eng "Row %ld doesn't contain data for all columns"
 ER_WARN_TOO_MANY_RECORDS 01000 
 	eng "Row %ld was truncated; it contained more data than there were input columns"
 ER_WARN_NULL_TO_NOTNULL 22004 
 	eng "Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld"
 	por "Dado truncado, NULL fornecido para NOT NULL coluna '%s' na linha %ld"
 ER_WARN_DATA_OUT_OF_RANGE 22003 
-	eng "Out of range value adjusted for column '%s' at row %ld"
-	por "Dado truncado, fora de alcance para coluna '%s' na linha %ld"
+	eng "Out of range value for column '%s' at row %ld"
 WARN_DATA_TRUNCATED 01000 
 	eng "Data truncated for column '%s' at row %ld"
 	por "Dado truncado para coluna '%s' na linha %ld"
 ER_WARN_USING_OTHER_HANDLER  
@@ -4913,40 +4912,40 @@
 ER_CANT_AGGREGATE_2COLLATIONS  
 	eng "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'"
 ER_DROP_USER  
 	eng "Cannot drop one or more of the requested users"
 ER_REVOKE_GRANTS  
-	eng "Can't revoke all privileges, grant for one or more of the requested users"
-	ger "Kann nicht alle Berechtigungen widerrufen, grant for one or more of the requested users"
+	eng "Can't revoke all privileges for one or more of the requested users"
 	spa "No puede revocar todos los privilegios, derecho para uno o mas de los usuarios solicitados"
 ER_CANT_AGGREGATE_3COLLATIONS  
 	eng "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'"
 ER_CANT_AGGREGATE_NCOLLATIONS  
 	eng "Illegal mix of collations for operation '%s'"
 ER_VARIABLE_IS_NOT_STRUCT  
 	eng "Variable '%-.64s' is not a variable component (can't be used as XXXX.variable_name)"
-	ger "Variable '%-.64s' ist keine Variablen-Komponenten (kann nicht als XXXX.variablen_name verwendet werden)"
+	ger "Variable '%-.64s' ist keine Variablen-Komponente (kann nicht als XXXX.variablen_name verwendet werden)"
 	spa "Variable '%-.64s' no es una variable componente (No puede ser usada como XXXX.variable_name)"
 ER_UNKNOWN_COLLATION  
 	eng "Unknown collation: '%-.64s'"
-	ger "Unbekannte Kollation: '%-.64s'"
+	ger "Unbekannte Sortierreihenfolge: '%-.64s'"
 	por "Collation desconhecida: '%-.64s'"
 	spa "Collation desconocida: '%-.64s'"
 ER_SLAVE_IGNORED_SSL_PARAMS  
 	eng "SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support; they can be used later if MySQL slave with SSL is started"
 	spa "Parametros SSL en CHANGE MASTER son ignorados porque este slave MySQL fue compilado sin soporte SSL; pueden ser usados despues cuando el slave MySQL con SSL sea inicializado"
 ER_SERVER_IS_IN_SECURE_AUTH_MODE  
@@ -4969,7 +4968,7 @@
 ER_MISSING_SKIP_SLAVE  
 	eng "It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL; otherwise, you will get problems if you get an unexpected slave's mysqld restart"
 ER_UNTIL_COND_IGNORED  
@@ -4979,16 +4978,19 @@
 	spa "SQL thread no es inicializado tal que opciones UNTIL son ignoradas"
 ER_WRONG_NAME_FOR_INDEX 42000 
 	eng "Incorrect index name '%-.100s'"
+	ger "Falscher Indexname '%-.100s'"
 	swe "Felaktigt index namn '%-.100s'"
 ER_WRONG_NAME_FOR_CATALOG 42000 
 	eng "Incorrect catalog name '%-.100s'"
+	ger "Falscher Katalogname '%-.100s'"
 	spa "Nombre de catalog incorrecto '%-.100s'"
 	swe "Felaktigt katalog namn '%-.100s'"
 ER_WARN_QC_RESIZE  
 	eng "Query cache failed to set size %lu; new query cache size is %lu"
@@ -4996,28 +4998,34 @@
 ER_BAD_FT_COLUMN  
 	eng "Column '%-.64s' cannot be part of FULLTEXT index"
+	ger "Feld '%-.64s' kann nicht Teil eines FULLTEXT-Index sein"
 	spa "Columna '%-.64s' no puede ser parte de FULLTEXT index"
 	swe "Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index"
 ER_UNKNOWN_KEY_CACHE  
 	eng "Unknown key cache '%-.100s'"
 	por "Key cache desconhecida '%-.100s'"
 	spa "Desconocida key cache '%-.100s'"
 ER_WARN_HOSTNAME_WONT_WORK  
 	eng "MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work"
 ER_UNKNOWN_STORAGE_ENGINE 42000 
 	eng "Unknown table engine '%s'"
+	ger "Unbekannte Speicher-Engine '%s'"
 	por "Motor de tabela desconhecido '%s'"
 	spa "Desconocido motor de tabla '%s'"
 ER_WARN_DEPRECATED_SYNTAX  
 	eng "'%s' is deprecated; use '%s' instead"
+	ger "'%s' ist veraltet. Bitte benutzen Sie '%s'"
 ER_NON_UPDATABLE_TABLE  
 	eng "The target table %-.100s of the %s is not updatable"
+	ger "Die Zieltabelle %-.100s von %s ist nicht aktualisierbar"
 	spa "La tabla destino %-.100s del %s no es actualizable"
@@ -5025,402 +5033,575 @@
 ER_FEATURE_DISABLED  
 	eng "The '%s' feature is disabled; you need MySQL built with '%s' to have it working"
 	spa "El recurso '%s' fue deshabilitado; usted necesita construir MySQL con '%s' para tener eso funcionando"
 ER_OPTION_PREVENTS_STATEMENT  
 	eng "The MySQL server is running with the %s option so it cannot execute this statement"
 ER_DUPLICATED_VALUE_IN_TYPE  
 	eng "Column '%-.100s' has duplicated value '%-.64s' in %s"
+	ger "Feld '%-.100s' hat doppelten Wert '%-.64s' in %s"
 	por "Coluna '%-.100s' tem valor duplicado '%-.64s' em %s"
 	spa "Columna '%-.100s' tiene valor doblado '%-.64s' en %s"
 ER_TRUNCATED_WRONG_VALUE 22007 
 	eng "Truncated incorrect %-.32s value: '%-.128s'"
 	por "Truncado errado %-.32s valor: '%-.128s'"
 	spa "Equivocado truncado %-.32s valor: '%-.128s'"
 ER_TOO_MUCH_AUTO_TIMESTAMP_COLS  
 	eng "Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
+	ger "Fehlerhafte Tabellendefinition. Es kann nur eine einzige TIMESTAMP-Spalte mit CURRENT_TIMESTAMP als DEFAULT oder in einer ON-UPDATE-Klausel geben"
 ER_INVALID_ON_UPDATE  
 	eng "Invalid ON UPDATE clause for '%-.64s' column"
 ER_UNSUPPORTED_PS  
 	eng "This command is not supported in the prepared statement protocol yet"
 ER_GET_ERRMSG  
 	dan "Modtog fejl %d '%-.100s' fra %s"
 	eng "Got error %d '%-.100s' from %s"
+	ger "Fehler %d '%-.100s' von %s"
 	nor "Mottok feil %d '%-.100s' fa %s"
 	norwegian-ny "Mottok feil %d '%-.100s' fra %s"
 ER_GET_TEMPORARY_ERRMSG  
 	dan "Modtog temporary fejl %d '%-.100s' fra %s"
 	eng "Got temporary error %d '%-.100s' from %s"
 	nor "Mottok temporary feil %d '%-.100s' fra %s"
 	norwegian-ny "Mottok temporary feil %d '%-.100s' fra %s"
 ER_UNKNOWN_TIME_ZONE  
 	eng "Unknown or incorrect time zone: '%-.64s'"
+	ger "Unbekannte oder falsche Zeitzone: '%-.64s'"
 ER_WARN_INVALID_TIMESTAMP  
 	eng "Invalid TIMESTAMP value in column '%s' at row %ld"
 ER_INVALID_CHARACTER_STRING  
 	eng "Invalid %s character string: '%.64s'"
 ER_WARN_ALLOWED_PACKET_OVERFLOWED  
 	eng "Result of %s() was larger than max_allowed_packet (%ld) - truncated"
 ER_CONFLICTING_DECLARATIONS  
 	eng "Conflicting declarations: '%s%s' and '%s%s'"
 ER_SP_NO_RECURSIVE_CREATE 2F003 
 	eng "Can't create a %s from within another stored routine"
+	ger "Kann kein %s innerhalb einer anderen gespeicherten Routine erzeugen"
 ER_SP_ALREADY_EXISTS 42000 
 	eng "%s %s already exists"
+	ger "%s %s existiert bereits"
 ER_SP_DOES_NOT_EXIST 42000 
 	eng "%s %s does not exist"
+	ger "%s %s existiert nicht"
 ER_SP_DROP_FAILED  
 	eng "Failed to DROP %s %s"
+	ger "DROP %s %s ist fehlgeschlagen"
 ER_SP_STORE_FAILED  
 	eng "Failed to CREATE %s %s"
+	ger "CREATE %s %s ist fehlgeschlagen"
 ER_SP_LILABEL_MISMATCH 42000 
 	eng "%s with no matching label: %s"
+	ger "%s ohne passende Marke: %s"
 ER_SP_LABEL_REDEFINE 42000 
 	eng "Redefining label %s"
+	ger "Neudefinition der Marke %s"
 ER_SP_LABEL_MISMATCH 42000 
 	eng "End-label %s without match"
 ER_SP_UNINIT_VAR 01000 
 	eng "Referring to uninitialized variable %s"
+	ger "Zugriff auf nichtinitialisierte Variable %s"
 ER_SP_BADSELECT 0A000 
 	eng "PROCEDURE %s can't return a result set in the given context"
 ER_SP_BADRETURN 42000 
 	eng "RETURN is only allowed in a FUNCTION"
+	ger "RETURN ist nur innerhalb einer FUNCTION erlaubt"
 ER_SP_BADSTATEMENT 0A000 
 	eng "%s is not allowed in stored procedures"
+	ger "%s ist in gespeicherten Prozeduren nicht erlaubt"
 ER_UPDATE_LOG_DEPRECATED_IGNORED 42000 
 	eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored"
 ER_UPDATE_LOG_DEPRECATED_TRANSLATED 42000 
 	eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN"
 ER_QUERY_INTERRUPTED 70100 
 	eng "Query execution was interrupted"
 ER_SP_WRONG_NO_OF_ARGS 42000 
 	eng "Incorrect number of arguments for %s %s; expected %u, got %u"
 ER_SP_COND_MISMATCH 42000 
 	eng "Undefined CONDITION: %s"
+	ger "Undefinierte CONDITION: %s"
 ER_SP_NORETURN 42000 
 	eng "No RETURN found in FUNCTION %s"
+	ger "Kein RETURN in FUNCTION %s gefunden"
 ER_SP_NORETURNEND 2F005 
 	eng "FUNCTION %s ended without RETURN"
+	ger "FUNCTION %s endete ohne RETURN"
 ER_SP_BAD_CURSOR_QUERY 42000 
 	eng "Cursor statement must be a SELECT"
+	ger "Cursor-Anweisung muss ein SELECT sein"
 ER_SP_BAD_CURSOR_SELECT 42000 
 	eng "Cursor SELECT must not have INTO"
+	ger "Cursor-SELECT darf kein INTO haben"
 ER_SP_CURSOR_MISMATCH 42000 
 	eng "Undefined CURSOR: %s"
+	ger "Undefinierter CURSOR: %s"
 ER_SP_CURSOR_ALREADY_OPEN 24000 
 	eng "Cursor is already open"
 ER_SP_CURSOR_NOT_OPEN 24000 
 	eng "Cursor is not open"
 ER_SP_UNDECLARED_VAR 42000 
 	eng "Undeclared variable: %s"
+	ger "Nicht deklarierte Variable: %s"
 ER_SP_WRONG_NO_OF_FETCH_ARGS  
 	eng "Incorrect number of FETCH variables"
+	ger "Falsche Anzahl von FETCH-Variablen"
 ER_SP_FETCH_NO_DATA 02000 
 	eng "No data to FETCH"
+	ger "Keine Daten mit FETCH abzuholen"
 ER_SP_DUP_PARAM 42000 
 	eng "Duplicate parameter: %s"
+	ger "Doppelter Parameter: %s"
 ER_SP_DUP_VAR 42000 
 	eng "Duplicate variable: %s"
+	ger "Doppelte Variable: %s"
 ER_SP_DUP_COND 42000 
 	eng "Duplicate condition: %s"
+	ger "Doppelte Bedingung: %s"
 ER_SP_DUP_CURS 42000 
 	eng "Duplicate cursor: %s"
+	ger "Doppelter Cursor: %s"
 ER_SP_CANT_ALTER  
 	eng "Failed to ALTER %s %s"
+	ger "ALTER %s %s fehlgeschlagen"
 ER_SP_SUBSELECT_NYI 0A000 
 	eng "Subselect value not supported"
 ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG 0A000
         eng "%s is not allowed in stored function or trigger"
+	ger "%s ist in gespeicherten Funktionen und in Triggern nicht erlaubt"
 ER_SP_VARCOND_AFTER_CURSHNDLR 42000 
 	eng "Variable or condition declaration after cursor or handler declaration"
+	ger "Deklaration einer Variablen oder einer Bedingung nach der Deklaration eines Cursors oder eines Handlers"
 ER_SP_CURSOR_AFTER_HANDLER 42000 
 	eng "Cursor declaration after handler declaration"
+	ger "Deklaration eines Cursors nach der Deklaration eines Handlers"
 ER_SP_CASE_NOT_FOUND 20000 
 	eng "Case not found for CASE statement"
 ER_FPARSER_TOO_BIG_FILE  
 	eng "Configuration file '%-.64s' is too big"
 ER_FPARSER_BAD_HEADER  
 	eng "Malformed file type header in file '%-.64s'"
+	ger "Nicht wohlgeformter Dateityp-Header in Datei '%-.64s'"
 ER_FPARSER_EOF_IN_COMMENT  
 	eng "Unexpected end of file while parsing comment '%-.64s'"
+	ger "Unerwartetes Dateiende beim Parsen des Kommentars '%-.64s'"
 ER_FPARSER_ERROR_IN_PARAMETER  
 	eng "Error while parsing parameter '%-.64s' (line: '%-.64s')"
+	ger "Fehler beim Parsen des Parameters '%-.64s' (Zeile: '%-.64s')"
 ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER  
 	eng "Unexpected end of file while skipping unknown parameter '%-.64s'"
 ER_VIEW_NO_EXPLAIN  
 	eng "EXPLAIN/SHOW can not be issued; lacking privileges for underlying table"
 ER_FRM_UNKNOWN_TYPE  
 	eng "File '%-.64s' has unknown type '%-.64s' in its header"
+	ger "Datei '%-.64s' hat unbekannten Typ '%-.64s' im Header"
 ER_WRONG_OBJECT  
 	eng "'%-.64s.%-.64s' is not %s"
+	ger "'%-.64s.%-.64s' ist nicht %s"
 ER_NONUPDATEABLE_COLUMN  
 	eng "Column '%-.64s' is not updatable"
+	ger "Feld '%-.64s' ist nicht aktualisierbar"
 ER_VIEW_SELECT_DERIVED  
 	eng "View's SELECT contains a subquery in the FROM clause"
 ER_VIEW_SELECT_CLAUSE  
 	eng "View's SELECT contains a '%s' clause"
 ER_VIEW_SELECT_VARIABLE  
 	eng "View's SELECT contains a variable or parameter"
 ER_VIEW_SELECT_TMPTABLE  
 	eng "View's SELECT refers to a temporary table '%-.64s'"
 ER_VIEW_WRONG_LIST  
 	eng "View's SELECT and view's field list have different column counts"
+	ger "SELECT- und Feldliste der Views haben unterschiedliche Anzahlen von Spalten"
 ER_WARN_VIEW_MERGE  
 	eng "View merge algorithm can't be used here for now (assumed undefined algorithm)"
+	ger "View-Merge-Algorithmus kann hier momentan nicht verwendet werden (undefinierter Algorithmus wird angenommen)"
 ER_WARN_VIEW_WITHOUT_KEY  
 	eng "View being updated does not have complete key of underlying table in it"
 ER_VIEW_INVALID  
 	eng "View '%-.64s.%-.64s' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them"
 ER_SP_NO_DROP_SP  
 	eng "Can't drop or alter a %s from within another stored routine"
 ER_SP_GOTO_IN_HNDLR  
 	eng "GOTO is not allowed in a stored procedure handler"
+	ger "GOTO ist im Handler einer gespeicherten Prozedur nicht erlaubt"
 ER_TRG_ALREADY_EXISTS  
 	eng "Trigger already exists"
+	ger "Trigger existiert bereits"
 ER_TRG_DOES_NOT_EXIST  
 	eng "Trigger does not exist"
+	ger "Trigger existiert nicht"
 ER_TRG_ON_VIEW_OR_TEMP_TABLE  
 	eng "Trigger's '%-.64s' is view or temporary table"
 ER_TRG_CANT_CHANGE_ROW  
 	eng "Updating of %s row is not allowed in %strigger"
+	ger "Aktualisieren einer %s-Zeile ist in einem %-Trigger nicht erlaubt"
 ER_TRG_NO_SUCH_ROW_IN_TRG  
 	eng "There is no %s row in %s trigger"
+	ger "Es gibt keine %s-Zeile im %s-Trigger"
 ER_NO_DEFAULT_FOR_FIELD  
 	eng "Field '%-.64s' doesn't have a default value"
+	ger "Feld '%-.64s' hat keinen Vorgabewert"
 ER_DIVISION_BY_ZERO 22012 
 	eng "Division by 0"
+	ger "Division durch 0"
 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD  
 	eng "Incorrect %-.32s value: '%-.128s' for column '%.64s' at row %ld"
 ER_ILLEGAL_VALUE_FOR_TYPE 22007 
 	eng "Illegal %s '%-.64s' value found during parsing"
 ER_VIEW_NONUPD_CHECK  
 	eng "CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
+	ger "CHECK OPTION auf nicht-aktualisierbarem View '%-.64s.%-.64s'"
 ER_VIEW_CHECK_FAILED  
 	eng "CHECK OPTION failed '%-.64s.%-.64s'"
+	ger "CHECK OPTION fehlgeschlagen: '%-.64s.%-.64s'"
 ER_PROCACCESS_DENIED_ERROR 42000 
 	eng "%-.16s command denied to user '%-.32s'@'%-.64s' for routine '%-.64s'"
 ER_RELAY_LOG_FAIL  
 	eng "Failed purging old relay logs: %s"
+	ger "Bereinigen alter Relais-Logs fehlgeschlagen: %s"
 ER_PASSWD_LENGTH  
 	eng "Password hash should be a %d-digit hexadecimal number"
+	ger "Passwort-Hash sollte eine Hexdaezimalzahl mit %d Stellen sein"
 ER_UNKNOWN_TARGET_BINLOG  
 	eng "Target log not found in binlog index"
+	ger "Ziel-Log im Binlog-Index nicht gefunden"
 ER_IO_ERR_LOG_INDEX_READ  
 	eng "I/O error reading log index file"
+	ger "Fehler beim Lesen der Log-Index-Datei"
 ER_BINLOG_PURGE_PROHIBITED  
 	eng "Server configuration does not permit binlog purge"
+	ger "Server-Konfiguration erlaubt keine Binlog-Bereinigung"
 ER_FSEEK_FAIL  
 	eng "Failed on fseek()"
+	ger "fseek() fehlgeschlagen"
 ER_BINLOG_PURGE_FATAL_ERR  
 	eng "Fatal error during log purge"
+	ger "Schwerwiegender Fehler bei der Log-Bereinigung"
 ER_LOG_IN_USE  
 	eng "A purgeable log is in use, will not purge"
+	ger "Ein zu bereinigendes Log wird gerade benutzt, daher keine Bereinigung"
 ER_LOG_PURGE_UNKNOWN_ERR  
 	eng "Unknown error during log purge"
+	ger "Unbekannter Fehler bei Log-Bereinigung"
 ER_RELAY_LOG_INIT  
 	eng "Failed initializing relay log position: %s"
+	ger "Initialisierung der Relais-Log-Position fehlgeschlagen: %s"
 ER_NO_BINARY_LOGGING  
 	eng "You are not using binary logging"
 ER_RESERVED_SYNTAX  
 	eng "The '%-.64s' syntax is reserved for purposes internal to the MySQL server"
 ER_WSAS_FAILED  
 	eng "WSAStartup Failed"
+	ger "WSAStartup fehlgeschlagen"
 ER_DIFF_GROUPS_PROC  
 	eng "Can't handle procedures with differents groups yet"
+	ger "Kann Prozeduren mit unterschiedlichen Gruppen noch nicht verarbeiten"
 ER_NO_GROUP_FOR_PROC  
 	eng "Select must have a group with this procedure"
+	ger "SELECT muss bei dieser Prozedur ein GROUP BY haben"
 ER_ORDER_WITH_PROC  
 	eng "Can't use ORDER clause with this procedure"
+	ger "Kann bei dieser Prozedur keine ORDER-BY-Klausel verwenden"
 ER_LOGGING_PROHIBIT_CHANGING_OF  
 	eng "Binary logging and replication forbid changing the global server %s"
 ER_NO_FILE_MAPPING  
 	eng "Can't map file: %-.64s, errno: %d"
+	ger "Kann Datei nicht abbilden: %-.64s, Fehler: %d"
 ER_WRONG_MAGIC  
 	eng "Wrong magic in %-.64s"
+	ger "Falsche magische Zahlen in %-.64s"
 ER_PS_MANY_PARAM  
 	eng "Prepared statement contains too many placeholders"
 ER_KEY_PART_0  
 	eng "Key part '%-.64s' length cannot be 0"
 ER_VIEW_CHECKSUM  
 	eng "View text checksum failed"
 ER_VIEW_MULTIUPDATE  
 	eng "Can not modify more than one base table through a join view '%-.64s.%-.64s'"
 ER_VIEW_NO_INSERT_FIELD_LIST  
 	eng "Can not insert into join view '%-.64s.%-.64s' without fields list"
 ER_VIEW_DELETE_MERGE_VIEW  
 	eng "Can not delete from join view '%-.64s.%-.64s'"
 ER_CANNOT_USER  
 	eng "Operation %s failed for %.256s"
 	norwegian-ny "Operation %s failed for '%.256s'"
 ER_XAER_NOTA XAE04
         eng "XAER_NOTA: Unknown XID"
+	ger "XAER_NOTA: Unbekannte XID"
 ER_XAER_INVAL XAE05
         eng "XAER_INVAL: Invalid arguments (or unsupported command)"
 ER_XAER_RMFAIL XAE07
         eng "XAER_RMFAIL: The command cannot be executed when global transaction is in the  %.64s state"
 ER_XAER_OUTSIDE XAE09
         eng "XAER_OUTSIDE: Some work is done outside global transaction"
 ER_XAER_RMERR XAE03
         eng "XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency"
 ER_XA_RBROLLBACK XA100
         eng "XA_RBROLLBACK: Transaction branch was rolled back"
 ER_NONEXISTING_PROC_GRANT 42000 
 	eng "There is no such grant defined for user '%-.32s' on host '%-.64s' on routine '%-.64s'"
 ER_PROC_AUTO_GRANT_FAIL
 	eng "Failed to grant EXECUTE and ALTER ROUTINE privileges"
 ER_PROC_AUTO_REVOKE_FAIL
 	eng "Failed to revoke all privileges to dropped routine"
 ER_DATA_TOO_LONG 22001
 	eng "Data too long for column '%s' at row %ld"
 ER_SP_BAD_SQLSTATE 42000
 	eng "Bad SQLSTATE: '%s'"
 ER_STARTUP
 	eng "%s: ready for connections.\nVersion: '%s'  socket: '%s'  port: %d  %s"
 ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR
         eng "Can't load value from file with fixed size rows to variable"
 ER_CANT_CREATE_USER_WITH_GRANT 42000
 	eng "You are not allowed to create a user with GRANT"
 ER_WRONG_VALUE_FOR_TYPE  
 	eng "Incorrect %-.32s value: '%-.128s' for function %-.32s"
 ER_TABLE_DEF_CHANGED
 	eng "Table definition has changed, please retry transaction"
 ER_SP_DUP_HANDLER 42000
 	eng "Duplicate handler declared in the same block"
+	ger "Doppelter Handler im selben Block deklariert"
 ER_SP_NOT_VAR_ARG 42000
 	eng "OUT or INOUT argument %d for routine %s is not a variable"
 ER_SP_NO_RETSET 0A000
 	eng "Not allowed to return a result set from a %s"
 ER_CANT_CREATE_GEOMETRY_OBJECT 22003 
 	eng "Cannot get geometry object from data you send to the GEOMETRY field"
 ER_FAILED_ROUTINE_BREAK_BINLOG
 	eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
 ER_BINLOG_UNSAFE_ROUTINE
-	eng "This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
+	eng "This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
 ER_BINLOG_CREATE_ROUTINE_NEED_SUPER
-	eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
+	eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
 ER_EXEC_STMT_WITH_OPEN_CURSOR
 	eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it."
 ER_STMT_HAS_NO_OPEN_CURSOR
 	eng "The statement (%lu) has no open cursor."
 ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
         eng "Explicit or implicit commit is not allowed in stored function or trigger."
+	ger "Explizites oder implizites Commit ist in gespeicherten Funktionen und in Triggern nicht erlaubt"
 ER_NO_DEFAULT_FOR_VIEW_FIELD
         eng "Field of view '%-.64s.%-.64s' underlying table doesn't have a default value"
+	ger "Ein Feld der dem View '%-.64s.%-.64s' zugrundeliegenden Tabelle hat keinen Vorgabewert"
 ER_SP_NO_RECURSION
-        eng "Recursive stored routines are not allowed."
+        eng "Recursive stored functions and triggers are not allowed."
+	ger "Rekursive gespeicherte Routinen und Triggers sind nicht erlaubt"
 ER_TOO_BIG_SCALE 42000 S1009
         eng "Too big scale %d specified for column '%-.64s'. Maximum is %d."
 ER_TOO_BIG_PRECISION 42000 S1009
         eng "Too big precision %d specified for column '%-.64s'. Maximum is %d."
 ER_M_BIGGER_THAN_D 42000 S1009
         eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')."
 ER_WRONG_LOCK_OF_SYSTEM_TABLE
         eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
 ER_CONNECT_TO_FOREIGN_DATA_SOURCE
-        eng "Unable to connect to foreign data source - database '%.64s'!"
+        eng "Unable to connect to foreign data source: %.64s"
+	ger "Kann nicht mit Fremddatenquelle verbinden: %.64s"
 ER_QUERY_ON_FOREIGN_DATA_SOURCE
-        eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'"
+        eng "There was a problem processing the query on the foreign data source. Data source error: %-.64"
+	ger "Bei der Verarbeitung der Abfrage ist in der Fremddatenquelle ein Problem aufgetreten. Datenquellenfehlermeldung: %-.64s"
 ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST
-        eng "The foreign data source you are trying to reference does not exist. Data source error : '%-.64s'"
+        eng "The foreign data source you are trying to reference does not exist. Data source error:  %-.64s"
+	ger "Die Fremddatenquelle, auf die Sie zugreifen wollen, existiert nicht. Datenquellenfehlermeldung:  %-.64s"
 ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE
         eng "Can't create federated table. The data source connection string '%-.64s' is not in the correct format"
 ER_FOREIGN_DATA_STRING_INVALID
         eng "The data source connection string '%-.64s' is not in the correct format"
+	ger "Der Datenquellen-Verbindungsstring '%-.64s' hat kein korrektes Format"
 ER_CANT_CREATE_FEDERATED_TABLE  
-	eng "Can't create federated table. Foreign data src error : '%-.64s'"
+	eng "Can't create federated table. Foreign data src error:  %-.64s"
 ER_TRG_IN_WRONG_SCHEMA  
 	eng "Trigger in wrong schema"
+	ger "Trigger im falschen Schema"
 ER_STACK_OVERRUN_NEED_MORE
 	eng "Thread stack overrun:  %ld bytes used of a %ld byte stack, and %ld bytes needed.  Use 'mysqld -O thread_stack=#' to specify a bigger stack."
 ER_TOO_LONG_BODY 42000 S1009
 	eng "Routine body for '%-.100s' is too long"
 ER_WARN_CANT_DROP_DEFAULT_KEYCACHE
 	eng "Cannot drop default keycache"
 ER_TOO_BIG_DISPLAYWIDTH 42000 S1009
 	eng "Display width out of range for column '%-.64s' (max = %d)"
 ER_XAER_DUPID XAE08
         eng "XAER_DUPID: The XID already exists"
+	ger "XAER_DUPID: Die XID existiert bereits"
 ER_DATETIME_FUNCTION_OVERFLOW 22008
         eng "Datetime function: %-.32s field overflow"
 ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
         eng "Can't update table '%-.64s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger."
+	ger "Kann Tabelle '%-.64s' in gespeicherter Funktion oder Trigger nicht aktualisieren, weil sie bereits von der Anweisung verwendet wird, die diese gespeicherte Funktion oder den Trigger aufrief"
 ER_VIEW_PREVENT_UPDATE
         eng "The definition of table '%-.64s' prevents operation %.64s on table '%-.64s'."
+	ger "Die Definition der Tabelle '%-.64s' verhindert die Operation %.64s auf Tabelle '%-.64s'"
 ER_PS_NO_RECURSION
         eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner"
 ER_SP_CANT_SET_AUTOCOMMIT
 	eng "Not allowed to set autocommit from a stored function or trigger"
-ER_NO_VIEW_USER
-        eng "View definer is not fully qualified"
+        ger "Es ist nicht erlaubt, innerhalb einer gespeicherten Funktion oder eines Triggers AUTOCOMMIT zu setzen"
+ER_MALFORMED_DEFINER
+	eng "Definer is not fully qualified"
 ER_VIEW_FRM_NO_USER
-        eng "View %-.64s.%-.64s has not definer information (old table format). Current user is used as definer. Please recreate view!"
+        eng "View '%-.64s'.'%-.64s' has no definer information (old table format). Current user is used as definer. Please recreate the view!"
+	ger "View '%-.64s'.'%-.64s' hat keine Definierer-Information (altes Tabellenformat). Der aktuelle Benutzer wird als Definierer verwendet. Bitte erstellen Sie den View neu"
 ER_VIEW_OTHER_USER
-        eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
+	eng "You need the SUPER privilege for creation view with '%-.64s'@'%-.64s' definer"
+	ger "Sie brauchen die SUPER-Berechtigung, um einen View mit dem Definierer '%-.64s'@'%-.64s' zu erzeugen"
 ER_NO_SUCH_USER
-        eng "There is not %-.64s@%-.64s registered"
+        eng "There is no '%-.64s'@'%-.64s' registered"
+	ger "'%-.64s'@'%-.64s' ist nicht registriert"
 ER_FORBID_SCHEMA_CHANGE
 	eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
+	ger "Wechsel des Schemas von '%-.64s' auf '%-.64s' ist nicht erlaubt"
 ER_ROW_IS_REFERENCED_2 23000
 	eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
 ER_NO_REFERENCED_ROW_2 23000
 	eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
 ER_SP_BAD_VAR_SHADOW 42000
-	eng "Variable '%-.64s' must be quoted with `...`, or renamed"
+        eng "Variable '%-.64s' must be quoted with `...`, or renamed"
+ER_TRG_NO_DEFINER
+        eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
+ER_OLD_FILE_FORMAT
+        eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
+        ger "'%-.64s' hat altes Format, Sie sollten die '%s'-Objekt(e) neu erzeugen"
+ER_SP_RECURSION_LIMIT
+        eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
+ER_SP_PROC_TABLE_CORRUPT
+	eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
 ER_PARTITION_REQUIRES_VALUES_ERROR
         eng "%s PARTITIONING requires definition of VALUES %s for each partition"
@@ -5542,6 +5723,10 @@
 ER_PLUGIN_IS_NOT_LOADED
 	eng "Plugin '%-.64s' is not loaded"
+ER_WRONG_VALUE
+	eng "Incorrect %-.32s value: '%-.128s'"
+ER_NO_PARTITION_FOR_GIVEN_VALUE
+	eng "Table has no partition for value %ld"
 ER_TABLESPACE_OPTION_ONLY_ONCE
         eng "It is not allowed to specify %s more than once"
 ER_CREATE_TABLESPACE_FAILED

--- 1.217/sql/ha_ndbcluster.cc	2005-11-15 02:11:20 +11:00
+++ 1.218/sql/ha_ndbcluster.cc	2005-12-22 11:29:11 +11:00
@@ -56,9 +56,10 @@
 static int ndbcluster_close_connection(THD *thd);
 static int ndbcluster_commit(THD *thd, bool all);
 static int ndbcluster_rollback(THD *thd, bool all);
-static handler* ndbcluster_create_handler(TABLE *table);
+static handler* ndbcluster_create_handler(TABLE_SHARE *table);
 
 handlerton ndbcluster_hton = {
+  MYSQL_HANDLERTON_INTERFACE_VERSION,
   "ndbcluster",
   SHOW_OPTION_YES,
   "Clustered, fault-tolerant, memory-based tables", 
@@ -82,16 +83,13 @@
   ndbcluster_create_handler, /* Create a new handler */
   ndbcluster_drop_database, /* Drop a database */
   ndbcluster_end, /* Panic call */
-  NULL, /* Release temporary latches */
-  NULL, /* Update Statistics */
   NULL, /* Start Consistent Snapshot */
   NULL, /* Flush logs */
   ndbcluster_show_status, /* Show status */
-  NULL, /* Replication Report Sent Binlog */
   HTON_NO_FLAGS
 };
 
-static handler *ndbcluster_create_handler(TABLE *table)
+static handler *ndbcluster_create_handler(TABLE_SHARE *table)
 {
   return new ha_ndbcluster(table);
 }
@@ -101,6 +99,8 @@
 #define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0
 #define NDB_AUTO_INCREMENT_RETRIES 10
 
+#define NDB_INVALID_SCHEMA_OBJECT 241
+
 #define ERR_PRINT(err) \
   DBUG_PRINT("error", ("%d  message: %s", err.code, err.message))
 
@@ -368,7 +368,21 @@
 Thd_ndb::~Thd_ndb()
 {
   if (ndb)
+  {
+#ifndef DBUG_OFF
+    Ndb::Free_list_usage tmp; tmp.m_name= 0;
+    while (ndb->get_free_list_usage(&tmp))
+    {
+      uint leaked= (uint) tmp.m_created - tmp.m_free;
+      if (leaked)
+        fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n",
+                leaked, tmp.m_name,
+                (leaked == 1)?"":"'s",
+                (leaked == 1)?"has":"have");
+    }
+#endif
     delete ndb;
+  }
   ndb= NULL;
   changed_tables.empty();
 }
@@ -969,6 +983,10 @@
   IMPLEMENTATION
     - check that frm-file on disk is equal to frm-file
       of table accessed in NDB
+
+  RETURN
+    0    ok
+    -2   Meta data has changed; Re-read data and try again
 */
 
 static int cmp_frm(const NDBTAB *ndbtab, const void *pack_data,
@@ -991,7 +1009,6 @@
   const NDBTAB *tab;
   int error;
   bool invalidating_ndb_table= FALSE;
-
   DBUG_ENTER("get_metadata");
   DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path));
 
@@ -1037,7 +1054,7 @@
                     memcmp(pack_data, tab->getFrmData(), pack_length)));
         DBUG_DUMP("pack_data", (char*)pack_data, pack_length);
         DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength());
-        error= 3;
+        error= HA_ERR_TABLE_DEF_CHANGED;
         invalidating_ndb_table= FALSE;
       }
     }
@@ -1113,7 +1130,7 @@
     m_index[i].type= idx_type;
     if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX)
     {
-      strxnmov(unique_index_name, FN_LEN, index_name, unique_suffix, NullS);
+      strxnmov(unique_index_name, FN_LEN-1, index_name, unique_suffix, NullS);
       DBUG_PRINT("info", ("Created unique index name \'%s\' for index %d",
                           unique_index_name, i));
     }
@@ -1147,7 +1164,7 @@
       if (error)
       {
         DBUG_PRINT("error", ("Failed to create index %u", i));
-        drop_table();
+        intern_drop_table();
         break;
       }
     }
@@ -1199,11 +1216,12 @@
 */
 NDB_INDEX_TYPE ha_ndbcluster::get_index_type_from_table(uint inx) const
 {
-  bool is_hash_index=  (table->key_info[inx].algorithm == HA_KEY_ALG_HASH);
-  if (inx == table->s->primary_key)
+  bool is_hash_index=  (table_share->key_info[inx].algorithm ==
+                        HA_KEY_ALG_HASH);
+  if (inx == table_share->primary_key)
     return is_hash_index ? PRIMARY_KEY_INDEX : PRIMARY_KEY_ORDERED_INDEX;
 
-  return ((table->key_info[inx].flags & HA_NOSAME) ? 
+  return ((table_share->key_info[inx].flags & HA_NOSAME) ? 
           (is_hash_index ? UNIQUE_INDEX : UNIQUE_ORDERED_INDEX) :
           ORDERED_INDEX);
 } 
@@ -1322,7 +1340,7 @@
                                         bool all_parts) const 
 { 
   DBUG_ENTER("ha_ndbcluster::index_flags");
-  DBUG_PRINT("info", ("idx_no: %d", idx_no));
+  DBUG_PRINT("enter", ("idx_no: %u", idx_no));
   DBUG_ASSERT(get_index_type_from_table(idx_no) < index_flags_size);
   DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)] | 
               HA_KEY_SCAN_NOT_ROR);
@@ -2994,8 +3012,26 @@
         }      
         *buff++= 0;
       }
-      memcpy(buff, record + key_part->offset, key_part->length);
-      buff += key_part->length;
+
+      size_t len = key_part->length;
+      const byte * ptr = record + key_part->offset;
+      Field *field = key_part->field;
+      if ((field->type() ==  MYSQL_TYPE_VARCHAR) &&
+	  ((Field_varstring*)field)->length_bytes == 1)
+      {
+	/** 
+	 * Keys always use 2 bytes length
+	 */
+	buff[0] = ptr[0];
+	buff[1] = 0;
+	memcpy(buff+2, ptr + 1, len);	
+	len += 2;
+      }
+      else
+      {
+	memcpy(buff, ptr, len);
+      }
+      buff += len;
     }
   } 
   else 
@@ -3415,14 +3451,20 @@
         DBUG_PRINT("info", ("Table schema version: %d", 
                             tab->getObjectVersion()));
       }
-      if (m_table != (void *)tab || m_table_version < tab->getObjectVersion())
+      if (m_table_version < tab->getObjectVersion())
       {
         /*
-          The table has been altered, refresh the index list
+          The table has been altered, caller has to retry
         */
-        build_index_list(ndb, table, ILBP_OPEN);  
+        NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT);
+        DBUG_RETURN(ndb_to_mysql_error(&err));
+      }
+      if (m_table != (void *)tab)
+      {
         m_table= (void *)tab;
         m_table_version = tab->getObjectVersion();
+        if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN)))
+          DBUG_RETURN(my_errno);
       }
       m_table_info= tab_info;
     }
@@ -3913,15 +3955,16 @@
   uint pack_length, length, i, pk_length= 0;
   const void *data, *pack_data;
   char name2[FN_HEADLEN];
-  bool create_from_engine= test(info->table_options &
-                                HA_OPTION_CREATE_FROM_ENGINE);
-   
+  bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE);
+
   DBUG_ENTER("ha_ndbcluster::create");
   DBUG_PRINT("enter", ("name: %s", name));
+
   fn_format(name2, name, "", "",2);       // Remove the .frm extension
   set_dbname(name2);
   set_tabname(name2);    
 
+  table= form;
   if (create_from_engine)
   {
     /*
@@ -4031,7 +4074,7 @@
   }
 
   // Check partition info
-  partition_info *part_info= form->s->part_info;
+  partition_info *part_info= form->part_info;
   if (part_info)
   {
     int error;
@@ -4228,7 +4271,7 @@
   int res;
   if (h)
   {
-    res= h->drop_table();
+    res= h->intern_drop_table();
   }
   else
   {
@@ -4265,12 +4308,12 @@
   Drop table in NDB Cluster
  */
 
-int ha_ndbcluster::drop_table()
+int ha_ndbcluster::intern_drop_table()
 {
   Ndb *ndb= get_ndb();
   NdbDictionary::Dictionary *dict= ndb->getDictionary();
 
-  DBUG_ENTER("drop_table");
+  DBUG_ENTER("intern_drop_table");
   DBUG_PRINT("enter", ("Deleting %s", m_tabname));
   release_metadata();
   if (dict->dropTable(m_tabname))
@@ -4331,7 +4374,7 @@
                 HA_CAN_GEOMETRY | \
                 HA_CAN_BIT_FIELD
 
-ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
+ha_ndbcluster::ha_ndbcluster(TABLE_SHARE *table_arg):
   handler(&ndbcluster_hton, table_arg),
   m_active_trans(NULL),
   m_active_cursor(NULL),
@@ -4428,18 +4471,24 @@
   Open a table for further use
   - fetch metadata for this table from NDB
   - check that table exists
+
+  RETURN
+    0    ok
+    < 0  Table has changed
 */
 
 int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
 {
   int res;
   KEY *key;
-  DBUG_ENTER("open");
-  DBUG_PRINT("enter", ("this: %d name: %s  mode: %d test_if_locked: %d",
-                       this, name, mode, test_if_locked));
+  DBUG_ENTER("ha_ndbcluster::open");
+  DBUG_PRINT("enter", ("name: %s  mode: %d  test_if_locked: %d",
+                       name, mode, test_if_locked));
   
-  // Setup ref_length to make room for the whole 
-  // primary key to be written in the ref variable
+  /*
+    Setup ref_length to make room for the whole 
+    primary key to be written in the ref variable
+  */
   
   if (table->s->primary_key != MAX_KEY) 
   {
@@ -4465,18 +4514,18 @@
   if (!res)
     info(HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
-  if (table->s->part_info)
-  {
-    m_part_info= table->s->part_info;
-    if (!(m_part_info->part_type == HASH_PARTITION &&
-          m_part_info->list_of_part_fields &&
-          !is_sub_partitioned(m_part_info)))
-      m_use_partition_function= TRUE;
-  }
 
   DBUG_RETURN(res);
 }
 
+void ha_ndbcluster::set_part_info(partition_info *part_info)
+{
+  m_part_info= part_info;
+  if (!(m_part_info->part_type == HASH_PARTITION &&
+        m_part_info->list_of_part_fields &&
+        !is_sub_partitioned(m_part_info)))
+    m_use_partition_function= TRUE;
+}
 
 /*
   Close the table
@@ -4702,12 +4751,13 @@
   }
   // Drop any tables belonging to database
   char full_path[FN_REFLEN];
-  char *tmp= strxnmov(full_path, FN_REFLEN, share_prefix, dbname, "/", NullS);
+  char *tmp= strxnmov(full_path, FN_REFLEN-1, share_prefix, dbname, "/",
+                      NullS);
   ndb->setDatabaseName(dbname);
   List_iterator_fast<char> it(drop_list);
   while ((tabname=it++))
   {
-    strxnmov(tmp, FN_REFLEN - (tmp - full_path), tabname, NullS);
+    strxnmov(tmp, FN_REFLEN - (tmp - full_path)-1, tabname, NullS);
     if (ha_ndbcluster::delete_table(0, ndb, full_path, dbname, tabname))
     {
       const NdbError err= dict->getNdbError();
@@ -4774,7 +4824,7 @@
       if (ndbtab->getFrmLength() == 0)
         continue;
     
-      strxnmov(key, FN_LEN, mysql_data_home, "/",
+      strxnmov(key, FN_LEN-1, mysql_data_home, "/",
                elmt.database, "/", elmt.name, NullS);
       const void *data= 0, *pack_data= 0;
       uint length, pack_length;
@@ -4890,7 +4940,7 @@
     }
     
     // File is not in NDB, check for .ndb file with this name
-    (void)strxnmov(name, FN_REFLEN, 
+    (void)strxnmov(name, FN_REFLEN-1,
                    mysql_data_home,"/",db,"/",file_name,ha_ndb_ext,NullS);
     DBUG_PRINT("info", ("Check access for %s", name));
     if (access(name, F_OK))
@@ -4920,7 +4970,7 @@
     file_name= hash_element(&ndb_tables, i);
     if (!hash_search(&ok_tables, file_name, strlen(file_name)))
     {
-      strxnmov(name, sizeof(name),
+      strxnmov(name, sizeof(name)-1,
                mysql_data_home, "/", db, "/", file_name, reg_ext, NullS);
       if (access(name, F_OK))
       {
@@ -4966,7 +5016,7 @@
       files->push_back(thd->strdup(file_name)); 
   }
 
-  pthread_mutex_unlock(&LOCK_open);      
+  pthread_mutex_unlock(&LOCK_open);
   
   hash_free(&ok_tables);
   hash_free(&ndb_tables);
@@ -5110,7 +5160,21 @@
   (void) pthread_mutex_unlock(&LOCK_ndb_util_thread);
 
   if (g_ndb)
+  {
+#ifndef DBUG_OFF
+    Ndb::Free_list_usage tmp; tmp.m_name= 0;
+    while (g_ndb->get_free_list_usage(&tmp))
+    {
+      uint leaked= (uint) tmp.m_created - tmp.m_free;
+      if (leaked)
+        fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n",
+                leaked, tmp.m_name,
+                (leaked == 1)?"":"'s",
+                (leaked == 1)?"has":"have");
+    }
+#endif
     delete g_ndb;
+  }
   g_ndb= NULL;
   if (g_ndb_cluster_connection)
     delete g_ndb_cluster_connection;
@@ -5134,11 +5198,13 @@
 void ndbcluster_print_error(int error, const NdbOperation *error_op)
 {
   DBUG_ENTER("ndbcluster_print_error");
-  TABLE tab;
+  TABLE_SHARE share;
   const char *tab_name= (error_op) ? error_op->getTableName() : "";
-  tab.alias= (char *) tab_name;
-  ha_ndbcluster error_handler(&tab);
-  tab.file= &error_handler;
+  share.db.str= (char*) "";
+  share.db.length= 0;
+  share.table_name.str= (char *) tab_name;
+  share.table_name.length= strlen(tab_name);
+  ha_ndbcluster error_handler(&share);
   error_handler.print_error(error, MYF(0));
   DBUG_VOID_RETURN;
 }
@@ -5390,11 +5456,11 @@
 uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
                          Uint64 *commit_count)
 {
-  DBUG_ENTER("ndb_get_commitcount");
-
   char name[FN_REFLEN];
   NDB_SHARE *share;
-  (void)strxnmov(name, FN_REFLEN, share_prefix, dbname, "/", tabname, NullS);
+  DBUG_ENTER("ndb_get_commitcount");
+
+  (void)strxnmov(name, FN_REFLEN-1, share_prefix, dbname, "/", tabname, NullS);
   DBUG_PRINT("enter", ("name: %s", name));
   pthread_mutex_lock(&ndbcluster_mutex);
   if (!(share=(NDB_SHARE*) hash_search(&ndbcluster_open_tables,
@@ -6030,7 +6096,7 @@
   DBUG_ENTER("write_ndb_file");
   DBUG_PRINT("enter", ("db: %s, name: %s", m_dbname, m_tabname));
 
-  (void)strxnmov(path, FN_REFLEN, 
+  (void)strxnmov(path, FN_REFLEN-1, 
                  mysql_data_home,"/",m_dbname,"/",m_tabname,ha_ndb_ext,NullS);
 
   if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
@@ -7032,9 +7098,9 @@
           }
           else
           {
-            DBUG_PRINT("info", ("Was not expecting field from table %s(%s)",
-                                context->table->s->table_name, 
-                                field->table->s->table_name));
+            DBUG_PRINT("info", ("Was not expecting field from table %s (%s)",
+                                context->table->s->table_name.str, 
+                                field->table->s->table_name.str));
             context->supported= FALSE;
           }
           break;
@@ -8002,10 +8068,12 @@
     Ndb::Free_list_usage tmp; tmp.m_name= 0;
     while (ndb->get_free_list_usage(&tmp))
     {
-      my_snprintf(buf, sizeof(buf),
+      uint buflen=
+        my_snprintf(buf, sizeof(buf),
                   "created=%u, free=%u, sizeof=%u",
                   tmp.m_created, tmp.m_free, tmp.m_sizeof);
-      if (stat_print(thd, ndbcluster_hton.name, tmp.m_name, buf))
+      if (stat_print(thd, ndbcluster_hton.name, strlen(ndbcluster_hton.name),
+                     tmp.m_name, strlen(tmp.m_name), buf, buflen))
         DBUG_RETURN(TRUE);
     }
   }

--- 1.99/sql/ha_ndbcluster.h	2005-11-15 02:11:21 +11:00
+++ 1.100/sql/ha_ndbcluster.h	2005-12-22 11:29:11 +11:00
@@ -478,7 +478,7 @@
 class ha_ndbcluster: public handler
 {
  public:
-  ha_ndbcluster(TABLE *table);
+  ha_ndbcluster(TABLE_SHARE *table);
   ~ha_ndbcluster();
 
   int open(const char *name, int mode, uint test_if_locked);
@@ -535,6 +535,7 @@
     return (HA_CAN_PARTITION | HA_CAN_UPDATE_PARTITION_KEY |
             HA_CAN_PARTITION_UNIQUE);
   }
+  void set_part_info(partition_info *part_info);
   ulong index_flags(uint idx, uint part, bool all_parts) const;
   uint max_supported_record_length() const;
   uint max_supported_keys() const;
@@ -621,7 +622,7 @@
 			  const char *path,
 			  const char *db,
 			  const char *table_name);
-  int drop_table();
+  int intern_drop_table();
   int create_index(const char *name, KEY *key_info, bool unique);
   int create_ordered_index(const char *name, KEY *key_info);
   int create_unique_index(const char *name, KEY *key_info);

--- 1.71/libmysqld/Makefile.am	2005-11-15 02:11:20 +11:00
+++ 1.72/libmysqld/Makefile.am	2005-12-22 11:29:10 +11:00
@@ -48,6 +48,7 @@
 	item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
 	item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
 	item_geofunc.cc item_uniq.cc item_subselect.cc item_row.cc\
+	item_xmlfunc.cc \
 	key.cc lock.cc log.cc log_event.cc sql_state.c \
 	protocol.cc net_serv.cc opt_range.cc \
 	opt_sum.cc procedure.cc records.cc sql_acl.cc \
@@ -144,19 +145,19 @@
 link_sources:
 	  set -x; \
 	  for f in $(sqlsources); do \
-	    rm -f $(srcdir)/$$f; \
-	    @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
+	    rm -f $$f; \
+	    @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
 	  done; \
 	  for f in $(libmysqlsources); do \
-	    rm -f $(srcdir)/$$f; \
-	    @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \
+	    rm -f $$f; \
+	    @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
 	  done; \
 	  for f in $(sqlstoragesources); do \
-	    rm -f $(srcdir)/$$f; \
-	    @LN_CP_F@ `find $(srcdir)/../sql -name $$f` $(srcdir)/$$f; \
+	    rm -f $$f; \
+	    @LN_CP_F@ `find $(srcdir)/../sql -name $$f` $$f; \
 	  done; \
-	  rm -f $(srcdir)/client_settings.h; \
-	  @LN_CP_F@ $(srcdir)/../libmysql/client_settings.h $(srcdir)/client_settings.h;
+	  rm -f client_settings.h; \
+	  @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h
 
 
 clean-local:
Thread
bk commit into 5.1 tree (stewart:1.1979)Stewart Smith22 Dec