List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:June 12 2007 10:15pm
Subject:bk commit into 5.1 tree (mats:1.2552)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats 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@stripped, 2007-06-12 22:14:54+02:00, mats@stripped +20 -0
  Merge kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl
  into  kindahl-laptop.dnsalias.net:/home/bk/b23051-mysql-5.1-rpl
  MERGE: 1.2500.31.5

  sql/ha_ndbcluster.cc@stripped, 2007-06-12 22:12:32+02:00, mats@stripped
+0 -0
    Auto merged
    MERGE: 1.452.2.1

  sql/handler.cc@stripped, 2007-06-12 22:12:33+02:00, mats@stripped +0 -0
    Auto merged
    MERGE: 1.309.1.1

  sql/handler.h@stripped, 2007-06-12 22:12:33+02:00, mats@stripped +0 -0
    Auto merged
    MERGE: 1.260.1.1

  sql/mysql_priv.h@stripped, 2007-06-12 22:12:33+02:00, mats@stripped +0
-0
    Auto merged
    MERGE: 1.509.2.5

  sql/set_var.cc@stripped, 2007-06-12 22:12:33+02:00, mats@stripped +0 -0
    Auto merged
    MERGE: 1.234.1.1

  sql/share/errmsg.txt@stripped, 2007-06-12 22:14:49+02:00, mats@stripped
+0 -0
    SCCS merged
    MERGE: 1.156.1.1

  sql/sql_base.cc@stripped, 2007-06-12 22:12:34+02:00, mats@stripped +0 -0
    Auto merged
    MERGE: 1.403.1.4

  sql/sql_class.h@stripped, 2007-06-12 22:12:34+02:00, mats@stripped +0 -0
    Auto merged
    MERGE: 1.362.1.4

  sql/sql_insert.cc@stripped, 2007-06-12 22:12:34+02:00, mats@stripped +0
-0
    Auto merged
    MERGE: 1.273.1.1

  sql/sql_parse.cc@stripped, 2007-06-12 22:12:34+02:00, mats@stripped +0
-0
    Auto merged
    MERGE: 1.674.1.1

  storage/archive/ha_archive.h@stripped, 2007-06-12 22:12:35+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.63.1.1

  storage/blackhole/ha_blackhole.h@stripped, 2007-06-12 22:12:35+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.16.1.1

  storage/csv/ha_tina.h@stripped, 2007-06-12 22:12:35+02:00, mats@stripped
+0 -0
    Auto merged
    MERGE: 1.28.1.1

  storage/example/ha_example.h@stripped, 2007-06-12 22:12:35+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.22.1.1

  storage/federated/ha_federated.h@stripped, 2007-06-12 22:12:35+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.45.1.1

  storage/heap/ha_heap.h@stripped, 2007-06-12 22:12:35+02:00, mats@stripped
+0 -0
    Auto merged
    MERGE: 1.52.1.1

  storage/innobase/handler/ha_innodb.cc@stripped, 2007-06-12 22:12:36+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.338.1.1

  storage/innobase/handler/ha_innodb.h@stripped, 2007-06-12 22:12:36+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.139.1.1

  storage/myisam/ha_myisam.cc@stripped, 2007-06-12 22:12:36+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.220.1.1

  storage/myisammrg/ha_myisammrg.h@stripped, 2007-06-12 22:12:36+02:00,
mats@stripped +0 -0
    Auto merged
    MERGE: 1.52.1.1

# 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:	mats
# Host:	kindahl-laptop.dnsalias.net
# Root:	/home/bk/b23051-mysql-5.1-rpl/RESYNC

--- 1.53/storage/heap/ha_heap.h	2007-06-12 22:15:06 +02:00
+++ 1.54/storage/heap/ha_heap.h	2007-06-12 22:15:06 +02:00
@@ -48,6 +48,7 @@
   ulonglong table_flags() const
   {
     return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
             HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
             HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
   }

--- 1.221/storage/myisam/ha_myisam.cc	2007-06-12 22:15:06 +02:00
+++ 1.222/storage/myisam/ha_myisam.cc	2007-06-12 22:15:06 +02:00
@@ -474,6 +474,7 @@
 ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
   :handler(hton, table_arg), file(0),
   int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
+                  HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
                   HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
                   HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
                   HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |

