Commit d4350444 authored by unknown's avatar unknown

Merge mronstrom@bk-internal.mysql.com:/home/bk/mysql-5.1

into  dator5.(none):/home/pappa/bug17138


sql/item_sum.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
parents 50a8fba8 60d070b2
...@@ -1057,4 +1057,29 @@ alter table t1 add partition (partition p2 values in (3)); ...@@ -1057,4 +1057,29 @@ alter table t1 add partition (partition p2 values in (3));
alter table t1 drop partition p2; alter table t1 drop partition p2;
use test; use test;
drop database db99; drop database db99;
drop procedure if exists mysqltest_1;
create table t1 (a int)
partition by list (a)
(partition p0 values in (0));
insert into t1 values (0);
create procedure mysqltest_1 ()
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 mysqltest_1()//
drop table t1;
drop procedure mysqltest_1;
create table t1 (a int, index(a))
partition by hash(a);
insert into t1 values (1),(2);
select * from t1 ORDER BY a DESC;
a
2
1
drop table t1;
End of 5.1 tests End of 5.1 tests
...@@ -1223,4 +1223,42 @@ alter table t1 drop partition p2; ...@@ -1223,4 +1223,42 @@ alter table t1 drop partition p2;
use test; use test;
drop database db99; drop database db99;
#
#BUG 17138 Problem with stored procedure and analyze partition
#
--disable_warnings
drop procedure if exists mysqltest_1;
--enable_warnings
create table t1 (a int)
partition by list (a)
(partition p0 values in (0));
insert into t1 values (0);
delimiter //;
create procedure mysqltest_1 ()
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 mysqltest_1()//
delimiter ;//
drop table t1;
drop procedure mysqltest_1;
#
# Bug 20583 Partitions: Crash using index_last
#
create table t1 (a int, index(a))
partition by hash(a);
insert into t1 values (1),(2);
select * from t1 ORDER BY a DESC;
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -655,6 +655,13 @@ class ha_ndbcluster: public handler ...@@ -655,6 +655,13 @@ class ha_ndbcluster: public handler
int get_default_no_partitions(HA_CREATE_INFO *info); int get_default_no_partitions(HA_CREATE_INFO *info);
bool get_no_parts(const char *name, uint *no_parts); bool get_no_parts(const char *name, uint *no_parts);
void set_auto_partitions(partition_info *part_info); void set_auto_partitions(partition_info *part_info);
virtual bool is_fatal_error(int error, uint flags)
{
if (!handler::is_fatal_error(error, flags) ||
error == HA_ERR_NO_PARTITION_FOUND)
return FALSE;
return TRUE;
}
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **store_lock(THD *thd,
THR_LOCK_DATA **to, THR_LOCK_DATA **to,
......
...@@ -3400,7 +3400,8 @@ int ha_partition::common_first_last(byte *buf) ...@@ -3400,7 +3400,8 @@ int ha_partition::common_first_last(byte *buf)
if ((error= partition_scan_set_up(buf, FALSE))) if ((error= partition_scan_set_up(buf, FALSE)))
return error; return error;
if (!m_ordered_scan_ongoing) if (!m_ordered_scan_ongoing &&
m_index_scan_type != partition_index_last)
return handle_unordered_scan_next_partition(buf); return handle_unordered_scan_next_partition(buf);
return handle_ordered_index_scan(buf); return handle_ordered_index_scan(buf);
} }
......
...@@ -302,6 +302,13 @@ class ha_partition :public handler ...@@ -302,6 +302,13 @@ class ha_partition :public handler
virtual void start_bulk_insert(ha_rows rows); virtual void start_bulk_insert(ha_rows rows);
virtual int end_bulk_insert(); virtual int end_bulk_insert();
virtual bool is_fatal_error(int error, uint flags)
{
if (!handler::is_fatal_error(error, flags) ||
error == HA_ERR_NO_PARTITION_FOUND)
return FALSE;
return TRUE;
}
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE full table scan MODULE full table scan
......
...@@ -218,11 +218,6 @@ ...@@ -218,11 +218,6 @@
#define HA_BLOCK_LOCK 256 /* unlock when reading some records */ #define HA_BLOCK_LOCK 256 /* unlock when reading some records */
#define HA_OPEN_TEMPORARY 512 #define HA_OPEN_TEMPORARY 512
/* Errors on write which is recoverable (Key exist) */
#define HA_WRITE_SKIP 121 /* Duplicate key on write */
#define HA_READ_CHECK 123 /* Update with is recoverable */
#define HA_CANT_DO_THAT 131 /* Databasehandler can't do it */
/* Some key definitions */ /* Some key definitions */
#define HA_KEY_NULL_LENGTH 1 #define HA_KEY_NULL_LENGTH 1
#define HA_KEY_BLOB_LENGTH 2 #define HA_KEY_BLOB_LENGTH 2
...@@ -242,6 +237,11 @@ ...@@ -242,6 +237,11 @@
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */ /* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1 #define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
/* Flags for method is_fatal_error */
#define HA_CHECK_DUP_KEY 1
#define HA_CHECK_DUP_UNIQUE 2
#define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
enum legacy_db_type enum legacy_db_type
{ {
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
...@@ -973,6 +973,26 @@ class handler :public Sql_alloc ...@@ -973,6 +973,26 @@ class handler :public Sql_alloc
{ return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; } { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
virtual uint extra_rec_buf_length() const { return 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_DUP_UNIQUE is a special case in MyISAM that means the
same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
a slightly different error message.
*/
virtual bool is_fatal_error(int error, uint flags)
{
if (!error ||
((flags & HA_CHECK_DUP_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 Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
......
...@@ -2662,8 +2662,7 @@ bool Item_sum_count_distinct::add() ...@@ -2662,8 +2662,7 @@ bool Item_sum_count_distinct::add()
return tree->unique_add(table->record[0] + table->s->null_bytes); return tree->unique_add(table->record[0] + table->s->null_bytes);
} }
if ((error= table->file->ha_write_row(table->record[0])) && if ((error= table->file->ha_write_row(table->record[0])) &&
error != HA_ERR_FOUND_DUPP_KEY && table->file->is_fatal_error(error, HA_CHECK_DUP))
error != HA_ERR_FOUND_DUPP_UNIQUE)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
......
...@@ -2049,8 +2049,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ...@@ -2049,8 +2049,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
} }
else if ((error=table->file->ha_write_row(table->record[0]))) // insert else if ((error=table->file->ha_write_row(table->record[0]))) // insert
{ // This should never happen { // This should never happen
if (error && error != HA_ERR_FOUND_DUPP_KEY && if (table->file->is_fatal_error(error, HA_CHECK_DUP))
error != HA_ERR_FOUND_DUPP_UNIQUE) /* purecov: inspected */
{ {
table->file->print_error(error,MYF(0)); /* purecov: deadcode */ table->file->print_error(error,MYF(0)); /* purecov: deadcode */
error= -1; /* purecov: deadcode */ error= -1; /* purecov: deadcode */
...@@ -2172,7 +2171,7 @@ static int replace_db_table(TABLE *table, const char *db, ...@@ -2172,7 +2171,7 @@ static int replace_db_table(TABLE *table, const char *db,
} }
else if (rights && (error= table->file->ha_write_row(table->record[0]))) 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->is_fatal_error(error, HA_CHECK_DUP_KEY))
goto table_error; /* purecov: deadcode */ goto table_error; /* purecov: deadcode */
} }
...@@ -2744,7 +2743,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ...@@ -2744,7 +2743,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
else else
{ {
error=table->file->ha_write_row(table->record[0]); error=table->file->ha_write_row(table->record[0]);
if (error && error != HA_ERR_FOUND_DUPP_KEY) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
goto table_error; /* purecov: deadcode */ goto table_error; /* purecov: deadcode */
} }
...@@ -2862,7 +2861,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, ...@@ -2862,7 +2861,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
else else
{ {
error=table->file->ha_write_row(table->record[0]); error=table->file->ha_write_row(table->record[0]);
if (error && error != HA_ERR_FOUND_DUPP_KEY) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
goto table_error; goto table_error;
} }
......
...@@ -976,12 +976,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -976,12 +976,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
while ((error=table->file->ha_write_row(table->record[0]))) while ((error=table->file->ha_write_row(table->record[0])))
{ {
uint key_nr; uint key_nr;
if (error != HA_WRITE_SKIP) bool is_duplicate_key_error;
if (table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err; goto err;
table->file->restore_auto_increment(); // it's too early here! BUG#20188 table->file->restore_auto_increment(); // it's too early here! BUG#20188
is_duplicate_key_error= table->file->is_fatal_error(error, 0);
if (!is_duplicate_key_error)
{
/*
We come here when we had an ignorable error which is not a duplicate
key error. In this we ignore error if ignore flag is set, otherwise
report error as usual. We will not do any duplicate key processing.
*/
if (info->ignore)
goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */
goto err;
}
if ((int) (key_nr = table->file->get_dup_key(error)) < 0) if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
{ {
error=HA_WRITE_SKIP; /* Database can't find key */ error= HA_ERR_FOUND_DUPP_KEY; /* Database can't find key */
goto err; goto err;
} }
/* Read all columns for the row we are going to replace */ /* Read all columns for the row we are going to replace */
...@@ -1062,7 +1075,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1062,7 +1075,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if ((error=table->file->ha_update_row(table->record[1], if ((error=table->file->ha_update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) if (info->ignore &&
!table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
goto ok_or_after_trg_err; goto ok_or_after_trg_err;
goto err; goto err;
} }
...@@ -1145,7 +1159,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1145,7 +1159,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
else if ((error=table->file->ha_write_row(table->record[0]))) else if ((error=table->file->ha_write_row(table->record[0])))
{ {
if (!info->ignore || if (!info->ignore ||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err; goto err;
table->file->restore_auto_increment(); table->file->restore_auto_increment();
goto ok_or_after_trg_err; goto ok_or_after_trg_err;
......
...@@ -9393,8 +9393,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, ...@@ -9393,8 +9393,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
/* copy row that filled HEAP table */ /* copy row that filled HEAP table */
if ((write_err=new_table.file->write_row(table->record[0]))) if ((write_err=new_table.file->write_row(table->record[0])))
{ {
if (write_err != HA_ERR_FOUND_DUPP_KEY && if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error) !ignore_last_dupp_key_error)
goto err; goto err;
} }
...@@ -10816,8 +10816,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -10816,8 +10816,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->found_records++; join->found_records++;
if ((error=table->file->write_row(table->record[0]))) if ((error=table->file->write_row(table->record[0])))
{ {
if (error == HA_ERR_FOUND_DUPP_KEY || if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
error == HA_ERR_FOUND_DUPP_UNIQUE)
goto end; goto end;
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
error,1)) error,1))
......
...@@ -6322,12 +6322,10 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -6322,12 +6322,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
} }
if ((error=to->file->ha_write_row((byte*) to->record[0]))) if ((error=to->file->ha_write_row((byte*) to->record[0])))
{ {
if ((!ignore && if (!ignore || handle_duplicates != DUP_ERROR ||
handle_duplicates != DUP_REPLACE) || to->file->is_fatal_error(error, HA_CHECK_DUP))
(error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE))
{ {
if (error == HA_ERR_FOUND_DUPP_KEY) if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
{ {
uint key_nr= to->file->get_dup_key(error); uint key_nr= to->file->get_dup_key(error);
if ((int) key_nr >= 0) if ((int) key_nr >= 0)
......
...@@ -65,7 +65,7 @@ bool select_union::send_data(List<Item> &values) ...@@ -65,7 +65,7 @@ bool select_union::send_data(List<Item> &values)
if ((error= table->file->ha_write_row(table->record[0]))) if ((error= table->file->ha_write_row(table->record[0])))
{ {
/* create_myisam_from_heap will generate error if needed */ /* 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->is_fatal_error(error, HA_CHECK_DUP) &&
create_myisam_from_heap(thd, table, &tmp_table_param, error, 1)) create_myisam_from_heap(thd, table, &tmp_table_param, error, 1))
return 1; return 1;
} }
......
...@@ -541,13 +541,14 @@ int mysql_update(THD *thd, ...@@ -541,13 +541,14 @@ int mysql_update(THD *thd,
break; break;
} }
} }
else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) else if (!ignore ||
table->file->is_fatal_error(error, HA_CHECK_DUP_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... do anything; otherwise...
*/ */
if (error != HA_ERR_FOUND_DUPP_KEY) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
thd->fatal_error(); /* Other handler errors are fatal */ thd->fatal_error(); /* Other handler errors are fatal */
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
error= 1; error= 1;
...@@ -1422,13 +1423,14 @@ bool multi_update::send_data(List<Item> &not_used_values) ...@@ -1422,13 +1423,14 @@ bool multi_update::send_data(List<Item> &not_used_values)
table->record[0]))) table->record[0])))
{ {
updated--; updated--;
if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) if (!ignore ||
table->file->is_fatal_error(error, HA_CHECK_DUP_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... do anything; otherwise...
*/ */
if (error != HA_ERR_FOUND_DUPP_KEY) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
thd->fatal_error(); /* Other handler errors are fatal */ thd->fatal_error(); /* Other handler errors are fatal */
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -1457,8 +1459,7 @@ bool multi_update::send_data(List<Item> &not_used_values) ...@@ -1457,8 +1459,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
/* Write row, ignoring duplicated updates to a row */ /* Write row, ignoring duplicated updates to a row */
if ((error= tmp_table->file->ha_write_row(tmp_table->record[0]))) if ((error= tmp_table->file->ha_write_row(tmp_table->record[0])))
{ {
if (error != HA_ERR_FOUND_DUPP_KEY && if (tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
error != HA_ERR_FOUND_DUPP_UNIQUE &&
create_myisam_from_heap(thd, tmp_table, create_myisam_from_heap(thd, tmp_table,
tmp_table_param + offset, error, 1)) tmp_table_param + offset, error, 1))
{ {
...@@ -1581,7 +1582,8 @@ int multi_update::do_updates(bool from_send_error) ...@@ -1581,7 +1582,8 @@ int multi_update::do_updates(bool from_send_error)
if ((local_error=table->file->ha_update_row(table->record[1], if ((local_error=table->file->ha_update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY) if (!ignore ||
table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
goto err; goto err;
} }
updated++; updated++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment