MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:antony Date:June 19 2007 11:58pm
Subject:bk commit into 5.0 tree (antony:1.2492) BUG#29019
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of antony. When antony 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-19 16:58:27-07:00, antony@stripped +4 -0
  Bug#29019
    "REPLACE/INSERT IGNORE/UPDATE IGNORE doesn't work"
    Federated does not record neccessary HA_EXTRA flags in order to
    support REPLACE/INSERT IGNORE/UPDATE IGNORE.
    Implement ::extra() to capture flags neccessary for functionality.
  New function append_ident() to better escape identifiers.

  mysql-test/r/federated.result@stripped, 2007-06-19 16:58:23-07:00, antony@stripped +24 -0
    Test for bug29019

  mysql-test/t/federated.test@stripped, 2007-06-19 16:58:23-07:00, antony@stripped +26 -0
    Test for bug29019

  sql/ha_federated.cc@stripped, 2007-06-19 16:58:24-07:00, antony@stripped +104 -44
    Bug29019
      "REPLACE/INSERT IGNORE/UPDATE IGNORE doesn't work"
      Federated does not record neccessary HA_EXTRA flags in order to
      support REPLACE/INSERT IGNORE/UPDATE IGNORE.
      Implement ::extra() to capture flags neccessary for functionality.
    New function append_ident() to better escape identifiers.

  sql/ha_federated.h@stripped, 2007-06-19 16:58:24-07:00, antony@stripped +2 -4
    bug29019
      remove a couple of unused defines
      add 2 member values to ha_federated class
        ignore_duplicates and replace_duplicates.
      add 1 member method to ha_federated class
        extra()

# 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:	antony
# Host:	ppcg5.local
# Root:	/private/Network/Servers/anubis.xiphis.org/home/antony/work/p2-bug29019.2

--- 1.40/mysql-test/r/federated.result	2006-11-29 10:56:41 -08:00
+++ 1.41/mysql-test/r/federated.result	2007-06-19 16:58:23 -07:00
@@ -1843,6 +1843,30 @@
 D18DD184D184D0B5D0BAD182D0B8D0B2D0BDD183D18E
 drop table federated.t1;
 drop table federated.t1;
+create table federated.t1 (a int primary key, b varchar(64))
+DEFAULT CHARSET=utf8;
+create table federated.t1 (a int primary key, b varchar(64))
+ENGINE=FEDERATED
+connection='mysql://root@stripped:12002/federated/t1'
+  DEFAULT CHARSET=utf8;
+insert ignore into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
+select * from federated.t1;
+a	b
+1	Larry
+2	Curly
+truncate federated.t1;
+replace into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
+select * from federated.t1;
+a	b
+1	Moe
+2	Curly
+update ignore federated.t1 set a=a+1;
+select * from federated.t1;
+a	b
+1	Moe
+3	Curly
+drop table federated.t1;
+drop table federated.t1;
 DROP TABLE IF EXISTS federated.t1;
 DROP DATABASE IF EXISTS federated;
 DROP TABLE IF EXISTS federated.t1;

--- 1.35/mysql-test/t/federated.test	2006-11-29 10:56:18 -08:00
+++ 1.36/mysql-test/t/federated.test	2007-06-19 16:58:23 -07:00
@@ -1576,4 +1576,30 @@
 drop table federated.t1;
 
 
+#
+# BUG#21019 Federated Engine does not support REPLACE/INSERT IGNORE/UPDATE IGNORE
+#
+connection slave;
+create table federated.t1 (a int primary key, b varchar(64))
+  DEFAULT CHARSET=utf8;
+connection master;
+eval create table federated.t1 (a int primary key, b varchar(64))
+  ENGINE=FEDERATED
+  connection='mysql://root@stripped:$SLAVE_MYPORT/federated/t1'
+  DEFAULT CHARSET=utf8;
+
+insert ignore into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
+select * from federated.t1;
+
+truncate federated.t1;
+replace into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
+select * from federated.t1;
+
+update ignore federated.t1 set a=a+1;
+select * from federated.t1;
+
+drop table federated.t1;
+connection slave;
+drop table federated.t1;
+
 source include/federated_cleanup.inc;

--- 1.75/sql/ha_federated.cc	2007-01-22 04:10:38 -08:00
+++ 1.76/sql/ha_federated.cc	2007-06-19 16:58:24 -07:00
@@ -440,6 +440,52 @@
   return FALSE;
 }
 
+
+/**
+  @brief Append identifiers to the string.
+  @param string The target string.
+  @param name Identifier name
+  @param length Length of identifier name in bytes
+  @param quote_char Quote char to use for quoting identifier.
+  @return FALSE if successful
+  @note This function is based upon the append_identifier() function
+        in sql_show.cc except that quoting always occurs.
+*/
+
+static bool append_ident(String *string, const char *name, uint length,
+                         const char quote_char= '`')
+{
+  bool result;
+  const char *name_end;
+  DBUG_ENTER("append_ident");
+  
+  if (quote_char)
+  {
+    string->reserve(length * 2 + 2);
+    if ((result= string->append(&quote_char, 1, system_charset_info)))
+      goto err;
+
+    for (name_end= name+length; name < name_end; name+= length)
+    {
+      uchar c= *(uchar *) name;
+      if (!(length= my_mbcharlen(system_charset_info, c)))
+        length= 1;
+      if (length == 1 && c == (uchar) quote_char &&
+          (result= string->append(&quote_char, 1, system_charset_info)))
+        goto err;
+      if ((result= string->append(name, length, string->charset())))
+        goto err;
+    }
+    result= string->append(&quote_char, 1, system_charset_info);
+  }
+  else
+    result= string->append(name, length, system_charset_info);
+  
+err:
+  DBUG_RETURN(result);
+}
+
+
 /*
  Check (in create) whether the tables exists, and that it can be connected to
 
@@ -458,7 +504,6 @@
 static int check_foreign_data_source(FEDERATED_SHARE *share,
                                      bool table_create_flag)
 {
-  char escaped_table_name[NAME_LEN*2];
   char query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
   char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
   uint error_code;
@@ -499,7 +544,6 @@
   }
   else
   {
-    int escaped_table_name_length= 0;
     /*
       Since we do not support transactions at this version, we can let the 
       client API silently reconnect. For future versions, we will need more 
@@ -517,14 +561,7 @@
     query.append(FEDERATED_SELECT);
     query.append(FEDERATED_STAR);
     query.append(FEDERATED_FROM);
-    query.append(FEDERATED_BTICK);
-    escaped_table_name_length=
-      escape_string_for_mysql(&my_charset_bin, (char*)escaped_table_name,
-                            sizeof(escaped_table_name),
-                            share->table_name,
-                            share->table_name_length);
-    query.append(escaped_table_name, escaped_table_name_length);
-    query.append(FEDERATED_BTICK);
+    append_ident(&query, share->table_name, share->table_name_length);
     query.append(FEDERATED_WHERE);
     query.append(FEDERATED_FALSE);
 
@@ -784,9 +821,7 @@
 static bool emit_key_part_name(String *to, KEY_PART_INFO *part)
 {
   DBUG_ENTER("emit_key_part_name");
-  if (to->append(FEDERATED_BTICK) ||
-      to->append(part->field->field_name) ||
-      to->append(FEDERATED_BTICK))
+  if (append_ident(to, part->field->field_name, strlen(part->field->field_name)))
     DBUG_RETURN(1);                           // Out of memory
   DBUG_RETURN(0);
 }
@@ -1309,31 +1344,26 @@
     query.append(FEDERATED_SELECT);
     for (field= table->field; *field; field++)
     {
-      query.append(FEDERATED_BTICK);
-      query.append((*field)->field_name);
-      query.append(FEDERATED_BTICK);
+      append_ident(&query, (*field)->field_name, strlen((*field)->field_name));
       query.append(FEDERATED_COMMA);
     }
     query.length(query.length()- strlen(FEDERATED_COMMA));
     query.append(FEDERATED_FROM);
-    query.append(FEDERATED_BTICK);
+
+    tmp_share.table_name_length= strlen(tmp_share.table_name);
+    append_ident(&query, tmp_share.table_name, tmp_share.table_name_length);
 
     if (!(share= (FEDERATED_SHARE *)
           my_multi_malloc(MYF(MY_WME),
                           &share, sizeof(*share),
-                          &select_query,
-                          query.length()+table->s->connect_string.length+1,
+                          &select_query, query.length()+1,
                           NullS)))
       goto error;
 
     memcpy(share, &tmp_share, sizeof(tmp_share));
+    memcpy(select_query, query.ptr(), query.length()+1);
 
-    share->table_name_length= strlen(share->table_name);
-    /* TODO: share->table_name to LEX_STRING object */
-    query.append(share->table_name, share->table_name_length);
-    query.append(FEDERATED_BTICK);
     share->select_query= select_query;