--- 1.53/storage/myisammrg/ha_myisammrg.h	2007-06-12 22:15:06 +02:00
+++ 1.54/storage/myisammrg/ha_myisammrg.h	2007-06-12 22:15:06 +02:00
@@ -35,6 +35,7 @@
   ulonglong table_flags() const
   {
     return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS |
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
 	    HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
             HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
             HA_NO_COPY_ON_ALTER);

--- 1.310/sql/handler.cc	2007-06-12 22:15:06 +02:00
+++ 1.311/sql/handler.cc	2007-06-12 22:15:06 +02:00
@@ -3639,7 +3639,15 @@
     taken a table lock), ha_release_auto_increment() was too.
   */
   DBUG_ASSERT(next_insert_id == 0);
-  DBUG_RETURN(external_lock(thd, lock_type));
+
+  /*
+    We cache the table flags if the locking succeeded. Otherwise, we
+    keep them as they were when they were fetched in ha_open().
+  */
+  int error= external_lock(thd, lock_type);
+  if (error == 0)
+    cached_table_flags= table_flags();
+  DBUG_RETURN(error);
 }
 
 

--- 1.262/sql/handler.h	2007-06-12 22:15:06 +02:00
+++ 1.263/sql/handler.h	2007-06-12 22:15:06 +02:00
@@ -117,6 +117,18 @@
 #define HA_HAS_RECORDS	       (LL(1) << 32) /* records() gives exact count*/
 /* Has it's own method of binlog logging */
 #define HA_HAS_OWN_BINLOGGING  (LL(1) << 33)
+/*
+  Engine is capable of row-format and statement-format logging,
+  respectively
+*/
+#define HA_BINLOG_ROW_CAPABLE  (LL(1) << 34)
+#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
+
+/*
+  Set of all binlog flags. Currently only contain the capabilities
+  flags.
+ */
+#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
 
 /* bits in index_flags(index_number) for what you can do with index */
 #define HA_READ_NEXT            1       /* TODO really use this flag */
@@ -688,7 +700,7 @@
 };
 
 
-/* Possible flags of a handlerton */
+/* Possible flags of a handlerton (there can be 32 of them) */
 #define HTON_NO_FLAGS                 0
 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
 #define HTON_ALTER_NOT_SUPPORTED     (1 << 1) //Engine does not support alter
@@ -793,19 +805,37 @@
 class TABLEOP_HOOKS
 {
 public:
+  TABLEOP_HOOKS() {}
+  virtual ~TABLEOP_HOOKS() {}
+
   inline void prelock(TABLE **tables, uint count)
   {
     do_prelock(tables, count);
   }
-  virtual ~TABLEOP_HOOKS() {}
-  TABLEOP_HOOKS() {}
 
+  inline int postlock(TABLE **tables, uint count)
+  {
+    return do_postlock(tables, count);
+  }
 private:
   /* Function primitive that is called prior to locking tables */
   virtual void do_prelock(TABLE **tables, uint count)
   {
     /* Default is to do nothing */
   }
+
+  /**
+     Primitive called after tables are locked.
+
+     If an error is returned, the tables will be unlocked and error
+     handling start.
+
+     @return Error code or zero.
+   */
+  virtual int do_postlock(TABLE **tables, uint count)
+  {
+    return 0;                           /* Default is to do nothing */
+  }
 };
 
 typedef struct st_savepoint SAVEPOINT;
@@ -900,10 +930,13 @@
   friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
                              const char*,bool);
 
+public:
+  typedef ulonglong Table_flags;
+
  protected:
   struct st_table_share *table_share;   /* The table definition */
   struct st_table *table;               /* The current open table */
-  ulonglong cached_table_flags;         /* Set on init() and open() */
+  Table_flags cached_table_flags;       /* Set on init() and open() */
 
   virtual int index_init(uint idx, bool sorted) { active_index=idx; return 0; }
   virtual int index_end() { active_index=MAX_KEY; return 0; }
@@ -916,7 +949,7 @@
   */
   virtual int rnd_init(bool scan) =0;
   virtual int rnd_end() { return 0; }
-  virtual ulonglong table_flags(void) const =0;
+  virtual Table_flags table_flags(void) const =0;
 
   void ha_statistic_increment(ulong SSV::*offset) const;
   void **ha_data(THD *) const;
@@ -1130,7 +1163,7 @@
   {
     return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
   }
-  longlong ha_table_flags() { return cached_table_flags; }
+  Table_flags ha_table_flags() const { return cached_table_flags; }
 
   /*
     Signal that the table->read_set and table->write_set table maps changed
@@ -1694,6 +1727,8 @@
 	/* Some extern variables used with handlers */
 
 extern const char *ha_row_type[];
