List:Internals« Previous MessageNext Message »
From:Lars Thalmann Date:August 11 2005 12:34am
Subject:bk commit into 5.0 tree (lars:1.1978)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of lthalmann. When lthalmann 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.1978 05/08/11 02:33:53 lars@stripped +81 -0
  Merge mysql.com:/users/lthalmann/ltx/dev/mysql-5.0
  into  mysql.com:/users/lthalmann/ltx/dev/mysql-5.0-wl1012

  mysql-test/t/rpl_loaddata_rule_s.test
    1.8 05/08/11 02:33:36 lars@stripped +2 -3
    Manual merge

  mysql-test/t/rpl_insert_id.test
    1.10 05/08/11 02:32:33 lars@stripped +1 -0
    Manual merge

  mysql-test/t/ps_grant.test
    1.7 05/08/11 02:31:41 lars@stripped +11 -3
    Manual merge

  sql/table.h
    1.105 05/08/11 02:16:35 lars@stripped +0 -0
    Auto merged

  sql/table.cc
    1.176 05/08/11 02:16:35 lars@stripped +0 -0
    Auto merged

  sql/sql_update.cc
    1.166 05/08/11 02:16:34 lars@stripped +0 -0
    Auto merged

  sql/sql_union.cc
    1.124 05/08/11 02:16:34 lars@stripped +0 -0
    Auto merged

  sql/sql_table.cc
    1.268 05/08/11 02:16:34 lars@stripped +0 -0
    Auto merged

  sql/sql_show.cc
    1.259 05/08/11 02:16:33 lars@stripped +0 -0
    Auto merged

  sql/sql_select.cc
    1.345 05/08/11 02:16:33 lars@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.456 05/08/11 02:16:32 lars@stripped +0 -0
    Auto merged

  sql/sql_insert.cc
    1.170 05/08/11 02:16:31 lars@stripped +0 -0
    Auto merged

  sql/sql_class.h
    1.255 05/08/11 02:16:31 lars@stripped +0 -0
    Auto merged

  sql/sql_class.cc
    1.199 05/08/11 02:16:30 lars@stripped +0 -0
    Auto merged

  sql/sql_acl.cc
    1.163 05/08/11 02:16:30 lars@stripped +0 -0
    Auto merged

  sql/sp.cc
    1.85 05/08/11 02:16:30 lars@stripped +0 -0
    Auto merged

  sql/slave.h
    1.89 05/08/11 02:16:29 lars@stripped +0 -0
    Auto merged

  sql/slave.cc
    1.255 05/08/11 02:16:29 lars@stripped +0 -0
    Auto merged

  sql/set_var.cc
    1.132 05/08/11 02:16:29 lars@stripped +0 -0
    Auto merged

  sql/mysqld.cc
    1.478 05/08/11 02:16:28 lars@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.338 05/08/11 02:16:27 lars@stripped +0 -0
    Auto merged

  sql/log.cc
    1.170 05/08/11 02:16:27 lars@stripped +0 -0
    Auto merged

  sql/item_sum.cc
    1.154 05/08/11 02:16:27 lars@stripped +0 -0
    Auto merged

  sql/handler.cc
    1.188 05/08/11 02:16:26 lars@stripped +0 -0
    Auto merged

  sql/ha_innodb.cc
    1.241 05/08/11 02:16:26 lars@stripped +0 -0
    Auto merged

  mysql-test/t/user_var.test
    1.31 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/user_var-binlog.test
    1.4 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_user_variables.test
    1.13 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_until.test
    1.18 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_timezone.test
    1.9 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_temporary.test
    1.16 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_server_id1.test
    1.6 05/08/11 02:16:25 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_rotate_logs.test
    1.62 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_rewrite_db.test
    1.5 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_reset_slave.test
    1.9 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_replicate_do.test
    1.22 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_relayrotate.test
    1.15 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_redirect.test
    1.13 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_openssl.test
    1.8 05/08/11 02:16:24 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_mystery22.test
    1.8 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_multi_query.test
    1.7 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_max_relay_size.test
    1.14 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_log_pos.test
    1.35 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_log.test
    1.27 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_loaddata_rule_m.test
    1.10 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_loaddata.test
    1.18 05/08/11 02:16:23 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_heap.test
    1.6 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_flush_tables.test
    1.8 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_flush_log_loop.test
    1.11 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_error_ignored_table.test
    1.15 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_empty_master_crash.test
    1.11 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_do_grant.test
    1.5 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_delete_all.test
    1.6 05/08/11 02:16:22 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_deadlock.test
    1.8 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_ddl.test
    1.6 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_create_database.test
    1.5 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_charset.test
    1.17 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_change_master.test
    1.11 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl_EE_error.test
    1.6 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl000017.test
    1.14 05/08/11 02:16:21 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl000015.test
    1.32 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl000012.test
    1.18 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl000002.test
    1.21 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/rpl000001.test
    1.40 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/mysqlbinlog2.test
    1.8 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/mysqlbinlog.test
    1.20 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/mix_innodb_myisam_binlog.test
    1.17 05/08/11 02:16:20 lars@stripped +0 -0
    Auto merged

  mysql-test/t/insert_select-binlog.test
    1.3 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/innodb.test
    1.98 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/flush_block_commit.test
    1.8 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/drop_temp_table.test
    1.7 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/date_formats.test
    1.15 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/ctype_utf8.test
    1.66 05/08/11 02:16:19 lars@stripped +0 -0
    Auto merged

  mysql-test/t/ctype_ucs_binlog.test
    1.6 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  mysql-test/t/ctype_ucs.test
    1.35 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  mysql-test/t/blackhole.test
    1.5 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  mysql-test/r/user_var.result
    1.36 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  mysql-test/r/innodb.result
    1.125 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  libmysql/Makefile.shared
    1.66 05/08/11 02:16:18 lars@stripped +0 -0
    Auto merged

  configure.in
    1.332 05/08/11 02:16:17 lars@stripped +0 -0
    Auto merged

  BitKeeper/etc/config
    1.18 05/08/11 02:16:17 lars@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:	lars
# Host:	dl145h.mysql.com
# Root:	/users/lthalmann/ltx/dev/mysql-5.0-wl1012/RESYNC

--- 1.331/configure.in	2005-08-05 21:13:01 +02:00
+++ 1.332/configure.in	2005-08-11 02:16:17 +02:00
@@ -47,6 +47,7 @@
 sinclude(config/ac-macros/misc.m4)
 sinclude(config/ac-macros/openssl.m4)
 sinclude(config/ac-macros/readline.m4)
+sinclude(config/ac-macros/replication.m4)
 sinclude(config/ac-macros/yassl.m4)
 sinclude(config/ac-macros/zlib.m4)
 
@@ -1896,7 +1897,8 @@
 AC_FUNC_UTIME_NULL
 AC_FUNC_VPRINTF
 
-AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
+AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
+  chsize cuserid fchmod fcntl \
   fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \
   getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
   getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
@@ -2436,6 +2438,7 @@
 MYSQL_CHECK_BLACKHOLEDB
 MYSQL_CHECK_NDBCLUSTER
 MYSQL_CHECK_FEDERATED
+MYSQL_CHECK_REPLICATION
 
 # If we have threads generate some library functions and test programs
 sql_server_dirs=

--- 1.187/sql/handler.cc	2005-08-04 16:18:42 +02:00
+++ 1.188/sql/handler.cc	2005-08-11 02:16:26 +02:00
@@ -601,7 +601,7 @@
   my_xid xid= thd->transaction.xid.get_my_xid();
   DBUG_ENTER("ha_commit_trans");
 
-  if (thd->transaction.in_sub_stmt)
+  if (thd->in_sub_stmt)
   {
     /*
       Since we don't support nested statement transactions in 5.0,
@@ -721,7 +721,7 @@
   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
   bool is_real_trans=all || thd->transaction.all.nht == 0;
   DBUG_ENTER("ha_rollback_trans");
-  if (thd->transaction.in_sub_stmt)
+  if (thd->in_sub_stmt)
   {
     /*
       If we are inside stored function or trigger we should not commit or

--- 1.153/sql/item_sum.cc	2005-07-25 12:48:02 +02:00
+++ 1.154/sql/item_sum.cc	2005-08-11 02:16:27 +02:00
@@ -321,6 +321,22 @@
       field->flags&= ~NOT_NULL_FLAG;
     return field;
   }
+  /*
+    DATE/TIME fields have STRING_RESULT result types.
+    In order to preserve field type, it's needed to handle DATE/TIME
+    fields creations separately.
+  */
+  switch (args[0]->field_type()) {
+  case MYSQL_TYPE_DATE:
+    return new Field_date(maybe_null, name, table, collation.collation);
+  case MYSQL_TYPE_TIME:
+    return new Field_time(maybe_null, name, table, collation.collation);
+  case MYSQL_TYPE_TIMESTAMP:
+  case MYSQL_TYPE_DATETIME:
+    return new Field_datetime(maybe_null, name, table, collation.collation);
+  default:
+    break;
+  }
   return Item_sum::create_tmp_field(group, table, convert_blob_length);
 }
 
@@ -2275,7 +2291,8 @@
   DBUG_ASSERT(table == 0);
   if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
 				0,
-				select_lex->options | thd->options,
+				(select_lex->options | thd->options) & 
+                                ~TMP_TABLE_FORCE_MYISAM,
 				HA_POS_ERROR, (char*)"")))
     return TRUE;
   table->file->extra(HA_EXTRA_NO_ROWS);		// Don't update rows
@@ -2632,7 +2649,11 @@
       the temporary table, not the original field
     */
     Field *field= (*field_item)->get_tmp_table_field();
-    if (field)
+    /* 
+      If field_item is a const item then either get_tp_table_field returns 0
+      or it is an item over a const table. 
+    */
+    if (field && !(*field_item)->const_item())
     {
       int res;
       uint offset= field->offset() - table->s->null_bytes;
@@ -2666,8 +2687,11 @@
       the temporary table, not the original field
     */
     Field *field= item->get_tmp_table_field();
-    /* If the item is a constant, there is no tmp table field */
-    if (field)
+    /* 
+      If item is a const item then either get_tp_table_field returns 0
+      or it is an item over a const table. 
+    */
+    if (field && !item->const_item())
     {
       int res;
       uint offset= field->offset() - table->s->null_bytes;
@@ -2976,6 +3000,10 @@
       maybe_null|= args[i]->maybe_null;
   }
 
+  if (agg_item_charsets(collation, func_name(),
+                        args, arg_count, MY_COLL_ALLOW_CONV))
+    return 1;
+
   result_field= 0;
   null_value= 1;
   thd->allow_sum_func= 1;
@@ -3046,7 +3074,8 @@
   */
   if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
                                 (ORDER*) 0, 0, TRUE,
-                                select_lex->options | thd->options,
+                                (select_lex->options | thd->options) & 
+                                ~TMP_TABLE_FORCE_MYISAM,
                                 HA_POS_ERROR, (char*) "")))
     DBUG_RETURN(TRUE);
   table->file->extra(HA_EXTRA_NO_ROWS);

--- 1.169/sql/log.cc	2005-08-04 15:03:51 +02:00
+++ 1.170/sql/log.cc	2005-08-11 02:16:27 +02:00
@@ -58,7 +58,11 @@
   binlog_prepare,
   NULL,                         /* recover */
   NULL,                         /* commit_by_xid */
-  NULL                          /* rollback_by_xid */
+  NULL,                         /* rollback_by_xid */
+  NULL,                         /* create_cursor_read_view */
+  NULL,                         /* set_cursor_read_view */
+  NULL,    			/* close_cursor_read_view */
+  HTON_NO_FLAGS
 };
 
 /*
@@ -2234,7 +2238,7 @@
      On Windows is necessary a temporary file for to rename
      the current error file.
     */
-    strmov(strmov(err_temp, err_renamed),"-tmp");
+    strxmov(err_temp, err_renamed,"-tmp",NullS);
     (void) my_delete(err_temp, MYF(0)); 
     if (freopen(err_temp,"a+",stdout))
     {

--- 1.337/sql/mysql_priv.h	2005-08-03 22:33:13 +02:00
+++ 1.338/sql/mysql_priv.h	2005-08-11 02:16:27 +02:00
@@ -256,6 +256,13 @@
 #define OPTION_WARNINGS         (1L << 13)      // THD, user
 #define OPTION_AUTO_IS_NULL     (1L << 14)      // THD, user, binlog
 #define OPTION_FOUND_COMMENT    (1L << 15)      // SELECT, intern, parser
+/* 
+  Force the used temporary table to be a MyISAM table (because we will use
+  fulltext functions when reading from it. This uses the same constant as
+  OPTION_FOUND_COMMENT because we've run out of bits and these two values 
+  are not used together.
+*/
+#define TMP_TABLE_FORCE_MYISAM          (1L << 15)
 #define OPTION_SAFE_UPDATES     (1L << 16)      // THD, user
 #define OPTION_BUFFER_RESULT    (1L << 17)      // SELECT, user
 #define OPTION_BIN_LOG          (1L << 18)      // THD, user
@@ -487,8 +494,7 @@
 void free_items(Item *item);
 void cleanup_items(Item *item);
 class THD;
-void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0,
-                         TABLE *stopper= 0);
+void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
 bool check_one_table_access(THD *thd, ulong privilege,
 			   TABLE_LIST *tables);
 bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
@@ -823,8 +829,6 @@
 bool mysqld_help (THD *thd, const char *text);
 void calc_sum_of_all_status(STATUS_VAR *to);
 
-
-
 /* information schema */
 extern LEX_STRING information_schema_name;
 LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
@@ -928,10 +932,10 @@
 int setup_ftfuncs(SELECT_LEX* select);
 int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
 void wait_for_refresh(THD *thd);
-int open_tables(THD *thd, TABLE_LIST **tables, uint *counter);
+int open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags);
 int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
 bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
-bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables);
+bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
 int lock_tables(THD *thd, TABLE_LIST *tables, uint counter);
 TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
 			    const char *table_name, bool link_in_list);
@@ -952,12 +956,16 @@
 			    const char *table_name);
 void remove_db_from_cache(const char *db);
 void flush_tables();
+bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
+
+/* bits for last argument to remove_table_from_cache() */
 #define RTFC_NO_FLAG                0x0000
 #define RTFC_OWNED_BY_THD_FLAG      0x0001
 #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
 #define RTFC_CHECK_KILLED_FLAG      0x0004
 bool remove_table_from_cache(THD *thd, const char *db, const char *table,
                              uint flags);
+
 bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
 void copy_field_from_tmp_record(Field *field,int offset);
 bool fill_record(THD *thd, Field **field, List<Item> &values,
@@ -1159,6 +1167,7 @@
 extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
 extern FILE *bootstrap_file;
 extern int bootstrap_error;
+extern FILE *stderror_file;
 extern pthread_key(MEM_ROOT**,THR_MALLOC);
 extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
        LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
@@ -1193,6 +1202,7 @@
 extern I_List<i_string> binlog_do_db, binlog_ignore_db;
 extern const char* any_db;
 extern struct my_option my_long_options[];
+extern const LEX_STRING view_type;
 
 /* optional things, have_* variables */
 
@@ -1252,12 +1262,12 @@
 void unireg_init(ulong options);
 void unireg_end(void);
 bool mysql_create_frm(THD *thd, my_string file_name,
-                      const char *table, const char* db,
+                      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 *table, const char* db,
+                     const char *db, const char *table,
                      HA_CREATE_INFO *create_info,
 		     List<create_field> &create_field,
 		     uint key_count,KEY *key_info);
@@ -1276,7 +1286,7 @@
 ulong convert_month_to_period(ulong month);
 void get_date_from_daynr(long daynr,uint *year, uint *month,
 			 uint *day);
-my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist);
+my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *not_exist);
 bool str_to_time_with_warn(const char *str,uint length,TIME *l_time);
 timestamp_type str_to_datetime_with_warn(const char *str, uint length,
                                          TIME *l_time, uint flags);
@@ -1325,7 +1335,7 @@
 		     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 *table, const char *db,
+int create_frm(THD *thd, char *name, const char *db, const char *table,
                uint reclength,uchar *fileinfo,
 	       HA_CREATE_INFO *create_info, uint keys);
 void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
@@ -1452,6 +1462,12 @@
   table->status= STATUS_NO_RECORD;
   table->keys_in_use_for_query= table->s->keys_in_use;
   table->maybe_null= table_list->outer_join;
+  TABLE_LIST *embedding= table_list->embedding;
+  while (!table->maybe_null && embedding)
+  {
+    table->maybe_null= embedding->outer_join;
+    embedding= embedding->embedding;
+  }
   table->tablenr= tablenr;
   table->map= (table_map) 1 << tablenr;
   table->force_index= table_list->force_index;

--- 1.477/sql/mysqld.cc	2005-08-04 13:27:48 +02:00
+++ 1.478/sql/mysqld.cc	2005-08-11 02:16:28 +02:00
@@ -379,6 +379,33 @@
 my_bool opt_noacl;
 my_bool sp_automatic_privileges= 1;
 
+/*
+  This variable below serves as an optimization for (opt_binlog_format ==
+  BF_ROW) as we need to do this test for every row. Stmt-based is default.
+*/
+my_bool binlog_row_based= FALSE;
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ulong opt_binlog_rows_event_max_size;
+const char *binlog_format_names[]= {"STATEMENT", "ROW", NullS};
+/*
+  Note that BF_UNSPECIFIED is last, after the end of binlog_format_names: it
+  has no corresponding cell in this array. We use this value to be able to
+  know if the user has explicitely specified a binlog format (then we require
+  also --log-bin) or not (then we fall back to statement-based).
+*/
+enum binlog_format { BF_STMT= 0, BF_ROW= 1, BF_UNSPECIFIED= 2 };
+#else
+const char *binlog_format_names[]= {"STATEMENT", NullS};
+enum binlog_format { BF_STMT= 0, BF_UNSPECIFIED= 2 };
+#endif
+
+TYPELIB binlog_format_typelib=
+  { array_elements(binlog_format_names)-1,"",
+    binlog_format_names, NULL };
+const char *opt_binlog_format= 0;
+enum binlog_format opt_binlog_format_id= BF_UNSPECIFIED;
+
 #ifdef HAVE_INITGROUPS
 static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
 #endif
@@ -469,6 +496,7 @@
 SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam, have_ndbcluster, 
   have_example_db, have_archive_db, have_csv_db;
 SHOW_COMP_OPTION have_federated_db;
+SHOW_COMP_OPTION have_row_based_replication;
 SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
 SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 SHOW_COMP_OPTION have_crypt, have_compress;
@@ -2847,8 +2875,42 @@
   {
     sql_print_warning("You need to use --log-bin to make "
                       "--log-slave-updates work.");
-      unireg_abort(1);
+    unireg_abort(1);
+  }
+
+  if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
+  {
+    sql_print_warning("You need to use --log-bin to make "
+                      "--binlog-format work.");
+    unireg_abort(1);
+  }
+  if (opt_binlog_format_id == BF_UNSPECIFIED)
+  {
+    /*
+      We use statement-based by default, but could change this to be row-based
+      if this is a cluster build (i.e. have_ndbcluster is true)...
+    */
+    opt_binlog_format_id= BF_STMT;
+  }
+#ifdef HAVE_ROW_BASED_REPLICATION
+  if (opt_binlog_format_id == BF_ROW) 
+  {
+    binlog_row_based= TRUE;
+    /*
+      Row-based binlogging turns on InnoDB unsafe locking, because the locks
+      are not needed when using row-based binlogging. In fact
+      innodb-locks-unsafe-for-binlog is unsafe only for stmt-based, it's
+      safe for row-based.
+    */
+#ifdef HAVE_INNOBASE_DB
+    innobase_locks_unsafe_for_binlog= TRUE;
+#endif
   }
+#endif
+  /* Check that we have not let the format to unspecified at this point */
+  DBUG_ASSERT(opt_binlog_format_id <=
+              array_elements(binlog_format_names)-1);
+  opt_binlog_format= binlog_format_names[opt_binlog_format_id];
 
   if (opt_slow_log)
     mysql_slow_log.open_slow_log(opt_slow_logname);
@@ -4276,6 +4338,10 @@
   OPT_SQL_BIN_UPDATE_SAME,     OPT_REPLICATE_DO_DB,
   OPT_REPLICATE_IGNORE_DB,     OPT_LOG_SLAVE_UPDATES,
   OPT_BINLOG_DO_DB,            OPT_BINLOG_IGNORE_DB,
+  OPT_BINLOG_FORMAT,
+#ifdef HAVE_ROW_BASED_REPLICATION
+  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
+#endif
   OPT_WANT_CORE,               OPT_CONCURRENT_INSERT,
   OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
   OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
@@ -4487,12 +4553,38 @@
   {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
    (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"binlog-format", OPT_BINLOG_FORMAT,
+#ifdef HAVE_ROW_BASED_REPLICATION
+   "Tell the master the form of binary logging to use: either 'row' for "
+   "row-based binary logging (which automatically turns on "
+   "innodb_locks_unsafe_for_binlog as it is safe in this case), or "
+   "'statement' for statement-based logging. ",
+#else
+   "Tell the master the form of binary logging to use: this release build "
+   "supports only statement-based binary logging, so only 'statement' is "
+   "a legal value; MySQL-Max release builds support row-based binary logging "
+   "in addition.",
+#endif
+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },   
   {"binlog-do-db", OPT_BINLOG_DO_DB,
    "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
    "Tells the master that updates to the given database should not be logged tothe binary log.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_ROW_BASED_REPLICATION
+  {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+   "The maximum size of a row-based binary log event in bytes. Rows will be "
+   "grouped into events smaller than this size if possible. "
+   "The value has to be a multiple of 256.",
+   (gptr*) &opt_binlog_rows_event_max_size, 
+   (gptr*) &opt_binlog_rows_event_max_size, 0, 
+   GET_ULONG, REQUIRED_ARG, 
+   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
+   /* sub_size */     0, /* block_size */ 256, 
+   /* app_type */ 0
+  },
+#endif
   {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"character-set-server", 'C', "Set the default character set.",
@@ -4655,7 +4747,9 @@
    (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
    0, 0, 0},
   {"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
-   "Force InnoDB not to use next-key locking. Instead use only row-level locking",
+   "Force InnoDB not to use next-key locking, to use only row-level locking."
+   " This is unsafe if you are using statement-based binary logging, and safe"
+   " if you are using row-based binary logging.",
    (gptr*) &innobase_locks_unsafe_for_binlog,
    (gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
@@ -6154,6 +6248,11 @@
 #else
   have_federated_db= SHOW_OPTION_NO;
 #endif
+#ifdef HAVE_ROW_BASED_REPLICATION
+  have_row_based_replication= SHOW_OPTION_YES;
+#else
+  have_row_based_replication= SHOW_OPTION_NO;
+#endif
 #ifdef HAVE_CSV_DB
   have_csv_db= SHOW_OPTION_YES;
 #else
@@ -6380,6 +6479,28 @@
     binlog_ignore_db.push_back(db);
     break;
   }
+  case OPT_BINLOG_FORMAT:
+  {
+    int id;
+    if ((id= find_type(argument, &binlog_format_typelib, 2)) <= 0)
+    {
+#ifdef HAVE_ROW_BASED_REPLICATION
+      fprintf(stderr, 
+	      "Unknown binary log format: '%s' "
+	      "(should be '%s' or '%s')\n", 
+	      argument,
+              binlog_format_names[BF_STMT],
+              binlog_format_names[BF_ROW]);
+#else
+      fprintf(stderr, 
+	      "Unknown binary log format: '%s' (only legal value is '%s')\n", 
+	      argument, binlog_format_names[BF_STMT]);
+#endif
+      exit(1);
+    }
+    opt_binlog_format_id= (enum binlog_format)(id-1);
+    break;
+  }
   case (int)OPT_BINLOG_DO_DB:
   {
     i_string *db = new i_string(argument);
@@ -6913,6 +7034,7 @@
       init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
 				  &global_system_variables.datetime_format))
     exit(1);
+
 }
 
 

--- 1.254/sql/slave.cc	2005-08-02 22:06:24 +02:00
+++ 1.255/sql/slave.cc	2005-08-11 02:16:29 +02:00
@@ -2102,7 +2102,8 @@
 		    &my_charset_bin);
     protocol->store((ulonglong) mi->rli.group_relay_log_pos);
     protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
-    protocol->store(mi->slave_running ? "Yes":"No", &my_charset_bin);
+    protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT
+        ? "Yes":"No", &my_charset_bin);
     protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
     protocol->store(&replicate_do_db);
     protocol->store(&replicate_ignore_db);
@@ -3342,9 +3343,9 @@
   mi->abort_slave = 0; // TODO: check if this is needed
   DBUG_ASSERT(thd->net.buff != 0);
   net_end(&thd->net); // destructor will not free it, because net.vio is 0
+  close_thread_tables(thd, 0);
   pthread_mutex_lock(&LOCK_thread_count);
   THD_CHECK_SENTRY(thd);
-  close_thread_tables(thd);
   delete thd;
   pthread_mutex_unlock(&LOCK_thread_count);
   pthread_cond_broadcast(&mi->stop_cond);	// tell the world we are done

