From: Date: June 20 2006 5:44pm Subject: bk commit - 5.1 tree (mikael:....) BUG#17138 List-Archive: http://lists.mysql.com/internals/33653 Message-Id: <72f223ab57164b1710352edc6951e75a@mysql.com> MIME-Version: 1.0 (Apple Message framework v623) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Content-Transfer-Encoding: 7bit diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/mysql-test/r/partition.result clean-bug17138/mysql-test/r/partition.result --- clean-mysql-5.1/mysql-test/r/partition.result 2006-06-15 14:04:29 -04:00 +++ clean-bug17138/mysql-test/r/partition.result 2006-06-20 17:14:23 -04:00 @@ -1043,4 +1043,19 @@ alter table t1 drop partition p2; use test; drop database db99; +create table t1 (a int) +partition by list (a) +(partition p0 values in (0)); +insert into t1 values (0); +create procedure po () +begin +begin +declare continue handler for sqlexception begin end; +update ignore t1 set a = 1 where a = 0; +end; +prepare stmt1 from 'alter table t1'; +execute stmt1; +end// +call po()// +drop table t1; End of 5.1 tests diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/mysql-test/t/partition.test clean-bug17138/mysql-test/t/partition.test --- clean-mysql-5.1/mysql-test/t/partition.test 2006-06-15 14:04:29 -04:00 +++ clean-bug17138/mysql-test/t/partition.test 2006-06-20 17:14:24 -04:00 @@ -1199,4 +1199,27 @@ use test; drop database db99; +# +#BUG 17138 Problem with stored procedure and analyze partition +# +create table t1 (a int) +partition by list (a) +(partition p0 values in (0)); + +insert into t1 values (0); +delimiter //; + +create procedure po () +begin + begin + declare continue handler for sqlexception begin end; + update ignore t1 set a = 1 where a = 0; + end; + prepare stmt1 from 'alter table t1'; + execute stmt1; +end// + +call po()// +delimiter ;// +drop table t1; --echo End of 5.1 tests diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/ha_ndbcluster.h clean-bug17138/sql/ha_ndbcluster.h --- clean-mysql-5.1/sql/ha_ndbcluster.h 2006-06-13 11:43:34 -04:00 +++ clean-bug17138/sql/ha_ndbcluster.h 2006-06-20 17:14:25 -04:00 @@ -654,6 +654,14 @@ int get_default_no_partitions(ulonglong max_rows); bool get_no_parts(const char *name, uint *no_parts); void set_auto_partitions(partition_info *part_info); + virtual bool cannot_ignore_error(int error, uint flags) + { + if (!handler::cannot_ignore_error(error, flags)) + return FALSE; + if (error == HA_ERR_NO_PARTITION_FOUND) + return FALSE; + return TRUE; + } THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/ha_partition.h clean-bug17138/sql/ha_partition.h --- clean-mysql-5.1/sql/ha_partition.h 2006-06-12 14:23:08 -04:00 +++ clean-bug17138/sql/ha_partition.h 2006-06-20 17:14:25 -04:00 @@ -302,6 +302,14 @@ virtual void start_bulk_insert(ha_rows rows); virtual int end_bulk_insert(); + virtual bool cannot_ignore_error(int error, uint flags) + { + if (!handler::cannot_ignore_error(error, flags)) + return FALSE; + if (error == HA_ERR_NO_PARTITION_FOUND) + return FALSE; + return TRUE; + } /* ------------------------------------------------------------------------ - MODULE full table scan diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/handler.h clean-bug17138/sql/handler.h --- clean-mysql-5.1/sql/handler.h 2006-06-15 14:04:29 -04:00 +++ clean-bug17138/sql/handler.h 2006-06-20 17:14:25 -04:00 @@ -970,7 +970,30 @@ bool has_transactions() { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; } virtual uint extra_rec_buf_length() const { return 0; } - + + /* + This method is used to analyse the error to see whether the error + is ignorable or not, certain handlers can have more error that are + ignorable than others. E.g. the partition handler can get inserts + into a range where there is no partition and this is an ignorable + error. + HA_ERR_FOUND_DUPP_UNIQUE is a special case in MyISAM that means the + same thing as HA_ERR_FOUND_DUPP_KEY but can in some cases lead to + a slightly different error message. + */ +#define HA_CHECK_DUPP_KEY 1 +#define HA_CHECK_DUPP_UNIQUE 2 +#define HA_CHECK_DUPP (HA_CHECK_DUPP_KEY + HA_CHECK_DUPP_UNIQUE) + virtual bool cannot_ignore_error(int error, uint flags) + { + if (!error || + ((flags & HA_CHECK_DUPP_KEY) && + (error == HA_ERR_FOUND_DUPP_KEY || + error == HA_ERR_FOUND_DUPP_UNIQUE))) + return FALSE; + return TRUE; + } + /* Number of rows in table. It will only be called if (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0 @@ -1022,7 +1045,7 @@ DBUG_RETURN(rnd_end()); } int ha_reset(); - + /* this is necessary in many places, e.g. in HANDLER command */ int ha_index_or_rnd_end() { diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/item_sum.cc clean-bug17138/sql/item_sum.cc --- clean-mysql-5.1/sql/item_sum.cc 2006-06-19 11:31:11 -04:00 +++ clean-bug17138/sql/item_sum.cc 2006-06-20 17:14:25 -04:00 @@ -2663,8 +2663,7 @@ return tree->unique_add(table->record[0] + table->s->null_bytes); } if ((error= table->file->ha_write_row(table->record[0])) && - error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE) + table->file->cannot_ignore_error(error, HA_CHECK_DUPP)) return TRUE; return FALSE; } diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_acl.cc clean-bug17138/sql/sql_acl.cc --- clean-mysql-5.1/sql/sql_acl.cc 2006-06-19 11:31:11 -04:00 +++ clean-bug17138/sql/sql_acl.cc 2006-06-20 17:14:25 -04:00 @@ -2049,8 +2049,7 @@ } else if ((error=table->file->ha_write_row(table->record[0]))) // insert { // This should never happen - if (error && error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE) /* purecov: inspected */ + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP)) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ error= -1; /* purecov: deadcode */ @@ -2172,7 +2171,7 @@ } else if (rights && (error= table->file->ha_write_row(table->record[0]))) { - if (error && error != HA_ERR_FOUND_DUPP_KEY) /* purecov: inspected */ + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) goto table_error; /* purecov: deadcode */ } @@ -2744,7 +2743,7 @@ else { error=table->file->ha_write_row(table->record[0]); - if (error && error != HA_ERR_FOUND_DUPP_KEY) + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) goto table_error; /* purecov: deadcode */ } @@ -2862,7 +2861,7 @@ else { error=table->file->ha_write_row(table->record[0]); - if (error && error != HA_ERR_FOUND_DUPP_KEY) + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) goto table_error; } diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_insert.cc clean-bug17138/sql/sql_insert.cc --- clean-mysql-5.1/sql/sql_insert.cc 2006-06-19 11:31:11 -04:00 +++ clean-bug17138/sql/sql_insert.cc 2006-06-20 17:14:25 -04:00 @@ -979,6 +979,9 @@ if (error != HA_WRITE_SKIP) goto err; table->file->restore_auto_increment(); // it's too early here! BUG#20188 + if (info->ignore && + !table->file->cannot_ignore_error(error, 0)) + goto ok_or_after_trg_err; if ((int) (key_nr = table->file->get_dup_key(error)) < 0) { error=HA_WRITE_SKIP; /* Database can't find key */ @@ -1062,7 +1065,8 @@ if ((error=table->file->ha_update_row(table->record[1], table->record[0]))) { - if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) + if (info->ignore && + !table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) goto ok_or_after_trg_err; goto err; } @@ -1148,7 +1152,7 @@ else if ((error=table->file->ha_write_row(table->record[0]))) { if (!info->ignore || - (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) + table->file->cannot_ignore_error(error, HA_CHECK_DUPP)) goto err; table->file->restore_auto_increment(); } diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_select.cc clean-bug17138/sql/sql_select.cc --- clean-mysql-5.1/sql/sql_select.cc 2006-06-19 11:31:11 -04:00 +++ clean-bug17138/sql/sql_select.cc 2006-06-20 17:14:25 -04:00 @@ -9354,9 +9354,9 @@ /* copy row that filled HEAP table */ if ((write_err=new_table.file->write_row(table->record[0]))) { - if (write_err != HA_ERR_FOUND_DUPP_KEY && - write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error) - goto err; + if (new_table.file->cannot_ignore_error(write_err, HA_CHECK_DUPP) || + !ignore_last_dupp_key_error) + goto err; } /* remove heap table and change to use myisam table */ @@ -10777,8 +10777,7 @@ join->found_records++; if ((error=table->file->write_row(table->record[0]))) { - if (error == HA_ERR_FOUND_DUPP_KEY || - error == HA_ERR_FOUND_DUPP_UNIQUE) + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP)) goto end; if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, error,1)) diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_table.cc clean-bug17138/sql/sql_table.cc --- clean-mysql-5.1/sql/sql_table.cc 2006-06-19 11:31:11 -04:00 +++ clean-bug17138/sql/sql_table.cc 2006-06-20 17:14:25 -04:00 @@ -6268,10 +6268,8 @@ } if ((error=to->file->ha_write_row((byte*) to->record[0]))) { - if ((!ignore && - handle_duplicates != DUP_REPLACE) || - (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE)) + if (!ignore || + to->file->cannot_ignore_error(error, HA_CHECK_DUPP)) { if (error == HA_ERR_FOUND_DUPP_KEY) { diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_union.cc clean-bug17138/sql/sql_union.cc --- clean-mysql-5.1/sql/sql_union.cc 2006-06-12 14:23:09 -04:00 +++ clean-bug17138/sql/sql_union.cc 2006-06-20 17:14:25 -04:00 @@ -65,7 +65,7 @@ if ((error= table->file->ha_write_row(table->record[0]))) { /* create_myisam_from_heap will generate error if needed */ - if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE && + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP) && create_myisam_from_heap(thd, table, &tmp_table_param, error, 1)) return 1; } diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_update.cc clean-bug17138/sql/sql_update.cc --- clean-mysql-5.1/sql/sql_update.cc 2006-06-20 15:04:14 -04:00 +++ clean-bug17138/sql/sql_update.cc 2006-06-20 17:14:25 -04:00 @@ -541,13 +541,14 @@ break; } } - else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) + else if (!ignore || + table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) { /* - If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + If (ignore && error is ignorable) we don't have to do anything; otherwise... */ - if (error != HA_ERR_FOUND_DUPP_KEY) + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); error= 1; @@ -1422,13 +1423,14 @@ table->record[0]))) { updated--; - if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) + if (!ignore || + table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) { /* - If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + If (ignore && error == is ignorable) we don't have to do anything; otherwise... */ - if (error != HA_ERR_FOUND_DUPP_KEY) + if (table->file->cannot_ignore_error(error, HA_CHECK_DUPP_KEY)) thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); DBUG_RETURN(1); @@ -1457,8 +1459,7 @@ /* Write row, ignoring duplicated updates to a row */ if ((error= tmp_table->file->ha_write_row(tmp_table->record[0]))) { - if (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE && + if (tmp_table->file->cannot_ignore_error(error, HA_CHECK_DUPP) && create_myisam_from_heap(thd, tmp_table, tmp_table_param + offset, error, 1)) { @@ -1581,7 +1582,8 @@ if ((local_error=table->file->ha_update_row(table->record[1], table->record[0]))) { - if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY) + if (!ignore || + table->file->cannot_ignore_error(local_error, HA_CHECK_DUPP_KEY)) goto err; } updated++; Mikael Ronstrom, Senior Software Architect MySQL AB, www.mysql.com Jumpstart your cluster: http://www.mysql.com/consulting/packaged/cluster.html My blog: http://mikaelronstrom.blogspot.com