List:Commits« Previous MessageNext Message »
From:guilhem Date:February 25 2006 6:36pm
Subject:bk commit into 5.1 tree (guilhem:1.2166)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of guilhem. When guilhem 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.2166 06/02/25 19:36:15 guilhem@stripped +45 -0
  WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
  and new binlog format called "mixed" for now (is statement-based except if UDF or UUID is used).
  Will put more descriptive comments here at the moment of the commit-for-push.

  mysql-test/t/rpl_switch_stm_row_mixed_UDF.test
    1.1 06/02/25 19:36:09 guilhem@stripped +148 -0
    test (will NOT be pushed) about UDF's and "mixed" mode.

  mysql-test/t/rpl_switch_stm_row_mixed.test
    1.1 06/02/25 19:36:09 guilhem@stripped +151 -0
    test to see if one can switch between SBR, RBR, and "mixed" mode

  mysql-test/t/rpl_switch_stm_row_mixed_UDF.test
    1.0 06/02/25 19:36:09 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/t/rpl_switch_stm_row_mixed_UDF.test

  mysql-test/t/rpl_switch_stm_row_mixed.test
    1.0 06/02/25 19:36:09 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/t/rpl_switch_stm_row_mixed.test

  mysql-test/t/ndb_binlog_basic2.test
    1.1 06/02/25 19:36:08 guilhem@stripped +14 -0
    new test to verify that if cluster is enabled, can't change binlog format on the fly.

  mysql-test/r/rpl_switch_stm_row_mixed_UDF.result
    1.1 06/02/25 19:36:08 guilhem@stripped +185 -0
    new result (will not be pushed)

  mysql-test/r/rpl_switch_stm_row_mixed.result
    1.1 06/02/25 19:36:08 guilhem@stripped +200 -0
    new result

  mysql-test/t/ndb_binlog_basic2.test
    1.0 06/02/25 19:36:08 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/t/ndb_binlog_basic2.test

  mysql-test/r/rpl_switch_stm_row_mixed_UDF.result
    1.0 06/02/25 19:36:08 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/r/rpl_switch_stm_row_mixed_UDF.result

  mysql-test/r/rpl_switch_stm_row_mixed.result
    1.0 06/02/25 19:36:08 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/r/rpl_switch_stm_row_mixed.result

  mysql-test/r/ndb_binlog_basic2.result
    1.1 06/02/25 19:36:07 guilhem@stripped +12 -0
    new result

  tests/mysql_client_test.c
    1.179 06/02/25 19:36:07 guilhem@stripped +2 -2
    compiler warning

  sql/sql_table.cc
    1.309 06/02/25 19:36:07 guilhem@stripped +9 -9
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/sql_show.cc
    1.310 06/02/25 19:36:07 guilhem@stripped +1 -1
    compiler warning

  sql/sql_repl.cc
    1.150 06/02/25 19:36:07 guilhem@stripped +2 -0
    if RBR, log_loaded_block() returns immediately.

  sql/sql_partition.cc
    1.41 06/02/25 19:36:07 guilhem@stripped +1 -1
    compiler warning

  sql/sql_parse.cc
    1.523 06/02/25 19:36:07 guilhem@stripped +1 -0
    when we are done with a statement, we reset the current_stmt_binlog_row_based to the value
    derived from THD::variables.binlog_format.

  sql/sql_load.cc
    1.93 06/02/25 19:36:07 guilhem@stripped +3 -3
    binlog_row_based -> thd->current_stmt_binlog_row_based.
    Always calling log_loaded_block as it was not easy to read thd (but see sql_repl.cc)

  sql/sql_insert.cc
    1.187 06/02/25 19:36:07 guilhem@stripped +4 -4
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/sql_delete.cc
    1.175 06/02/25 19:36:07 guilhem@stripped +1 -1
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/sql_class.h
    1.285 06/02/25 19:36:07 guilhem@stripped +13 -0
    new THD::variables.binlog_format (the value of the session variable set by SET
    or inherited from the global value), and THD::current_stmt_binlog_row_based which tells if the
    current statement does row-based or statement-based binlogging. Both members are needed
    as the 2nd one cannot be derived only from the first one (the statement's type plays a role too),
    and the 1st one is needed to reset the 2nd one.

  sql/sql_class.cc
    1.246 06/02/25 19:36:07 guilhem@stripped +11 -10
    When a THD is initialized, we set its current_stmt_binlog_row_based

  sql/sql_base.cc
    1.305 06/02/25 19:36:07 guilhem@stripped +1 -1
    binlog_row_based -> thd->current_stmt_binlog_row_based

  mysql-test/r/ndb_binlog_basic2.result
    1.0 06/02/25 19:36:07 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.1-new/mysql-test/r/ndb_binlog_basic2.result

  sql/sp_head.cc
    1.205 06/02/25 19:36:06 guilhem@stripped +1 -1
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/share/errmsg.txt
    1.87 06/02/25 19:36:06 guilhem@stripped +5 -3
    some messages for when one can't toggle from one binlog format to another

  sql/set_var.h
    1.84 06/02/25 19:36:06 guilhem@stripped +12 -0
    new class for the thread's binlog_format (see set_var.cc)

  sql/set_var.cc
    1.176 06/02/25 19:36:06 guilhem@stripped +45 -3
    new class of thread's variable, to handle the binlog_format (like sys_var_thd_enum except
    that is_readonly() is overriden for more checks before update).
    compiler warnings (ok'd by Serg)

  sql/partition_info.cc
    1.5 06/02/25 19:36:06 guilhem@stripped +4 -4
    compiler warnings

  sql/mysqld.cc
    1.538 06/02/25 19:36:06 guilhem@stripped +24 -61
    simplification in the handling of --binlog-format (but with no user-visible change), thanks to
    the new global system variable.
    RBR does not anymore turn on --log-bin-trust-function-creators and --innodb-locks-unsafe-for-binlog
    as these are global options and RBR is now settable per session.

  sql/mysql_priv.h
    1.381 06/02/25 19:36:06 guilhem@stripped +0 -3
    this global variable not used anymore

  sql/log_event.h
    1.129 06/02/25 19:36:06 guilhem@stripped +0 -8
    this global variable not used anymore

  sql/log_event.cc
    1.206 06/02/25 19:36:06 guilhem@stripped +5 -1
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/log.h
    1.6 06/02/25 19:36:06 guilhem@stripped +20 -0
    the enum enum_binlog_format moves to log.h from mysqld.cc as we need it in several places.

  sql/log.cc
    1.193 06/02/25 19:36:06 guilhem@stripped +6 -4
    binlog_row_based -> thd->current_stmt_binlog_row_based

  sql/item_strfunc.cc
    1.265 06/02/25 19:36:06 guilhem@stripped +1 -0
    UUID() requires row-based binlogging if this is the "mixed" binlog format

  sql/item_func.cc
    1.275 06/02/25 19:36:06 guilhem@stripped +1 -0
    UDFs require row-based if this is the "mixed" binlog format.

  sql/handler.h
    1.195 06/02/25 19:36:06 guilhem@stripped +3 -4
    it's good to initialize statically (to get no compiler warning) even if to a null value.

  sql/handler.cc
    1.218 06/02/25 19:36:05 guilhem@stripped +6 -2
    please pay attention to this structure when you change it...

  sql/ha_partition.cc
    1.33 06/02/25 19:36:05 guilhem@stripped +4 -2
    please pay attention to this structure when you change it...

  sql/ha_ndbcluster_binlog.cc
    1.24 06/02/25 19:36:05 guilhem@stripped +1 -1
    no more global 'binlog_row_based'

  sql/ha_myisammrg.cc
    1.81 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_myisam.cc
    1.174 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_innodb.cc
    1.258 06/02/25 19:36:05 guilhem@stripped +4 -1
    please pay attention to this structure when you change it...

  sql/ha_heap.cc
    1.83 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_federated.cc
    1.53 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_blackhole.cc
    1.28 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_berkeley.cc
    1.172 06/02/25 19:36:05 guilhem@stripped +3 -1
    please pay attention to this structure when you change it...

  sql/ha_archive.cc
    1.84 06/02/25 19:36:05 guilhem@stripped +3 -2
    please pay attention to this structure when you change it...

  mysql-test/t/rpl_row_4_bytes.test
    1.2 06/02/25 19:36:05 guilhem@stripped +1 -1
    don't influence next tests

  mysql-test/r/rpl_row_4_bytes.result
    1.2 06/02/25 19:36:05 guilhem@stripped +1 -1
    update

# 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:	guilhem
# Host:	gbichot3.local
# Root:	/home/mysql_src/mysql-5.1-new

--- 1.171/sql/ha_berkeley.cc	2006-02-02 09:59:18 +01:00
+++ 1.172/sql/ha_berkeley.cc	2006-02-25 19:36:05 +01:00
@@ -153,7 +153,9 @@
   NULL, /* Alter table flags */
   NULL, /* Alter Tablespace */
   NULL, /* Fill Files Table */
-  HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME
+  HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME,
+  NULL, /* binlog_func */
+  NULL  /* binlog_log_query */
 };
 
 handler *berkeley_create_handler(TABLE_SHARE *table)