--- 1.162/sql/sql_acl.cc	2005-07-25 12:48:03 +02:00
+++ 1.163/sql/sql_acl.cc	2005-08-11 02:16:30 +02:00
@@ -3551,9 +3551,9 @@
 {
   char helping [NAME_LEN+USERNAME_LENGTH+2];
   uint len;
-  bool error=1;
+  bool error= 1;
 
-  len  = (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1;
+  len= (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1;
   rw_rdlock(&LOCK_grant);
 
   for (uint idx=0 ; idx < column_priv_hash.records ; idx++)

--- 1.198/sql/sql_class.cc	2005-08-03 22:33:13 +02:00
+++ 1.199/sql/sql_class.cc	2005-08-11 02:16:30 +02:00
@@ -159,8 +159,8 @@
 ** Thread specific functions
 ****************************************************************************/
 
-Open_tables_state::Open_tables_state()
-  :version(refresh_version)
+Open_tables_state::Open_tables_state(ulong version_arg)
+  :version(version_arg)
 {
   reset_open_tables_state();
 }
@@ -174,9 +174,9 @@
 
 THD::THD()
   :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0),
-   Open_tables_state(),
+   Open_tables_state(refresh_version),
    lock_id(&main_lock_id),
-   user_time(0), global_read_lock(0), is_fatal_error(0),
+   user_time(0), in_sub_stmt(FALSE), global_read_lock(0), is_fatal_error(0),
    rand_used(0), time_zone_used(0),
    last_insert_id_used(0), insert_id_used(0), clear_next_insert_id(0),
    in_lock_tables(0), bootstrap(0), derived_tables_processing(FALSE),
@@ -534,6 +534,10 @@
     if this is the slave SQL thread.
   */
   variables.pseudo_thread_id= thread_id;
+  /*
+    We have to call thr_lock_info_init() again here as THD may have been
+    created in another thread
+  */
   thr_lock_info_init(&lock_info);
   return 0;
 }
@@ -1834,32 +1838,27 @@
   access to mysql.proc table to find definitions of stored routines.
 ****************************************************************************/
 
-bool THD::push_open_tables_state()
+void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
 {
-  Open_tables_state *state;
-  DBUG_ENTER("push_open_table_state");
-  /* Currently we only push things one level */
-  DBUG_ASSERT(open_state_list.elements == 0);
-
-  if (!(state= (Open_tables_state*) alloc(sizeof(*state))))
-    DBUG_RETURN(1);                             // Fatal error is set
-  /* Store state for currently open tables */
-  state->set_open_tables_state(this);
-  if (open_state_list.push_back(state, mem_root))
-    DBUG_RETURN(1);                             // Fatal error is set
+  DBUG_ENTER("reset_n_backup_open_tables_state");
+  backup->set_open_tables_state(this);
   reset_open_tables_state();
-  DBUG_RETURN(0);
+  DBUG_VOID_RETURN;
 }
 
-void THD::pop_open_tables_state()
-{
-  Open_tables_state *state;
-  DBUG_ENTER("pop_open_table_state");
-  /* Currently we only push things one level */
-  DBUG_ASSERT(open_state_list.elements == 1);
 
-  state= open_state_list.pop();
-  set_open_tables_state(state);
+void THD::restore_backup_open_tables_state(Open_tables_state *backup)
+{
+  DBUG_ENTER("restore_backup_open_tables_state");
+  /*
+    Before we will throw away current open tables state we want
+    to be sure that it was properly cleaned up.
+  */
+  DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
+              handler_tables == 0 && derived_tables == 0 &&
+              lock == 0 && locked_tables == 0 &&
+              prelocked_mode == NON_PRELOCKED);
+  set_open_tables_state(backup);
   DBUG_VOID_RETURN;
 }
 

--- 1.254/sql/sql_class.h	2005-08-03 22:33:13 +02:00
+++ 1.255/sql/sql_class.h	2005-08-11 02:16:31 +02:00
@@ -1028,7 +1028,13 @@
   ulong	version;
   uint current_tablenr;
 
-  Open_tables_state();
+  /*
+    This constructor serves for creation of Open_tables_state instances
+    which are used as backup storage.
+  */
+  Open_tables_state() {};
+
+  Open_tables_state(ulong version_arg);
 
   void set_open_tables_state(Open_tables_state *state)
   {
@@ -1151,6 +1157,10 @@
   thr_lock_type update_lock_default;
   delayed_insert *di;
   my_bool    tablespace_op;	/* This is TRUE in DISCARD/IMPORT TABLESPACE */
+  
+  /* TRUE if we are inside of trigger or stored function. */
+  bool in_sub_stmt;
+  
   /* container for handler's private per-connection data */
   void *ha_data[MAX_HA];
 
@@ -1256,8 +1266,6 @@
     THD_TRANS all;			// Trans since BEGIN WORK
     THD_TRANS stmt;			// Trans for current statement
     bool on;                            // see ha_enable_transaction()
-    /* TRUE if we are inside of trigger or stored function. */
-    bool in_sub_stmt;
     XID  xid;                           // transaction identifier
     enum xa_states xa_state;            // used by external XA only
 #ifdef HAVE_ROW_BASED_REPLICATION
@@ -1350,7 +1358,6 @@
   List	     <MYSQL_ERROR> warn_list;
   uint	     warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
   uint	     total_warn_count;
-  List	     <Open_tables_state> open_state_list;
   /*
     Id of current query. Statement can be reused to execute several queries
     query_id is global in context of the whole MySQL server.
@@ -1610,8 +1617,8 @@
   void set_status_var_init();
   bool is_context_analysis_only()
     { return current_arena->is_stmt_prepare() || lex->view_prepare_mode; }
-  bool push_open_tables_state();
-  void pop_open_tables_state();
+  void reset_n_backup_open_tables_state(Open_tables_state *backup);
+  void restore_backup_open_tables_state(Open_tables_state *backup);
 };
 
 
@@ -1835,8 +1842,8 @@
 
   TMP_TABLE_PARAM()
     :copy_field(0), group_parts(0),
-    group_length(0), group_null_parts(0), convert_blob_length(0),
-    schema_table(0)
+     group_length(0), group_null_parts(0), convert_blob_length(0),
+     schema_table(0)
   {}
   ~TMP_TABLE_PARAM()
   {

--- 1.169/sql/sql_insert.cc	2005-08-03 22:33:13 +02:00
+++ 1.170/sql/sql_insert.cc	2005-08-11 02:16:31 +02:00
@@ -812,11 +812,11 @@
 
   table_list->next_local= 0;
   select_lex->context.resolve_in_table_list_only(table_list);
-  if ((values && check_insert_fields(thd, table_list, fields, *values,
-                                     !insert_into_view)) ||
-      (values && setup_fields(thd, 0, *values, 0, 0, 0)))
-    res= TRUE;
-  else if (duplic == DUP_UPDATE)
+  if (values &&
+      !(res= check_insert_fields(thd, table_list, fields, *values,
+                                     !insert_into_view) ||
+             setup_fields(thd, 0, *values, 0, 0, 0)) &&
+      duplic == DUP_UPDATE)
   {
     select_lex->no_wrap_view_item= TRUE;
     res= check_update_fields(thd, table_list, update_fields);
@@ -1093,7 +1093,9 @@
 
 err:
   info->last_errno= error;
-  thd->lex->current_select->no_error= 0;        // Give error
+  /* current_select is NULL if this is a delayed insert */
+  if (thd->lex->current_select)
+    thd->lex->current_select->no_error= 0;        // Give error
   table->file->print_error(error,MYF(0));
 
 before_trg_err:
@@ -2092,7 +2094,26 @@
   */
   lex->current_select= &lex->select_lex;
   res= check_insert_fields(thd, table_list, *fields, values,
-                           !insert_into_view);
+                           !insert_into_view) ||
+       setup_fields(thd, 0, values, 0, 0, 0);
+  if (info.handle_duplicates == DUP_UPDATE)
+  {
+    TABLE_LIST *save_next_local= table_list->next_local;
+    table_list->next_local= 0;
+    lex->select_lex.context.resolve_in_table_list_only(table_list);
+    lex->select_lex.no_wrap_view_item= TRUE;
+    res= res || check_update_fields(thd, table_list, *info.update_fields);
+    lex->select_lex.no_wrap_view_item= FALSE;
+
+    /*
+      When we are not using GROUP BY we can refer to other tables in the
+      ON DUPLICATE KEY part
+    */       
+    if (!lex->select_lex.group_list.elements)
+      table_list->next_local= save_next_local;
+    res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
+    table_list->next_local= save_next_local;
+  }
   lex->current_select= lex_current_select_save;
   if (res)
     DBUG_RETURN(1);

--- 1.455/sql/sql_parse.cc	2005-08-03 22:33:13 +02:00
+++ 1.456/sql/sql_parse.cc	2005-08-11 02:16:32 +02:00
@@ -27,6 +27,7 @@
 
 #include "sp_head.h"
 #include "sp.h"
+#include "sp_cache.h"
 
 #ifdef HAVE_OPENSSL
 /*
@@ -124,7 +125,7 @@
 {
   int error=0;
   DBUG_ENTER("end_active_trans");
-  if (unlikely(thd->transaction.in_sub_stmt))
+  if (unlikely(thd->in_sub_stmt))
   {
     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
     DBUG_RETURN(1);
@@ -147,11 +148,7 @@
 static bool begin_trans(THD *thd)
 {
   int error=0;
-  /*
-    QQ: May be it is better to simply prohibit COMMIT and ROLLBACK in
-        stored routines as SQL2003 suggests?
-  */
-  if (unlikely(thd->transaction.in_sub_stmt))
+  if (unlikely(thd->in_sub_stmt))
   {
     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
     return 1;
@@ -193,7 +190,7 @@
 				   const char *host,
 				   USER_RESOURCES *mqh)
 {
-  int return_val=0;
+  int return_val= 0;
   uint temp_len, user_len;
   char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
   struct  user_conn *uc;
@@ -201,7 +198,7 @@
   DBUG_ASSERT(user != 0);
   DBUG_ASSERT(host != 0);
 
-  user_len=strlen(user);
+  user_len= strlen(user);
   temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
   (void) pthread_mutex_lock(&LOCK_user_conn);
   if (!(uc = (struct  user_conn *) hash_search(&hash_user_connections,
@@ -213,21 +210,21 @@
 			 MYF(MY_WME)))))
     {
       net_send_error(thd, 0, NullS);		// Out of memory
-      return_val=1;
+      return_val= 1;
       goto end;
     }
     uc->user=(char*) (uc+1);
     memcpy(uc->user,temp_user,temp_len+1);
     uc->host= uc->user + user_len +  1;
-    uc->len = temp_len;
+    uc->len= temp_len;
     uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
-    uc->user_resources=*mqh;
-    uc->intime=thd->thr_create_time;
+    uc->user_resources= *mqh;
+    uc->intime= thd->thr_create_time;
     if (my_hash_insert(&hash_user_connections, (byte*) uc))
     {
       my_free((char*) uc,0);
       net_send_error(thd, 0, NullS);		// Out of memory
-      return_val=1;
+      return_val= 1;
       goto end;
     }
   }
@@ -1340,11 +1337,7 @@
   int res= 0;
   DBUG_ENTER("end_trans");
 
-  /*
-    QQ: May be it is better to simply prohibit COMMIT and ROLLBACK in
-        stored routines as SQL2003 suggests?
-  */
-  if (unlikely(thd->transaction.in_sub_stmt))
+  if (unlikely(thd->in_sub_stmt))
   {
     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
     DBUG_RETURN(1);
@@ -3645,6 +3638,7 @@
     if (!(res = mysql_create_function(thd, &lex->udf)))
       send_ok(thd);
 #else
+    my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
     res= TRUE;
 #endif
     break;
@@ -4074,8 +4068,8 @@
     name= thd->strdup(name); 
     db= thd->strmake(lex->sphead->m_db.str, lex->sphead->m_db.length);
     res= (result= lex->sphead->create(thd));
-    switch (result) {
-    case SP_OK:
+    if (result == SP_OK)
+    {
       lex->unit.cleanup();
       delete lex->sphead;
       lex->sphead= 0;
@@ -4095,27 +4089,26 @@
       }
 #endif
       send_ok(thd);
-      break;
-    case SP_WRITE_ROW_FAILED:
-      my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
-      lex->unit.cleanup();
-      delete lex->sphead;
-      lex->sphead= 0;
-      goto error;
-    case SP_NO_DB_ERROR:
-      my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
-      lex->unit.cleanup();
-      delete lex->sphead;
-      lex->sphead= 0;
-      goto error;
-    case SP_BAD_IDENTIFIER:
-      my_error(ER_TOO_LONG_IDENT, MYF(0), name);
-      lex->unit.cleanup();
-      delete lex->sphead;
-      lex->sphead= 0;
-      goto error;
-    default:
-      my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
+    }
+    else
+    {
+      switch (result) {
+      case SP_WRITE_ROW_FAILED:
+	my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
+	break;
+      case SP_NO_DB_ERROR:
+	my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
+	break;
+      case SP_BAD_IDENTIFIER:
+	my_error(ER_TOO_LONG_IDENT, MYF(0), name);
+	break;
+      case SP_BODY_TOO_LONG:
+	my_error(ER_TOO_LONG_BODY, MYF(0), name);
+	break;
+      default:
+	my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
+	break;
+      }
       lex->unit.cleanup();
       delete lex->sphead;
       lex->sphead= 0;
@@ -4136,9 +4129,8 @@
        goto error;
 
       /*
-        By this moment all needed SPs should be in cache so no need
-        to look into DB. Moreover we may be unable to do it becuase
-        we may don't have read lock on mysql.proc
+        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)))
       {
@@ -4203,7 +4195,7 @@
 	select_limit= thd->variables.select_limit;
 	thd->variables.select_limit= HA_POS_ERROR;
 
-	thd->row_count_func= 0;
+        thd->row_count_func= 0;
         tmp_disable_binlog(thd); /* don't binlog the substatements */
 	res= sp->execute_procedure(thd, &lex->value_list);
         reenable_binlog(thd);
@@ -5312,6 +5304,8 @@
   THD *thd;
   LEX *lex;
   LEX_STRING tmp, null_lex_string;
+  Item *var;
+  char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
   DBUG_ENTER("create_select_for_variable");
 
   thd= current_thd;
@@ -5321,8 +5315,14 @@
   tmp.str= (char*) var_name;
   tmp.length=strlen(var_name);
   bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
-  add_item_to_list(thd, get_system_var(thd, OPT_SESSION, tmp,
-				       null_lex_string));
+  /*
+    We set the name of Item to @@session.var_name because that then is used
+    as the column name in the output.
+  */
+  var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string);
+  end= strxmov(buff, "@@session.", var_name, NullS);
+  var->set_name(buff, end-buff, system_charset_info);
+  add_item_to_list(thd, var);
   DBUG_VOID_RETURN;
 }
 
@@ -5348,11 +5348,12 @@
 void mysql_parse(THD *thd, char *inBuf, uint length)
 {
   DBUG_ENTER("mysql_parse");
-
   mysql_init_query(thd, (uchar*) inBuf, length);
   if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
   {
     LEX *lex= thd->lex;
+    sp_cache_flush_obsolete(&thd->sp_proc_cache);
+    sp_cache_flush_obsolete(&thd->sp_func_cache);
     if (!yyparse((void *)thd) && ! thd->is_fatal_error)
     {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -5820,7 +5821,7 @@
         new_field->length= 1;
       if (new_field->length > MAX_BIT_FIELD_LENGTH)
       {
-        my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name,
+        my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
                  MAX_BIT_FIELD_LENGTH);
         DBUG_RETURN(NULL);
       }
@@ -5839,7 +5840,10 @@
         type != MYSQL_TYPE_STRING &&
         type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY)))
   {
-    my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0),
+    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);
   }
@@ -6396,6 +6400,13 @@
   bool result=0;
   select_errors=0;				/* Write if more errors */
   bool tmp_write_to_binlog= 1;