+extern const char *tx_isolation_names[];
+extern const char *binlog_format_names[];
 extern TYPELIB tx_isolation_typelib;
 extern TYPELIB myisam_stats_method_typelib;
 extern ulong total_ha, total_ha_2pc;

--- 1.516/sql/mysql_priv.h	2007-06-12 22:15:06 +02:00
+++ 1.517/sql/mysql_priv.h	2007-06-12 22:15:06 +02:00
@@ -1273,6 +1273,7 @@
 bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
 bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
 int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
+int decide_logging_format(THD *thd, TABLE_LIST *tables);
 TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
 			    const char *table_name, bool link_in_list);
 bool rm_temporary_table(handlerton *base, char *path);

--- 1.409/sql/sql_base.cc	2007-06-12 22:15:06 +02:00
+++ 1.410/sql/sql_base.cc	2007-06-12 22:15:06 +02:00
@@ -3955,6 +3955,121 @@
 }
 
 
+/**
+   Decide on logging format to use for the statement.
+
+   Compute the capabilities vector for the involved storage engines
+   and mask out the flags for the binary log. Right now, the binlog
+   flags only include the capabilities of the storage engines, so this
+   is safe.
+
+   We now have three alternatives that prevent the statement from
+   being loggable:
+
+   1. If there are no capabilities left (all flags are clear) it is
+      not possible to log the statement at all, so we roll back the
+      statement and report an error.
+
+   2. Statement mode is set, but the capabilities indicate that
+      statement format is not possible.
+
+   3. Row mode is set, but the capabilities indicate that row
+      format is not possible.
+
+   4. Statement is unsafe, but the capabilities indicate that row
+      format is not possible.
+
+   If we are in MIXED mode, we then decide what logging format to use:
+
+   1. If the statement is unsafe, row-based logging is used.
+
+   2. If statement-based logging is not possible, row-based logging is
+      used.
+
+   3. Otherwise, statement-based logging is used.
+
+   @param thd    Client thread
+   @param tables Tables involved in the query
+ */
+
+int decide_logging_format(THD *thd, TABLE_LIST *tables)
+{
+  if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+  {
+    handler::Table_flags binlog_flags= ~handler::Table_flags();
+    for (TABLE_LIST *table= tables; table; table= table->next_global)
+      if (!table->placeholder() && table->lock_type >=
TL_WRITE_ALLOW_WRITE)
+      {
+#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
+#ifndef DBUG_OFF
+        ulonglong flags= table->table->file->ha_table_flags();
+        DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s",
+                            table->table_name,
+                            FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE),
+                            FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE)));
+#endif
+        binlog_flags &= table->table->file->ha_table_flags();
+      }
+    binlog_flags&= HA_BINLOG_FLAGS;
+    DBUG_PRINT("info", ("binlog_flags: %s%s",
+                        FLAGSTR(binlog_flags, HA_BINLOG_STMT_CAPABLE),
+                        FLAGSTR(binlog_flags, HA_BINLOG_ROW_CAPABLE)));
+    DBUG_PRINT("info", ("thd->variables.binlog_format: %ld",
+                        thd->variables.binlog_format));
+
+    int error= 0;
+    if (binlog_flags == 0)
+    {
+      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
+               "Statement cannot be logged to the binary log in"
+               " row-based nor statement-based format");
+    }
+    else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
+             (binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0)
+    {
+      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
+                "Statement-based format required for this statement,"
+                " but not allowed by this combination of engines");
+    }
+    else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
+              thd->lex->is_stmt_unsafe()) &&
+             (binlog_flags & HA_BINLOG_ROW_CAPABLE) == 0)
+    {
+      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
+                "Row-based format required for this statement,"
+                " but not allowed by this combination of engines");
+    }
+
+    DBUG_PRINT("info", ("error: %d", error));
+
+    if (error)
+    {
+      ha_rollback_stmt(thd);
+      return -1;
+    }
+
+    /*
+      We switch to row-based format if we are in mixed mode and one of
+      the following are true:
+
+      1. If the statement is unsafe
+      2. If statement format cannot be used
+
+      Observe that point to cannot be decided before the tables
+      involved in a statement has been checked, i.e., we cannot put
+      this code in reset_current_stmt_binlog_row_based(), it has to be
+      here.
+    */
+    if (thd->lex->is_stmt_unsafe() ||
+        (binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0)
+    {
+      thd->set_current_stmt_binlog_row_based_if_mixed();
+    }
+  }
+
+  return 0;
+}
+
 /*
   Lock all tables in list
 
@@ -3993,17 +4108,10 @@
     in prelocked mode.
   */
   DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
