List:Commits« Previous MessageNext Message »
From:<gshchepa Date:April 26 2007 9:24pm
Subject:bk commit into 4.1 tree (gshchepa:1.2637) BUG#13191
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of uchum. When uchum 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-04-27 02:24:11+05:00, gshchepa@stripped +5 -0
  Fixed bug #13191.
  INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: 
  "Can't find record in ..." if we are inserting into
  InnoDB table where unique index of limited key length has
  underlying UTF-8 string field of larger length.
  
  This occurs because INSERT...ON DUPLICATE  uses trivial copying algorithm
  of key parts data for index search ignoring difference between the number
  of key bytes and the number of key characters.

  mysql-test/r/insert_update.result@stripped, 2007-04-27 01:55:01+05:00, gshchepa@stripped +33 -0
    Added test case for bug #13191.

  mysql-test/t/insert_update.test@stripped, 2007-04-27 01:54:43+05:00, gshchepa@stripped +42 -2
    Added test case for bug #13191.

  sql/field.cc@stripped, 2007-04-27 02:12:17+05:00, gshchepa@stripped +9 -0
    Fixed bug #13191.
    INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: 
    "Can't find record in ...".
    This occurs because INSERT...ON DUPLICATE  uses trivial copying algorithm 
    of key parts data for index search.
    Field_string::get_key_image() virtual function overloaded to implement
    multibyte-data-aware copying.

  sql/field.h@stripped, 2007-04-27 02:12:02+05:00, gshchepa@stripped +2 -0
    Fixed bug #13191.
    INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: 
    "Can't find record in ...".
    This occurs because INSERT...ON DUPLICATE  uses trivial copying algorithm 
    of key parts data for index search.
    Field_string::get_key_image() virtual function overloaded to implement
    multibyte-data-aware copying.

  sql/key.cc@stripped, 2007-04-27 02:15:00+05:00, gshchepa@stripped +9 -11
    Fixed bug #13191.
    INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: 
    "Can't find record in ...".
    This occurs because INSERT...ON DUPLICATE  uses trivial copying algorithm 
    of key parts data for index search.
    key_copy() function has been fixed.

# 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:	gshchepa
# Host:	gshchepa.loc
# Root:	/home/uchum/work/bk-trees/mysql-4.1-opt-13191

--- 1.235/sql/field.cc	2007-01-31 09:51:03 +04:00
+++ 1.236/sql/field.cc	2007-04-27 02:12:17 +05:00
@@ -5204,6 +5204,15 @@ uint Field_string::max_packed_col_length
   return (max_length > 255 ? 2 : 1)+max_length;
 }
 
+void Field_string::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+                                 imagetype type_arg)
+{
+  uint bytes = my_charpos(cs, ptr, ptr + field_length,
+                          length / field_charset->mbmaxlen);
+  memcpy(buff, ptr, bytes);
+  if (bytes < length)
+    memset(buff+bytes, 0x20, (length-bytes));
+}
 
 /****************************************************************************
 ** VARCHAR type  (Not available for the end user yet)

--- 1.137/sql/field.h	2007-03-26 15:17:39 +05:00
+++ 1.138/sql/field.h	2007-04-27 02:12:02 +05:00
@@ -947,6 +947,8 @@ public:
   enum_field_types real_type() const { return FIELD_TYPE_STRING; }
   bool has_charset(void) const
   { return charset() == &my_charset_bin ? FALSE : TRUE; }
+  void get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+                     imagetype type_arg);
 };
 
 

--- 1.26/sql/key.cc	2005-03-17 10:57:50 +04:00
+++ 1.27/sql/key.cc	2007-04-27 02:15:00 +05:00
@@ -89,20 +89,18 @@ void key_copy(byte *key,TABLE *table,uin
     }
     if (key_part->key_part_flag & HA_BLOB_PART)
     {
-      char *pos;
-      ulong blob_length=((Field_blob*) key_part->field)->get_length();
-      key_length-=2;
-      ((Field_blob*) key_part->field)->get_ptr(&pos);
-      length=min(key_length,key_part->length);
-      set_if_smaller(blob_length,length);
-      int2store(key,(uint) blob_length);
-      key+=2;					// Skip length info
-      memcpy(key,pos,blob_length);
+      key_length-= HA_KEY_BLOB_LENGTH;
+      length= min(key_length, key_part->length);
+      key_part->field->get_key_image((char *) key, length,
+                                     key_part->field->charset(),
+                                     Field::itRAW);
+      key+= HA_KEY_BLOB_LENGTH;
     }
     else
     {
-      length=min(key_length,key_part->length);
-      memcpy(key,table->record[0]+key_part->offset,(size_t) length);
+      length= min(key_length,key_part->length);
+      key_part->field->get_key_image((char *) key, length,
+                                     key_part->field->charset(), Field::itRAW);
     }
     key+=length;
     key_length-=length;

--- 1.17/mysql-test/r/insert_update.result	2006-09-08 12:24:07 +05:00
+++ 1.18/mysql-test/r/insert_update.result	2007-04-27 01:55:01 +05:00
@@ -219,3 +219,36 @@ SELECT * FROM t1;
 a	b
 45	2
 DROP TABLE t1;
+CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1	cnt
+1a	1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1	cnt
+1a	2
+DROP TABLE t1;
+CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1	cnt
+1a	1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1	cnt
+1a	2
+DROP TABLE t1;
+CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1	cnt
+1a	1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1	cnt
+1a	2
+DROP TABLE t1;

--- 1.18/mysql-test/t/insert_update.test	2006-09-08 12:24:07 +05:00
+++ 1.19/mysql-test/t/insert_update.test	2007-04-27 01:54:43 +05:00
@@ -1,3 +1,5 @@
+-- source include/have_innodb.inc
+
 --disable_warnings
 DROP TABLE IF EXISTS t1;
 --enable_warnings
@@ -119,8 +121,6 @@ DROP TABLE t1;
 # Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
 #
 
-
-# End of 4.1 tests
 CREATE TABLE t1
 (
   a   BIGINT UNSIGNED,
@@ -139,3 +139,43 @@ INSERT INTO t1 VALUES (45, 1) ON DUPLICA
 SELECT * FROM t1;
 
 DROP TABLE t1;
+
+#
+# Bug #13191: INSERT...ON DUPLICATE KEY UPDATE of the key of the
+# limited length larger than length of underlying UTF-8 string field.
+#
+
+CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+# End of 4.1 tests
Thread
bk commit into 4.1 tree (gshchepa:1.2637) BUG#13191gshchepa26 Apr