+
+  if (thd->in_sub_stmt)
+  {
+    my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
+    return 1;
+  }
+
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   if (options & REFRESH_GRANT)
   {
@@ -6450,6 +6461,23 @@
   {
     if ((options & REFRESH_READ_LOCK) && thd)
     {
+      /*
+        We must not try to aspire a global read lock if we have a write
+        locked table. This would lead to a deadlock when trying to
+        reopen (and re-lock) the table after the flush.
+      */
+      if (thd->locked_tables)
+      {
+        THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
+        THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
+
+        for (; lock_p < end_p; lock_p++)
+          if ((*lock_p)->type == TL_WRITE)
+          {
+            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+            return 1;
+          }
+      }
       /*
 	Writing to the binlog could cause deadlocks, as we don't log
 	UNLOCK TABLES

--- 1.344/sql/sql_select.cc	2005-07-25 12:48:04 +02:00
+++ 1.345/sql/sql_select.cc	2005-08-11 02:16:33 +02:00
@@ -1016,7 +1016,7 @@
 			    group_list : (ORDER*) 0),
 			   group_list ? 0 : select_distinct,
 			   group_list && simple_group,
-			   select_options,
+			   select_options & ~TMP_TABLE_FORCE_MYISAM,
 			   (order == 0 || skip_sort_order) ? select_limit :
 			   HA_POS_ERROR,
 			   (char *) "")))
@@ -1090,9 +1090,10 @@
 	  order=0;
       }
     }
-    
-    if (thd->lex->subqueries)
+
+    if (select_lex->uncacheable && !is_top_level_join())
     {
+      /* If this join belongs to an uncacheable subquery */
       if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
 	DBUG_RETURN(-1);
       error= 0;				// Ensure that tmp_join.error= 0
@@ -1198,7 +1199,14 @@
     {
       result->send_fields(fields_list,
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
-      if (cond_value != Item::COND_FALSE && (!having || having->val_int()))
+      /*
+        We have to test for 'conds' here as the WHERE may not be constant
+        even if we don't have any tables for prepared statements or if
+        conds uses something like 'rand()'.
+      */
+      if (cond_value != Item::COND_FALSE &&
+          (!conds || conds->val_int()) &&
+          (!having || having->val_int()))
       {
 	if (do_send_rows && (procedure ? (procedure->send_row(fields_list) ||
                                           procedure->end_of_records())
@@ -1389,7 +1397,8 @@
 						(ORDER*) 0,
 						curr_join->select_distinct && 
 						!curr_join->group_list,
-						1, curr_join->select_options,
+						1, curr_join->select_options
+                                                & ~TMP_TABLE_FORCE_MYISAM,
 						HA_POS_ERROR,
 						(char *) "")))
 	  DBUG_VOID_RETURN;
@@ -1628,9 +1637,7 @@
   curr_join->fields= curr_fields_list;
   curr_join->procedure= procedure;
 
-  if (unit == &thd->lex->unit &&
-      (unit->fake_select_lex == 0 || select_lex == unit->fake_select_lex) &&
-      thd->cursor && tables != const_tables)
+  if (is_top_level_join() && thd->cursor && tables != const_tables)
   {
     /*
       We are here if this is JOIN::exec for the last select of the main unit
@@ -1707,6 +1714,7 @@
 Cursor::Cursor(THD *thd)
   :Query_arena(&main_mem_root, INITIALIZED),
    join(0), unit(0),
+   protocol(thd),
    close_at_commit(FALSE)
 {
   /* We will overwrite it at open anyway. */
@@ -1755,7 +1763,7 @@
   for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
   {
     const handlerton *ht= *pht;
-    close_at_commit|= (ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
+    close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
     if (ht->create_cursor_read_view)
     {
       info->ht= ht;
@@ -1842,6 +1850,7 @@
   JOIN_TAB *join_tab= join->join_tab + join->const_tables;
   enum_nested_loop_state error= NESTED_LOOP_OK;
   Query_arena backup_arena;
+  Engine_info *info;
   DBUG_ENTER("Cursor::fetch");
   DBUG_PRINT("enter",("rows: %lu", num_rows));
 
@@ -1856,7 +1865,7 @@
   /* save references to memory, allocated during fetch */
   thd->set_n_backup_item_arena(this, &backup_arena);
 
-  for (Engine_info *info= ht_info; info->read_view ; info++)
+  for (info= ht_info; info->read_view ; info++)
     (info->ht->set_cursor_read_view)(info->read_view);
 
   join->fetch_limit+= num_rows;
@@ -1875,7 +1884,7 @@
   /* Grab free_list here to correctly free it in close */
   thd->restore_backup_item_arena(this, &backup_arena);
 
-  for (Engine_info *info= ht_info; info->read_view; info++)
+  for (info= ht_info; info->read_view; info++)
     (info->ht->set_cursor_read_view)(0);
 
   if (error == NESTED_LOOP_CURSOR_LIMIT)
@@ -2750,9 +2759,9 @@
     We use null_rejecting in add_not_null_conds() to add
     'othertbl.field IS NOT NULL' to tab->select_cond.
   */
-  (*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) &&
-                                 ((*value)->type() == Item::FIELD_ITEM) &&
-                                 ((Item_field*)*value)->field->maybe_null();
+  (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC) &&
+                                  ((*value)->type() == Item::FIELD_ITEM) &&
+                                  ((Item_field*)*value)->field->maybe_null());
   (*key_fields)++;
 }
 
@@ -7936,7 +7945,15 @@
 				   item->name, table, item->unsigned_flag);
     break;
   case STRING_RESULT:
-    if (item->max_length > 255 && convert_blob_length)
+    enum enum_field_types type;
+    /*
+      DATE/TIME fields have STRING_RESULT result type. To preserve
+      type they needed to be handled separately.
+    */
+    if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
+        type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
+      new_field= item->tmp_table_field_from_field_type(table);
+    else if (item->max_length > 255 && convert_blob_length)
       new_field= new Field_varstring(convert_blob_length, maybe_null,
                                      item->name, table,
                                      item->collation.collation);
@@ -8026,6 +8043,14 @@
                         bool table_cant_handle_bit_fields,
                         uint convert_blob_length)
 {
+  if (type != Item::FIELD_ITEM &&
+      item->real_item()->type() == Item::FIELD_ITEM &&
+      (item->type() != Item::REF_ITEM ||
+       !((Item_ref *) item)->depended_from))
+  {
+    item= item->real_item();
+    type= Item::FIELD_ITEM;
+  }
   switch (type) {
   case Item::SUM_FUNC_ITEM:
   {
@@ -8039,30 +8064,31 @@
   case Item::DEFAULT_VALUE_ITEM:
   {
     Item_field *field= (Item_field*) item;
-    if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT)
+    /*
+      If item have to be able to store NULLs but underlaid field can't do it,
+      create_tmp_field_from_field() can't be used for tmp field creation.
+    */
+    if (field->maybe_null && !field->field->maybe_null())
+    {
+      Field *res= create_tmp_field_from_item(thd, item, table, NULL,
+                                       modify_item, convert_blob_length);
+      *from_field= field->field;
+      if (res && modify_item)
+        ((Item_field*)item)->result_field= res;
+      return res;
+    }
+
+    if (table_cant_handle_bit_fields && 
+        field->field->type() == FIELD_TYPE_BIT)
       return create_tmp_field_from_item(thd, item, table, copy_func,
                                         modify_item, convert_blob_length);
     return create_tmp_field_from_field(thd, (*from_field= field->field),
                                        item->name, table,
-                                       modify_item ? (Item_field*) item : NULL,
+                                       modify_item ? (Item_field*) item :
+                                       NULL,
                                        convert_blob_length);
   }
-  case Item::REF_ITEM:
-  {
-    Item *tmp_item;
-    if ((tmp_item= item->real_item())->type() == Item::FIELD_ITEM)
-    {
-      Item_field *field= (Item_field*) tmp_item;
-      Field *new_field= create_tmp_field_from_field(thd, 
-                               (*from_field= field->field),
-                               item->name, table,
-                               NULL,
-                               convert_blob_length);
-      if (modify_item)
-        item->set_result_field(new_field);
-      return new_field;
-    }
-  }
+  /* Fall through */
   case Item::FUNC_ITEM:
   case Item::COND_ITEM:
   case Item::FIELD_AVG_ITEM:
@@ -8074,6 +8100,7 @@
   case Item::REAL_ITEM:
   case Item::DECIMAL_ITEM:
   case Item::STRING_ITEM:
+  case Item::REF_ITEM:
   case Item::NULL_ITEM:
   case Item::VARBIN_ITEM:
     return create_tmp_field_from_item(thd, item, table, copy_func, modify_item,
@@ -8355,7 +8382,7 @@
   /* If result table is small; use a heap */
   if (blob_count || using_unique_constraint ||
       (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
-      OPTION_BIG_TABLES)
+      OPTION_BIG_TABLES ||(select_options & TMP_TABLE_FORCE_MYISAM))
   {
     table->file=get_new_handler(table,table->s->db_type= DB_TYPE_MYISAM);
     if (group &&
@@ -9718,7 +9745,13 @@
       table->file->extra(HA_EXTRA_KEYREAD);
       tab->index= tab->ref.key;
     }
-    if ((error=join_read_const(tab)))
+    error=join_read_const(tab);
+    if (table->key_read)
+    {
+      table->key_read=0;
+      table->file->extra(HA_EXTRA_NO_KEYREAD);
+    }
+    if (error)
     {
       tab->info="unique row not found";
       /* Mark for EXPLAIN that the row was not found */
@@ -9726,11 +9759,6 @@
       if (!table->maybe_null || error > 0)
 	DBUG_RETURN(error);
     }
-    if (table->key_read)
-    {
-      table->key_read=0;
-      table->file->extra(HA_EXTRA_NO_KEYREAD);
-    }
   }
   if (*tab->on_expr_ref && !table->null_row)
   {
@@ -9851,6 +9879,11 @@
   int error;
   TABLE *table= tab->table;
 
+  for (uint i= 0 ; i < tab->ref.key_parts ; i++)
+  {
+    if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
+        return -1;
+  } 
   if (!table->file->inited)
     table->file->ha_index_init(tab->ref.key);
   if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
@@ -10904,13 +10937,13 @@
   usable_keys.set_all();
   for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
   {
-    if ((*tmp_order->item)->type() != Item::FIELD_ITEM)
+    Item *item= (*tmp_order->item)->real_item();
+    if (item->type() != Item::FIELD_ITEM)
     {
       usable_keys.clear_all();
       DBUG_RETURN(0);
     }
-    usable_keys.intersect(((Item_field*) (*tmp_order->item))->
-			  field->part_of_sortkey);
+    usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
     if (usable_keys.is_clear_all())
       DBUG_RETURN(0);					// No usable keys
   }

--- 1.258/sql/sql_show.cc	2005-07-25 12:48:04 +02:00
+++ 1.259/sql/sql_show.cc	2005-08-11 02:16:33 +02:00
@@ -20,6 +20,7 @@
 #include "mysql_priv.h"
 #include "sql_select.h"                         // For select_describe
 #include "repl_failsafe.h"
+#include "sp.h"
 #include "sp_head.h"
 #include "sql_trigger.h"
 #include <my_dir.h>
@@ -352,7 +353,7 @@
   thd->lex->view_prepare_mode= TRUE;
 
   /* Only one table for now, but VIEW can involve several tables */
-  if (open_normal_and_derived_tables(thd, table_list))
+  if (open_normal_and_derived_tables(thd, table_list, 0))
   {
     DBUG_RETURN(TRUE);
   }
@@ -551,7 +552,7 @@
   DBUG_ENTER("mysqld_list_fields");
   DBUG_PRINT("enter",("table: %s",table_list->table_name));
 
-  if (open_normal_and_derived_tables(thd, table_list))
+  if (open_normal_and_derived_tables(thd, table_list, 0))
     DBUG_VOID_RETURN;
   table= table_list->table;
 
@@ -1936,6 +1937,8 @@
   TABLE *table= tables->table;
   SELECT_LEX *select_lex= &lex->select_lex;
   SELECT_LEX *old_all_select_lex= lex->all_selects_list;
+  TABLE_LIST **save_query_tables_last= lex->query_tables_last;
+  enum_sql_command save_sql_command= lex->sql_command;
   SELECT_LEX *lsel= tables->schema_select_lex;
   ST_SCHEMA_TABLE *schema_table= tables->schema_table;
   SELECT_LEX sel;
@@ -1944,40 +1947,49 @@
   uint len;
   bool with_i_schema;
   enum enum_schema_tables schema_table_idx;
-  thr_lock_type lock_type;
   List<char> bases;
   List_iterator_fast<char> it(bases);
   COND *partial_cond; 
   uint derived_tables= lex->derived_tables; 
   int error= 1;
+  Open_tables_state open_tables_state_backup;
   DBUG_ENTER("get_all_tables");
 
   LINT_INIT(end);
   LINT_INIT(len);
 
+  /*
+    Let us set fake sql_command so views won't try to merge
+    themselves into main statement.
+  */
+  lex->sql_command= SQLCOM_SHOW_FIELDS;
+
+  /*
+    We should not introduce deadlocks even if we already have some
+    tables open and locked, since we won't lock tables which we will
+    open and will ignore possible name-locks for these tables.
+  */
+  thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
+
   if (lsel)
   {
-    TABLE *old_open_tables= thd->open_tables;
     TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
     bool res;
 
     lex->all_selects_list= lsel;
-    res= open_normal_and_derived_tables(thd, show_table_list);
+    res= open_normal_and_derived_tables(thd, show_table_list,
+                                        MYSQL_LOCK_IGNORE_FLUSH);
     if (schema_table->process_table(thd, show_table_list,
                                     table, res, show_table_list->db,
                                     show_table_list->alias))
       goto err;
-    close_thread_tables(thd, 0, 0, old_open_tables);
+    close_thread_tables(thd);
     show_table_list->table= 0;
     error= 0;
     goto err;
   }
 
   schema_table_idx= get_schema_table_idx(schema_table);
-  lock_type= TL_UNLOCK;
-
-  if (schema_table_idx == SCH_TABLES)
-    lock_type= TL_READ;
 
   if (make_db_list(thd, &bases, &idx_field_vals,
                    &with_i_schema, 0))
@@ -2060,19 +2072,18 @@
           else
           {
             int res;
-            TABLE *old_open_tables= thd->open_tables;
             if (make_table_list(thd, &sel, base_name, file_name))
               goto err;
             TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
-            show_table_list->lock_type= lock_type;
             lex->all_selects_list= &sel;
             lex->derived_tables= 0;
-            res= open_normal_and_derived_tables(thd, show_table_list);
+            res= open_normal_and_derived_tables(thd, show_table_list,
+                                                MYSQL_LOCK_IGNORE_FLUSH);
             if (schema_table->process_table(thd, show_table_list, table,
                                             res, base_name,
                                             show_table_list->alias))
               goto err;
-            close_thread_tables(thd, 0, 0, old_open_tables);
+            close_thread_tables(thd);
           }
         }
       }
@@ -2086,8 +2097,12 @@
 
   error= 0;
 err:
+  thd->restore_backup_open_tables_state(&open_tables_state_backup);
   lex->derived_tables= derived_tables;
   lex->all_selects_list= old_all_select_lex;
+  lex->query_tables_last= save_query_tables_last;
+  *save_query_tables_last= 0;
+  lex->sql_command= save_sql_command;
   DBUG_RETURN(error);
 }
 
@@ -2192,7 +2207,8 @@
     TABLE_SHARE *share= show_table->s;
     handler *file= show_table->file;
 
-    file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK);
+    file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
+               HA_STATUS_NO_LOCK);
     if (share->tmp_table == TMP_TABLE)
       table->field[3]->store("TEMPORARY", 9, cs);
     else
@@ -2248,13 +2264,8 @@
     table->field[12]->store((longlong) file->delete_length);
     if (show_table->found_next_number_field)
     {
-      show_table->next_number_field=show_table->found_next_number_field;
-      show_table->next_number_field->reset();
-      file->update_auto_increment();
-      table->field[13]->store((longlong) show_table->
-                              next_number_field->val_int());
+      table->field[13]->store((longlong) file->auto_increment_value);
       table->field[13]->set_notnull();
-      show_table->next_number_field=0;
     }
     if (file->create_time)
     {
@@ -2727,12 +2738,14 @@
   TABLE_LIST proc_tables;
   const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
   int res= 0;
-  TABLE *table= tables->table, *old_open_tables= thd->open_tables;
+  TABLE *table= tables->table;
   bool full_access;
   char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
+  Open_tables_state open_tables_state_backup;
   DBUG_ENTER("fill_schema_proc");
 
   strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+  /* We use this TABLE_LIST instance only for checking of privileges. */
   bzero((char*) &proc_tables,sizeof(proc_tables));
   proc_tables.db= (char*) "mysql";
   proc_tables.db_length= 5;
@@ -2740,7 +2753,7 @@
   proc_tables.table_name_length= 4;
   proc_tables.lock_type= TL_READ;
   full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
-  if (!(proc_table= open_ltable(thd, &proc_tables, TL_READ)))
+  if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
   {
     DBUG_RETURN(1);
   }
@@ -2766,7 +2779,7 @@
 
 err:
   proc_table->file->ha_index_end();
-  close_thread_tables(thd, 0, 0, old_open_tables);
+  close_proc_table(thd, &open_tables_state_backup);
   DBUG_RETURN(res);
 }
 
@@ -2983,9 +2996,13 @@
                           const char *tname, LEX_STRING *trigger_name,
                           enum trg_event_type event,
                           enum trg_action_time_type timing,
-                          LEX_STRING *trigger_stmt)
+                          LEX_STRING *trigger_stmt,
+                          ulong sql_mode)
 {
   CHARSET_INFO *cs= system_charset_info;
+  byte *sql_mode_str;
+  ulong sql_mode_len;
+
   restore_record(table, s->default_values);
   table->field[1]->store(db, strlen(db), cs);
   table->field[2]->store(trigger_name->str, trigger_name->length, cs);
@@ -2999,6 +3016,12 @@
                           trg_action_time_type_names[timing].length, cs);
   table->field[14]->store("OLD", 3, cs);
   table->field[15]->store("NEW", 3, cs);
+
+  sql_mode_str=
+    sys_var_thd_sql_mode::symbolic_mode_representation(thd,
+                                                       sql_mode,
+                                                       &sql_mode_len);
+  table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
   return schema_table_store_record(thd, table);
 }
 
@@ -3031,13 +3054,16 @@
       {
         LEX_STRING trigger_name;
         LEX_STRING trigger_stmt;
+        ulong sql_mode;
         if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
                                        (enum trg_action_time_type)timing,
-                                       &trigger_name, &trigger_stmt))
+                                       &trigger_name, &trigger_stmt,
+                                       &sql_mode))
           continue;
         if (store_trigger(thd, table, base_name, file_name, &trigger_name,
                          (enum trg_event_type) event,
-                         (enum trg_action_time_type) timing, &trigger_stmt))
+                         (enum trg_action_time_type) timing, &trigger_stmt,
+                         sql_mode))
           DBUG_RETURN(1);
       }
     }