--- 1.82/sql/ha_heap.cc	2006-02-08 22:21:14 +01:00
+++ 1.83/sql/ha_heap.cc	2006-02-25 19:36:05 +01:00
@@ -58,7 +58,9 @@
   NULL,    /* Alter table flags */
   NULL,    /* Alter Tablespace */
   NULL,    /* Fill Files Table */
-  HTON_CAN_RECREATE
+  HTON_CAN_RECREATE,
+  NULL,    /* binlog_func */
+  NULL     /* binlog_log_query */
 };
 
 static handler *heap_create_handler(TABLE_SHARE *table)

--- 1.173/sql/ha_myisam.cc	2006-02-12 02:24:24 +01:00
+++ 1.174/sql/ha_myisam.cc	2006-02-25 19:36:05 +01:00
@@ -90,7 +90,9 @@
   NULL,    /* Alter table flags */
   NULL,    /* Alter Tablespace */
   NULL,    /* Fill Files Table */
-  HTON_CAN_RECREATE
+  HTON_CAN_RECREATE,
+  NULL,    /* binlog_func */
+  NULL     /* binlog_log_query */
 };
 
 

--- 1.80/sql/ha_myisammrg.cc	2006-02-14 22:35:52 +01:00
+++ 1.81/sql/ha_myisammrg.cc	2006-02-25 19:36:05 +01:00
@@ -68,7 +68,9 @@
   NULL,    /* Alter table flags */
   NULL,    /* Alter Tablespace */
   NULL,    /* Fill Files Table */
-  HTON_CAN_RECREATE
+  HTON_CAN_RECREATE,
+  NULL,    /* binlog_func */
+  NULL     /* binlog_log_query */
 };
 
 static handler *myisammrg_create_handler(TABLE_SHARE *table)

--- 1.217/sql/handler.cc	2006-02-17 10:33:59 +01:00
+++ 1.218/sql/handler.cc	2006-02-25 19:36:05 +01:00
@@ -64,7 +64,11 @@
   NULL, NULL, NULL,
   create_default,
   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-  HTON_NO_FLAGS
+  NULL,                         /* alter_tablespace */
+  NULL,                         /* fill_files_table */
+  HTON_NO_FLAGS,                /* flags */
+  NULL,                         /* binlog_func */
+  NULL                          /* binlog_log_query */
 };
 
 static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
@@ -3147,7 +3151,7 @@
   bool check_table_binlog_row_based(THD *thd, TABLE *table)
   {
     return
-      binlog_row_based &&
+      thd->current_stmt_binlog_row_based &&
       thd && (thd->options & OPTION_BIN_LOG) &&
       (table->s->tmp_table == NO_TMP_TABLE) &&
       binlog_filter->db_ok(table->s->db.str);

--- 1.194/sql/handler.h	2006-02-21 17:29:29 +01:00
+++ 1.195/sql/handler.h	2006-02-25 19:36:06 +01:00
@@ -543,10 +543,9 @@
                            struct st_table_list *tables,
                            class Item *cond);
    uint32 flags;                                /* global handler flags */
-   /* 
-      Handlerton functions are not set in the different storage
-      engines static initialization.  They are initialized at handler init.
-      Thus, leave them last in the struct.
+   /*
+      Those handlerton functions below are properly initialized at handler
+      init.
    */
    int (*binlog_func)(THD *thd, enum_binlog_func fn, void *arg);
    void (*binlog_log_query)(THD *thd, enum_binlog_command binlog_command,

--- 1.274/sql/item_func.cc	2006-02-09 11:34:35 +01:00
+++ 1.275/sql/item_func.cc	2006-02-25 19:36:06 +01:00
@@ -2657,6 +2657,7 @@
              u_d->name.str, ER(ER_UNKNOWN_ERROR));
     DBUG_RETURN(TRUE);
   }
+  thd->set_current_stmt_binlog_row_based_if_mixed();
   DBUG_RETURN(FALSE);
 }
 

--- 1.264/sql/item_strfunc.cc	2006-02-17 19:56:36 +01:00
+++ 1.265/sql/item_strfunc.cc	2006-02-25 19:36:06 +01:00
@@ -3002,6 +3002,7 @@
   char *s;
   THD *thd= current_thd;
 
+  thd->set_current_stmt_binlog_row_based_if_mixed();
   pthread_mutex_lock(&LOCK_uuid_generator);
   if (! uuid_time) /* first UUID() call. initializing data */
   {

--- 1.192/sql/log.cc	2006-02-18 19:07:28 +01:00
+++ 1.193/sql/log.cc	2006-02-25 19:36:06 +01:00
@@ -102,7 +102,9 @@
   NULL,                         /* Alter table flags */
   NULL,                         /* Alter Tablespace */
   NULL,                         /* Fill FILES table */
-  HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
+  HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
+  NULL,                         /* binlog_func */
+  NULL                          /* binlog_log_query */
 };
 
 
