mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge mronstrom@bk-internal.mysql.com:/home/bk/mysql-5.1
into dator5.(none):/home/pappa/bug17138
This commit is contained in:
commit
d5bb513021
13 changed files with 148 additions and 39 deletions
|
@ -1057,4 +1057,29 @@ alter table t1 add partition (partition p2 values in (3));
|
|||
alter table t1 drop partition p2;
|
||||
use test;
|
||||
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
|
||||
|
|
|
@ -1223,4 +1223,42 @@ alter table t1 drop partition p2;
|
|||
use test;
|
||||
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
|
||||
|
|
|
@ -655,6 +655,13 @@ class ha_ndbcluster: public handler
|
|||
int get_default_no_partitions(HA_CREATE_INFO *info);
|
||||
bool get_no_parts(const char *name, uint *no_parts);
|
||||
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 **to,
|
||||
|
|
|
@ -3400,7 +3400,8 @@ int ha_partition::common_first_last(byte *buf)
|
|||
|
||||
if ((error= partition_scan_set_up(buf, FALSE)))
|
||||
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_ordered_index_scan(buf);
|
||||
}
|
||||
|
|
|
@ -302,6 +302,13 @@ public:
|
|||
virtual void start_bulk_insert(ha_rows rows);
|
||||
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
|
||||
|
|
|
@ -218,11 +218,6 @@
|
|||
#define HA_BLOCK_LOCK 256 /* unlock when reading some records */
|
||||
#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 */
|
||||
#define HA_KEY_NULL_LENGTH 1
|
||||
#define HA_KEY_BLOB_LENGTH 2
|
||||
|
@ -242,6 +237,11 @@
|
|||
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
|
||||
#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
|
||||
{
|
||||
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
|
||||
|
@ -972,7 +972,27 @@ public:
|
|||
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_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
|
||||
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
|
||||
|
@ -1024,7 +1044,7 @@ public:
|
|||
DBUG_RETURN(rnd_end());
|
||||
}
|
||||
int ha_reset();
|
||||
|
||||
|
||||
/* this is necessary in many places, e.g. in HANDLER command */
|
||||
int ha_index_or_rnd_end()
|
||||
{
|
||||
|
|
|
@ -2662,8 +2662,7 @@ bool Item_sum_count_distinct::add()
|
|||
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->is_fatal_error(error, HA_CHECK_DUP))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{ // This should never happen
|
||||
if (error && error != HA_ERR_FOUND_DUPP_KEY &&
|
||||
error != HA_ERR_FOUND_DUPP_UNIQUE) /* purecov: inspected */
|
||||
if (table->file->is_fatal_error(error, HA_CHECK_DUP))
|
||||
{
|
||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||
error= -1; /* purecov: deadcode */
|
||||
|
@ -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])))
|
||||
{
|
||||
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 */
|
||||
}
|
||||
|
||||
|
@ -2744,7 +2743,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||
else
|
||||
{
|
||||
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 */
|
||||
}
|
||||
|
||||
|
@ -2862,7 +2861,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
|
|||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -976,12 +976,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
while ((error=table->file->ha_write_row(table->record[0])))
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
error=HA_WRITE_SKIP; /* Database can't find key */
|
||||
error= HA_ERR_FOUND_DUPP_KEY; /* Database can't find key */
|
||||
goto err;
|
||||
}
|
||||
/* 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)
|
|||
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->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||
goto ok_or_after_trg_err;
|
||||
goto err;
|
||||
}
|
||||
|
@ -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])))
|
||||
{
|
||||
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;
|
||||
table->file->restore_auto_increment();
|
||||
goto ok_or_after_trg_err;
|
||||
|
|
|
@ -9393,9 +9393,9 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|||
/* 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->is_fatal_error(write_err, HA_CHECK_DUP) ||
|
||||
!ignore_last_dupp_key_error)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* remove heap table and change to use myisam table */
|
||||
|
@ -10816,8 +10816,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||
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->is_fatal_error(error, HA_CHECK_DUP))
|
||||
goto end;
|
||||
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
|
||||
error,1))
|
||||
|
|
|
@ -6322,12 +6322,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
|||
}
|
||||
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 || handle_duplicates != DUP_ERROR ||
|
||||
to->file->is_fatal_error(error, HA_CHECK_DUP))
|
||||
{
|
||||
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);
|
||||
if ((int) key_nr >= 0)
|
||||
|
|
|
@ -65,7 +65,7 @@ bool select_union::send_data(List<Item> &values)
|
|||
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->is_fatal_error(error, HA_CHECK_DUP) &&
|
||||
create_myisam_from_heap(thd, table, &tmp_table_param, error, 1))
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -541,13 +541,14 @@ int mysql_update(THD *thd,
|
|||
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...
|
||||
*/
|
||||
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 */
|
||||
table->file->print_error(error,MYF(0));
|
||||
error= 1;
|
||||
|
@ -1422,13 +1423,14 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
|||
table->record[0])))
|
||||
{
|
||||
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...
|
||||
*/
|
||||
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 */
|
||||
table->file->print_error(error,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
|
@ -1457,8 +1459,7 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
|||
/* 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->is_fatal_error(error, HA_CHECK_DUP) &&
|
||||
create_myisam_from_heap(thd, tmp_table,
|
||||
tmp_table_param + offset, error, 1))
|
||||
{
|
||||
|
@ -1581,7 +1582,8 @@ int multi_update::do_updates(bool from_send_error)
|
|||
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->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
|
||||
goto err;
|
||||
}
|
||||
updated++;
|
||||
|
|
Loading…
Reference in a new issue