-    strmov(share->select_query, query.ptr());
     share->use_count= 0;
     DBUG_PRINT("info",
                ("share->select_query %s", share->select_query));
@@ -1467,6 +1497,8 @@
                table->s->reclength);
   DBUG_PRINT("info", ("ref_length: %u", ref_length));
 
+  reset();
+
   DBUG_RETURN(0);
 }
 
@@ -1579,10 +1611,13 @@
   /*
     start both our field and field values strings
   */
-  insert_string.append(FEDERATED_INSERT);
-  insert_string.append(FEDERATED_BTICK);
-  insert_string.append(share->table_name, share->table_name_length);
-  insert_string.append(FEDERATED_BTICK);
+  if (replace_duplicates)
+    insert_string.append(STRING_WITH_LEN("REPLACE INTO "));
+  else if (ignore_duplicates)
+    insert_string.append(STRING_WITH_LEN("INSERT IGNORE INTO "));
+  else
+    insert_string.append(STRING_WITH_LEN("INSERT INTO "));
+  append_ident(&insert_string, share->table_name, share->table_name_length);
   insert_string.append(FEDERATED_OPENPAREN);
 
   values_string.append(FEDERATED_VALUES);
@@ -1688,9 +1723,7 @@
 
   query.set_charset(system_charset_info);
   query.append(FEDERATED_OPTIMIZE);