@@ -2630,7 +2632,7 @@
 int MYSQL_LOG::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
 {
   DBUG_ENTER("MYSQL_LOG::flush_and_set_pending_rows_event(event)");
-  DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+  DBUG_ASSERT(thd->current_stmt_binlog_row_based && mysql_bin_log.is_open());
   DBUG_PRINT("enter", ("event=%p", event));
 
   int error= 0;
@@ -2847,7 +2849,7 @@
     */
     if (thd)
     {
-      if (!binlog_row_based)
+      if (!thd->current_stmt_binlog_row_based)
       {
         if (thd->last_insert_id_used)
         {
@@ -3517,7 +3519,7 @@
                        table, table->s->table_name, table->s->table_map_id));
 
   /* Pre-conditions */
-  DBUG_ASSERT(binlog_row_based && is_open());
+  DBUG_ASSERT(thd->current_stmt_binlog_row_based && is_open());
   DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
 
 #ifndef DBUG_OFF

--- 1.205/sql/log_event.cc	2006-02-22 18:03:19 +01:00
+++ 1.206/sql/log_event.cc	2006-02-25 19:36:06 +01:00
@@ -5854,13 +5854,17 @@
       (!rpl_filter->is_on() || rpl_filter->tables_ok("", &table_list)))
   {
     /*
+      TODO: Mats will soon change this test below so that a SBR slave always
+      accepts RBR events from the master (and binlogs them RBR).
+    */
+    /*
       Check if the slave is set to use SBR.  If so, the slave should
       stop immediately since it is not possible to daisy-chain from
       RBR to SBR.  Once RBR is used, the rest of the chain has to use
       RBR.
     */
     if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
-        !binlog_row_based)
+        !thd->current_stmt_binlog_row_based)
     {
       slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_RBR_TO_SBR,
                       "It is not possible to use statement-based binlogging "

--- 1.128/sql/log_event.h	2006-01-20 13:17:10 +01:00
+++ 1.129/sql/log_event.h	2006-02-25 19:36:06 +01:00
@@ -28,14 +28,6 @@
 
 #include <my_bitmap.h>
 
-#if !defined(MYSQL_CLIENT)
-#ifdef HAVE_ROW_BASED_REPLICATION
-extern my_bool binlog_row_based;
-#else
-extern const my_bool binlog_row_based;
-#endif
-#endif
-
 #define LOG_READ_EOF    -1
 #define LOG_READ_BOGUS  -2
 #define LOG_READ_IO     -3

--- 1.380/sql/mysql_priv.h	2006-02-22 11:59:56 +01:00
+++ 1.381/sql/mysql_priv.h	2006-02-25 19:36:06 +01:00
@@ -1290,10 +1290,7 @@
 extern ulong max_binlog_size, max_relay_log_size;
 extern const char *opt_binlog_format;
 #ifdef HAVE_ROW_BASED_REPLICATION
-extern my_bool binlog_row_based;
 extern ulong opt_binlog_rows_event_max_size;
-#else
-extern const my_bool binlog_row_based;
 #endif
 extern ulong rpl_recovery_rank, thread_cache_size;
 extern ulong back_log;

--- 1.537/sql/mysqld.cc	2006-02-18 23:37:51 +01:00
+++ 1.538/sql/mysqld.cc	2006-02-25 19:36:06 +01:00
@@ -465,31 +465,14 @@
 my_bool sp_automatic_privileges= 1;
 
 #ifdef HAVE_ROW_BASED_REPLICATION
-/*
-  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;
 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 };
+const char *binlog_format_names[]= {"STATEMENT", "ROW", "MIXED", NullS};
 #else
-const my_bool binlog_row_based= FALSE;
 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. */
@@ -3187,42 +3170,25 @@
     unireg_abort(1);
   }
 
-  if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
+ if (!opt_bin_log && (global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC))
   {
     sql_print_warning("You need to use --log-bin to make "
                       "--binlog-format work.");
     unireg_abort(1);
   }
-  if (opt_binlog_format_id == BF_UNSPECIFIED)
+  if (global_system_variables.binlog_format == BINLOG_FORMAT_UNSPEC)
   {
 #ifdef HAVE_NDB_BINLOG
     if (opt_bin_log && have_ndbcluster == SHOW_OPTION_YES)
-      opt_binlog_format_id= BF_ROW;
+      global_system_variables.binlog_format= BINLOG_FORMAT_ROW;
     else
 #endif
-      opt_binlog_format_id= BF_STMT;
+      global_system_variables.binlog_format= BINLOG_FORMAT_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
-    /* Trust stored function creators because they can do no harm */
-    trust_function_creators= 1;
-  }
-#endif
+
   /* Check that we have not let the format to unspecified at this point */
-  DBUG_ASSERT((uint)opt_binlog_format_id <=
+  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
               array_elements(binlog_format_names)-1);
-  opt_binlog_format= binlog_format_names[opt_binlog_format_id];
 
 #ifdef HAVE_REPLICATION
   if (opt_log_slave_updates && replicate_same_server_id)
@@ -4929,23 +4895,19 @@
   {"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,
+  {"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. "
+   "row-based binary logging, or 'statement' for statement-based binary logging. "
 #ifdef HAVE_NDB_BINLOG
-   "If ndbcluster is enabled, the default will be set to 'row'."
+   "If ndbcluster is enabled, the default is 'row'."
 #endif
-   ,
 #else
-   "Tell the master the form of binary logging to use: this release build "
+   "Tell the master the form of binary logging to use: this 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.",
+   "a legal value."
 #endif
-   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },   
+   , 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},
@@ -5148,9 +5110,7 @@
    (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, 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.",
+   "Force InnoDB to not use next-key locking, to use only row-level locking.",
    (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,
@@ -5231,8 +5191,9 @@
    "a stored function (or trigger) is allowed only to users having the SUPER privilege "
    "and only if this stored function (trigger) may not break binary logging."
 #ifdef HAVE_ROW_BASED_REPLICATION
-   " If using --binlog-format=row, the security issues do not exist and the "
-   "binary logging cannot break so this option is automatically set to 1."
+   "Note that if ALL connections to this server ALWAYS use row-based binary "
+   "logging, the security issues do not exist and the binary logging cannot "
+   "break, so you can safely set this to 1."
 #endif
    ,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -7070,6 +7031,7 @@
   max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
   global_system_variables.old_passwords= 0;
   global_system_variables.old_alter_table= 0;
+  global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
   /*
     Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
     when collecting index statistics for MyISAM tables.
@@ -7314,18 +7276,19 @@
 #ifdef HAVE_ROW_BASED_REPLICATION
       fprintf(stderr, 
 	      "Unknown binary log format: '%s' "
-	      "(should be '%s' or '%s')\n", 
+	      "(should be one of '%s', '%s', '%s')\n", 
 	      argument,
-              binlog_format_names[BF_STMT],
-              binlog_format_names[BF_ROW]);
+              binlog_format_names[BINLOG_FORMAT_STMT],
+              binlog_format_names[BINLOG_FORMAT_ROW],
+              binlog_format_names[BINLOG_FORMAT_MIXED]);
 #else
       fprintf(stderr, 
 	      "Unknown binary log format: '%s' (only legal value is '%s')\n", 
-	      argument, binlog_format_names[BF_STMT]);
+	      argument, binlog_format_names[BINLOG_FORMAT_STMT]);
 #endif
       exit(1);
     }
-    opt_binlog_format_id= (enum binlog_format)(id-1);
+    global_system_variables.binlog_format= id-1;
     break;
   }
   case (int)OPT_BINLOG_DO_DB:

--- 1.304/sql/sql_base.cc	2006-02-22 12:04:17 +01:00
+++ 1.305/sql/sql_base.cc	2006-02-25 19:36:07 +01:00
@@ -1189,7 +1189,7 @@
     close_temporary(table, 1, 1);
   }
   if (query && found_user_tables && mysql_bin_log.is_open() &&
-      !binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
+      !thd->current_stmt_binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
   {
     /* The -1 is to remove last ',' */
     thd->clear_error();

--- 1.245/sql/sql_class.cc	2006-02-14 06:41:15 +01:00
+++ 1.246/sql/sql_class.cc	2006-02-25 19:36:07 +01:00
@@ -329,6 +329,7 @@
   bzero((char*) warn_count, sizeof(warn_count));
   total_warn_count= 0;
   update_charset();
+  reset_current_stmt_binlog_row_based();
   bzero((char *) &status_var, sizeof(status_var));
 }
 
@@ -2026,12 +2027,12 @@
 
       INSERT INTO t1 VALUES (1), (foo()), (2);
   */
-  if (binlog_row_based)
+  if (current_stmt_binlog_row_based)
     binlog_flush_pending_rows_event(false);
 #endif /* HAVE_ROW_BASED_REPLICATION */
 
   if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
-      !binlog_row_based)
+      !current_stmt_binlog_row_based)
     options&= ~OPTION_BIN_LOG;
   /* Disable result sets */
   client_capabilities &= ~CLIENT_MULTI_RESULTS;