-
   *need_reopen= FALSE;
 
-  /*
-    CREATE ... SELECT UUID() locks no tables, we have to test here.
-  */
-  if (thd->lex->is_stmt_unsafe())
-    thd->set_current_stmt_binlog_row_based_if_mixed();
-
   if (!tables && !thd->lex->requires_prelocking())
-    DBUG_RETURN(0);
+    DBUG_RETURN(decide_logging_format(thd, tables));
 
   /*
     We need this extra check for thd->prelocked_mode because we want to avoid
@@ -4056,6 +4164,7 @@
       }
       DBUG_RETURN(-1);
     }
+
     if (thd->lex->requires_prelocking() &&
         thd->lex->sql_command != SQLCOM_LOCK_TABLES)
     {
@@ -4122,7 +4231,8 @@
       thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
     }
   }
-  DBUG_RETURN(0);
+
+  DBUG_RETURN(decide_logging_format(thd, tables));
 }
 
 

--- 1.367/sql/sql_class.h	2007-06-12 22:15:06 +02:00
+++ 1.368/sql/sql_class.h	2007-06-12 22:15:06 +02:00
@@ -1991,20 +1991,21 @@
 class select_create: public select_insert {
   ORDER *group;
   TABLE_LIST *create_table;
+  TABLE_LIST *select_tables;
   HA_CREATE_INFO *create_info;
   Alter_info *alter_info;
   Field **field;
 public:
-  select_create(TABLE_LIST *table_arg,
-                HA_CREATE_INFO *create_info_arg,
-                Alter_info *alter_info_arg,
-                List<Item> &select_fields,
-                enum_duplicates duplic, bool ignore)
-    :select_insert(NULL, NULL, &select_fields, 0, 0, duplic, ignore),
+  select_create (TABLE_LIST *table_arg,
+		 HA_CREATE_INFO *create_info_par,
+		 List<create_field> &fields_par,
+		 List<Key> &keys_par,
+		 List<Item> &select_fields,enum_duplicates duplic, bool ignore,
+                 TABLE_LIST *select_tables_arg)
+    :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore),
     create_table(table_arg),
-    create_info(create_info_arg),
-    alter_info(alter_info_arg)
-  {}
+    create_info(create_info_par), select_tables(select_tables_arg)
+    {}
   int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
 
   void binlog_show_create_table(TABLE **tables, uint count);

--- 1.274/sql/sql_insert.cc	2007-06-12 22:15:06 +02:00
+++ 1.275/sql/sql_insert.cc	2007-06-12 22:15:06 +02:00
@@ -3341,8 +3341,15 @@
   table->reginfo.lock_type=TL_WRITE;
   hooks->prelock(&table, 1);                    // Call prelock hooks
   if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
-                                    MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
+                                    MYSQL_LOCK_IGNORE_FLUSH, &not_used)) ||
+        hooks->postlock(&table, 1))
   {
+    if (*lock)
+    {
+      mysql_unlock_tables(thd, *lock);
+      *lock= 0;
+    }
+
     if (!create_info->table_existed)
       drop_open_table(thd, table, create_table->db, create_table->table_name);
     DBUG_RETURN(0);
@@ -3377,24 +3384,35 @@
    */
   class MY_HOOKS : public TABLEOP_HOOKS {
   public:
-    MY_HOOKS(select_create *x) : ptr(x) { }
+    MY_HOOKS(select_create *x, TABLE_LIST *create_table,
+             TABLE_LIST *select_tables)
+      : ptr(x), all_tables(*create_table)
+      {
+        all_tables.next_global= select_tables;
+      }
 
   private:
-    virtual void do_prelock(TABLE **tables, uint count)
+    virtual int do_postlock(TABLE **tables, uint count)
     {
+      THD *thd= const_cast<THD*>(ptr->get_thd());
+      if (int error= decide_logging_format(thd, &all_tables))
+        return error;
+
       TABLE const *const table = *tables;
-      if (ptr->get_thd()->current_stmt_binlog_row_based  &&
+      if (thd->current_stmt_binlog_row_based  &&
           !table->s->tmp_table &&
           !ptr->get_create_info()->table_existed)
       {
         ptr->binlog_show_create_table(tables, count);
       }
+      return 0;
     }
 
     select_create *ptr;
+    TABLE_LIST all_tables;
   };
 
-  MY_HOOKS hooks(this);
+  MY_HOOKS hooks(this, create_table, select_tables);
   hook_ptr= &hooks;
 
   unit= u;

--- 1.677/sql/sql_parse.cc	2007-06-12 22:15:06 +02:00
+++ 1.678/sql/sql_parse.cc	2007-06-12 22:15:06 +02:00
@@ -2228,7 +2228,8 @@
                                        &alter_info,
                                        select_lex->item_list,
                                        lex->duplicates,
-                                       lex->ignore)))
+                                       lex->ignore,
+                                       select_tables)))
         {
           /*
             CREATE from SELECT give its SELECT_LEX for SELECT,

--- 1.157/sql/share/errmsg.txt	2007-06-12 22:15:06 +02:00
+++ 1.158/sql/share/errmsg.txt	2007-06-12 22:15:06 +02:00
@@ -6072,3 +6072,5 @@
         eng "Failed to create %s"
 ER_SLAVE_MASTER_COM_FAILURE
         eng "Master command %s failed: %s"
+ER_BINLOG_LOGGING_IMPOSSIBLE
+        eng "Binary logging not possible. Message: %s"

--- 1.64/storage/archive/ha_archive.h	2007-06-12 22:15:06 +02:00
+++ 1.65/storage/archive/ha_archive.h	2007-06-12 22:15:06 +02:00
@@ -87,6 +87,7 @@
   ulonglong table_flags() const
   {
     return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD |
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
             HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY);
   }
   ulong index_flags(uint idx, uint part, bool all_parts) const

--- 1.29/storage/csv/ha_tina.h	2007-06-12 22:15:06 +02:00
+++ 1.30/storage/csv/ha_tina.h	2007-06-12 22:15:06 +02:00
@@ -99,7 +99,8 @@
   const char **bas_ext() const;
   ulonglong table_flags() const
   {
-    return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT);
+    return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
   }
   ulong index_flags(uint idx, uint part, bool all_parts) const
   {

--- 1.23/storage/example/ha_example.h	2007-06-12 22:15:06 +02:00
+++ 1.24/storage/example/ha_example.h	2007-06-12 22:15:06 +02:00
@@ -82,7 +82,12 @@
   */
   ulonglong table_flags() const
   {
-    return 0;
+    /*
+      We are saying that this engine is just row capable to have an
+      engine that can only handle row-based logging. This is used in
+      testing.
+    */
+    return HA_BINLOG_ROW_CAPABLE;
   }
 
   /** @brief

--- 1.17/storage/blackhole/ha_blackhole.h	2007-06-12 22:15:06 +02:00
+++ 1.18/storage/blackhole/ha_blackhole.h	2007-06-12 22:15:06 +02:00
@@ -53,6 +53,7 @@
   ulonglong table_flags() const
   {
     return(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
+           HA_BINLOG_STMT_CAPABLE |
            HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
            HA_FILE_BASED | HA_CAN_GEOMETRY | HA_CAN_INSERT_DELAYED);
   }

--- 1.456/sql/ha_ndbcluster.cc	2007-06-12 22:15:06 +02:00
+++ 1.457/sql/ha_ndbcluster.cc	2007-06-12 22:15:06 +02:00
@@ -4488,7 +4488,6 @@
       DBUG_PRINT("warning", ("ops_pending != 0L"));
     m_ops_pending= 0;
   }
-  thd->set_current_stmt_binlog_row_based_if_mixed();
   DBUG_RETURN(error);
 }
 
@@ -4538,7 +4537,6 @@
   m_active_trans= trans;
   // Start of statement
   m_ops_pending= 0;    
-  thd->set_current_stmt_binlog_row_based_if_mixed();
 
   DBUG_RETURN(error);
 }
@@ -6099,6 +6097,7 @@
                 HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | \
                 HA_PARTIAL_COLUMN_READ | \
                 HA_HAS_OWN_BINLOGGING | \
+                HA_BINLOG_ROW_CAPABLE | \
                 HA_HAS_RECORDS
 
 ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
@@ -8906,7 +8905,6 @@
   my_net_init(&thd->net, 0);
   thd->main_security_ctx.master_access= ~0;
   thd->main_security_ctx.priv_user = 0;
-  thd->current_stmt_binlog_row_based= TRUE;     // If in mixed mode
 
   /* Signal successful initialization */
   ndb_util_thread_running= 1;

--- 1.339/storage/innobase/handler/ha_innodb.cc	2007-06-12 22:15:07 +02:00
+++ 1.340/storage/innobase/handler/ha_innodb.cc	2007-06-12 22:15:07 +02:00
@@ -958,6 +958,7 @@
 		  HA_CAN_SQL_HANDLER |
 		  HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
 		  HA_PRIMARY_KEY_IN_READ_INDEX |
+                  HA_BINLOG_ROW_CAPABLE |
 		  HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
 		  HA_TABLE_SCAN_ON_INDEX),
   start_of_scan(0),
