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#13191 | gshchepa | 26 Apr |