@@ -3306,7 +3332,8 @@
   if (!(table= create_tmp_table(thd, tmp_table_param,
                                 field_list, (ORDER*) 0, 0, 0, 
                                 (select_lex->options | thd->options |
-                                 TMP_TABLE_ALL_COLUMNS),
+                                 TMP_TABLE_ALL_COLUMNS) &
+                                ~TMP_TABLE_FORCE_MYISAM,
                                 HA_POS_ERROR, table_list->alias)))
     DBUG_RETURN(0);
   table_list->schema_table_param= tmp_table_param;
@@ -3543,9 +3570,8 @@
   if (table_list->schema_table_reformed) // show command
   {
     SELECT_LEX *sel= lex->current_select;
-    uint i= 0;
     Item *item;
-    Field_translator *transl;
+    Field_translator *transl, *org_transl;
 
     if (table_list->field_translation)
     {
@@ -3566,16 +3592,17 @@
     {
       DBUG_RETURN(1);
     }
-    while ((item= it++))
+    for (org_transl= transl; (item= it++); transl++)
     {
-      char *name= item->name;
-      transl[i].item= item;
-      if (!item->fixed && item->fix_fields(thd, &transl[i].item))
+      transl->item= item;
+      transl->name= item->name;
+      if (!item->fixed && item->fix_fields(thd, &transl->item))
+      {
         DBUG_RETURN(1);
-      transl[i++].name= name;
+      }
     }
-    table_list->field_translation= transl;
-    table_list->field_translation_end= transl + sel->item_list.elements;
+    table_list->field_translation= org_transl;
+    table_list->field_translation_end= transl;
   }
 
   DBUG_RETURN(0);
@@ -3650,11 +3677,6 @@
     TABLE_LIST *table_list= tab->table->pos_in_table_list;
     if (table_list->schema_table && thd->fill_derived_tables())
     {
-      TABLE_LIST **query_tables_last= lex->query_tables_last;
-      TABLE *old_derived_tables= thd->derived_tables;
-      MYSQL_LOCK *sql_lock= thd->lock;
-      lex->sql_command= SQLCOM_SHOW_FIELDS;
-      DBUG_ASSERT(!*query_tables_last);
       if (&lex->unit != lex->current_select->master_unit()) // is subselect
       {
         table_list->table->file->extra(HA_EXTRA_RESET_STATE);
@@ -3665,16 +3687,9 @@
       else
         table_list->table->file->records= 0;
 
-      thd->derived_tables= 0;
-      thd->lock=0;
       if (table_list->schema_table->fill_table(thd, table_list,
                                                tab->select_cond))
         result= 1;
-      thd->lock= sql_lock;
-      lex->sql_command= SQLCOM_SELECT;
-      thd->derived_tables= old_derived_tables;
-      lex->query_tables_last= query_tables_last;
-      *query_tables_last= 0;
     }
   }
   thd->no_warnings_for_error= 0;
@@ -3949,6 +3964,7 @@
   {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
   {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
   {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
+  {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
@@ -3967,46 +3983,46 @@
 
 ST_SCHEMA_TABLE schema_tables[]=
 {
-  {"SCHEMATA", schema_fields_info, create_schema_table,
-   fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0},
-  {"TABLES", tables_fields_info, create_schema_table, 
-   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
-  {"COLUMNS", columns_fields_info, create_schema_table, 
-   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
    fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
   {"COLLATIONS", collation_fields_info, create_schema_table, 
    fill_schema_collation, make_old_format, 0, -1, -1, 0},
   {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
    create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0},
-  {"ROUTINES", proc_fields_info, create_schema_table, 
-    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
-  {"STATISTICS", stat_fields_info, create_schema_table, 
-    get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0},
-  {"VIEWS", view_fields_info, create_schema_table, 
-    get_all_tables, 0, get_schema_views_record, 1, 2, 0},
-  {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-    fill_schema_user_privileges, 0, 0, -1, -1, 0},
-  {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-    fill_schema_schema_privileges, 0, 0, -1, -1, 0},
-  {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
-    fill_schema_table_privileges, 0, 0, -1, -1, 0},
+  {"COLUMNS", columns_fields_info, create_schema_table, 
+   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
   {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
     fill_schema_column_privileges, 0, 0, -1, -1, 0},
-  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
-    get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
   {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
     get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
-  {"TABLE_NAMES", table_names_fields_info, create_schema_table,
-   get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
   {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
    fill_open_tables, make_old_format, 0, -1, -1, 1},
+  {"ROUTINES", proc_fields_info, create_schema_table, 
+    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
+  {"SCHEMATA", schema_fields_info, create_schema_table,
+   fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0},
+  {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
+    fill_schema_schema_privileges, 0, 0, -1, -1, 0},
+  {"STATISTICS", stat_fields_info, create_schema_table, 
+    get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0},
   {"STATUS", variables_fields_info, create_schema_table, fill_status, 
    make_old_format, 0, -1, -1, 1},
-  {"TRIGGERS", triggers_fields_info, create_schema_table, 
+  {"TABLES", tables_fields_info, create_schema_table, 
+   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
+  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
+    get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
+  {"TABLE_NAMES", table_names_fields_info, create_schema_table,
+   get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+  {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
+    fill_schema_table_privileges, 0, 0, -1, -1, 0},
+  {"TRIGGERS", triggers_fields_info, create_schema_table,
    get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
    make_old_format, 0, -1, -1, 1},
+  {"VIEWS", view_fields_info, create_schema_table, 
+    get_all_tables, 0, get_schema_views_record, 1, 2, 0},
+  {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
+    fill_schema_user_privileges, 0, 0, -1, -1, 0},
   {0, 0, 0, 0, 0, 0, 0, 0, 0}
 };
 

--- 1.267/sql/sql_table.cc	2005-08-03 22:33:13 +02:00
+++ 1.268/sql/sql_table.cc	2005-08-11 02:16:34 +02:00
@@ -229,7 +229,6 @@
   for (table= tables; table; table= table->next_local)
   {
     char *db=table->db;
-    uint flags;
     mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL);
     if (!close_temporary_table(thd, db, table->table_name))
     {
@@ -240,10 +239,11 @@
     error=0;
     if (!drop_temporary)
     {
-      abort_locked_tables(thd,db,table->table_name);
-      flags= RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG;
-      remove_table_from_cache(thd,db,table->table_name,flags);
-      drop_locked_tables(thd,db,table->table_name);
+      abort_locked_tables(thd, db, table->table_name);
+      remove_table_from_cache(thd, db, table->table_name,
+	                      RTFC_WAIT_OTHER_THREAD_FLAG |
+			      RTFC_CHECK_KILLED_FLAG);
+      drop_locked_tables(thd, db, table->table_name);
       if (thd->killed)
       {
         thd->no_warnings_for_error= 0;
@@ -1620,7 +1620,7 @@
     create_info->data_file_name= create_info->index_file_name= 0;
   create_info->table_options=db_options;
 
-  if (rea_create_table(thd, path, table_name, db,
+  if (rea_create_table(thd, path, db, table_name,
                        create_info, fields, key_count,
 		       key_info_buffer))
     goto end;
@@ -2260,14 +2260,14 @@
     /* Close all instances of the table to allow repair to rename files */
     if (lock_type == TL_WRITE && table->table->s->version)
     {
-      uint flags;
       pthread_mutex_lock(&LOCK_open);
       const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 					      "Waiting to get writelock");
       mysql_lock_abort(thd,table->table);
-      flags= RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG;
       remove_table_from_cache(thd, table->table->s->db,
-                              table->table->s->table_name, flags);
+                              table->table->s->table_name,
+                              RTFC_WAIT_OTHER_THREAD_FLAG |
+                              RTFC_CHECK_KILLED_FLAG);
       thd->exit_cond(old_message);
       if (thd->killed)
 	goto err;
@@ -2641,6 +2641,15 @@
     }
   }
 
+  /* 
+     create like should be not allowed for Views, Triggers, ... 
+  */
+  if (mysql_frm_type(src_path) != FRMTYPE_TABLE)
+  {
+    my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE");
+    goto err;
+  }
+
   /*
     Validate the destination table
 
@@ -3750,9 +3759,10 @@
     if (table)
     {
       VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
+      /* Mark in-use copies old */
       remove_table_from_cache(thd,db,table_name,RTFC_NO_FLAG);
-                                                 // Mark in-use copies old
-      mysql_lock_abort(thd,table);		 // end threads waiting on lock
+      /* end threads waiting on lock */
+      mysql_lock_abort(thd,table);
     }
     VOID(quick_rm_table(old_db_type,db,old_name));
     if (close_data_tables(thd,db,table_name) ||

--- 1.165/sql/sql_update.cc	2005-08-03 22:33:13 +02:00
+++ 1.166/sql/sql_update.cc	2005-08-11 02:16:34 +02:00
@@ -138,7 +138,7 @@
 
   LINT_INIT(timestamp_query_id);
 
-  if (open_tables(thd, &table_list, &table_count))
+  if (open_tables(thd, &table_list, &table_count, 0))
     DBUG_RETURN(1);
 
   if (table_list->multitable_view)
@@ -636,7 +636,8 @@
   thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
 
   /* open tables and create derived ones, but do not lock and fill them */
-  if ((original_multiupdate && open_tables(thd, &table_list, & table_count)) ||
+  if ((original_multiupdate &&
+       open_tables(thd, &table_list, &table_count, 0)) ||
       mysql_handle_derived(lex, &mysql_derived_prepare))
     DBUG_RETURN(TRUE);
   /*

--- 1.175/sql/table.cc	2005-07-25 12:54:44 +02:00
+++ 1.176/sql/table.cc	2005-08-11 02:16:35 +02:00
@@ -1348,8 +1348,8 @@
 
 	/* Create a .frm file */
 
-File create_frm(THD *thd, register my_string name, const char *table,
-                const char *db, uint reclength, uchar *fileinfo,
+File create_frm(THD *thd, my_string name, const char *db,
+                const char *table, uint reclength, uchar *fileinfo,
 		HA_CREATE_INFO *create_info, uint keys)
 {
   register File file;

--- 1.104/sql/table.h	2005-07-25 12:48:04 +02:00
+++ 1.105/sql/table.h	2005-08-11 02:16:35 +02:00
@@ -282,11 +282,26 @@
 
 enum enum_schema_tables
 {
-  SCH_SCHEMATA= 0, SCH_TABLES, SCH_COLUMNS, SCH_CHARSETS, SCH_COLLATIONS,
-  SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_PROCEDURES, SCH_STATISTICS,
-  SCH_VIEWS, SCH_USER_PRIVILEGES, SCH_SCHEMA_PRIVILEGES, SCH_TABLE_PRIVILEGES,
-  SCH_COLUMN_PRIVILEGES, SCH_TABLE_CONSTRAINTS, SCH_KEY_COLUMN_USAGE,
-  SCH_TABLE_NAMES, SCH_OPEN_TABLES, SCH_STATUS, SCH_TRIGGERS, SCH_VARIABLES
+  SCH_CHARSETS= 0,
+  SCH_COLLATIONS,
+  SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
+  SCH_COLUMNS,
+  SCH_COLUMN_PRIVILEGES,
+  SCH_KEY_COLUMN_USAGE,
+  SCH_OPEN_TABLES,
+  SCH_PROCEDURES,
+  SCH_SCHEMATA,
+  SCH_SCHEMA_PRIVILEGES,
+  SCH_STATISTICS,
+  SCH_STATUS,
+  SCH_TABLES,
+  SCH_TABLE_CONSTRAINTS,
+  SCH_TABLE_NAMES,
+  SCH_TABLE_PRIVILEGES,
+  SCH_TRIGGERS,
+  SCH_VARIABLES,
+  SCH_VIEWS,
+  SCH_USER_PRIVILEGES
 };
 
 

--- 1.123/sql/sql_union.cc	2005-07-25 12:48:04 +02:00
+++ 1.124/sql/sql_union.cc	2005-08-11 02:16:34 +02:00
@@ -119,8 +119,6 @@
 st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) 
 {
   thd->lex->current_select= fake_select_lex;
-  fake_select_lex->ftfunc_list_alloc.empty();
-  fake_select_lex->ftfunc_list= &fake_select_lex->ftfunc_list_alloc;
   fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
 					   (byte **)
 					   &result_table_list.next_local);
@@ -235,7 +233,13 @@
 
     if ((res= (res || thd_arg->is_fatal_error)))
       goto err;
-    if (sl == first_select)
+    /*
+      Use items list of underlaid select for derived tables to preserve
+      information about fields lengths and exact types
+    */
+    if (!is_union)
+      types= first_select_in_union()->item_list;
+    else if (sl == first_select)
     {
       /*
         We need to create an empty table object. It is used
@@ -295,15 +299,24 @@
         goto err;
       }
     }
+    
+    ulong create_options= (first_select_in_union()->options | thd_arg->options |
+                          TMP_TABLE_ALL_COLUMNS) & ~TMP_TABLE_FORCE_MYISAM;
+    /*
+      Force the temporary table to be a MyISAM table if we're going to use
+      fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading
+      from it (this should be removed in 5.2 when fulltext search is moved 
+      out of MyISAM).
+    */
+    if (global_parameters->ftfunc_list->elements)
+      create_options= create_options | TMP_TABLE_FORCE_MYISAM;
 
     union_result->tmp_table_param.field_count= types.elements;
     if (!(table= create_tmp_table(thd_arg,
 				  &union_result->tmp_table_param, types,
 				  (ORDER*) 0, (bool) union_distinct, 1, 
-				  (first_select_in_union()->options |
-				   thd_arg->options |
-				   TMP_TABLE_ALL_COLUMNS),
-				  HA_POS_ERROR, (char *) tmp_table_alias)))
+                                  create_options, HA_POS_ERROR,
+                                  (char *) tmp_table_alias)))
       goto err;
     table->file->extra(HA_EXTRA_WRITE_CACHE);
     table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);

--- 1.34/mysql-test/t/ctype_ucs.test	2005-07-25 12:47:59 +02:00
+++ 1.35/mysql-test/t/ctype_ucs.test	2005-08-11 02:16:18 +02:00
@@ -422,6 +422,8 @@
 select hex(a) from t1;
 drop table t1;
 
+# End of 4.1 tests
+
 #
 # Conversion from an UCS2 string to a decimal column
 #

--- 1.65/mysql-test/t/ctype_utf8.test	2005-07-25 12:54:42 +02:00
+++ 1.66/mysql-test/t/ctype_utf8.test	2005-08-11 02:16:19 +02:00
@@ -845,6 +845,8 @@
 select hex(a) from t1;
 drop table t1;
 
+# End of 4.1 tests
+
 #
 # Test for bug #11484: wrong results for a DISTINCT varchar column in uft8. 
 #

--- 1.4/mysql-test/t/blackhole.test	2005-07-25 12:47:59 +02:00
+++ 1.5/mysql-test/t/blackhole.test	2005-08-11 02:16:18 +02:00
@@ -131,3 +131,5 @@
 show binlog events;
 
 drop table t1,t2,t3;
+
+# End of 4.1 tests

--- 1.8/mysql-test/t/rpl_timezone.test	2005-07-25 12:48:02 +02:00
+++ 1.9/mysql-test/t/rpl_timezone.test	2005-08-11 02:16:25 +02:00
@@ -125,3 +125,5 @@
 connection master;
 drop table t1, t2;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.19/mysql-test/t/mysqlbinlog.test	2005-07-28 20:24:54 +02:00
+++ 1.20/mysql-test/t/mysqlbinlog.test	2005-08-11 02:16:20 +02:00
@@ -112,3 +112,4 @@
 # clean up
 drop table t1, t2;
 
+# End of 4.1 tests

--- 1.7/mysql-test/t/rpl_openssl.test	2005-07-25 12:48:02 +02:00
+++ 1.8/mysql-test/t/rpl_openssl.test	2005-08-11 02:16:24 +02:00
@@ -60,3 +60,5 @@
 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
 --replace_column 1 # 8 # 9 # 16 # 23 # 33 #
 show slave status;
+
+# End of 4.1 tests

--- 1.17/mysql-test/t/rpl_until.test	2005-07-28 16:09:48 +02:00
+++ 1.18/mysql-test/t/rpl_until.test	2005-08-11 02:16:25 +02:00
@@ -1,5 +1,8 @@
 source include/master-slave.inc;
 
+# Test is dependent on binlog positions
+source include/have_binlog_format_statement.inc
+
 # prepare version for substitutions
 let $VERSION=`select version()`;
 
@@ -19,12 +22,10 @@
 insert into t2 values (1),(2);
 insert into t2 values (3),(4);
 drop table t2;
---replace_result $VERSION VERSION
-show binlog events;
 
 # try to replicate all queries until drop of t1
 connection slave;
-start slave until master_log_file='master-bin.000001', master_log_pos=319;
+start slave until master_log_file='master-bin.000001', master_log_pos=323;
 sleep 2;
 wait_for_slave_to_stop;
 # here table should be still not deleted

--- 1.14/mysql-test/t/date_formats.test	2005-08-02 22:06:23 +02:00
+++ 1.15/mysql-test/t/date_formats.test	2005-08-11 02:16:19 +02:00
@@ -263,3 +263,5 @@
 select str_to_date("2003-04-05  g", "%Y-%m-%d") as f1,
        str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
 --enable_ps_protocol
+
+# End of 4.1 tests

--- 1.12/mysql-test/t/rpl_user_variables.test	2005-07-25 12:48:02 +02:00
+++ 1.13/mysql-test/t/rpl_user_variables.test	2005-08-11 02:16:25 +02:00
@@ -57,3 +57,5 @@
 connection slave;
 sync_with_master;
 stop slave;
+
+# End of 4.1 tests

--- 1.6/mysql-test/t/drop_temp_table.test	2005-07-25 12:48:00 +02:00
+++ 1.7/mysql-test/t/drop_temp_table.test	2005-08-11 02:16:19 +02:00
@@ -26,3 +26,5 @@
 --replace_column 2 # 5 #
 show binlog events;
 drop database `drop-temp+table-test`;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/flush_block_commit.test	2005-07-25 12:48:00 +02:00
+++ 1.8/mysql-test/t/flush_block_commit.test	2005-08-11 02:16:19 +02:00
@@ -80,6 +80,8 @@
 
 drop table t1;
 
+# End of 4.1 tests
+
 # FLUSH TABLES WITH READ LOCK should block writes to binlog too
 connection con1;
 create table t1 (a int) engine=innodb;

--- 1.16/mysql-test/t/mix_innodb_myisam_binlog.test	2005-07-25 12:48:00 +02:00
+++ 1.17/mysql-test/t/mix_innodb_myisam_binlog.test	2005-08-11 02:16:20 +02:00
@@ -231,3 +231,5 @@
 
 # cleanup
 drop table t1,t2;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/mysqlbinlog2.test	2005-07-25 12:48:00 +02:00
+++ 1.8/mysql-test/t/mysqlbinlog2.test	2005-08-11 02:16:20 +02:00
@@ -159,3 +159,5 @@
 select "--- end of test --" as "";
 --enable_query_log
 drop table t1;
+
+# End of 4.1 tests

--- 1.5/mysql-test/t/rpl_EE_error.test	2005-07-25 12:48:00 +02:00
+++ 1.6/mysql-test/t/rpl_EE_error.test	2005-08-11 02:16:21 +02:00
@@ -34,3 +34,5 @@
 save_master_pos;
 connection slave;
 wait_for_slave_to_stop;
+
+# End of 4.1 tests

--- 1.10/mysql-test/t/rpl_change_master.test	2005-07-25 12:48:00 +02:00
+++ 1.11/mysql-test/t/rpl_change_master.test	2005-08-11 02:16:21 +02:00
@@ -33,3 +33,5 @@
 save_master_pos;
 connection slave;
 sync_with_master;
+
+# End of 4.1 tests

--- 1.16/mysql-test/t/rpl_charset.test	2005-07-25 12:48:00 +02:00
+++ 1.17/mysql-test/t/rpl_charset.test	2005-08-11 02:16:21 +02:00
@@ -172,3 +172,5 @@
 update t1 set pk='test' where pk=@p;
 drop table t1;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/rpl_deadlock.test	2005-07-25 12:48:00 +02:00
+++ 1.8/mysql-test/t/rpl_deadlock.test	2005-08-11 02:16:21 +02:00
@@ -109,3 +109,5 @@
 connection master;
 drop table t1,t2,t3,t4;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.5/mysql-test/t/rpl_delete_all.test	2005-07-25 12:48:00 +02:00
+++ 1.6/mysql-test/t/rpl_delete_all.test	2005-08-11 02:16:22 +02:00
@@ -42,3 +42,5 @@
 connection master;
 drop table t1;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.4/mysql-test/t/rpl_do_grant.test	2005-07-25 12:48:00 +02:00
+++ 1.5/mysql-test/t/rpl_do_grant.test	2005-08-11 02:16:22 +02:00
@@ -47,3 +47,5 @@
 # no need to delete manually, as the DELETEs must have done some real job on
 # master (updated binlog)
 flush privileges;
+
+# End of 4.1 tests

--- 1.14/mysql-test/t/rpl_error_ignored_table.test	2005-07-25 12:48:00 +02:00
+++ 1.15/mysql-test/t/rpl_error_ignored_table.test	2005-08-11 02:16:22 +02:00
@@ -58,3 +58,5 @@
 # SQL slave thread should not have stopped (because table of the killed
 # query is in the ignore list).
 sync_with_master;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/rpl_flush_tables.test	2005-07-25 12:48:00 +02:00
+++ 1.8/mysql-test/t/rpl_flush_tables.test	2005-08-11 02:16:22 +02:00
@@ -6,7 +6,10 @@
 # RENAME TABLE work with MERGE tables on the slave.
 # Test of FLUSH NO_WRITE_TO_BINLOG by the way.
 #
-source include/master-slave.inc;
+--source include/master-slave.inc
+# Skipped on Windows because it can't handle a table underlying an open
+# merge table getting renamed.
+--source include/not_windows.inc
 
 create table t1 (a int);
 insert into t1 values (10);
@@ -38,3 +41,5 @@
 select * from t3;
 # Note that all this confusion may cause warnings 'table xx is open on rename'
 # in the .err files; these are not fatal and are not reported by mysql-test-run.
+
+# End of 4.1 tests

--- 1.5/mysql-test/t/rpl_heap.test	2005-07-25 12:48:01 +02:00
+++ 1.6/mysql-test/t/rpl_heap.test	2005-08-11 02:16:22 +02:00
@@ -52,3 +52,5 @@
 save_master_pos;
 connection slave;
 sync_with_master;
+
+# End of 4.1 tests

--- 1.9/mysql-test/t/rpl_loaddata_rule_m.test	2005-07-25 12:48:01 +02:00
+++ 1.10/mysql-test/t/rpl_loaddata_rule_m.test	2005-08-11 02:16:23 +02:00
@@ -28,3 +28,5 @@
 --replace_column 2 # 5 #
 show binlog events from 102;
 drop database mysqltest;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/rpl_loaddata_rule_s.test	2005-07-25 12:48:02 +02:00
+++ 1.8/mysql-test/t/rpl_loaddata_rule_s.test	2005-08-11 02:33:36 +02:00
@@ -22,3 +22,5 @@
 select count(*) from t1; # check that LOAD was replicated
 --replace_column 2 # 5 #
 show binlog events from 102; # should be nothing
+
+# End of 4.1 tests

--- 1.13/mysql-test/t/rpl_max_relay_size.test	2005-07-25 12:48:02 +02:00
+++ 1.14/mysql-test/t/rpl_max_relay_size.test	2005-08-11 02:16:23 +02:00
@@ -95,3 +95,5 @@
 flush logs;
 -- replace_column 3 <Binlog_Ignore_DB>
 show master status;
+
+# End of 4.1 tests

--- 1.6/mysql-test/t/rpl_multi_query.test	2005-07-25 12:48:02 +02:00
+++ 1.7/mysql-test/t/rpl_multi_query.test	2005-08-11 02:16:23 +02:00
@@ -30,3 +30,5 @@
 show binlog events from 102;
 drop database mysqltest;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.14/mysql-test/t/rpl_relayrotate.test	2005-07-25 12:48:02 +02:00
+++ 1.15/mysql-test/t/rpl_relayrotate.test	2005-08-11 02:16:24 +02:00
@@ -79,3 +79,5 @@
 save_master_pos;
 connection slave;
 sync_with_master;
+
+# End of 4.1 tests

--- 1.8/mysql-test/t/rpl_reset_slave.test	2005-07-25 12:48:02 +02:00
+++ 1.9/mysql-test/t/rpl_reset_slave.test	2005-08-11 02:16:24 +02:00
@@ -49,3 +49,5 @@
 start slave;
 sync_with_master;
 show status like 'slave_open_temp_tables';
+
+# End of 4.1 tests

--- 1.4/mysql-test/t/rpl_rewrite_db.test	2005-07-25 12:48:02 +02:00
+++ 1.5/mysql-test/t/rpl_rewrite_db.test	2005-08-11 02:16:24 +02:00
@@ -81,3 +81,4 @@
 connection master;
 drop table t1;
 
+# End of 4.1 tests

--- 1.5/mysql-test/t/rpl_server_id1.test	2005-07-25 12:48:02 +02:00
+++ 1.6/mysql-test/t/rpl_server_id1.test	2005-08-11 02:16:25 +02:00
@@ -22,3 +22,5 @@
 sleep 2; # enough time for the event to be replicated (it should not)
 show status like "slave_running";
 drop table t1;
+
+# End of 4.1 tests

--- 1.5/mysql-test/t/ctype_ucs_binlog.test	2005-07-25 12:48:00 +02:00
+++ 1.6/mysql-test/t/ctype_ucs_binlog.test	2005-08-11 02:16:18 +02:00
@@ -20,4 +20,4 @@
 --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 
 drop table t2;
 
-
+# End of 4.1 tests

--- 1.2/mysql-test/t/insert_select-binlog.test	2005-07-25 12:48:00 +02:00
+++ 1.3/mysql-test/t/insert_select-binlog.test	2005-08-11 02:16:19 +02:00
@@ -35,3 +35,4 @@
 show binlog events;
 drop table t1;
 
+# End of 4.1 tests

--- 1.6/mysql-test/t/ps_grant.test	2005-07-28 16:09:48 +02:00
+++ 1.7/mysql-test/t/ps_grant.test	2005-08-11 02:31:41 +02:00
@@ -129,3 +129,14 @@
 --error 1295
 prepare stmt3 from ' drop user drop_user@localhost ';
 drop user drop_user@localhost;
+
+# This test must be the last one, otherwise it may produce extra
+# rows in the processlist under high load.
+# Tested here simply so it is not tested with embedded server
+--disable_query_log;
+sleep 4;
+--enable_query_log;
+prepare stmt4 from ' show full processlist ';
+--replace_column 1 number 6 time 3 localhost
+execute stmt4;
+deallocate prepare stmt4;

--- 1.3/mysql-test/t/user_var-binlog.test	2005-07-25 12:48:02 +02:00
+++ 1.4/mysql-test/t/user_var-binlog.test	2005-08-11 02:16:25 +02:00
@@ -21,3 +21,5 @@
 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
 --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 
 drop table t1;
+
+# End of 4.1 tests

--- 1.5/mysql-test/t/rpl_ddl.test	2005-07-25 12:48:00 +02:00
+++ 1.6/mysql-test/t/rpl_ddl.test	2005-08-11 02:16:21 +02:00
@@ -349,3 +349,5 @@
 DROP DATABASE IF EXISTS mysqltest2;
 DROP DATABASE IF EXISTS mysqltest3;
 --enable_warnings
+
+# End of 4.1 tests

--- 1.4/mysql-test/t/rpl_create_database.test	2005-07-25 12:48:00 +02:00
+++ 1.5/mysql-test/t/rpl_create_database.test	2005-08-11 02:16:21 +02:00
@@ -66,3 +66,5 @@
 DROP DATABASE IF EXISTS mysqltest_sisyfos;
 DROP DATABASE IF EXISTS mysqltest_bob;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.124/mysql-test/r/innodb.result	2005-07-25 12:47:58 +02:00
+++ 1.125/mysql-test/r/innodb.result	2005-08-11 02:16:18 +02:00
@@ -1452,16 +1452,16 @@
 checksum table t1, t2, t3, t4;
 Table	Checksum
 test.t1	2948697075
-test.t2	1157260244
-test.t3	1157260244
+test.t2	3835700799
+test.t3	3835700799
 test.t4	NULL
 Warnings:
 Error	1146	Table 'test.t4' doesn't exist
 checksum table t1, t2, t3, t4 extended;
 Table	Checksum
 test.t1	3092701434
-test.t2	1157260244
-test.t3	1157260244
+test.t2	3835700799
+test.t3	3835700799
 test.t4	NULL
 Warnings:
 Error	1146	Table 'test.t4' doesn't exist
@@ -2437,3 +2437,11 @@
 GRADE
 151
 DROP TABLE t1;
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+f1	f2
+drop table t1,t2;

--- 1.97/mysql-test/t/innodb.test	2005-07-25 12:48:00 +02:00
+++ 1.98/mysql-test/t/innodb.test	2005-08-11 02:16:19 +02:00
@@ -1196,6 +1196,8 @@
 DROP TABLE t2;
 DROP TABLE t1;
 
+# End of 4.1 tests
+
 #
 # range optimizer problem
 #
@@ -1325,7 +1327,6 @@
 select * from t1;
 drop table t1;
 
-
 #
 # Test that update does not change internal auto-increment value
 #
@@ -1350,3 +1351,13 @@
 SELECT GRADE  FROM t1 WHERE GRADE= 151;
 DROP TABLE t1;
 
+#
+# Bug #12340 multitable delete deletes only one record
+#
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+drop table t1,t2;

--- 1.240/sql/ha_innodb.cc	2005-08-10 16:36:03 +02:00
+++ 1.241/sql/ha_innodb.cc	2005-08-11 02:16:26 +02:00
@@ -780,6 +780,7 @@
                   HA_CAN_INDEX_BLOBS |
                   HA_CAN_SQL_HANDLER |
                   HA_NOT_EXACT_COUNT |
+                  HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS |
                   HA_PRIMARY_KEY_IN_READ_INDEX |
                   HA_TABLE_SCAN_ON_INDEX),
   last_dup_key((uint) -1),

--- 1.10/mysql-test/t/rpl_flush_log_loop.test	2005-07-25 12:48:00 +02:00
+++ 1.11/mysql-test/t/rpl_flush_log_loop.test	2005-08-11 02:16:22 +02:00
@@ -30,3 +30,5 @@
 --replace_result $SLAVE_MYPORT SLAVE_PORT
 --replace_column 1 # 8 # 9 # 16 # 23 # 33 #
 show slave status;
+
+# End of 4.1 tests

--- 1.9/mysql-test/t/rpl_insert_id.test	2005-07-25 12:48:01 +02:00
+++ 1.10/mysql-test/t/rpl_insert_id.test	2005-08-11 02:32:33 +02:00
@@ -75,3 +75,5 @@
 --error 1062
 INSERT INTO t1 VALUES (1),(1);
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.17/mysql-test/t/rpl_loaddata.test	2005-07-25 12:48:01 +02:00
+++ 1.18/mysql-test/t/rpl_loaddata.test	2005-08-11 02:16:23 +02:00
@@ -152,3 +152,5 @@
 drop table t2;
 connection master;
 drop table t2;
+
+# End of 4.1 tests

--- 1.131/sql/set_var.cc	2005-08-07 20:39:11 +02:00
+++ 1.132/sql/set_var.cc	2005-08-11 02:16:29 +02:00
@@ -744,6 +744,7 @@
   {"bdb_tmpdir",              (char*) &berkeley_tmpdir,             SHOW_CHAR_PTR},
 #endif
   {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size,	    SHOW_SYS},
+  {"binlog_format",           (char*) &opt_binlog_format,           SHOW_CHAR_PTR},
   {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
   {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
   {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
@@ -791,6 +792,7 @@
   {"have_openssl",	      (char*) &have_openssl,		    SHOW_HAVE},
   {"have_query_cache",        (char*) &have_query_cache,            SHOW_HAVE},
   {"have_raid",		      (char*) &have_raid,		    SHOW_HAVE},
+  {"have_row_based_replication",(char*) &have_row_based_replication,SHOW_HAVE},
   {"have_rtree_keys",         (char*) &have_rtree_keys,             SHOW_HAVE},
   {"have_symlink",            (char*) &have_symlink,                SHOW_HAVE},
   {"init_connect",            (char*) &sys_init_connect,            SHOW_SYS},

--- 1.10/mysql-test/t/rpl_empty_master_crash.test	2005-07-25 12:48:00 +02:00
+++ 1.11/mysql-test/t/rpl_empty_master_crash.test	2005-08-11 02:16:22 +02:00
@@ -11,3 +11,5 @@
 connection slave;
 --error 1188
 load table t1 from master;
+
+# End of 4.1 tests

--- 1.84/sql/sp.cc	2005-07-25 12:48:03 +02:00
+++ 1.85/sql/sp.cc	2005-08-11 02:16:30 +02:00
@@ -68,13 +68,16 @@
 
   SYNOPSIS
     close_proc_table()
-      thd  Thread context
+      thd     Thread context
+      backup  Pointer to Open_tables_state instance which holds
+              information about tables which were open before we
+              decided to access mysql.proc.
 */
 
-static void close_proc_table(THD *thd)
+void close_proc_table(THD *thd, Open_tables_state *backup)
 {
   close_thread_tables(thd);
-  thd->pop_open_tables_state();
+  thd->restore_backup_open_tables_state(backup);
 }
 
 
@@ -83,7 +86,10 @@
 
   SYNOPSIS
     open_proc_table_for_read()
-      thd  Thread context
+      thd     Thread context
+      backup  Pointer to Open_tables_state instance where information about
+              currently open tables will be saved, and from which will be
+              restored when we will end work with mysql.proc.
 
   NOTES
     Thanks to restrictions which we put on opening and locking of
@@ -97,11 +103,10 @@
     #	Pointer to TABLE object of mysql.proc
 */
 
-static TABLE *open_proc_table_for_read(THD *thd)
+TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
 {
   TABLE_LIST tables;
   TABLE *table;
-  bool old_open_tables= thd->open_tables != 0;
   bool refresh;
   DBUG_ENTER("open_proc_table");
 
@@ -112,8 +117,7 @@
   if (!mysql_proc_table_exists)
     DBUG_RETURN(0);
 
-  if (thd->push_open_tables_state())
-    DBUG_RETURN(0);
+  thd->reset_n_backup_open_tables_state(backup);
 
   bzero((char*) &tables, sizeof(tables));
   tables.db= (char*) "mysql";
@@ -121,7 +125,7 @@
   if (!(table= open_table(thd, &tables, thd->mem_root, &refresh,
                           MYSQL_LOCK_IGNORE_FLUSH)))
   {
-    thd->pop_open_tables_state();
+    thd->restore_backup_open_tables_state(backup);
     mysql_proc_table_exists= 0;
     DBUG_RETURN(0);
   }
@@ -130,15 +134,13 @@
 
   table->reginfo.lock_type= TL_READ;
   /*
-    If we have other tables opened, we have to ensure we are not blocked
-    by a flush tables or global read lock, as this could lead to a deadlock
+    We have to ensure we are not blocked by a flush tables, as this
+    could lead to a deadlock if we have other tables opened.
   */
   if (!(thd->lock= mysql_lock_tables(thd, &table, 1,
-                                     old_open_tables ?
-                                     (MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
-                                      MYSQL_LOCK_IGNORE_FLUSH) : 0)))
+                                     MYSQL_LOCK_IGNORE_FLUSH)))
   {
-    close_proc_table(thd);
+    close_proc_table(thd, backup);
     DBUG_RETURN(0);
   }
   DBUG_RETURN(table);
@@ -271,12 +273,13 @@
   char buff[65];
   String str(buff, sizeof(buff), &my_charset_bin);
   ulong sql_mode;
+  Open_tables_state open_tables_state_backup;
   DBUG_ENTER("db_find_routine");
   DBUG_PRINT("enter", ("type: %d name: %*s",
 		       type, name->m_name.length, name->m_name.str));
 
   *sphp= 0;                                     // In case of errors
-  if (!(table= open_proc_table_for_read(thd)))
+  if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
 
   if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
@@ -371,7 +374,7 @@
   chistics.comment.str= ptr;
   chistics.comment.length= length;
 
-  close_proc_table(thd);
+  close_proc_table(thd, &open_tables_state_backup);
   table= 0;
 
   {
@@ -449,7 +452,7 @@
 
  done:
   if (table)
-    close_proc_table(thd);
+    close_proc_table(thd, &open_tables_state_backup);
   DBUG_RETURN(ret);
 }
 
@@ -503,6 +506,11 @@
       ret= SP_BAD_IDENTIFIER;
       goto done;
     }
+    if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length)
+    {
+      ret= SP_BODY_TOO_LONG;
+      goto done;
+    }
     table->field[MYSQL_PROC_FIELD_DB]->
       store(sp->m_db.str, sp->m_db.length, system_charset_info);
     table->field[MYSQL_PROC_FIELD_NAME]->
@@ -981,13 +989,11 @@
 sp_drop_procedure(THD *thd, sp_name *name)
 {
   int ret;
-  bool found;
   DBUG_ENTER("sp_drop_procedure");
   DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
 
-  found= sp_cache_remove(&thd->sp_proc_cache, name);
   ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name);
-  if (!found && !ret)
+  if (!ret)
     sp_cache_invalidate();
   DBUG_RETURN(ret);
 }
@@ -997,13 +1003,11 @@
 sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
 {
   int ret;
-  bool found;
   DBUG_ENTER("sp_update_procedure");
   DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
 
-  found= sp_cache_remove(&thd->sp_proc_cache, name);
   ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics);
-  if (!found && !ret)
+  if (!ret)
     sp_cache_invalidate();
   DBUG_RETURN(ret);
 }
@@ -1094,13 +1098,11 @@
 sp_drop_function(THD *thd, sp_name *name)
 {
   int ret;
-  bool found;
   DBUG_ENTER("sp_drop_function");
   DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
 
-  found= sp_cache_remove(&thd->sp_func_cache, name);
   ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name);
-  if (!found && !ret)
+  if (!ret)
     sp_cache_invalidate();
   DBUG_RETURN(ret);
 }
@@ -1110,13 +1112,11 @@
 sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics)
 {
   int ret;
-  bool found;
   DBUG_ENTER("sp_update_procedure");
   DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
 
-  found= sp_cache_remove(&thd->sp_func_cache, name);
   ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics);
-  if (!found && !ret)
+  if (!ret)
     sp_cache_invalidate();
   DBUG_RETURN(ret);
 }
@@ -1176,6 +1176,43 @@
 
 
 /*
+  Check if
+   - current statement (the one in thd->lex) needs table prelocking
+   - first routine in thd->lex->sroutines_list needs to execute its body in
+     prelocked mode.
+
+  SYNOPSIS
+    sp_get_prelocking_info()
+      thd                  Current thread, thd->lex is the statement to be
+                           checked.
+      need_prelocking      OUT TRUE  - prelocked mode should be activated
+                                       before executing the statement
+                               FALSE - Don't activate prelocking 
+      first_no_prelocking  OUT TRUE  - Tables used by first routine in
+                                       thd->lex->sroutines_list should be
+                                       prelocked.
+                               FALSE - Otherwise.
+  NOTES 
+    This function assumes that for any "CALL proc(...)" statement routines_list 
+    will have 'proc' as first element (it may have several, consider e.g.
+    "proc(sp_func(...)))". This property is currently guaranted by the parser.
+*/
+
+void sp_get_prelocking_info(THD *thd, bool *need_prelocking, 
+                            bool *first_no_prelocking)
+{
+  Sroutine_hash_entry *routine;
+  routine= (Sroutine_hash_entry*)thd->lex->sroutines_list.first;
+
+  DBUG_ASSERT(routine);
+  bool first_is_procedure= (routine->key.str[0] == TYPE_ENUM_PROCEDURE);
+
+  *first_no_prelocking= first_is_procedure;
+  *need_prelocking= !first_is_procedure || test(routine->next);
+}
+
+
+/*
   Auxilary function that adds new element to the set of stored routines
   used by statement.
 
@@ -1312,11 +1349,13 @@
 
   SYNOPSIS
     sp_cache_routines_and_add_tables_aux()
-      thd   - thread context
-      lex   - LEX representing statement
-      start - first routine from the list of routines to be cached
-              (this list defines mentioned sub-set).
-
+      thd              - thread context
+      lex              - LEX representing statement
+      start            - first routine from the list of routines to be cached
+                         (this list defines mentioned sub-set).
+      first_no_prelock - If true, don't add tables or cache routines used by
+                         the body of the first routine (i.e. *start)
+                         will be executed in non-prelocked mode.
   NOTE
     If some function is missing this won't be reported here.
     Instead this fact will be discovered during query execution.
@@ -1328,10 +1367,11 @@
 
 static bool
 sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
-                                     Sroutine_hash_entry *start)
+                                     Sroutine_hash_entry *start, 
+                                     bool first_no_prelock)
 {
   bool result= FALSE;
-
+  bool first= TRUE;
   DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
 
   for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
@@ -1367,9 +1407,13 @@
     }
     if (sp)
     {
-      sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
-      result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
+      if (!(first && first_no_prelock))
+      {
+        sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
+        result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
+      }
     }
+    first= FALSE;
   }
   DBUG_RETURN(result);
 }
@@ -1382,20 +1426,22 @@
 
   SYNOPSIS
     sp_cache_routines_and_add_tables()
-      thd   - thread context
-      lex   - LEX representing statement
-
+      thd              - thread context
+      lex              - LEX representing statement
+      first_no_prelock - If true, don't add tables or cache routines used by
+                         the body of the first routine (i.e. *start)
+                         
   RETURN VALUE
     TRUE  - some tables were added
     FALSE - no tables were added.
 */
 
 bool
-sp_cache_routines_and_add_tables(THD *thd, LEX *lex)
+sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
 {
-
   return sp_cache_routines_and_add_tables_aux(thd, lex,
-           (Sroutine_hash_entry *)lex->sroutines_list.first);
+           (Sroutine_hash_entry *)lex->sroutines_list.first,
+           first_no_prelock);
 }
 
 
@@ -1417,8 +1463,8 @@
   Sroutine_hash_entry **last_cached_routine_ptr=
                           (Sroutine_hash_entry **)lex->sroutines_list.next;
   sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines);
-  (void)sp_cache_routines_and_add_tables_aux(thd, lex,
-                                             *last_cached_routine_ptr);
+  (void)sp_cache_routines_and_add_tables_aux(thd, lex, 
+                                             *last_cached_routine_ptr, FALSE);
 }
 
 
@@ -1443,7 +1489,9 @@
     Sroutine_hash_entry **last_cached_routine_ptr=
                             (Sroutine_hash_entry **)lex->sroutines_list.next;
     for (int i= 0; i < (int)TRG_EVENT_MAX; i++)
+    {
       for (int j= 0; j < (int)TRG_ACTION_MAX; j++)
+      {
         if (triggers->bodies[i][j])
         {
           (void)triggers->bodies[i][j]->add_used_tables_to_table_list(thd,
@@ -1451,9 +1499,11 @@
           sp_update_stmt_used_routines(thd, lex,
                                        &triggers->bodies[i][j]->m_sroutines);
         }
-
+      }
+    }
     (void)sp_cache_routines_and_add_tables_aux(thd, lex,
-                                               *last_cached_routine_ptr);
+                                               *last_cached_routine_ptr, 
+                                               FALSE);
   }
 }
 

--- 1.35/mysql-test/r/user_var.result	2005-07-25 12:47:59 +02:00
+++ 1.36/mysql-test/r/user_var.result	2005-08-11 02:16:18 +02:00
@@ -183,6 +183,30 @@
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@honk=99' at line 1
 set one_shot @honk=99;
 ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
+select @@local.max_allowed_packet;
+@@local.max_allowed_packet
+#
+select @@session.max_allowed_packet;
+@@session.max_allowed_packet
+#
+select @@global.max_allowed_packet;
+@@global.max_allowed_packet
+#
+select @@max_allowed_packet;
+@@max_allowed_packet
+#
+select @@Max_Allowed_Packet;
+@@Max_Allowed_Packet
+#
+select @@version;
+@@version
+#
+select @@global.version;
+@@global.version
+#
+select @@session.VERSION;
+@@session.VERSION
+#
 set @first_var= NULL;
 create table t1 select @first_var;
 show create table t1;

--- 1.39/mysql-test/t/rpl000001.test	2005-07-25 12:48:00 +02:00
+++ 1.40/mysql-test/t/rpl000001.test	2005-08-11 02:16:20 +02:00
@@ -127,3 +127,5 @@
 save_master_pos;
 connection slave;
 sync_with_master;
+
+# End of 4.1 tests

--- 1.20/mysql-test/t/rpl000002.test	2005-07-25 12:48:00 +02:00
+++ 1.21/mysql-test/t/rpl000002.test	2005-08-11 02:16:20 +02:00
@@ -41,3 +41,5 @@
 connection master;
 drop table t2,t3,t5;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.21/mysql-test/t/rpl_replicate_do.test	2005-07-25 12:48:02 +02:00
+++ 1.22/mysql-test/t/rpl_replicate_do.test	2005-08-11 02:16:24 +02:00
@@ -36,3 +36,4 @@
 --replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
 show slave status;
 
+# End of 4.1 tests

--- 1.17/mysql-test/t/rpl000012.test	2005-07-25 12:48:00 +02:00
+++ 1.18/mysql-test/t/rpl000012.test	2005-08-11 02:16:20 +02:00
@@ -41,3 +41,5 @@
 save_master_pos;
 connection slave;
 sync_with_master;
+
+# End of 4.1 tests

--- 1.34/mysql-test/t/rpl_log_pos.test	2005-07-25 12:48:02 +02:00
+++ 1.35/mysql-test/t/rpl_log_pos.test	2005-08-11 02:16:23 +02:00
@@ -51,3 +51,5 @@
 connection master;
 drop table t1;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.31/mysql-test/t/rpl000015.test	2005-07-25 12:48:00 +02:00
+++ 1.32/mysql-test/t/rpl000015.test	2005-08-11 02:16:20 +02:00
@@ -40,3 +40,5 @@
 connection master;
 drop table t1;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.61/mysql-test/t/rpl_rotate_logs.test	2005-07-25 12:48:02 +02:00
+++ 1.62/mysql-test/t/rpl_rotate_logs.test	2005-08-11 02:16:24 +02:00
@@ -156,3 +156,4 @@
 drop table if exists t1,t2,t3,t4;
 sync_slave_with_master;
 
+# End of 4.1 tests

--- 1.13/mysql-test/t/rpl000017.test	2005-07-25 12:48:00 +02:00
+++ 1.14/mysql-test/t/rpl000017.test	2005-08-11 02:16:21 +02:00
@@ -17,3 +17,5 @@
 connection master;
 drop table t1;
 sync_slave_with_master;
+
+# End of 4.1 tests

--- 1.26/mysql-test/t/rpl_log.test	2005-07-25 12:48:02 +02:00
+++ 1.27/mysql-test/t/rpl_log.test	2005-08-11 02:16:23 +02:00
@@ -119,3 +119,5 @@
 
 --error 1220
 show binlog events in 'slave-bin.000005' from 4;
+
+# End of 4.1 tests

--- 1.12/mysql-test/t/rpl_redirect.test	2005-07-25 12:48:02 +02:00
+++ 1.13/mysql-test/t/rpl_redirect.test	2005-08-11 02:16:24 +02:00
@@ -41,3 +41,5 @@
 drop table t1;
 connection master;
 drop table t1;
+
+# End of 4.1 tests

--- 1.7/mysql-test/t/rpl_mystery22.test	2005-07-25 12:48:02 +02:00
+++ 1.8/mysql-test/t/rpl_mystery22.test	2005-08-11 02:16:23 +02:00
@@ -44,3 +44,4 @@
 drop table t1;
 sync_slave_with_master;
 
+# End of 4.1 tests

--- 1.30/mysql-test/t/user_var.test	2005-07-25 12:48:02 +02:00
+++ 1.31/mysql-test/t/user_var.test	2005-08-11 02:16:25 +02:00
@@ -125,6 +125,29 @@
 set one_shot @honk=99;
 
 #
+# Bug #10724  @@local not preserved in column name of select
+#
+# The value doesn't actually matter, we just care about the column name
+--replace_column 1 #
+select @@local.max_allowed_packet;
+--replace_column 1 #
+select @@session.max_allowed_packet;
+--replace_column 1 #
+select @@global.max_allowed_packet;
+--replace_column 1 #
+select @@max_allowed_packet;
+--replace_column 1 #
+select @@Max_Allowed_Packet;
+--replace_column 1 #
+select @@version;
+--replace_column 1 #
+select @@global.version;
+--replace_column 1 #
+select @@session.VERSION;
+
+# End of 4.1 tests
+
+#
 # Bug #6598: problem with cast(NULL as signed integer);
 #
 

--- 1.15/mysql-test/t/rpl_temporary.test	2005-07-25 12:48:02 +02:00
+++ 1.16/mysql-test/t/rpl_temporary.test	2005-08-11 02:16:25 +02:00
@@ -133,3 +133,5 @@
 sync_with_master;
 
 # The server will now close done
+
+# End of 4.1 tests
Thread
bk commit into 5.0 tree (lars:1.1978)Lars Thalmann11 Aug