@@ -2266,6 +2267,45 @@
 	}
 	ut_ad(0);
 	return(ROW_TYPE_NOT_USED);
+}
+
+
+
+/********************************************************************
+Get the table flags to use for the statement. */
+handler::Table_flags
+ha_innobase::table_flags() const
+{
+	THD *const thd= current_thd;
+        /* We are using thd->variables.tx_isolation here instead of
+           trx->isolation_level since store_lock() has not been called
+           yet.
+
+           The trx->isolation_level is set inside store_lock() (which
+           is called from mysql_lock_tables()) until after this
+           function has been called (which is called in lock_tables()
+           before that function calls mysql_lock_tables()). */
+        ulong const tx_isolation= thd->variables.tx_isolation;
+        if (tx_isolation <= ISO_READ_COMMITTED)
+        {
+	        ulong const binlog_format= thd->variables.binlog_format;
+                /* Statement based binlogging does not work in these
+                   isolation levels since the necessary locks cannot
+                   be taken */
+        	if (binlog_format == BINLOG_FORMAT_STMT)
+          	{
+			char buf[256];
+	                my_snprintf(buf, sizeof(buf),
+                                    "Transaction level '%s' in InnoDB is"
+                                    " not safe for binlog mode '%s'",
+                                    tx_isolation_names[tx_isolation],
+                                    binlog_format_names[binlog_format]);
+                        my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf);
+                }
+                return int_table_flags;
+        }
+
+        return int_table_flags | HA_BINLOG_STMT_CAPABLE;
 }
 
 /********************************************************************

--- 1.140/storage/innobase/handler/ha_innodb.h	2007-06-12 22:15:07 +02:00
+++ 1.141/storage/innobase/handler/ha_innodb.h	2007-06-12 22:15:07 +02:00
@@ -54,7 +54,7 @@
 	ulong		upd_and_key_val_buff_len;
 					/* the length of each of the previous
 					two buffers */
