From 326d2d56fe74c5affdcf7c6459c93c3b1dc37dd1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 25 Jan 2013 12:26:35 +0100 Subject: [PATCH 1/5] MDEV-759 lp:998340 - Valgrind complains on simple selects containing expression DAY(FROM_UNIXTIME(-1)) check item->null_value before using the result of item->val_int() --- mysql-test/r/func_str.result | 18 ++++++++++++++++++ mysql-test/t/func_str.test | 11 +++++++++++ sql/item_strfunc.cc | 20 ++++++++++++++------ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 8f4038e1239..aef452b7b50 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2628,4 +2628,22 @@ SELECT * FROM t1; a aaaaaaaaaaaaaa DROP TABLE t1; +SELECT SUBSTRING('1', DAY(FROM_UNIXTIME(-1))); +SUBSTRING('1', DAY(FROM_UNIXTIME(-1))) +NULL +SELECT LEFT('1', DAY(FROM_UNIXTIME(-1))); +LEFT('1', DAY(FROM_UNIXTIME(-1))) +NULL +SELECT RIGHT('1', DAY(FROM_UNIXTIME(-1))); +RIGHT('1', DAY(FROM_UNIXTIME(-1))) +NULL +SELECT REPEAT('1', DAY(FROM_UNIXTIME(-1))); +REPEAT('1', DAY(FROM_UNIXTIME(-1))) +NULL +SELECT RPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); +RPAD('hi', DAY(FROM_UNIXTIME(-1)),'?') +NULL +SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); +LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?') +NULL End of 5.1 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 92c4bae5327..9909974d3be 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1380,4 +1380,15 @@ LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1; SELECT * FROM t1; DROP TABLE t1; +# +# MDEV-759 lp:998340 - Valgrind complains on simple selects containing expression DAY(FROM_UNIXTIME(-1)) +# +SELECT SUBSTRING('1', DAY(FROM_UNIXTIME(-1))); +SELECT LEFT('1', DAY(FROM_UNIXTIME(-1))); +SELECT RIGHT('1', DAY(FROM_UNIXTIME(-1))); +SELECT REPEAT('1', DAY(FROM_UNIXTIME(-1))); +SELECT RPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); +SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); + + --echo End of 5.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4225687724f..9cc77849094 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1167,7 +1167,7 @@ void Item_str_func::left_right_max_length() if (args[1]->const_item()) { int length=(int) args[1]->val_int()*collation.collation->mbmaxlen; - if (length <= 0) + if (args[1]->null_value || length <= 0) max_length=0; else set_if_smaller(max_length,(uint) length); @@ -1270,7 +1270,9 @@ void Item_func_substr::fix_length_and_dec() if (args[1]->const_item()) { int32 start= (int32) args[1]->val_int(); - if (start < 0) + if (args[1]->null_value) + max_length= 0; + else if (start < 0) max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start); else max_length-= min((uint)(start - 1), max_length); @@ -1278,7 +1280,7 @@ void Item_func_substr::fix_length_and_dec() if (arg_count == 3 && args[2]->const_item()) { int32 length= (int32) args[2]->val_int(); - if (length <= 0) + if (args[2]->null_value || length <= 0) max_length=0; /* purecov: inspected */ else set_if_smaller(max_length,(uint) length); @@ -2411,7 +2413,9 @@ void Item_func_repeat::fix_length_and_dec() /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if (count > INT_MAX32) + if (args[1]->null_value) + count= 0; + else if (count > INT_MAX32) count= INT_MAX32; ulonglong max_result_length= (ulonglong) args[0]->max_length * count; @@ -2499,7 +2503,9 @@ void Item_func_rpad::fix_length_and_dec() /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if (temp > INT_MAX32) + if (args[1]->null_value) + temp= 0; + else if (temp > INT_MAX32) temp = INT_MAX32; length= temp * collation.collation->mbmaxlen; @@ -2616,7 +2622,9 @@ void Item_func_lpad::fix_length_and_dec() /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if (temp > INT_MAX32) + if (args[1]->null_value) + temp= 0; + else if (temp > INT_MAX32) temp= INT_MAX32; length= temp * collation.collation->mbmaxlen; From 7f208d3c356e559d3be15f161df8a0adbfa2dd1c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 25 Jan 2013 14:29:46 +0100 Subject: [PATCH 2/5] MDEV-729 lp:998028 - Server crashes on normal shutdown in closefrm after executing a query from MyISAM table don't write a key value into the record buffer - a key length can be larger then the record length. --- mysql-test/r/group_min_max.result | 7 +++++++ mysql-test/t/group_min_max.test | 8 ++++++++ sql/opt_range.cc | 8 +++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 6fef66b9d93..feb06ac4d7a 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2780,4 +2780,11 @@ ORDER BY min_a; min_a NULL DROP TABLE t1; +create table t1 (a int, b varchar(1), key(b,a)) engine=myisam; +insert t1 values (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(null,'i'); +select min(a), b from t1 where a=7 or b='z' group by b; +min(a) b +7 g +flush tables; +drop table t1; End of 5.1 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 8ab7e1c9cb4..4b5e8e82e54 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -1099,5 +1099,13 @@ ORDER BY min_a; DROP TABLE t1; +# +# MDEV-729 lp:998028 - Server crashes on normal shutdown in closefrm after executing a query from MyISAM table +# +create table t1 (a int, b varchar(1), key(b,a)) engine=myisam; +insert t1 values (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(null,'i'); +select min(a), b from t1 where a=7 or b='z' group by b; +flush tables; +drop table t1; --echo End of 5.1 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index a42a03f4c86..14c2eeddb9f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10815,9 +10815,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() */ if (min_max_arg_part && min_max_arg_part->field->is_null()) { + uchar *tmp_key_buff= (uchar*)my_alloca(index_info->key_length); /* Find the first subsequent record without NULL in the MIN/MAX field. */ - key_copy(tmp_record, record, index_info, 0); - result= file->index_read_map(record, tmp_record, + key_copy(tmp_key_buff, record, index_info, 0); + result= file->index_read_map(record, tmp_key_buff, make_keypart_map(real_key_parts), HA_READ_AFTER_KEY); /* @@ -10833,10 +10834,11 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() if (!result) { if (key_cmp(index_info->key_part, group_prefix, real_prefix_len)) - key_restore(record, tmp_record, index_info, 0); + key_restore(record, tmp_key_buff, index_info, 0); } else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) result= 0; /* There is a result in any case. */ + my_afree(tmp_key_buff); } } From 298008dc4fbf4c5cc98d86115218bf89611ff7ea Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Jan 2013 16:56:57 +0200 Subject: [PATCH 3/5] The problem was that expression with field after transformation (on the first execution) reached by fix_fields() (via reference) before row which it belongs to (on the second execution) and fix_field for row did not follow usual protocol for Items with argument (first check that the item fixed then call fix_fields). Item_row::fix_field fixed. --- mysql-test/r/subselect_sj.result | 15 +++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 15 +++++++++++++++ mysql-test/t/subselect_sj.test | 20 ++++++++++++++++++++ sql/item_row.cc | 3 ++- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index ad2d5f760e8..01ad6f9712f 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2757,4 +2757,19 @@ GROUP BY b HAVING t1sum <> 1; t1sum b DROP TABLE t1, t2; +# +# MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields +# on 2nd execution of PS with semijoin=on and IN subquery +# +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,4),(8,6); +CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7,1),(0,7); +PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) '; +execute stmt; +a b +execute stmt; +a b +deallocate prepare stmt; +drop table t1,t2; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 6247688d635..cf45162284c 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2771,6 +2771,21 @@ GROUP BY b HAVING t1sum <> 1; t1sum b DROP TABLE t1, t2; +# +# MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields +# on 2nd execution of PS with semijoin=on and IN subquery +# +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,4),(8,6); +CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7,1),(0,7); +PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) '; +execute stmt; +a b +execute stmt; +a b +deallocate prepare stmt; +drop table t1,t2; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 2facb089718..650c9d73893 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -2462,5 +2462,25 @@ HAVING t1sum <> 1; DROP TABLE t1, t2; +--echo # +--echo # MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields +--echo # on 2nd execution of PS with semijoin=on and IN subquery +--echo # + +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,4),(8,6); + +CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7,1),(0,7); + +eval PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) '; + +execute stmt; +execute stmt; + +deallocate prepare stmt; +drop table t1,t2; + + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/item_row.cc b/sql/item_row.cc index 72bae6f0900..d9d3e359338 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -68,7 +68,8 @@ bool Item_row::fix_fields(THD *thd, Item **ref) Item **arg, **arg_end; for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) { - if ((*arg)->fix_fields(thd, arg)) + if (!(*arg)->fixed && + (*arg)->fix_fields(thd, arg)) return TRUE; // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; From 0791692bdc311f39181b9df236981a2cb439638e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 26 Jan 2013 22:33:18 +0100 Subject: [PATCH 4/5] MDEV-3875 Wrong result (missing row) on a DISTINCT query with the same subquery in the SELECT list and GROUP BY fix remove_dup_with_hash_index() and remove_dup_with_compare() to take NULLs into account --- mysql-test/r/distinct.result | 32 ++++++++++++ mysql-test/t/distinct.test | 24 +++++++++ sql/field.cc | 15 ++++++ sql/field.h | 1 + sql/filesort.cc | 25 +++------- sql/sql_select.cc | 95 +++++++++++++++--------------------- 6 files changed, 120 insertions(+), 72 deletions(-) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 99d98d2a9bc..dc3b2fb1b47 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -847,3 +847,35 @@ time(f1) 00:00:00.000200 00:00:00.000300 drop table t1; +create table t1(i int, g int); +insert into t1 values (null, 1), (0, 2); +select distinct i from t1 group by g; +i +NULL +0 +drop table t1; +create table t1(i int, g blob); +insert into t1 values (null, 1), (0, 2); +select distinct i from t1 group by g; +i +NULL +0 +drop table t1; +create table t1 (a int) engine=myisam; +insert into t1 values (0),(7); +create table t2 (b int) engine=myisam; +insert into t2 values (7),(0),(3); +create algorithm=temptable view v as +select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1; +select * from v; +field1 +NULL +0 +7 +select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1; +field1 +NULL +0 +7 +drop view v; +drop table t1, t2; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 0f0cbcf26d0..302fb24f18c 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -658,3 +658,27 @@ select time(f1) from t1 ; select distinct time(f1) from t1 ; drop table t1; +# +# MDEV-3875 Wrong result (missing row) on a DISTINCT query with the same subquery in the SELECT list and GROUP BY +# MySQL Bug#66896 Distinct not distinguishing 0 from NULL when GROUP BY is used +# +create table t1(i int, g int); # remove_dup_with_hash_index +insert into t1 values (null, 1), (0, 2); +select distinct i from t1 group by g; +drop table t1; + +create table t1(i int, g blob); # remove_dup_with_compare +insert into t1 values (null, 1), (0, 2); +select distinct i from t1 group by g; +drop table t1; + +create table t1 (a int) engine=myisam; +insert into t1 values (0),(7); +create table t2 (b int) engine=myisam; +insert into t2 values (7),(0),(3); +create algorithm=temptable view v as +select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1; +select * from v; +select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1; +drop view v; +drop table t1, t2; diff --git a/sql/field.cc b/sql/field.cc index 9b0f6a7dfcd..fa098bef72c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1062,6 +1062,21 @@ bool Field::type_can_have_key_part(enum enum_field_types type) } +void Field::make_sort_key(uchar *buff,uint length) +{ + if (maybe_null()) + { + if (is_null()) + { + bzero(buff, length + 1); + return; + } + *buff++= 1; + } + sort_string(buff, length); +} + + /** Numeric fields base class constructor. */ diff --git a/sql/field.h b/sql/field.h index 208f1e381f5..115a9519b7b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -386,6 +386,7 @@ public: return bytes; } + void make_sort_key(uchar *buff, uint length); virtual void make_field(Send_field *); virtual void sort_string(uchar *buff,uint length)=0; virtual bool optimize_range(uint idx, uint part); diff --git a/sql/filesort.cc b/sql/filesort.cc index a4d4ec1b37f..703264b7ef5 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -783,21 +783,9 @@ static void make_sortkey(register SORTPARAM *param, bool maybe_null=0; if ((field=sort_field->field)) { // Field - if (field->maybe_null()) - { - if (field->is_null()) - { - if (sort_field->reverse) - bfill(to,sort_field->length+1,(char) 255); - else - bzero((char*) to,sort_field->length+1); - to+= sort_field->length+1; - continue; - } - else - *to++=1; - } - field->sort_string(to, sort_field->length); + field->make_sort_key(to, sort_field->length); + if ((maybe_null = field->maybe_null())) + to++; } else { // Item @@ -949,8 +937,11 @@ static void make_sortkey(register SORTPARAM *param, } if (sort_field->reverse) { /* Revers key */ - if (maybe_null) - to[-1]= ~to[-1]; + if (maybe_null && (to[-1]= !to[-1])) + { + to+= sort_field->length; // don't waste the time reversing all 0's + continue; + } length=sort_field->length; while (length--) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0897aa287db..5aa8c0479cf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -204,7 +204,7 @@ static int create_sort_index(THD *thd, JOIN *join, ORDER *order, static int remove_duplicates(JOIN *join,TABLE *entry,List &fields, Item *having); static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, - ulong offset,Item *having); + Item *having); static int remove_dup_with_hash_index(THD *thd,TABLE *table, uint field_count, Field **first_field, ulong key_length,Item *having); @@ -18891,19 +18891,24 @@ static bool fix_having(JOIN *join, Item **having) #endif -/***************************************************************************** - Remove duplicates from tmp table - This should be recoded to add a unique index to the table and remove - duplicates - Table is a locked single thread table - fields is the number of fields to check (from the end) -*****************************************************************************/ +/** + Compare fields from table->record[0] and table->record[1], + possibly skipping few first fields. + @param table + @param ptr field to start the comparison from, + somewhere in the table->field[] array + + @retval 1 different + @retval 0 identical +*/ static bool compare_record(TABLE *table, Field **ptr) { for (; *ptr ; ptr++) { - if ((*ptr)->cmp_offset(table->s->rec_buff_length)) + Field *f= *ptr; + if (f->is_null() != f->is_null(table->s->rec_buff_length) || + (!f->is_null() && f->cmp_offset(table->s->rec_buff_length))) return 1; } return 0; @@ -18931,15 +18936,15 @@ static void free_blobs(Field **ptr) static int -remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) +remove_duplicates(JOIN *join, TABLE *table, List &fields, Item *having) { int error; - ulong reclength,offset; + ulong keylength= 0; uint field_count; THD *thd= join->thd; DBUG_ENTER("remove_duplicates"); - entry->reginfo.lock_type=TL_WRITE; + table->reginfo.lock_type=TL_WRITE; /* Calculate how many saved fields there is in list */ field_count=0; @@ -18956,24 +18961,21 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) join->unit->select_limit_cnt= 1; // Only send first row DBUG_RETURN(0); } - Field **first_field=entry->field+entry->s->fields - field_count; - offset= (field_count ? - entry->field[entry->s->fields - field_count]-> - offset(entry->record[0]) : 0); - reclength=entry->s->reclength-offset; - free_io_cache(entry); // Safety - entry->file->info(HA_STATUS_VARIABLE); - if (entry->s->db_type() == heap_hton || - (!entry->s->blob_fields && - ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records < + Field **first_field=table->field+table->s->fields - field_count; + for (Field **ptr=first_field; *ptr; ptr++) + keylength+= (*ptr)->sort_length() + (*ptr)->maybe_null(); + + free_io_cache(table); // Safety + table->file->info(HA_STATUS_VARIABLE); + if (table->s->db_type() == heap_hton || + (!table->s->blob_fields && + ((ALIGN_SIZE(keylength) + HASH_OVERHEAD) * table->file->stats.records < thd->variables.sortbuff_size))) - error=remove_dup_with_hash_index(join->thd, entry, - field_count, first_field, - reclength, having); + error=remove_dup_with_hash_index(join->thd, table, field_count, first_field, + keylength, having); else - error=remove_dup_with_compare(join->thd, entry, first_field, offset, - having); + error=remove_dup_with_compare(join->thd, table, first_field, having); free_blobs(first_field); DBUG_RETURN(error); @@ -18981,18 +18983,13 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, - ulong offset, Item *having) + Item *having) { handler *file=table->file; - char *org_record,*new_record; - uchar *record; + uchar *record=table->record[0]; int error; - ulong reclength= table->s->reclength-offset; DBUG_ENTER("remove_dup_with_compare"); - org_record=(char*) (record=table->record[0])+offset; - new_record=(char*) table->record[1]+offset; - if (file->ha_rnd_init_with_error(1)) DBUG_RETURN(1); @@ -19029,7 +19026,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, error=0; goto err; } - memcpy(new_record,org_record,reclength); + store_record(table,record[1]); /* Read through rest of file and mark duplicated rows deleted */ bool found=0; @@ -19088,8 +19085,9 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, int error; handler *file= table->file; ulong extra_length= ALIGN_SIZE(key_length)-key_length; - uint *field_lengths,*field_length; + uint *field_lengths, *field_length; HASH hash; + Field **ptr; DBUG_ENTER("remove_dup_with_hash_index"); if (!my_multi_malloc(MYF(MY_WME), @@ -19101,21 +19099,8 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, NullS)) DBUG_RETURN(1); - { - Field **ptr; - ulong total_length= 0; - for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++) - { - uint length= (*ptr)->sort_length(); - (*field_length++)= length; - total_length+= length; - } - DBUG_PRINT("info",("field_count: %u key_length: %lu total_length: %lu", - field_count, key_length, total_length)); - DBUG_ASSERT(total_length <= key_length); - key_length= total_length; - extra_length= ALIGN_SIZE(key_length)-key_length; - } + for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++) + (*field_length++)= (*ptr)->sort_length(); if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0, key_length, (hash_get_key) 0, 0, 0)) @@ -19155,13 +19140,13 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, /* copy fields to key buffer */ org_key_pos= key_pos; field_length=field_lengths; - for (Field **ptr= first_field ; *ptr ; ptr++) + for (ptr= first_field ; *ptr ; ptr++) { - (*ptr)->sort_string(key_pos,*field_length); - key_pos+= *field_length++; + (*ptr)->make_sort_key(key_pos, *field_length); + key_pos+= (*ptr)->maybe_null() + *field_length++; } /* Check if it exists before */ - if (hash_search(&hash, org_key_pos, key_length)) + if (my_hash_search(&hash, org_key_pos, key_length)) { /* Duplicated found ; Remove the row */ if ((error= file->ha_delete_row(record))) From 5138bf4238d4a8850ee364a3adf10dc2687af67c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 28 Jan 2013 09:10:01 +0100 Subject: [PATCH 5/5] compilation error with -Wuninitialized -Werror --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f9179843810..53948f11923 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2084,7 +2084,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) { my_ptrdiff_t adjust_ptrs; Field **field,**org_field, *found_next_number_field; - Field **vfield; + Field **UNINIT_VAR(vfield); TABLE *copy; TABLE_SHARE *share; uchar *bitmap;