-  query.append(FEDERATED_BTICK);
-  query.append(share->table_name, share->table_name_length);
-  query.append(FEDERATED_BTICK);
+  append_ident(&query, share->table_name, share->table_name_length);
 
   if (mysql_real_query(mysql, query.ptr(), query.length()))
   {
@@ -1711,9 +1744,7 @@
 
   query.set_charset(system_charset_info);
   query.append(FEDERATED_REPAIR);
-  query.append(FEDERATED_BTICK);
-  query.append(share->table_name, share->table_name_length);
-  query.append(FEDERATED_BTICK);
+  append_ident(&query, share->table_name, share->table_name_length);
   if (check_opt->flags & T_QUICK)
     query.append(FEDERATED_QUICK);
   if (check_opt->flags & T_EXTEND)
@@ -1788,10 +1819,11 @@
   update_string.length(0);
   where_string.length(0);
 
-  update_string.append(FEDERATED_UPDATE);
-  update_string.append(FEDERATED_BTICK);
-  update_string.append(share->table_name);
-  update_string.append(FEDERATED_BTICK);
+  if (ignore_duplicates)
+    update_string.append(STRING_WITH_LEN("UPDATE IGNORE "));
+  else
+    update_string.append(STRING_WITH_LEN("UPDATE "));
+  append_ident(&update_string, share->table_name, share->table_name_length);
   update_string.append(FEDERATED_SET);
 
 /*
@@ -1888,9 +1920,7 @@
   delete_string.length(0);
   delete_string.append(FEDERATED_DELETE);
   delete_string.append(FEDERATED_FROM);
-  delete_string.append(FEDERATED_BTICK);
-  delete_string.append(share->table_name);
-  delete_string.append(FEDERATED_BTICK);
+  append_ident(&delete_string, share->table_name, share->table_name_length);
   delete_string.append(FEDERATED_WHERE);
 
   for (Field **field= table->field; *field; field++)
@@ -2484,6 +2514,38 @@
 }
 
 
+/**
+  @brief Handles extra signals from MySQL server
+  @param operation Signal
+ */
+int ha_federated::extra(ha_extra_function operation)
+{
+  DBUG_ENTER("ha_federated::extra");
+  switch (operation) {
+  case HA_EXTRA_IGNORE_DUP_KEY:
+    ignore_duplicates= TRUE;
+    break;
+  case HA_EXTRA_NO_IGNORE_DUP_KEY:
+    ignore_duplicates= FALSE;
+    break;
+  case HA_EXTRA_WRITE_CAN_REPLACE:
+    replace_duplicates= TRUE;
+    break;
+  case HA_EXTRA_WRITE_CANNOT_REPLACE:
+    replace_duplicates= FALSE;
+    break;
+  case HA_EXTRA_RESET:
+    ignore_duplicates= FALSE;
+    replace_duplicates= FALSE;
+    break;
+  default:
+    /* do nothing */
+    DBUG_PRINT("info",("unhandled operation: %d", (uint) operation));
+  }
+  DBUG_RETURN(0);
+}
+
+
 /*
   Used to delete all rows in a table. Both for cases of truncate and
   for cases where the optimizer realizes that all rows will be
@@ -2506,9 +2568,7 @@
 
   query.set_charset(system_charset_info);
   query.append(FEDERATED_TRUNCATE);
-  query.append(FEDERATED_BTICK);
-  query.append(share->table_name);
-  query.append(FEDERATED_BTICK);
+  append_ident(&query, share->table_name, share->table_name_length);
 
   /*
     TRUNCATE won't return anything in mysql_affected_rows

--- 1.30/sql/ha_federated.h	2006-12-23 11:04:24 -08:00
+++ 1.31/sql/ha_federated.h	2007-06-19 16:58:24 -07:00
@@ -59,8 +59,6 @@
 #define FEDERATED_TRUNCATE_LEN sizeof(FEDERATED_TRUNCATE)
 #define FEDERATED_DELETE "DELETE "
 #define FEDERATED_DELETE_LEN sizeof(FEDERATED_DELETE)
-#define FEDERATED_INSERT "INSERT INTO "
-#define FEDERATED_INSERT_LEN sizeof(FEDERATED_INSERT)
 #define FEDERATED_OPTIMIZE "OPTIMIZE TABLE "
 #define FEDERATED_OPTIMIZE_LEN sizeof(FEDERATED_OPTIMIZE)
 #define FEDERATED_REPAIR "REPAIR TABLE "
@@ -75,8 +73,6 @@
 #define FEDERATED_LIMIT1_LEN sizeof(FEDERATED_LIMIT1)
 #define FEDERATED_VALUES "VALUES "
 #define FEDERATED_VALUES_LEN sizeof(FEDERATED_VALUES)
-#define FEDERATED_UPDATE "UPDATE "
-#define FEDERATED_UPDATE_LEN sizeof(FEDERATED_UPDATE)
 #define FEDERATED_SET " SET "
 #define FEDERATED_SET_LEN sizeof(FEDERATED_SET)
 #define FEDERATED_AND " AND "
@@ -157,6 +153,7 @@
   MYSQL_ROW_OFFSET current_position;  // Current position used by ::position()
   int remote_error_number;
   char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE];
+  bool ignore_duplicates, replace_duplicates;
 
 private:
   /*
@@ -284,6 +281,7 @@
   int rnd_pos(byte *buf, byte *pos);                            //required
   void position(const byte *record);                            //required
   int info(uint);                                              //required
+  int extra(ha_extra_function operation);
 
   void update_auto_increment(void);
   int repair(THD* thd, HA_CHECK_OPT* check_opt);
Thread
bk commit into 5.0 tree (antony:1.2492) BUG#29019antony20 Jun
  • Re: bk commit into 5.0 tree (antony:1.2492) BUG#29019Ingo Strüwing23 Jun
    • Re: bk commit into 5.0 tree (antony:1.2492) BUG#29019Antony T Curtis23 Jun