mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge gbichot3.local:/home/mysql_src/mysql-5.0
into gbichot3.local:/home/mysql_src/mysql-5.1 mysql-test/r/rpl_auto_increment.result: Auto merged mysql-test/r/rpl_insert_id.result: Auto merged mysql-test/t/rpl_openssl.test: Auto merged sql/ha_ndbcluster.cc: Auto merged mysql-test/t/rpl_auto_increment.test: will fix by hand mysql-test/t/rpl_insert_id.test: will fix by hand sql/handler.cc: comment sql/handler.h: manual merge sql/sql_insert.cc: manual merge
This commit is contained in:
@ -183,3 +183,47 @@ a
|
|||||||
32
|
32
|
||||||
42
|
42
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a tinyint not null auto_increment primary key) engine=myisam;
|
||||||
|
insert into t1 values(103);
|
||||||
|
set auto_increment_increment=11;
|
||||||
|
set auto_increment_offset=4;
|
||||||
|
insert into t1 values(null);
|
||||||
|
insert into t1 values(null);
|
||||||
|
insert into t1 values(null);
|
||||||
|
ERROR 23000: Duplicate entry '125' for key 1
|
||||||
|
select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t1 order by a;
|
||||||
|
a mod(a-@@auto_increment_offset,@@auto_increment_increment)
|
||||||
|
103 0
|
||||||
|
114 0
|
||||||
|
125 0
|
||||||
|
create table t2 (a tinyint unsigned not null auto_increment primary key) engine=myisam;
|
||||||
|
set auto_increment_increment=10;
|
||||||
|
set auto_increment_offset=1;
|
||||||
|
set insert_id=1000;
|
||||||
|
insert into t2 values(null);
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'a' at row 1
|
||||||
|
select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 order by a;
|
||||||
|
a mod(a-@@auto_increment_offset,@@auto_increment_increment)
|
||||||
|
251 0
|
||||||
|
create table t3 like t1;
|
||||||
|
set auto_increment_increment=1000;
|
||||||
|
set auto_increment_offset=700;
|
||||||
|
insert into t3 values(null);
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'a' at row 1
|
||||||
|
select * from t3 order by a;
|
||||||
|
a
|
||||||
|
127
|
||||||
|
select * from t1 order by a;
|
||||||
|
a
|
||||||
|
103
|
||||||
|
114
|
||||||
|
125
|
||||||
|
select * from t2 order by a;
|
||||||
|
a
|
||||||
|
251
|
||||||
|
select * from t3 order by a;
|
||||||
|
a
|
||||||
|
127
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
@ -131,3 +131,68 @@ id last_id
|
|||||||
drop function bug15728;
|
drop function bug15728;
|
||||||
drop function bug15728_insert;
|
drop function bug15728_insert;
|
||||||
drop table t1, t2;
|
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;
|
||||||
|
@ -1533,6 +1533,66 @@ 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"
|
||||||
|
- of the form: auto_increment_offset + N * auto_increment_increment
|
||||||
|
where N>=0.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
prev_insert_id
|
||||||
|
nr Number to "round down"
|
||||||
|
variables variables struct containing auto_increment_increment and
|
||||||
|
auto_increment_offset
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
The number X if it exists, "nr" otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ulonglong
|
||||||
|
prev_insert_id(ulonglong nr, struct system_variables *variables)
|
||||||
|
{
|
||||||
|
if (unlikely(nr < variables->auto_increment_offset))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
There's nothing good we can do here. That is a pathological case, where
|
||||||
|
the offset is larger than the column's max possible value, i.e. not even
|
||||||
|
the first sequence value may be inserted. User will receive warning.
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
|
||||||
|
"auto_increment_offset: %lu",
|
||||||
|
nr, variables->auto_increment_offset));
|
||||||
|
return nr;
|
||||||
|
}
|
||||||
|
if (variables->auto_increment_increment == 1)
|
||||||
|
return nr; // optimization of the formula below
|
||||||
|
nr= (((nr - variables->auto_increment_offset)) /
|
||||||
|
(ulonglong) variables->auto_increment_increment);
|
||||||
|
return (nr * (ulonglong) variables->auto_increment_increment +
|
||||||
|
variables->auto_increment_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update the auto_increment field if necessary
|
Update the auto_increment field if necessary
|
||||||
|
|
||||||
@ -1624,22 +1684,13 @@ bool handler::update_auto_increment()
|
|||||||
a new value, write it down.
|
a new value, write it down.
|
||||||
*/
|
*/
|
||||||
auto_increment_column_changed=0;
|
auto_increment_column_changed=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update next_insert_id if we had already generated a value in this
|
Update next_insert_id if we had already generated a value in this
|
||||||
statement (case of INSERT VALUES(null),(3763),(null):
|
statement (case of INSERT VALUES(null),(3763),(null):
|
||||||
the last NULL needs to insert 3764, not the value of the first NULL plus
|
the last NULL needs to insert 3764, not the value of the first NULL plus
|
||||||
1).
|
1).
|
||||||
*/
|
*/
|
||||||
if (thd->clear_next_insert_id && nr >= thd->next_insert_id)
|
adjust_next_insert_id_after_explicit_value(nr);
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
if (!(nr= thd->next_insert_id))
|
if (!(nr= thd->next_insert_id))
|
||||||
@ -1706,10 +1757,19 @@ bool handler::update_auto_increment()
|
|||||||
/* Mark that we should clear next_insert_id before next stmt */
|
/* Mark that we should clear next_insert_id before next stmt */
|
||||||
thd->clear_next_insert_id= 1;
|
thd->clear_next_insert_id= 1;
|
||||||
|
|
||||||
if (!table->next_number_field->store((longlong) nr, TRUE))
|
if (likely(!table->next_number_field->store((longlong) nr, TRUE)))
|
||||||
thd->insert_id((ulonglong) nr);
|
thd->insert_id((ulonglong) nr);
|
||||||
else
|
else
|
||||||
thd->insert_id(table->next_number_field->val_int());
|
{
|
||||||
|
/*
|
||||||
|
overflow of the field; we'll use the max value, however we try to
|
||||||
|
decrease it to honour auto_increment_* variables:
|
||||||
|
*/
|
||||||
|
nr= prev_insert_id(table->next_number_field->val_int(), variables);
|
||||||
|
thd->insert_id(nr);
|
||||||
|
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
|
||||||
|
thd->insert_id(nr= table->next_number_field->val_int());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can't set next_insert_id if the auto-increment key is not the
|
We can't set next_insert_id if the auto-increment key is not the
|
||||||
|
@ -954,6 +954,7 @@ public:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
|
int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
|
||||||
|
void adjust_next_insert_id_after_explicit_value(ulonglong nr);
|
||||||
bool update_auto_increment();
|
bool update_auto_increment();
|
||||||
void print_keydup_error(uint key_nr, const char *msg);
|
void print_keydup_error(uint key_nr, const char *msg);
|
||||||
virtual void print_error(int error, myf errflag);
|
virtual void print_error(int error, myf errflag);
|
||||||
|
@ -980,7 +980,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
bool is_duplicate_key_error;
|
bool is_duplicate_key_error;
|
||||||
if (table->file->is_fatal_error(error, HA_CHECK_DUP))
|
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
|
|
||||||
is_duplicate_key_error= table->file->is_fatal_error(error, 0);
|
is_duplicate_key_error= table->file->is_fatal_error(error, 0);
|
||||||
if (!is_duplicate_key_error)
|
if (!is_duplicate_key_error)
|
||||||
{
|
{
|
||||||
@ -1067,22 +1066,22 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
if (res == VIEW_CHECK_ERROR)
|
if (res == VIEW_CHECK_ERROR)
|
||||||
goto before_trg_err;
|
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->ha_update_row(table->record[1],
|
if ((error=table->file->ha_update_row(table->record[1],
|
||||||
table->record[0])))
|
table->record[0])))
|
||||||
{
|
{
|
||||||
if (info->ignore &&
|
if (info->ignore &&
|
||||||
!table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
!table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||||
|
{
|
||||||
|
table->file->restore_auto_increment();
|
||||||
goto ok_or_after_trg_err;
|
goto ok_or_after_trg_err;
|
||||||
|
}
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
info->updated++;
|
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 &&
|
trg_error= (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||||
TRG_ACTION_AFTER, TRUE));
|
TRG_ACTION_AFTER, TRUE));
|
||||||
@ -1111,12 +1110,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
|
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
|
||||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
(!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->ha_update_row(table->record[1],
|
if ((error=table->file->ha_update_row(table->record[1],
|
||||||
table->record[0])))
|
table->record[0])))
|
||||||
goto err;
|
goto err;
|
||||||
@ -1187,6 +1180,7 @@ err:
|
|||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(0));
|
||||||
|
|
||||||
before_trg_err:
|
before_trg_err:
|
||||||
|
table->file->restore_auto_increment();
|
||||||
if (key)
|
if (key)
|
||||||
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
|
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
|
||||||
table->column_bitmaps_set(save_read_set, save_write_set);
|
table->column_bitmaps_set(save_read_set, save_write_set);
|
||||||
|
Reference in New Issue
Block a user