@@ -2394,7 +2395,7 @@
                           MY_BITMAP const* cols, my_size_t colcnt, 
                           byte const *record) 
 { 
-  DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
   /* 
      Pack records into format for transfer. We are allocating more
@@ -2441,7 +2442,7 @@
                            const byte *before_record,
                            const byte *after_record)
 { 
-  DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
   bool error= 0;
   my_size_t const before_maxlen = max_row_length(table, before_record);
@@ -2489,7 +2490,7 @@
                            MY_BITMAP const* cols, my_size_t colcnt,
                            byte const *record)
 { 
-  DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
   /* 
      Pack records into format for transfer. We are allocating more
@@ -2520,7 +2521,7 @@
 int THD::binlog_flush_pending_rows_event(bool stmt_end)
 {
   DBUG_ENTER("THD::binlog_flush_pending_rows_event");
-  if (!binlog_row_based || !mysql_bin_log.is_open())
+  if (!current_stmt_binlog_row_based || !mysql_bin_log.is_open())
     DBUG_RETURN(0);
 
   /*
@@ -2561,8 +2562,8 @@
 
 /*
   Member function that will log query, either row-based or
-  statement-based depending on the value of the 'binlog_row_based'
-  variable and the value of the 'qtype' flag.
+  statement-based depending on the value of the 'current_stmt_binlog_row_based'
+  the value of the 'qtype' flag.
 
   This function should be called after the all calls to ha_*_row()
   functions have been issued, but before tables are unlocked and
@@ -2586,11 +2587,11 @@
       moving back and forth between using RBR for replication of
       system tables and not using it.
 
-      Make sure to change in check_table_binlog_row_based() according
+      Make sure to change in check_table_current_stmt_binlog_row_based according
       to how you treat this.
     */
   case THD::ROW_QUERY_TYPE:
-    if (binlog_row_based)
+    if (current_stmt_binlog_row_based)
       DBUG_RETURN(binlog_flush_pending_rows_event(true));
     /* Otherwise, we fall through */
   case THD::STMT_QUERY_TYPE:

--- 1.284/sql/sql_class.h	2006-02-14 06:41:19 +01:00
+++ 1.285/sql/sql_class.h	2006-02-25 19:36:07 +01:00
@@ -274,6 +274,8 @@
   DATE_TIME_FORMAT *date_format;
   DATE_TIME_FORMAT *datetime_format;
   DATE_TIME_FORMAT *time_format;
+
+  ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
 };
 
 
@@ -1123,6 +1125,8 @@
   char	     scramble[SCRAMBLE_LENGTH+1];
 
   bool       slave_thread, one_shot_set;
+  /* tells if current statement should binlog row-based(1) or stmt-based(0) */
+  bool       current_stmt_binlog_row_based;
   bool	     locked, some_tables_deleted;
   bool       last_cuted_field;
   bool	     no_errors, password, is_fatal_error;
@@ -1377,6 +1381,15 @@
   void restore_sub_statement_state(Sub_statement_state *backup);
   void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
   void restore_active_arena(Query_arena *set, Query_arena *backup);
+  inline void set_current_stmt_binlog_row_based_if_mixed()
+  {
+    if (variables.binlog_format == BINLOG_FORMAT_MIXED)
+      current_stmt_binlog_row_based= 1;
+  }
+  inline void reset_current_stmt_binlog_row_based()
+  {
+    current_stmt_binlog_row_based= test(variables.binlog_format == BINLOG_FORMAT_ROW);
+  }
 };
 
 

--- 1.174/sql/sql_delete.cc	2006-02-06 16:33:31 +01:00
+++ 1.175/sql/sql_delete.cc	2006-02-25 19:36:07 +01:00
@@ -962,7 +962,7 @@
       {
         /*
           TRUNCATE must always be statement-based binlogged (not row-based) so
-          we don't test binlog_row_based.
+          we don't test current_stmt_binlog_row_based.
         */
         thd->clear_error();
         thd->binlog_query(THD::STMT_QUERY_TYPE,

--- 1.186/sql/sql_insert.cc	2006-02-02 14:57:07 +01:00
+++ 1.187/sql/sql_insert.cc	2006-02-25 19:36:07 +01:00
@@ -2411,7 +2411,7 @@
       thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
                         table->file->has_transactions(), FALSE);
     }
-    if (!binlog_row_based && !table->s->tmp_table)
+    if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table)
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
   if (info.copied || info.deleted || info.updated)
@@ -2556,7 +2556,7 @@
     on rollback, we clear the OPTION_STATUS_NO_TRANS_UPDATE bit of
     thd->options.
    */
-  DBUG_ASSERT(binlog_row_based && !create_table_written);
+  DBUG_ASSERT(thd->current_stmt_binlog_row_based && !create_table_written);
 
   thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
   char buf[2048];
@@ -2582,7 +2582,7 @@
     Before writing the first row, we write the CREATE TABLE statement
     to the binlog.
    */