-	ulong		int_table_flags;
+	Table_flags	int_table_flags;
 	uint		primary_key;
 	ulong		start_of_scan;	/* this is set to 1 when we are
 					starting a table scan but have not
@@ -84,7 +84,7 @@
 	const char* table_type() const { return("InnoDB");}
 	const char *index_type(uint key_number) { return "BTREE"; }
 	const char** bas_ext() const;
-	ulonglong table_flags() const { return int_table_flags; }
+	Table_flags table_flags() const;
 	ulong index_flags(uint idx, uint part, bool all_parts) const
 	{
 	  return (HA_READ_NEXT |

--- 1.238/sql/set_var.cc	2007-06-12 22:15:07 +02:00
+++ 1.239/sql/set_var.cc	2007-06-12 22:15:07 +02:00
@@ -1011,17 +1011,6 @@
     my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
     return 1;    
   }
-#ifdef HAVE_NDB_BINLOG
-  /*
-    Cluster does not support changing the binlog format on the fly yet.
-  */
-  LEX_STRING ndb_name= {(char*)STRING_WITH_LEN("ndbcluster")};
-  if (opt_bin_log && plugin_is_ready(&ndb_name, MYSQL_STORAGE_ENGINE_PLUGIN))
-  {
-    my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0));
-    return 1;
-  }
-#endif /* HAVE_NDB_BINLOG */
   return sys_var_thd_enum::is_readonly();
 }
 

--- 1.46/storage/federated/ha_federated.h	2007-06-12 22:15:07 +02:00
+++ 1.47/storage/federated/ha_federated.h	2007-06-12 22:15:07 +02:00
@@ -128,6 +128,7 @@
     /* fix server to be able to get remote server table flags */
     return (HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED
             | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS |
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
             HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
             HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
   }
Thread
bk commit into 5.1 tree (mats:1.2552)Mats Kindahl12 Jun