| Bug #9339 | Updating a column does not work if the table has a UTF-8 VARCHAR primary key | ||
|---|---|---|---|
| Submitted: | 22 Mar 2005 15:18 | Modified: | 22 Mar 2005 19:22 |
| Reporter: | Vesa Halttunen | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: MyISAM storage engine | Severity: | S1 (Critical) |
| Version: | mysql-5.0.3-alpha-nightly-20050320 | OS: | Linux (Fedora Core 2 (Linux 2.6.10)) |
| Assigned to: | Sergei Golubchik | CPU Architecture: | Any |
[22 Mar 2005 15:28]
Marko Mäkelä
This may be related to Bug #9314.
[22 Mar 2005 15:34]
Heikki Tuuri
Vesa, please post your my.cnf. I am not able to repeat this with a day old build. Regards, Heikki
[22 Mar 2005 15:52]
Heikki Tuuri
Vesa, I am able to repeat this bug both for MyISAM and InnoDB if the character set is UTF-8. We will now study this in gdb. Thank you for reporting this critical bug. Regards, Heikki
[22 Mar 2005 15:56]
Vesa Halttunen
I noticed this only happens if the database has been created so that it uses the UTF8 character set. Try doing mysql> create database utf8db character set utf8; Query OK, 1 row affected (0.00 sec) mysql> use utf8db; Database changed before the statements in the original submission. In 5.0.2 these kind of UTF8 databases worked fine. I didn't have /etc/my.cnf at all but using the stock my-medium.cnf provided with the distribution didn't affect this.
[22 Mar 2005 15:57]
Vesa Halttunen
I noticed this only happens if the database has been created so that it uses the UTF8 character set. Try doing mysql> create database utf8db character set utf8; Query OK, 1 row affected (0.00 sec) mysql> use utf8db; Database changed before the statements in the original submission. In 5.0.2 these kind of UTF8 databases worked fine. I didn't have /etc/my.cnf at all but using the stock my-medium.cnf provided with the distribution didn't affect this.
[22 Mar 2005 16:50]
Heikki Tuuri
Hi!
The range lower endpoint that MySQL passes to InnoDB is not very sensible. It is a 3-byte string 'tes'.
InnoDB does retrieve the row ('test', 'something'), and gives the row back to the SQL interpreter. Apparently, the SQL interpreter concludes that the row does not below to the range, and returns 'no matching rows found'.
The bug may be that MySQL calculates the search string length wrong for UTF-8.
Below is some of the execution path stepped inside gdb.
Regards,
Heikki
Breakpoint 2, row_search_for_mysql (
buf=0xa378de8 "þ\004test", '¥' <repeats 44 times>, "\tsomething", '¥' <repea
ts 140 times>..., mode=2, prebuilt=0x43edb668, match_mode=0, direction=0)
at row0sel.c:3033
3033 dict_index_t* index = prebuilt->index;
(gdb) bt
#0 row_search_for_mysql (
buf=0xa378de8 "þ\004test", '¥' <repeats 44 times>, "\tsomething", '¥' <repea
ts 140 times>..., mode=2, prebuilt=0x43edb668, match_mode=0, direction=0)
at row0sel.c:3033
#1 0x08276db1 in ha_innobase::index_read(char*, char const*, unsigned, ha_rkey_
function) (this=0xa378c60,
buf=0xa378de8 "þ\004test", '¥' <repeats 44 times>, "\tsomething", '¥' <repea
ts 140 times>..., key_ptr=0xa39cac8 "\003", key_len=50,
find_flag=HA_READ_KEY_OR_NEXT) at ha_innodb.cc:3402
#2 0x08269e44 in handler::read_range_first(st_key_range const*, st_key_range co
nst*, bool, bool) (this=0xa378c60, start_key=0xa36c878, end_key=0xa36c884,
eq_range_arg=false, sorted=false) at handler.cc:2249
#3 0x08269a90 in handler::read_multi_range_first(st_key_multi_range**, st_key_m
ulti_range*, unsigned, bool, st_handler_buffer*) (this=0xa378c60,
found_range_p=0x88f7d308, ranges=0xa36c878, range_count=1, sorted=false,
buffer=0x0) at handler.cc:2121
#4 0x08258094 in QUICK_RANGE_SELECT::get_next() (this=0xa37f7d8)
at opt_range.cc:6052
#5 0x08261625 in rr_quick (info=0x88f7d49c) at records.cc:157
#6 0x0821711f in mysql_update(THD*, st_table_list*, List<Item>&, List<Item>&, I
tem*, unsigned, st_order*, unsigned long, enum_duplicates, bool) (
thd=0xa37d1c0, table_list=0xa3749d8, fields=@0xa37d44c, values=@0xa37d608,
conds=0xa374d38, order_num=0, order=0x0, limit=4294967295,
handle_duplicates=DUP_ERROR, ignore=false) at sql_update.cc:401
#7 0x081b708d in mysql_execute_command(THD*) (thd=0xa37d1c0)
at sql_parse.cc:3099
#8 0x081bd1cf in mysql_parse(THD*, char*, unsigned) (thd=0xa37d1c0,
inBuf=0xa374948 "update test set othercol='somethingelse' where pkcol = 'tes
t'", length=61) at sql_parse.cc:5170
#9 0x081b30fb in dispatch_command(enum_server_command, THD*, char*, unsigned)
(command=COM_QUERY, thd=0xa37d1c0,
packet=0xa3959c1 "update test set othercol='somethingelse' where pkcol = 'te
st'", packet_length=62) at sql_parse.cc:1647
#10 0x081b2941 in do_command(THD*) (thd=0xa37d1c0) at sql_parse.cc:1453
#11 0x081b1ad0 in handle_one_connection (arg=0xa37d1c0) at sql_parse.cc:1110
#12 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0
#13 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0
#14 0x401f5327 in clone () from /lib/i686/libc.so.6
(gdb) frame 1
#1 0x08276db1 in ha_innobase::index_read(char*, char const*, unsigned, ha_rkey_
function) (this=0xa378c60,
buf=0xa378de8 "þ\004test", '¥' <repeats 44 times>, "\tsomething", '¥' <repea
ts 140 times>..., key_ptr=0xa39cac8 "\003", key_len=50,
find_flag=HA_READ_KEY_OR_NEXT) at ha_innodb.cc:3402
3402 ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mo
de, 0);
Current language: auto; currently c++
(gdb) x/50b key_ptr
0xa39cac8: 0x03 0x00 0x74 0x65 0x73 0x00 0x00 0x00
0xa39cad0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xa39cad8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xa39cae0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xa39cae8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xa39caf0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xa39caf8: 0x00 0x00
(gdb) next
3034 dtuple_t* search_tuple = prebuilt->search_tuple;
Current language: auto; currently c
(gdb)
3035 btr_pcur_t* pcur = prebuilt->pcur;
(gdb)
3036 trx_t* trx = prebuilt->trx;
(gdb)
3043 ulint err = DB_SUCCESS;
(gdb)
3048 ibool unique_search = FALSE;
(gdb)
3049 ibool unique_search_from_clust_index = FALSE;
(gdb)
3050 ibool mtr_has_extra_clust_latch = FALSE;
(gdb)
3051 ibool moves_up = FALSE;
(gdb)
3052 ibool set_also_gap_locks = TRUE;
(gdb)
3059 ulint cnt = 0;
(gdb)
3062 mem_heap_t* heap = NULL;
(gdb)
3064 ulint* offsets = offsets_;
(gdb)
3065 *offsets_ = (sizeof offsets_) / sizeof *offsets_;
(gdb)
3070 if (prebuilt->table->ibd_file_missing) {
(gdb)
3084 if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
(gdb)
3097 if (trx->n_mysql_tables_in_use == 0
(gdb)
3121 if (trx->has_search_latch
(gdb)
3138 if (direction == 0) {
(gdb)
3139 trx->op_info = "starting index read";
(gdb)
3141 prebuilt->n_rows_fetched = 0;
(gdb)
3142 prebuilt->n_fetch_cached = 0;
(gdb)
3143 prebuilt->fetch_cache_first = 0;
(gdb)
3145 if (prebuilt->sel_graph == NULL) {
(gdb)
3147 row_prebuild_sel_graph(prebuilt);
(gdb)
3209 if (match_mode == ROW_SEL_EXACT
(gdb)
3236 mtr_start(&mtr);
(gdb)
3247 if (unique_search
(gdb)
3349 if (trx->has_search_latch) {
(gdb)
3354 trx_start_if_not_started(trx);
(gdb)
3356 if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
(gdb)
3377 if (direction == 0) {
(gdb)
3378 if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) {
(gdb)
3379 moves_up = TRUE;
(gdb)
3385 thr = que_fork_get_first_thr(prebuilt->sel_graph);
(gdb)
3387 que_thr_move_to_run_state_for_mysql(thr, trx);
(gdb)
3389 clust_index = dict_table_get_first_index(index->table);
(gdb)
3391 if (direction != 0) {
(gdb)
3398 } else if (dtuple_get_n_fields(search_tuple) > 0) {
(gdb)
3400 btr_pcur_open_with_no_init(index, search_tuple, mode,
(gdb)
3413 if (!prebuilt->sql_stat_start) {
(gdb)
3426 } else if (prebuilt->select_lock_type == LOCK_NONE) {
(gdb)
3433 if (prebuilt->select_lock_type == LOCK_S) {
(gdb)
3436 err = lock_table(0, index->table, LOCK_IX, thr);
(gdb)
3439 if (err != DB_SUCCESS) {
(gdb)
3443 prebuilt->sql_stat_start = FALSE;
(gdb)
3450 rec = btr_pcur_get_rec(pcur);
(gdb)
3451 comp = index->table->comp;
(gdb)
3460 if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
(gdb)
3469 if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
(gdb)
3503 next_offs = rec_get_next_offs(rec, comp);
(gdb)
3505 if (next_offs >= UNIV_PAGE_SIZE
(gdb)
3552 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED,
&heap);
(gdb)
3554 if (srv_force_recovery > 0) {
(gdb)
3578 if (match_mode == ROW_SEL_EXACT) {
(gdb)
3616 } else if (match_mode == ROW_SEL_EXACT_PREFIX) {
(gdb)
3654 cons_read_requires_clust_rec = FALSE;
(gdb)
3656 if (prebuilt->select_lock_type != LOCK_NONE) {
(gdb)
3664 if (!set_also_gap_locks
(gdb)
3672 if (srv_locks_unsafe_for_binlog) {
(gdb)
3675 lock_type = LOCK_ORDINARY;
(gdb)
3679 err = sel_set_rec_lock(rec, index, offsets,
(gdb)
3683 if (err != DB_SUCCESS) {
(gdb)
3739 if (rec_get_deleted_flag(rec, comp)
(gdb)
3752 index_rec = rec;
(gdb)
3760 if (index != clust_index && (cons_read_requires_clust_rec
(gdb)
3804 if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD
(gdb)
3830 if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)
{
(gdb)
3836 if (!row_sel_store_mysql_rec(buf, prebuilt,
(gdb)
3844 if (prebuilt->clust_index_was_generated) {
(gdb)
3862 if (!unique_search_from_clust_index
(gdb)
3868 btr_pcur_store_position(pcur, &mtr);
(gdb)
3871 err = DB_SUCCESS;
(gdb)
3873 goto normal_return;
(gdb)
3957 que_thr_stop_for_mysql_no_error(thr, trx);
(gdb)
3959 mtr_commit(&mtr);
(gdb)
3961 if (prebuilt->n_fetch_cached > 0) {
(gdb)
3970 if (err == DB_SUCCESS) {
(gdb)
3971 srv_n_rows_read++;
(gdb)
3975 trx->op_info = "";
(gdb)
3976 if (heap) {
(gdb)
3979 return(err);
(gdb)
3980 }
(gdb)
ha_innobase::index_read(char*, char const*, unsigned, ha_rkey_function) (
this=0xa378c60,
buf=0xa378de8 "þ\004test", ' ' <repeats 44 times>, "\tsomething", ' ' <repea
ts 39 times>, '¥' <repeats 101 times>..., key_ptr=0xa39cac8 "\003",
key_len=50, find_flag=HA_READ_KEY_OR_NEXT) at ha_innodb.cc:3404
3404 innodb_srv_conc_exit_innodb(prebuilt->trx);
Current language: auto; currently c++
(gdb)
3406 if (ret == DB_SUCCESS) {
(gdb)
3407 error = 0;
(gdb)
3408 table->status = 0;
(gdb) x/110b buf
0xa378de8: 0xfe 0x04 0x74 0x65 0x73 0x74 0x20 0x20
0xa378df0: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378df8: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e00: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e08: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e10: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e18: 0x20 0x20 0x09 0x73 0x6f 0x6d 0x65 0x74
0xa378e20: 0x68 0x69 0x6e 0x67 0x20 0x20 0x20 0x20
0xa378e28: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e30: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e38: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e40: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0xa378e48: 0x20 0x20 0x20 0xa5 0xa5 0xa5 0xa5 0xa5
0xa378e50: 0xa5 0xa5 0xa5 0xa5 0xa5 0xa5
(gdb) next
3422 DBUG_RETURN(error);
(gdb)
3423 }
(gdb)
handler::read_range_first(st_key_range const*, st_key_range const*, bool, bool)
(this=0xa378c60, start_key=0xa36c878, end_key=0xa36c884,
eq_range_arg=false, sorted=false) at handler.cc:2253
2253 if (result)
(gdb)
2258 DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
(gdb) step
_db_return_ (_line_=2258, _sfunc_=0x88f7d244, _sfile_=0x88f7d240,
_slevel_=0x88f7d23c) at dbug.c:800
800 if (!_no_db_)
Current language: auto; currently c
(gdb)
845 }
(gdb)
handler::compare_key(st_key_range*) (this=0xa378c60, range=0xa378ccc)
at handler.cc:2317
2317 if (!range)
Current language: auto; currently c++
(gdb)
2319 cmp= key_cmp(range_key_part, range->key, range->length);
(gdb)
key_cmp(st_key_part_info*, char const*, unsigned) (key_part=0xa378c34,
key=0xa39cb00 "0", key_length=50) at key.cc:408
408 for (const byte *end=key + key_length;
(gdb)
413 store_length= key_part->store_length;
(gdb)
414 if (key_part->null_bit)
(gdb)
431 if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) <
0)
(gdb)
Field_varstring::key_cmp(char const*, unsigned) (this=0xa378ef8,
key_ptr=0xa39cb00 "0", max_key_length=48) at field.cc:5458
5458 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr)
;
(gdb)
5459 uint char_length= max_key_length / field_charset->mbmaxlen;
(gdb)
5461 char_length= my_charpos(field_charset, ptr + length_bytes,
(gdb)
my_charpos_mb (cs=0x8602320,
pos=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39
times>, '¥' <repeats 103 times>...,
end=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>..., length=16) at ctype-mb.c:255
255 const char *start= pos;
Current language: auto; currently c
(gdb)
257 while (length && pos < end)
(gdb)
260 pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2287
2287 int res=my_utf8_uni(cs,&wc, (const uchar*)b, (const uchar*)e);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d140,
s=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2288
2288 return (res>1) ? res : 0;
(gdb)
2289 }
(gdb)
my_charpos_mb (cs=0x8602320,
pos=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39
times>, '¥' <repeats 104 times>...,
end=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>..., length=16) at ctype-mb.c:261
261 length--;
(gdb)
257 while (length && pos < end)
(gdb)
260 pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2287
2287 int res=my_utf8_uni(cs,&wc, (const uchar*)b, (const uchar*)e);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d140,
s=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2288
2288 return (res>1) ? res : 0;
(gdb)
2289 }
(gdb)
my_charpos_mb (cs=0x8602320,
pos=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 105 times>...,
end=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>..., length=15) at ctype-mb.c:261
261 length--;
(gdb)
257 while (length && pos < end)
(gdb)
260 pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2287
2287 int res=my_utf8_uni(cs,&wc, (const uchar*)b, (const uchar*)e);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d140,
s=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2288
2288 return (res>1) ? res : 0;
(gdb)
2289 }
(gdb)
my_charpos_mb (cs=0x8602320,
pos=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 106 times>...,
end=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>..., length=14) at ctype-mb.c:261
261 length--;
(gdb)
257 while (length && pos < end)
(gdb)
260 pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2287
2287 int res=my_utf8_uni(cs,&wc, (const uchar*)b, (const uchar*)e);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d140,
s=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_ismbchar_utf8 (cs=0x8602320,
b=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:2288
2288 return (res>1) ? res : 0;
(gdb)
2289 }
(gdb)
my_charpos_mb (cs=0x8602320,
pos=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>...,
end=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>,
'¥' <repeats 107 times>..., length=13) at ctype-mb.c:261
261 length--;
(gdb)
257 while (length && pos < end)
(gdb)
263 return length ? end+2-start : pos-start;
(gdb)
264 }
(gdb)
Field_varstring::key_cmp(char const*, unsigned) (this=0xa378ef8,
key_ptr=0xa39cb00 "0", max_key_length=48) at field.cc:5463
5463 set_if_smaller(length, char_length);
Current language: auto; currently c++
(gdb)
5464 return field_charset->coll->strnncollsp(field_charset,
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>..., slen=4,
t=0xa39cb02 "tes", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2059
2059 const uchar *se= s+slen, *te= t+tlen;
Current language: auto; currently c
(gdb)
2062 diff_if_only_endspace_difference= 0;
(gdb)
2065 while ( s < se && t < te )
(gdb)
2068 s_res=my_utf8_uni(cs,&s_wc, s, se);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d160,
s=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>..., slen=4,
t=0xa39cb02 "tes", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2069
2069 t_res=my_utf8_uni(cs,&t_wc, t, te);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d15c,
s=0xa39cb02 "tes", ' ' <repeats 45 times>, "Z¥¥¥¥¥", e=0xa39cb32 "Z¥¥¥¥¥")
at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378dea "test", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 t
imes>, '¥' <repeats 103 times>..., slen=4,
t=0xa39cb02 "tes", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2071
2071 if ( s_res <= 0 || t_res <= 0 )
(gdb)
2077 plane=(s_wc>>8) & 0xFF;
(gdb)
2078 s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
(gdb)
2079 plane=(t_wc>>8) & 0xFF;
(gdb)
2080 t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
(gdb)
2081 if ( s_wc != t_wc )
(gdb)
2086 s+=s_res;
(gdb)
2087 t+=t_res;
(gdb)
2065 while ( s < se && t < te )
(gdb)
2068 s_res=my_utf8_uni(cs,&s_wc, s, se);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d160,
s=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>..., slen=4,
t=0xa39cb03 "es", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2069
2069 t_res=my_utf8_uni(cs,&t_wc, t, te);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d15c,
s=0xa39cb03 "es", ' ' <repeats 45 times>, "Z¥¥¥¥¥", e=0xa39cb32 "Z¥¥¥¥¥")
at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378deb "est", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 ti
mes>, '¥' <repeats 104 times>..., slen=4,
t=0xa39cb03 "es", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2071
2071 if ( s_res <= 0 || t_res <= 0 )
(gdb)
2077 plane=(s_wc>>8) & 0xFF;
(gdb)
2078 s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
(gdb)
2079 plane=(t_wc>>8) & 0xFF;
(gdb)
2080 t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
(gdb)
2081 if ( s_wc != t_wc )
(gdb)
2086 s+=s_res;
(gdb)
2087 t+=t_res;
(gdb)
2065 while ( s < se && t < te )
(gdb)
2068 s_res=my_utf8_uni(cs,&s_wc, s, se);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d160,
s=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>..., slen=4,
t=0xa39cb04 "s", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2069
2069 t_res=my_utf8_uni(cs,&t_wc, t, te);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d15c,
s=0xa39cb04 "s", ' ' <repeats 45 times>, "Z¥¥¥¥¥", e=0xa39cb32 "Z¥¥¥¥¥")
at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378dec "st", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 tim
es>, '¥' <repeats 105 times>..., slen=4,
t=0xa39cb04 "s", ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2071
2071 if ( s_res <= 0 || t_res <= 0 )
(gdb)
2077 plane=(s_wc>>8) & 0xFF;
(gdb)
2078 s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
(gdb)
2079 plane=(t_wc>>8) & 0xFF;
(gdb)
2080 t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
(gdb)
2081 if ( s_wc != t_wc )
(gdb)
2086 s+=s_res;
(gdb)
2087 t+=t_res;
(gdb)
2065 while ( s < se && t < te )
(gdb)
2068 s_res=my_utf8_uni(cs,&s_wc, s, se);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d160,
s=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>...,
e=0xa378dee ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 times>, '
¥' <repeats 107 times>...) at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>..., slen=4,
t=0xa39cb05 ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2069
2069 t_res=my_utf8_uni(cs,&t_wc, t, te);
(gdb)
my_utf8_uni (cs=0x8602320, pwc=0x88f7d15c,
s=0xa39cb05 ' ' <repeats 45 times>, "Z¥¥¥¥¥", e=0xa39cb32 "Z¥¥¥¥¥")
at ctype-utf8.c:1765
1765 if (s >= e)
(gdb)
1768 c= s[0];
(gdb)
1769 if (c < 0x80)
(gdb)
1771 *pwc = c;
(gdb)
1772 return 1;
(gdb)
1862 }
(gdb)
my_strnncollsp_utf8 (cs=0x8602320,
s=0xa378ded "t", ' ' <repeats 44 times>, "\tsomething", ' ' <repeats 39 time
s>, '¥' <repeats 106 times>..., slen=4,
t=0xa39cb05 ' ' <repeats 45 times>, "Z¥¥¥¥¥", tlen=48,
diff_if_only_endspace_difference=0 '\0') at ctype-utf8.c:2071
2071 if ( s_res <= 0 || t_res <= 0 )
(gdb)
2077 plane=(s_wc>>8) & 0xFF;
(gdb)
2078 s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
(gdb)
2079 plane=(t_wc>>8) & 0xFF;
(gdb)
2080 t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
(gdb)
2081 if ( s_wc != t_wc )
(gdb)
2083 return ((int) s_wc) - ((int) t_wc);
(gdb)
2124 }
(gdb)
Field_varstring::key_cmp(char const*, unsigned) (this=0xa378ef8,
key_ptr=0xa39cb00 "0", max_key_length=48) at field.cc:5470
5470 }
Current language: auto; currently c++
(gdb)
key_cmp(st_key_part_info*, char const*, unsigned) (key_part=0xa378c34,
key=0xa39cb00 "0", key_length=50) at key.cc:433
433 if (cmp > 0)
(gdb)
434 return 1;
(gdb)
437 }
(gdb)
handler::compare_key(st_key_range*) (this=0xa378c60, range=0xa378ccc)
at handler.cc:2320
2320 if (!cmp)
(gdb)
2322 return cmp;
(gdb)
2323 }
(gdb)
handler::read_range_first(st_key_range const*, st_key_range const*, bool, bool)
(this=0xa378c60, start_key=0xa36c878, end_key=0xa36c884,
eq_range_arg=false, sorted=false) at handler.cc:2259
2259 }
(gdb)
handler::read_multi_range_first(st_key_multi_range**, st_key_multi_range*, unsig
ned, bool, st_handler_buffer*) (this=0xa378c60, found_range_p=0x88f7d308,
ranges=0xa36c878, range_count=1, sorted=false, buffer=0x0)
at handler.cc:2127
2127 if (result != HA_ERR_END_OF_FILE)
(gdb)
2117 for (multi_range_curr= ranges, multi_range_end= ranges + range_count;
(gdb)
2131 *found_range_p= multi_range_curr;
(gdb)
2132 DBUG_PRINT("exit",("result %d", result));
(gdb)
2133 DBUG_RETURN(result);
(gdb)
_db_return_ (_line_=2133, _sfunc_=0x88f7d298, _sfile_=0x88f7d294,
_slevel_=0x88f7d290) at dbug.c:800
800 if (!_no_db_)
Current language: auto; currently c
(gdb)
845 }
(gdb)
handler::read_multi_range_first(st_key_multi_range**, st_key_multi_range*, unsig
ned, bool, st_handler_buffer*) (this=0xa378c60, found_range_p=0x88f7d308,
ranges=0xa36c878, range_count=1, sorted=false, buffer=0x0)
at handler.cc:2134
2134 }
Current language: auto; currently c++
(gdb)
QUICK_RANGE_SELECT::get_next() (this=0xa37f7d8) at opt_range.cc:6054
6054 if (result != HA_ERR_END_OF_FILE)
(gdb)
6059 in_range= FALSE; /* No matching rows; go to next set of ranges. */
(gdb)
6005 for (;;)
(gdb)
6007 if (in_range)
(gdb)
6018 uint count= min(multi_range_length, ranges.elements -
(gdb)
6020 if (count == 0)
(gdb)
6023 in_range= FALSE;
(gdb)
6024 DBUG_RETURN(HA_ERR_END_OF_FILE);
(gdb)
_db_return_ (_line_=6024, _sfunc_=0x88f7d2fc, _sfile_=0x88f7d2f8,
_slevel_=0x88f7d2f4) at dbug.c:800
800 if (!_no_db_)
Current language: auto; currently c
(gdb)
845 }
(gdb)
QUICK_RANGE_SELECT::get_next() (this=0xa37f7d8) at opt_range.cc:6061
6061 }
Current language: auto; currently c++
(gdb)
rr_quick (info=0x88f7d49c) at records.cc:159
159 if (info->thd->killed)
(gdb)
164 if (tmp != HA_ERR_RECORD_DELETED)
(gdb)
166 if (tmp == HA_ERR_END_OF_FILE)
(gdb)
167 tmp= -1;
(gdb)
178 return tmp;
(gdb)
179 }
(gdb)
mysql_update(THD*, st_table_list*, List<Item>&, List<Item>&, Item*, unsigned, st
_order*, unsigned long, enum_duplicates, bool) (thd=0xa37d1c0,
table_list=0xa3749d8, fields=@0xa37d44c, values=@0xa37d608,
conds=0xa374d38, order_num=0, order=0x0, limit=4294967295,
handle_duplicates=DUP_ERROR, ignore=false) at sql_update.cc:456
456 if (thd->killed && !error)
(gdb)
[22 Mar 2005 19:14]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/23297
[22 Mar 2005 19:22]
Sergei Golubchik
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.
If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information
about accessing the source trees is available at
http://www.mysql.com/doc/en/Installing_source_tree.html
Additional info:
Fixed in 5.0.3!

Description: Updating a varchar column using an UPDATE statement with a WHERE column='something' condition does not work if the table has a primary key. If the table does not have a primary key this does not happen - the column gets updated. This has been at least in the nightlies 2005-03-13 and 2005-03-20. I haven't tested earlier versions. MySQL is compiled with GCC 3.3.3 on a FC2 system running Linux 2.6.10. How to repeat: mysql> create table test (pkcol varchar(16), othercol varchar(16), primary key (pkcol)); Query OK, 0 rows affected (0.02 sec) mysql> insert into test values ('test', 'something'); Query OK, 1 row affected (0.00 sec) mysql> update test set othercol='somethingelse' where pkcol='test'; Query OK, 0 rows affected (0.00 sec) Rows matched: 0 Changed: 0 Warnings: 0 mysql> select * from test; +-------+-----------+ | pkcol | othercol | +-------+-----------+ | test | something | +-------+-----------+ 1 row in set (0.00 sec) After the UPDATE the column othercol should contain "somethingelse" instead of "something".