-  if (binlog_row_based && !create_table_written)
+  if (thd->current_stmt_binlog_row_based && !create_table_written)
   {
     binlog_show_create_table();
     create_table_written= TRUE;
@@ -2611,7 +2611,7 @@
     If no rows where written to the binary log, we write the CREATE
     TABLE statement to the binlog.
    */
-  if (binlog_row_based && !create_table_written)
+  if (thd->current_stmt_binlog_row_based && !create_table_written)
   {
     binlog_show_create_table();
     create_table_written= TRUE;

--- 1.92/sql/sql_load.cc	2006-02-09 11:34:36 +01:00
+++ 1.93/sql/sql_load.cc	2006-02-25 19:36:07 +01:00
@@ -426,7 +426,7 @@
         version for the binary log to mark that table maps are invalid
         after this point.
       */
-      if (binlog_row_based)
+      if (thd->current_stmt_binlog_row_based)
         thd->binlog_flush_pending_rows_event(true);
       else
 #endif
@@ -491,7 +491,7 @@
       version for the binary log to mark that table maps are invalid
       after this point.
      */
-    if (binlog_row_based)
+    if (thd->current_stmt_binlog_row_based)
       thd->binlog_flush_pending_rows_event(true);
     else
 #endif
@@ -948,7 +948,7 @@
       if (get_it_from_net)
 	cache.read_function = _my_b_net_read;
 
-      if (!binlog_row_based && mysql_bin_log.is_open())
+      if (mysql_bin_log.is_open())
 	cache.pre_read = cache.pre_close =
 	  (IO_CACHE_CALLBACK) log_loaded_block;
 #endif

--- 1.522/sql/sql_parse.cc	2006-02-15 17:12:20 +01:00
+++ 1.523/sql/sql_parse.cc	2006-02-25 19:36:07 +01:00
@@ -4990,6 +4990,7 @@
   */
   if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
     reset_one_shot_variables(thd);
+  thd->reset_current_stmt_binlog_row_based();
 
   /*
     The return value for ROW_COUNT() is "implementation dependent" if the

--- 1.309/sql/sql_show.cc	2006-02-21 17:29:30 +01:00
+++ 1.310/sql/sql_show.cc	2006-02-25 19:36:07 +01:00
@@ -1654,7 +1654,7 @@
 */
 static void shrink_var_array(DYNAMIC_ARRAY *array)
 {
-  int a,b;
+  uint a,b;
   SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
 
   for (a= b= 0; b < array->elements; b++)

--- 1.308/sql/sql_table.cc	2006-02-17 19:55:38 +01:00
+++ 1.309/sql/sql_table.cc	2006-02-25 19:36:07 +01:00
@@ -565,7 +565,7 @@
   String built_query;
   DBUG_ENTER("mysql_rm_table_part2");
 
-  if (binlog_row_based && !dont_log_query)
+  if (thd->current_stmt_binlog_row_based && !dont_log_query)
   {
     built_query.set_charset(system_charset_info);
     if (if_exists)
@@ -612,7 +612,7 @@
       being built.  The string always end in a comma and the comma
       will be chopped off before being written to the binary log.
       */
-    if (binlog_row_based && !dont_log_query)
+    if (thd->current_stmt_binlog_row_based && !dont_log_query)
     {
       ++non_temp_tables_count;
       /*
@@ -722,7 +722,7 @@
     query_cache_invalidate3(thd, tables, 0);
     if (!dont_log_query)
     {
-      if (!binlog_row_based ||
+      if (!thd->current_stmt_binlog_row_based ||
           non_temp_tables_count > 0 && !tmp_table_deleted)
       {
         /*
@@ -734,7 +734,7 @@
          */
         write_bin_log(thd, !error, thd->query, thd->query_length);
       }
-      else if (binlog_row_based &&
+      else if (thd->current_stmt_binlog_row_based &&
                non_temp_tables_count > 0 &&
                tmp_table_deleted)
       {
@@ -2248,8 +2248,8 @@
     Otherwise, the statement shall be binlogged.
    */
   if (!internal_tmp_table &&
-      (!binlog_row_based ||
-       (binlog_row_based &&
+      (!thd->current_stmt_binlog_row_based ||
+       (thd->current_stmt_binlog_row_based &&
         !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
     write_bin_log(thd, TRUE, thd->query, thd->query_length);
   error= FALSE;
@@ -3475,7 +3475,7 @@
   /*
     We have to write the query before we unlock the tables.
   */
-  if (binlog_row_based)
+  if (thd->current_stmt_binlog_row_based)
   {
     /*
        Since temporary tables are not replicated under row-based
@@ -4861,7 +4861,7 @@
       goto err;
     }
     /* We don't replicate alter table statement on temporary tables */
-    if (!binlog_row_based)
+    if (!thd->current_stmt_binlog_row_based)
       write_bin_log(thd, TRUE, thd->query, thd->query_length);
     goto end_temporary;
   }
@@ -5031,7 +5031,7 @@
                       thd->query, thd->query_length,
                       db, table_name);
 
-  DBUG_ASSERT(!(mysql_bin_log.is_open() && binlog_row_based &&
+  DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->current_stmt_binlog_row_based &&
                 (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
   write_bin_log(thd, TRUE, thd->query, thd->query_length);
   /*

--- 1.86/sql/share/errmsg.txt	2006-02-22 21:18:37 +01:00
+++ 1.87/sql/share/errmsg.txt	2006-02-25 19:36:06 +01:00
@@ -5812,8 +5812,10 @@
 	eng "Transaction isolation level can't be changed while a transaction is in progress"
 ER_WARN_DEPRECATED_STATEMENT
         eng  "The '%s' statement is deprecated and will be removed in MySQL %s. Please use client programs (e.g. %s) instead."
-
-ER_TABLE_NEEDS_UPGRADE
-         eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
 ER_SP_NO_AGGREGATE 42000
 	eng "AGGREGATE is not supported for stored functions"
+ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
+	eng "Your session has open temporary tables and so cannot switch out of row-based binary logging"
+ER_NDB_CANT_SWITCH_BINLOG_FORMAT
+	eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
+

--- 1.83/sql/ha_archive.cc	2006-02-15 09:59:20 +01:00
+++ 1.84/sql/ha_archive.cc	2006-02-25 19:36:05 +01:00
@@ -177,9 +177,10 @@
   NULL,    /* Partition flags */
   NULL,    /* Alter table flags */
   NULL,    /* Alter interface */
+  NULL,    /* fill_files_table */
   HTON_NO_FLAGS,
-  NULL, /* binlog_func */
-  NULL /* binlog_log_query */
+  NULL,    /* binlog_func */
+  NULL     /* binlog_log_query */
 };
 
 static handler *archive_create_handler(TABLE_SHARE *table)

--- 1.27/sql/ha_blackhole.cc	2006-01-28 04:16:18 +01:00
+++ 1.28/sql/ha_blackhole.cc	2006-02-25 19:36:05 +01:00
@@ -61,7 +61,9 @@
   NULL,    /* Alter table flags */
   NULL,    /* Alter Tablespace */
   NULL,    /* Fill FILES table */
-  HTON_CAN_RECREATE
+  HTON_CAN_RECREATE,
+  NULL, /* binlog_func */
+  NULL  /* binlog_log_query */
 };
 
 
--- New file ---
+++ mysql-test/r/ndb_binlog_basic2.result	06/02/25 19:36:07
set session binlog_format=row;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set session binlog_format=statement;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=row;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=statement;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set session binlog_format=default;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=default;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet

--- New file ---
+++ mysql-test/r/rpl_switch_stm_row_mixed.result	06/02/25 19:36:08
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
drop database if exists mysqltest1;
create database mysqltest1;
use mysqltest1;
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
ROW	ROW
CREATE TABLE t1 (a varchar(100));
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
create temporary table tmp(a char(3));
insert into tmp values("see");
set binlog_format=statement;
ERROR HY000: Your session has open temporary tables and so cannot switch out of row-based binary logging
insert into t1 select * from tmp;
drop temporary table tmp;
set binlog_format=statement;
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
ROW	STATEMENT
set global binlog_format=statement;
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
set global binlog_format=default;
ERROR 42000: Variable 'binlog_format' doesn't have a default value
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	MIXED
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
MIXED	MIXED
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
end|
call foo();
call foo2();
show binlog events from 102;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	102	Query	1	205	drop database if exists mysqltest1
master-bin.000001	205	Query	1	300	create database mysqltest1
master-bin.000001	300	Query	1	401	use `mysqltest1`; CREATE TABLE t1 (a varchar(100))
master-bin.000001	401	Table_map	1	446	mysqltest1.t1
master-bin.000001	446	Write_rows	1	481	
master-bin.000001	481	Table_map	1	526	mysqltest1.t1
master-bin.000001	526	Write_rows	1	602	
master-bin.000001	602	Table_map	1	647	mysqltest1.t1
master-bin.000001	647	Write_rows	1	718	
master-bin.000001	718	Table_map	1	763	mysqltest1.t1
master-bin.000001	763	Write_rows	1	803	
master-bin.000001	803	Table_map	1	848	mysqltest1.t1
master-bin.000001	848	Write_rows	1	918	
master-bin.000001	918	Table_map	1	963	mysqltest1.t1
master-bin.000001	963	Write_rows	1	1003	
master-bin.000001	1003	Table_map	1	1048	mysqltest1.t1
master-bin.000001	1048	Write_rows	1	1082	
master-bin.000001	1082	Query	1	1180	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	1180	User var	1	1228	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1228	Query	1	1328	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	1328	Query	1	1426	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	1426	User var	1	1474	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1474	Query	1	1574	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	1574	Query	1	1671	use `mysqltest1`; insert into t1 values("for")
master-bin.000001	1671	Query	1	1773	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	1773	Query	1	1871	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	1871	User var	1	1919	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1919	Query	1	2019	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	2019	Query	1	2117	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	2117	User var	1	2165	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	2165	Query	1	2265	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	2265	Query	1	2362	use `mysqltest1`; insert into t1 values("for")
master-bin.000001	2362	Query	1	2464	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	2464	Query	1	2562	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	2562	Table_map	1	2607	mysqltest1.t1
master-bin.000001	2607	Write_rows	1	2683	
master-bin.000001	2683	Table_map	1	2728	mysqltest1.t1
master-bin.000001	2728	Write_rows	1	2799	
master-bin.000001	2799	User var	1	2847	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	2847	Query	1	2947	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	2947	Table_map	1	2992	mysqltest1.t1
master-bin.000001	2992	Write_rows	1	3062	
master-bin.000001	3062	Query	1	3164	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	3164	Table_map	1	3209	mysqltest1.t1
master-bin.000001	3209	Write_rows	1	3280	
master-bin.000001	3280	User var	1	3328	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	3328	Query	1	3428	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	3428	Table_map	1	3473	mysqltest1.t1
master-bin.000001	3473	Write_rows	1	3543	
master-bin.000001	3543	Query	1	3645	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	3645	Query	1	3857	use `mysqltest1`; create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end
master-bin.000001	3857	Query	1	4086	use `mysqltest1`; create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
end
master-bin.000001	4086	Query	1	4192	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	4192	Table_map	1	4237	mysqltest1.t1
master-bin.000001	4237	Write_rows	1	4307	
master-bin.000001	4307	Query	1	4417	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	4417	Table_map	1	4462	mysqltest1.t1
master-bin.000001	4462	Write_rows	1	4538	
master-bin.000001	4538	Query	1	4644	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	4644	Table_map	1	4689	mysqltest1.t1
master-bin.000001	4689	Write_rows	1	4759	
drop database mysqltest1;

--- New file ---
+++ mysql-test/r/rpl_switch_stm_row_mixed_UDF.result	06/02/25 19:36:08
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
drop database if exists mysqltest1;
create database mysqltest1;
use mysqltest1;
set sql_log_bin=0;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
set sql_log_bin=1;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
ROW	ROW
CREATE TABLE t1 (a varchar(100));
prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";
set binlog_format=statement;
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	ROW
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
ROW	STATEMENT
set global binlog_format=statement;
show global variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
show session variables like "binlog_format%";
Variable_name	Value
binlog_format	STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
set global binlog_format=default;
ERROR 42000: Variable 'binlog_format' doesn't have a default value
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	STATEMENT
prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";
set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
STATEMENT	MIXED
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format	@@session.binlog_format
MIXED	MIXED
prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(metaphon("emergency"));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(metaphon("emergency"));
insert into t1 values("work");
insert into t1 values(metaphon("for"));
end|
call foo();
call foo2();
show binlog events from 102;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	102	Query	1	205	drop database if exists mysqltest1
master-bin.000001	205	Query	1	300	create database mysqltest1
master-bin.000001	300	Query	1	401	use `mysqltest1`; CREATE TABLE t1 (a varchar(100))
master-bin.000001	401	Table_map	1	446	mysqltest1.t1
master-bin.000001	446	Write_rows	1	481	
master-bin.000001	481	Table_map	1	526	mysqltest1.t1
master-bin.000001	526	Write_rows	1	563	
master-bin.000001	563	Table_map	1	608	mysqltest1.t1
master-bin.000001	608	Write_rows	1	642	
master-bin.000001	642	Table_map	1	687	mysqltest1.t1
master-bin.000001	687	Write_rows	1	727	
master-bin.000001	727	Table_map	1	772	mysqltest1.t1
master-bin.000001	772	Write_rows	1	805	
master-bin.000001	805	Table_map	1	850	mysqltest1.t1
master-bin.000001	850	Write_rows	1	890	
master-bin.000001	890	Query	1	988	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	988	User var	1	1036	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1036	Query	1	1146	use `mysqltest1`; insert into t1 select metaphon(@'string')
master-bin.000001	1146	Query	1	1254	use `mysqltest1`; insert into t1 values(metaphon("work"))
master-bin.000001	1254	User var	1	1302	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1302	Query	1	1402	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	1402	Query	1	1509	use `mysqltest1`; insert into t1 values(metaphon("for"))
master-bin.000001	1509	Query	1	1611	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	1611	Query	1	1709	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	1709	User var	1	1757	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	1757	Query	1	1867	use `mysqltest1`; insert into t1 select metaphon(@'string')
master-bin.000001	1867	Query	1	1975	use `mysqltest1`; insert into t1 values(metaphon("work"))
master-bin.000001	1975	User var	1	2023	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	2023	Query	1	2123	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	2123	Query	1	2230	use `mysqltest1`; insert into t1 values(metaphon("for"))
master-bin.000001	2230	Query	1	2332	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	2332	Query	1	2430	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	2430	Table_map	1	2475	mysqltest1.t1
master-bin.000001	2475	Write_rows	1	2512	
master-bin.000001	2512	Table_map	1	2557	mysqltest1.t1
master-bin.000001	2557	Write_rows	1	2591	
master-bin.000001	2591	User var	1	2639	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001	2639	Query	1	2739	use `mysqltest1`; insert into t1 select @'string'
master-bin.000001	2739	Table_map	1	2784	mysqltest1.t1
master-bin.000001	2784	Write_rows	1	2817	
master-bin.000001	2817	Query	1	2919	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	2919	Query	1	3132	use `mysqltest1`; create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(metaphon("emergency"));
insert into t1 select "yesterday";
end
master-bin.000001	3132	Query	1	3351	use `mysqltest1`; create procedure foo2()
begin
insert into t1 values(metaphon("emergency"));
insert into t1 values("work");
insert into t1 values(metaphon("for"));
end
master-bin.000001	3351	Query	1	3457	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	3457	Table_map	1	3502	mysqltest1.t1
master-bin.000001	3502	Write_rows	1	3539	
master-bin.000001	3539	Query	1	3649	use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001	3649	Table_map	1	3694	mysqltest1.t1
master-bin.000001	3694	Write_rows	1	3731	
master-bin.000001	3731	Query	1	3837	use `mysqltest1`; insert into t1 values("work")
master-bin.000001	3837	Table_map	1	3882	mysqltest1.t1
master-bin.000001	3882	Write_rows	1	3915	
drop function metaphon;
drop database mysqltest1;
drop function if exists metaphon;

--- New file ---
+++ mysql-test/t/ndb_binlog_basic2.test	06/02/25 19:36:08
-- source include/have_ndb.inc

--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=row;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=statement;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=row;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=statement;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=default;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=default;

--- New file ---
+++ mysql-test/t/rpl_switch_stm_row_mixed.test	06/02/25 19:36:09
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc

connection master;
--disable_warnings
drop database if exists mysqltest1;
create database mysqltest1;
--enable_warnings
use mysqltest1;

show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;

CREATE TABLE t1 (a varchar(100));

prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";

# verify that temp tables prevent a switch to SBR
create temporary table tmp(a char(3));
insert into tmp values("see");
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
set binlog_format=statement;
insert into t1 select * from tmp;
drop temporary table tmp;

# Now we go to SBR
set binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values("for");
insert into t1 select "yesterday";

# test SET DEFAULT (=statement at this point of test)
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
# due to cluster it's hard to set back to default
--error ER_NO_DEFAULT
set global binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values("for");
insert into t1 select "yesterday";

# and now the mixed mode

set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";

# inside a stored procedure (inside a function or trigger won't
# work)

delimiter |;
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
end|
delimiter ;|
call foo();
call foo2();

# and now compare:

show binlog events from 102;
sync_slave_with_master;
# as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_slave.sql

connection master;
drop database mysqltest1;
sync_slave_with_master;

# Let's compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file
# will be created. You will need to go to the mysql-test dir and diff
# the files your self to see what is not matching

--exec diff ./var/tmp/rpl_row_UDF_master.sql ./var/tmp/rpl_row_UDF_slave.sql;

--- New file ---
+++ mysql-test/t/rpl_switch_stm_row_mixed_UDF.test	06/02/25 19:36:09
# This test should NOT be pushed as it is
# as it contains UDFs which are not testable in an automated
# way on all platforms

-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc

connection master;
--disable_warnings
drop database if exists mysqltest1;
create database mysqltest1;
--enable_warnings
use mysqltest1;
# work around BUG#16771
set sql_log_bin=0;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
set sql_log_bin=1;
sync_slave_with_master;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
connection master;

show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;

CREATE TABLE t1 (a varchar(100));

prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";

# Now we go to SBR

set binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";

# test SET DEFAULT (=statement at this point of test)
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
# due to cluster it's hard to set back to default
--error ER_NO_DEFAULT
set global binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";

# and now the mixed mode

set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;

prepare stmt1 from 'insert into t1 select metaphon(?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;

prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(metaphon("work"));
execute stmt1 using @string;
deallocate prepare stmt1;

insert into t1 values(metaphon("for"));
insert into t1 select "yesterday";

# inside a stored procedure (inside a function or trigger won't
# work)

delimiter |;
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(metaphon("emergency"));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(metaphon("emergency"));
insert into t1 values("work");
insert into t1 values(metaphon("for"));
end|
delimiter ;|
call foo();
call foo2();

# and now compare:

show binlog events from 102;
sync_slave_with_master;
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_slave.sql

connection master;
drop function metaphon;
drop database mysqltest1;
sync_slave_with_master;
drop function if exists metaphon;

# Let's compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file
# will be created. You will need to go to the mysql-test dir and diff
# the files your self to see what is not matching

--exec diff ./var/tmp/rpl_row_UDF_master.sql ./var/tmp/rpl_row_UDF_slave.sql;


--- 1.1/mysql-test/r/rpl_row_4_bytes.result	2005-12-22 06:34:52 +01:00
+++ 1.2/mysql-test/r/rpl_row_4_bytes.result	2006-02-25 19:36:05 +01:00
@@ -24,4 +24,4 @@
 ABE
 ANG
 LIL
-DROP TABLE t1,t2;
+DROP DATABASE mysqltest1;

--- 1.1/mysql-test/t/rpl_row_4_bytes.test	2005-12-22 06:35:00 +01:00
+++ 1.2/mysql-test/t/rpl_row_4_bytes.test	2006-02-25 19:36:05 +01:00
@@ -29,5 +29,5 @@
 select * from t2 order by a;
 
 connection master;
-DROP TABLE t1,t2;
+DROP DATABASE mysqltest1;
 sync_slave_with_master;

--- 1.5/sql/log.h	2006-02-12 20:33:12 +01:00
+++ 1.6/sql/log.h	2006-02-25 19:36:06 +01:00
@@ -507,4 +507,24 @@
   void init_general_log(uint general_log_printer);
  };
 
+
+enum enum_binlog_format {
+  BINLOG_FORMAT_STMT= 0, // statement-based
+#ifdef HAVE_ROW_BASED_REPLICATION
+  BINLOG_FORMAT_ROW= 1, // row_based
+  /*
+    statement-based except for cases where only row-based can work (UUID()
+    etc):
+  */
+  BINLOG_FORMAT_MIXED= 2,
+#endif
+/*
+  This value is last, after the end of binlog_format_typelib: it has no
+  corresponding cell in this typelib. We use this value to be able to know if
+  the user has explicitely specified a binlog format at startup or not.
+*/
+  BINLOG_FORMAT_UNSPEC= 3
+};
+extern TYPELIB binlog_format_typelib;
+
 #endif /* LOG_H */

--- 1.257/sql/ha_innodb.cc	2006-02-12 22:26:23 +01:00
+++ 1.258/sql/ha_innodb.cc	2006-02-25 19:36:05 +01:00
@@ -237,8 +237,11 @@
   innobase_show_status,		/* Show status */
   NULL,                         /* Partition flags */
   NULL,                         /* Alter table flags */
+  NULL,                         /* alter_tablespace */
   NULL,                         /* Fill FILES table */
-  HTON_NO_FLAGS
+  HTON_NO_FLAGS,
+  NULL,                         /* binlog_func */
+  NULL                          /* binlog_log_query */
 };
 
 

--- 1.175/sql/set_var.cc	2006-02-18 17:38:04 +01:00
+++ 1.176/sql/set_var.cc	2006-02-25 19:36:06 +01:00
@@ -141,6 +141,7 @@
 static bool set_log_update(THD *thd, set_var *var);
 static int  check_pseudo_thread_id(THD *thd, set_var *var);
 static bool set_log_bin(THD *thd, set_var *var);
+void fix_binlog_format_after_update(THD *thd, enum_var_type type);
 static void fix_low_priority_updates(THD *thd, enum_var_type type);
 static int check_tx_isolation(THD *thd, set_var *var);
 static void fix_tx_isolation(THD *thd, enum_var_type type);
@@ -185,6 +186,8 @@
 
 sys_var_long_ptr	sys_binlog_cache_size("binlog_cache_size",
 					      &binlog_cache_size);
+sys_var_thd_binlog_format sys_binlog_format("binlog_format",
+                                            &SV::binlog_format);
 sys_var_thd_ulong	sys_bulk_insert_buff_size("bulk_insert_buffer_size",
 						  &SV::bulk_insert_buff_size);
 sys_var_character_set_server	sys_character_set_server("character_set_server");
@@ -653,11 +656,11 @@
   var->value= buff;
   if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
   {
-    var->value= "OFF";
+    var->value= const_cast<char *>("OFF");
   }
   else if (bitmap_is_set_all(&slave_error_mask))
   {
-    var->value= "ALL";
+    var->value= const_cast<char *>("ALL");
   }
   else
   {
@@ -706,7 +709,7 @@
   {"bdb_shared_data",	      (char*) &berkeley_shared_data,	    SHOW_BOOL},
   {"bdb_tmpdir",              (char*) &berkeley_tmpdir,             SHOW_CHAR_PTR},
   {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size,	    SHOW_SYS},
-  {"binlog_format",           (char*) &opt_binlog_format,           SHOW_CHAR_PTR},
+  {sys_binlog_format.name,    (char*) &sys_binlog_format,	    SHOW_SYS},
   {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},
@@ -1241,6 +1244,45 @@
     ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
     break;
   }
+}
+
+
+bool sys_var_thd_binlog_format::is_readonly() const
+{
+  /*
+    Under certain circumstances, the variable is read-only (unchangeable):
+  */
+  THD *thd= current_thd;
+  /*
+    If RBR and open temporary tables, their CREATE TABLE may not be in the
+    binlog, so we can't toggle to SBR in this connection.
+    The test below will also prevent SET GLOBAL, well it was not easy to test
+    if global or not here.
+    And this test will also prevent switching from RBR to RBR (a no-op which
+    should not happen too often).
+  */
+  if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
+      thd->temporary_tables)
+  {
+    my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
+    return 1;
+  }
+#ifdef HAVE_NDB_BINLOG
+  /*
+    Cluster does not support changing the binlog format on the fly yet.
+  */
+  if (opt_bin_log && (have_ndbcluster == SHOW_OPTION_YES))
+  {
+    my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0));
+    return 1;
+  }
+#endif
+  return sys_var_thd_enum::is_readonly();
+}
+
+void fix_binlog_format_after_update(THD *thd, enum_var_type type)
+{
+  thd->reset_current_stmt_binlog_row_based();
 }
 
 static void fix_max_binlog_size(THD *thd, enum_var_type type)

--- 1.83/sql/set_var.h	2006-02-17 20:00:41 +01:00
+++ 1.84/sql/set_var.h	2006-02-25 19:36:06 +01:00
@@ -826,6 +826,18 @@
   bool update(THD *thd, set_var *var);
 };
 
+extern void fix_binlog_format_after_update(THD *thd, enum_var_type type);
+
+class sys_var_thd_binlog_format :public sys_var_thd_enum
+{
+public:
+  sys_var_thd_binlog_format(const char *name_arg, ulong SV::*offset_arg)
+    :sys_var_thd_enum(name_arg, offset_arg,
+                      &binlog_format_typelib,
+                      fix_binlog_format_after_update)
+  {};
+  bool is_readonly() const;
+};
 
 /****************************************************************************
   Classes for parsing of the SET command

--- 1.32/sql/ha_partition.cc	2006-02-21 17:29:29 +01:00
+++ 1.33/sql/ha_partition.cc	2006-02-25 19:36:05 +01:00
@@ -102,7 +102,9 @@
   alter_table_flags, /* Partition flags */
   NULL, /* Alter Tablespace */
   NULL, /* Fill FILES table */
-  HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
+  HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
+  NULL,                         /* binlog_func */
+  NULL                          /* binlog_log_query */
 };
 
 /*
@@ -2609,7 +2611,7 @@
     ADDITIONAL INFO:
 
     Most handlers set timestamp when calling write row if any such fields
+    exists. Since we are calling an underlying handler we assume the´
     underlying handler will assume this responsibility.
 
     Underlying handlers will also call update_auto_increment to calculate

--- 1.40/sql/sql_partition.cc	2006-02-22 00:39:57 +01:00
+++ 1.41/sql/sql_partition.cc	2006-02-25 19:36:07 +01:00
@@ -697,7 +697,7 @@
     my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
     goto end;
   }
-  if (same_name= part_info->has_unique_names())
+  if ((same_name= part_info->has_unique_names()))
   {
     my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
     goto end;

--- 1.52/sql/ha_federated.cc	2006-02-07 22:33:23 +01:00
+++ 1.53/sql/ha_federated.cc	2006-02-25 19:36:05 +01:00
@@ -398,7 +398,9 @@
   NULL,    /* Alter table flags */
   NULL,    /* Alter Tablespace */
   NULL,    /* Fill FILES table */
-  HTON_ALTER_NOT_SUPPORTED
+  HTON_ALTER_NOT_SUPPORTED,
+  NULL,    /* binlog_func */
+  NULL     /* binlog_log_query */
 };
 
 

--- 1.204/sql/sp_head.cc	2006-02-18 23:37:51 +01:00
+++ 1.205/sql/sp_head.cc	2006-02-25 19:36:06 +01:00
@@ -1301,7 +1301,7 @@
     each substatement be binlogged its way.
   */
   need_binlog_call= mysql_bin_log.is_open() &&
-    (thd->options & OPTION_BIN_LOG) && !binlog_row_based;
+    (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
   if (need_binlog_call)
   {
     reset_dynamic(&thd->user_var_events);

--- 1.4/sql/partition_info.cc	2006-02-22 00:39:57 +01:00
+++ 1.5/sql/partition_info.cc	2006-02-25 19:36:06 +01:00
@@ -278,7 +278,7 @@
   List_iterator<partition_element> parts_it(partitions);
   
   partition_element *el;
-  while (el= (parts_it++))
+  while ((el= (parts_it++)))
   {
     if (!(my_strcasecmp(system_charset_info, el->partition_name, 
                         name_to_check)) && el != element)
@@ -288,7 +288,7 @@
     {
       partition_element *sub_el;    
       List_iterator<partition_element> subparts_it(el->subpartitions);
-      while (sub_el= (subparts_it++))
+      while ((sub_el= (subparts_it++)))
       {
         if (!(my_strcasecmp(system_charset_info, sub_el->partition_name, 
                             name_to_check)) && sub_el != element)
@@ -323,7 +323,7 @@
   List_iterator<partition_element> parts_it(partitions);
 
   partition_element *el;  
-  while (el= (parts_it++))
+  while ((el= (parts_it++)))
   {
     if (! has_unique_name(el))
       DBUG_RETURN(el->partition_name);
@@ -332,7 +332,7 @@
     {
       List_iterator<partition_element> subparts_it(el->subpartitions);
       partition_element *subel;
-      while (subel= (subparts_it++))
+      while ((subel= (subparts_it++)))
       {
         if (! has_unique_name(subel))
           DBUG_RETURN(subel->partition_name);

--- 1.149/sql/sql_repl.cc	2006-02-02 14:48:06 +01:00
+++ 1.150/sql/sql_repl.cc	2006-02-25 19:36:07 +01:00
@@ -1576,6 +1576,8 @@
   if (!(block_len = (char*) file->read_end - (char*) buffer))
     return 0;
   lf_info = (LOAD_FILE_INFO*) file->arg;
+  if (lf_info->thd->current_stmt_binlog_row_based)
+    return 0;
   if (lf_info->last_pos_in_file != HA_POS_ERROR &&
       lf_info->last_pos_in_file >= file->pos_in_file)
     return 0;

--- 1.23/sql/ha_ndbcluster_binlog.cc	2006-02-22 18:15:13 +01:00
+++ 1.24/sql/ha_ndbcluster_binlog.cc	2006-02-25 19:36:05 +01:00
@@ -2774,7 +2774,7 @@
   ndb_binlog_thread_running= 1;
   if (opt_bin_log)
   {
-    if (binlog_row_based)
+    if (global_system_variables.binlog_format == BINLOG_FORMAT_ROW)
     {
       ndb_binlog_running= TRUE;
     }

--- 1.178/tests/mysql_client_test.c	2006-02-16 10:09:47 +01:00
+++ 1.179/tests/mysql_client_test.c	2006-02-25 19:36:07 +01:00
@@ -14724,9 +14724,9 @@
 
   mysql_close(mysql);
 
-  if (rc= mysql_stmt_execute(prep_stmt))
+  if ((rc= mysql_stmt_execute(prep_stmt)))
   {
-    if (rc= mysql_stmt_reset(prep_stmt))
+    if ((rc= mysql_stmt_reset(prep_stmt)))
       printf("OK!\n");
     else
     {
Thread
bk commit into 5.1 tree (guilhem:1.2166)guilhem25 Feb