Commit 0129f32b authored by unknown's avatar unknown

Manual merge of tree containing fix for bug #5915 "ALTER TABLE behaves

differently when converting column to auto_increment in 4.1" with
current tree.


mysql-test/t/type_timestamp.test:
  Auto merged
mysql-test/r/type_timestamp.result:
  Manual merge.
sql/sql_table.cc:
  Manual merge.
parents 5b3444d2 34789efd
...@@ -289,3 +289,55 @@ a b ...@@ -289,3 +289,55 @@ a b
0 13 0 13
500 14 500 14
drop table t1; drop table t1;
create table t1 (a bigint);
insert into t1 values (1), (2), (3), (NULL), (NULL);
alter table t1 modify a bigint not null auto_increment primary key;
select * from t1;
a
1
2
3
4
5
drop table t1;
create table t1 (a bigint);
insert into t1 values (1), (2), (3), (0), (0);
alter table t1 modify a bigint not null auto_increment primary key;
select * from t1;
a
1
2
3
4
5
drop table t1;
create table t1 (a bigint);
insert into t1 values (0), (1), (2), (3);
set sql_mode=NO_AUTO_VALUE_ON_ZERO;
alter table t1 modify a bigint not null auto_increment primary key;
set sql_mode= '';
select * from t1;
a
0
1
2
3
drop table t1;
create table t1 (a int auto_increment primary key , b int null);
set sql_mode=NO_AUTO_VALUE_ON_ZERO;
insert into t1 values (0,1),(1,2),(2,3);
select * from t1;
a b
0 1
1 2
2 3
set sql_mode= '';
alter table t1 modify b varchar(255);
insert into t1 values (0,4);
select * from t1;
a b
0 1
1 2
2 3
3 4
drop table t1;
...@@ -405,17 +405,14 @@ a b ...@@ -405,17 +405,14 @@ a b
NULL NULL NULL NULL
NULL 2003-01-01 00:00:00 NULL 2003-01-01 00:00:00
drop table t1; drop table t1;
create table t1 (ts timestamp(19)); create table t1 (a bigint, b bigint);
show create table t1; insert into t1 values (NULL, NULL), (20030101000000, 20030102000000);
Table Create Table set timestamp=1000000019;
t1 CREATE TABLE `t1` ( alter table t1 modify a timestamp, modify b timestamp;
`ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set TIMESTAMP=1000000000;
insert into t1 values ();
select * from t1; select * from t1;
ts a b
2001-09-09 04:46:40 2001-09-09 04:46:59 2001-09-09 04:46:59
2003-01-01 00:00:00 2003-01-02 00:00:00
drop table t1; drop table t1;
create table t1 (a char(2), t timestamp); create table t1 (a char(2), t timestamp);
insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'), insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'),
......
...@@ -168,3 +168,41 @@ update t1 set a=NULL where b=13; ...@@ -168,3 +168,41 @@ update t1 set a=NULL where b=13;
update t1 set a=500 where b=14; update t1 set a=500 where b=14;
select * from t1 order by b; select * from t1 order by b;
drop table t1; drop table t1;
#
# Test of behavior of ALTER TABLE when coulmn containing NULL or zeroes is
# converted to AUTO_INCREMENT column
#
create table t1 (a bigint);
insert into t1 values (1), (2), (3), (NULL), (NULL);
alter table t1 modify a bigint not null auto_increment primary key;
select * from t1;
drop table t1;
create table t1 (a bigint);
insert into t1 values (1), (2), (3), (0), (0);
alter table t1 modify a bigint not null auto_increment primary key;
select * from t1;
drop table t1;
# We still should be able to preserve zero in NO_AUTO_VALUE_ON_ZERO mode
create table t1 (a bigint);
insert into t1 values (0), (1), (2), (3);
set sql_mode=NO_AUTO_VALUE_ON_ZERO;
alter table t1 modify a bigint not null auto_increment primary key;
set sql_mode= '';
select * from t1;
drop table t1;
# It also sensible to preserve zeroes if we are converting auto_increment
# column to auto_increment column (or not touching it at all, which is more
# common case probably)
create table t1 (a int auto_increment primary key , b int null);
set sql_mode=NO_AUTO_VALUE_ON_ZERO;
insert into t1 values (0,1),(1,2),(2,3);
select * from t1;
set sql_mode= '';
alter table t1 modify b varchar(255);
insert into t1 values (0,4);
select * from t1;
drop table t1;
...@@ -267,13 +267,13 @@ select * from t1; ...@@ -267,13 +267,13 @@ select * from t1;
drop table t1; drop table t1;
# #
# Test for bug #4491, TIMESTAMP(19) should be possible to create and not # Let us test behavior of ALTER TABLE when it converts columns
# only read in 4.0 # containing NULL to TIMESTAMP columns.
# #
create table t1 (ts timestamp(19)); create table t1 (a bigint, b bigint);
show create table t1; insert into t1 values (NULL, NULL), (20030101000000, 20030102000000);
set TIMESTAMP=1000000000; set timestamp=1000000019;
insert into t1 values (); alter table t1 modify a timestamp, modify b timestamp;
select * from t1; select * from t1;
drop table t1; drop table t1;
......
...@@ -252,7 +252,8 @@ static void do_copy_timestamp(Copy_field *copy) ...@@ -252,7 +252,8 @@ static void do_copy_timestamp(Copy_field *copy)
{ {
if (*copy->from_null_ptr & copy->from_bit) if (*copy->from_null_ptr & copy->from_bit)
{ {
((Field_timestamp*) copy->to_field)->set_time();// Same as set_field_to_null /* Same as in set_field_to_null_with_conversions() */
((Field_timestamp*) copy->to_field)->set_time();
} }
else else
(copy->do_copy2)(copy); (copy->do_copy2)(copy);
...@@ -262,7 +263,11 @@ static void do_copy_timestamp(Copy_field *copy) ...@@ -262,7 +263,11 @@ static void do_copy_timestamp(Copy_field *copy)
static void do_copy_next_number(Copy_field *copy) static void do_copy_next_number(Copy_field *copy)
{ {
if (*copy->from_null_ptr & copy->from_bit) if (*copy->from_null_ptr & copy->from_bit)
copy->to_field->reset(); // Same as set_field_to_null {
/* Same as in set_field_to_null_with_conversions() */
copy->to_field->table->auto_increment_field_not_null= FALSE;
copy->to_field->reset();
}
else else
(copy->do_copy2)(copy); (copy->do_copy2)(copy);
} }
...@@ -437,18 +442,20 @@ void Copy_field::set(Field *to,Field *from,bool save) ...@@ -437,18 +442,20 @@ void Copy_field::set(Field *to,Field *from,bool save)
} }
} }
else else
do_copy=do_copy_not_null; {
if (to_field->type() == FIELD_TYPE_TIMESTAMP)
do_copy= do_copy_timestamp; // Automatic timestamp
else if (to_field == to_field->table->next_number_field)
do_copy= do_copy_next_number;
else
do_copy= do_copy_not_null;
}
} }
else if (to_field->real_maybe_null()) else if (to_field->real_maybe_null())
{ {
to_null_ptr= to->null_ptr; to_null_ptr= to->null_ptr;
to_bit= to->null_bit; to_bit= to->null_bit;
if (to_field->type() == FIELD_TYPE_TIMESTAMP) do_copy= do_copy_maybe_null;
do_copy=do_copy_timestamp; // Automatic timestamp
else if (to_field == to_field->table->next_number_field)
do_copy=do_copy_next_number;
else
do_copy=do_copy_maybe_null;
} }
else else
do_copy=0; do_copy=0;
......
...@@ -3302,8 +3302,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3302,8 +3302,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
List<Item> all_fields; List<Item> all_fields;
ha_rows examined_rows; ha_rows examined_rows;
bool auto_increment_field_copied= 0; bool auto_increment_field_copied= 0;
ulong old_sql_mode; ulong save_sql_mode;
bool no_auto_on_zero;
DBUG_ENTER("copy_data_between_tables"); DBUG_ENTER("copy_data_between_tables");
if (!(copy= new Copy_field[to->fields])) if (!(copy= new Copy_field[to->fields]))
...@@ -3314,6 +3313,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3314,6 +3313,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
from->file->info(HA_STATUS_VARIABLE); from->file->info(HA_STATUS_VARIABLE);
to->file->start_bulk_insert(from->file->records); to->file->start_bulk_insert(from->file->records);
save_sql_mode= thd->variables.sql_mode;
List_iterator<create_field> it(create); List_iterator<create_field> it(create);
create_field *def; create_field *def;
copy_end=copy; copy_end=copy;
...@@ -3323,7 +3324,17 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3323,7 +3324,17 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (def->field) if (def->field)
{ {
if (*ptr == to->next_number_field) if (*ptr == to->next_number_field)
{
auto_increment_field_copied= TRUE; auto_increment_field_copied= TRUE;
/*
If we are going to copy contents of one auto_increment column to
another auto_increment column it is sensible to preserve zeroes.
This condition also covers case when we are don't actually alter
auto_increment column.
*/
if (def->field == from->found_next_number_field)
thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
}
(copy_end++)->set(*ptr,def->field,0); (copy_end++)->set(*ptr,def->field,0);
} }
...@@ -3363,11 +3374,6 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3363,11 +3374,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
goto err; goto err;
} }
/* Turn on NO_AUTO_VALUE_ON_ZERO if not already on */
old_sql_mode= thd->variables.sql_mode;
if (!(no_auto_on_zero= thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO))
thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
/* Handler must be told explicitly to retrieve all columns, because /* Handler must be told explicitly to retrieve all columns, because
this function does not set field->query_id in the columns to the this function does not set field->query_id in the columns to the
current query id */ current query id */
...@@ -3425,10 +3431,6 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3425,10 +3431,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
ha_enable_transaction(thd,TRUE); ha_enable_transaction(thd,TRUE);
/* Turn off NO_AUTO_VALUE_ON_ZERO if it was not already off */
if (!no_auto_on_zero)
thd->variables.sql_mode= old_sql_mode;
/* /*
Ensure that the new table is saved properly to disk so that we Ensure that the new table is saved properly to disk so that we
can do a rename can do a rename
...@@ -3439,6 +3441,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3439,6 +3441,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
error=1; error=1;
err: err:
thd->variables.sql_mode= save_sql_mode;
free_io_cache(from); free_io_cache(from);
*copied= found_count; *copied= found_count;
*deleted=delete_count; *deleted=delete_count;
......
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