mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
Merge gbichot3.local:/home/mysql_src/mysql-5.0-20524
into gbichot3.local:/home/mysql_src/mysql-5.0
This commit is contained in:
commit
dd84ef1b8a
5 changed files with 157 additions and 24 deletions
|
@ -132,3 +132,68 @@ id last_id
|
|||
drop function bug15728;
|
||||
drop function bug15728_insert;
|
||||
drop table t1, t2;
|
||||
create table t1 (n int primary key auto_increment not null,
|
||||
b int, unique(b));
|
||||
set sql_log_bin=0;
|
||||
insert into t1 values(null,100);
|
||||
replace into t1 values(null,50),(null,100),(null,150);
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 50
|
||||
3 100
|
||||
4 150
|
||||
truncate table t1;
|
||||
set sql_log_bin=1;
|
||||
insert into t1 values(null,100);
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
1 100
|
||||
insert into t1 values(null,200),(null,300);
|
||||
delete from t1 where b <> 100;
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
1 100
|
||||
replace into t1 values(null,100),(null,350);
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
3 350
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
3 350
|
||||
insert into t1 values (NULL,400),(3,500),(NULL,600) on duplicate key UPDATE n=1000;
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
4 400
|
||||
1000 350
|
||||
1001 600
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
4 400
|
||||
1000 350
|
||||
1001 600
|
||||
drop table t1;
|
||||
create table t1 (n int primary key auto_increment not null,
|
||||
b int, unique(b));
|
||||
insert into t1 values(null,100);
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
1 100
|
||||
insert into t1 values(null,200),(null,300);
|
||||
delete from t1 where b <> 100;
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
1 100
|
||||
insert into t1 values(null,100),(null,350) on duplicate key update n=2;
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
3 350
|
||||
select * from t1 order by n;
|
||||
n b
|
||||
2 100
|
||||
3 350
|
||||
drop table t1;
|
||||
|
|
|
@ -147,6 +147,69 @@ drop function bug15728;
|
|||
drop function bug15728_insert;
|
||||
drop table t1, t2;
|
||||
|
||||
# test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in
|
||||
# auto_increment breaks binlog
|
||||
|
||||
create table t1 (n int primary key auto_increment not null,
|
||||
b int, unique(b));
|
||||
|
||||
# First, test that we do not call restore_auto_increment() too early
|
||||
# in write_record():
|
||||
set sql_log_bin=0;
|
||||
insert into t1 values(null,100);
|
||||
replace into t1 values(null,50),(null,100),(null,150);
|
||||
select * from t1 order by n;
|
||||
truncate table t1;
|
||||
set sql_log_bin=1;
|
||||
|
||||
insert into t1 values(null,100);
|
||||
select * from t1 order by n;
|
||||
sync_slave_with_master;
|
||||
# make slave's table autoinc counter bigger
|
||||
insert into t1 values(null,200),(null,300);
|
||||
delete from t1 where b <> 100;
|
||||
# check that slave's table content is identical to master
|
||||
select * from t1 order by n;
|
||||
# only the auto_inc counter differs.
|
||||
|
||||
connection master;
|
||||
replace into t1 values(null,100),(null,350);
|
||||
select * from t1 order by n;
|
||||
sync_slave_with_master;
|
||||
select * from t1 order by n;
|
||||
|
||||
# Same test as for REPLACE, but for ON DUPLICATE KEY UPDATE
|
||||
|
||||
# We first check that if we update a row using a value larger than the
|
||||
# table's counter, the counter for next row is bigger than the
|
||||
# after-value of the updated row.
|
||||
connection master;
|
||||
insert into t1 values (NULL,400),(3,500),(NULL,600) on duplicate key UPDATE n=1000;
|
||||
select * from t1 order by n;
|
||||
sync_slave_with_master;
|
||||
select * from t1 order by n;
|
||||
|
||||
# and now test for the bug:
|
||||
connection master;
|
||||
drop table t1;
|
||||
create table t1 (n int primary key auto_increment not null,
|
||||
b int, unique(b));
|
||||
insert into t1 values(null,100);
|
||||
select * from t1 order by n;
|
||||
sync_slave_with_master;
|
||||
insert into t1 values(null,200),(null,300);
|
||||
delete from t1 where b <> 100;
|
||||
select * from t1 order by n;
|
||||
|
||||
connection master;
|
||||
insert into t1 values(null,100),(null,350) on duplicate key update n=2;
|
||||
select * from t1 order by n;
|
||||
sync_slave_with_master;
|
||||
select * from t1 order by n;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
||||
sync_slave_with_master;
|
||||
|
|
|
@ -1471,6 +1471,26 @@ next_insert_id(ulonglong nr,struct system_variables *variables)
|
|||
}
|
||||
|
||||
|
||||
void handler::adjust_next_insert_id_after_explicit_value(ulonglong nr)
|
||||
{
|
||||
/*
|
||||
If we have set THD::next_insert_id previously and plan to insert an
|
||||
explicitely-specified value larger than this, we need to increase
|
||||
THD::next_insert_id to be greater than the explicit value.
|
||||
*/
|
||||
THD *thd= table->in_use;
|
||||
if (thd->clear_next_insert_id && (nr >= thd->next_insert_id))
|
||||
{
|
||||
if (thd->variables.auto_increment_increment != 1)
|
||||
nr= next_insert_id(nr, &thd->variables);
|
||||
else
|
||||
nr++;
|
||||
thd->next_insert_id= nr;
|
||||
DBUG_PRINT("info",("next_insert_id: %lu", (ulong) nr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Computes the largest number X:
|
||||
- smaller than or equal to "nr"
|
||||
|
@ -1587,17 +1607,7 @@ bool handler::update_auto_increment()
|
|||
/* Clear flag for next row */
|
||||
/* Mark that we didn't generate a new value **/
|
||||
auto_increment_column_changed=0;
|
||||
|
||||
/* Update next_insert_id if we have already generated a value */
|
||||
if (thd->clear_next_insert_id && nr >= thd->next_insert_id)
|
||||
{
|
||||
if (variables->auto_increment_increment != 1)
|
||||
nr= next_insert_id(nr, variables);
|
||||
else
|
||||
nr++;
|
||||
thd->next_insert_id= nr;
|
||||
DBUG_PRINT("info",("next_insert_id: %lu", (ulong) nr));
|
||||
}
|
||||
adjust_next_insert_id_after_explicit_value(nr);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (!(nr= thd->next_insert_id))
|
||||
|
|
|
@ -563,6 +563,7 @@ public:
|
|||
{}
|
||||
virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
|
||||
int ha_open(const char *name, int mode, int test_if_locked);
|
||||
void adjust_next_insert_id_after_explicit_value(ulonglong nr);
|
||||
bool update_auto_increment();
|
||||
virtual void print_error(int error, myf errflag);
|
||||
virtual bool get_error_message(int error, String *buf);
|
||||
|
|
|
@ -955,7 +955,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
uint key_nr;
|
||||
if (error != HA_WRITE_SKIP)
|
||||
goto err;
|
||||
table->file->restore_auto_increment();
|
||||
if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
|
||||
{
|
||||
error=HA_WRITE_SKIP; /* Database can't find key */
|
||||
|
@ -1028,20 +1027,20 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
if (res == VIEW_CHECK_ERROR)
|
||||
goto before_trg_err;
|
||||
|
||||
if (thd->clear_next_insert_id)
|
||||
{
|
||||
/* Reset auto-increment cacheing if we do an update */
|
||||
thd->clear_next_insert_id= 0;
|
||||
thd->next_insert_id= 0;
|
||||
}
|
||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||
{
|
||||
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
|
||||
{
|
||||
table->file->restore_auto_increment();
|
||||
goto ok_or_after_trg_err;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
info->updated++;
|
||||
|
||||
if (table->next_number_field)
|
||||
table->file->adjust_next_insert_id_after_explicit_value(table->next_number_field->val_int());
|
||||
|
||||
trg_error= (table->triggers &&
|
||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||
TRG_ACTION_AFTER, TRUE));
|
||||
|
@ -1070,12 +1069,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
{
|
||||
if (thd->clear_next_insert_id)
|
||||
{
|
||||
/* Reset auto-increment cacheing if we do an update */
|
||||
thd->clear_next_insert_id= 0;
|
||||
thd->next_insert_id= 0;
|
||||
}
|
||||
if ((error=table->file->update_row(table->record[1],
|
||||
table->record[0])))
|
||||
goto err;
|
||||
|
@ -1139,6 +1132,7 @@ err:
|
|||
table->file->print_error(error,MYF(0));
|
||||
|
||||
before_trg_err:
|
||||
table->file->restore_auto_increment();
|
||||
if (key)
|
||||
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
|
||||
DBUG_RETURN(1);
|
||||
|
|
Loading…
Reference in a new issue