Skip to content

Commit

Permalink
fix: CREATE TABLE (col TIMESTAMP(6) DEFAULT NOW(2))
Browse files Browse the repository at this point in the history
That is, when the precision of DEFAULT NOW() is less than
the precision of the column, do not convert it to unireg_check,
use the new approach where DEFAULT is tryly an expression.
  • Loading branch information
vuvova committed Aug 27, 2016
1 parent 73a220a commit 266563a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 70 deletions.
2 changes: 1 addition & 1 deletion mysql-test/r/default.result
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ CREATE or replace TABLE t1 (event_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIM
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(2) ON UPDATE CURRENT_TIMESTAMP(6)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE or replace TABLE t1 (event_time TIMESTAMP(6) NOT NULL DEFAULT SYSDATE(2) ON UPDATE CURRENT_TIMESTAMP);
SHOW CREATE TABLE t1;
Expand Down
4 changes: 2 additions & 2 deletions mysql-test/r/func_default.result
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ insert t1 () values ();
insert t1 (a) values (10);
select default(a),default(b),default(c),default(d),default(e),default(f) from t1;
default(a) default(b) default(c) default(d) default(e) default(f)
1 2 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.123456
1 11 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.123456
1 2 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000
1 11 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000
drop table t1;
67 changes: 49 additions & 18 deletions mysql-test/r/type_timestamp_hires.result
Original file line number Diff line number Diff line change
Expand Up @@ -272,33 +272,64 @@ select * from t1;
a
2011-01-01 01:01:01.12345
drop table t1;
create table t1 (a timestamp(5) default current_timestamp);
create or replace table t1 (a timestamp(5) default current_timestamp);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a timestamp(5) default current_timestamp());
drop table t1;
create table t1 (a timestamp(5) default current_timestamp(2));
create or replace table t1 (a timestamp(5) default current_timestamp());
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a timestamp(5) default current_timestamp(5));
drop table t1;
create table t1 (a timestamp(5) default current_timestamp(6));
drop table t1;
create table t1 (a timestamp(5) on update current_timestamp);
drop table t1;
create table t1 (a timestamp(5) on update current_timestamp());
drop table t1;
create table t1 (a timestamp(5) on update current_timestamp(3));
create or replace table t1 (a timestamp(5) default current_timestamp(2));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT current_timestamp(2)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert t1 () values ();
select * from t1;
a
2011-01-01 01:01:01.12000
create or replace table t1 (a timestamp(5) default current_timestamp(5));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1 (a timestamp(5) default current_timestamp(6));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1 (a timestamp(5) on update current_timestamp);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000' ON UPDATE CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1 (a timestamp(5) on update current_timestamp());
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000' ON UPDATE CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1 (a timestamp(5) on update current_timestamp(3));
ERROR HY000: Invalid ON UPDATE clause for 'a' column
create table t1 (a timestamp(5) on update current_timestamp(5));
drop table t1;
create table t1 (a timestamp(5) on update current_timestamp(6));
create or replace table t1 (a timestamp(5) on update current_timestamp(5));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000' ON UPDATE CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1 (a timestamp(5) on update current_timestamp(6));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000' ON UPDATE CURRENT_TIMESTAMP(5)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
32 changes: 20 additions & 12 deletions mysql-test/t/type_timestamp_hires.test
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,26 @@ drop table t1;
#
# MDEV-438 Microseconds: Precision is ignored in CURRENT_TIMESTAMP(N) when it is given as a default column value
#
create table t1 (a timestamp(5) default current_timestamp);
create or replace table t1 (a timestamp(5) default current_timestamp);
show create table t1;
drop table t1;
create table t1 (a timestamp(5) default current_timestamp()); drop table t1;
create table t1 (a timestamp(5) default current_timestamp(2));
create or replace table t1 (a timestamp(5) default current_timestamp());
show create table t1;
create or replace table t1 (a timestamp(5) default current_timestamp(2));
show create table t1;
insert t1 () values ();
select * from t1;
create or replace table t1 (a timestamp(5) default current_timestamp(5));
show create table t1;
create or replace table t1 (a timestamp(5) default current_timestamp(6));
show create table t1;
create or replace table t1 (a timestamp(5) on update current_timestamp);
show create table t1;
create or replace table t1 (a timestamp(5) on update current_timestamp());
show create table t1;
drop table t1;
create table t1 (a timestamp(5) default current_timestamp(5)); drop table t1;
create table t1 (a timestamp(5) default current_timestamp(6)); drop table t1;
create table t1 (a timestamp(5) on update current_timestamp); drop table t1;
create table t1 (a timestamp(5) on update current_timestamp()); drop table t1;
--error ER_INVALID_ON_UPDATE
create table t1 (a timestamp(5) on update current_timestamp(3));
create table t1 (a timestamp(5) on update current_timestamp(5)); drop table t1;
create table t1 (a timestamp(5) on update current_timestamp(6)); drop table t1;
create or replace table t1 (a timestamp(5) on update current_timestamp(3));
create or replace table t1 (a timestamp(5) on update current_timestamp(5));
show create table t1;
create or replace table t1 (a timestamp(5) on update current_timestamp(6));
show create table t1;
drop table t1;
58 changes: 21 additions & 37 deletions sql/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9863,59 +9863,43 @@ bool Column_definition::check(THD *thd)
}
}
}

if (default_value && (flags & AUTO_INCREMENT_FLAG))
{
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
DBUG_RETURN(1);
}

if (default_value && !default_value->expr_item->basic_const_item())
if (default_value && !default_value->expr_item->basic_const_item() &&
mysql_type_to_time_type(sql_type) == MYSQL_TIMESTAMP_DATETIME &&
default_value->expr_item->type() == Item::FUNC_ITEM)
{
Item *def_expr= default_value->expr_item;

unireg_check= Field::NONE;
/*
NOW() for TIMESTAMP and DATETIME fields are handled as in MariaDB 10.1
by marking them in unireg_check.
Special case: NOW() for TIMESTAMP and DATETIME fields are handled
as in MariaDB 10.1 by marking them in unireg_check.
*/
if (def_expr->type() == Item::FUNC_ITEM &&
(static_cast<Item_func*>(def_expr)->functype() ==
Item_func::NOW_FUNC &&
(mysql_type_to_time_type(sql_type) == MYSQL_TIMESTAMP_DATETIME)))
Item_func *fn= static_cast<Item_func*>(default_value->expr_item);
if (fn->functype() == Item_func::NOW_FUNC &&
(fn->decimals == 0 || fn->decimals >= length))
{
/*
We are not checking the number of decimals for timestamps
to allow one to write (for historical reasons)
TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
Instead we are going to use the number of decimals specifed by the
column.
*/
default_value= 0;
unireg_check= (on_update ?
Field::TIMESTAMP_DNUN_FIELD : // for insertions and for updates.
Field::TIMESTAMP_DN_FIELD); // only for insertions.
unireg_check= Field::TIMESTAMP_DN_FIELD;
}
else if (on_update)
unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
}
else
{
/* No function default for insertions. Either NULL or a constant. */
if (on_update)
unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
else
unireg_check= ((flags & AUTO_INCREMENT_FLAG) ?
Field::NEXT_NUMBER : // Automatic increment.
Field::NONE);
}

if (on_update &&
(mysql_type_to_time_type(sql_type) != MYSQL_TIMESTAMP_DATETIME ||
on_update->decimals < length))
if (on_update)
{
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
DBUG_RETURN(TRUE);
if (mysql_type_to_time_type(sql_type) != MYSQL_TIMESTAMP_DATETIME ||
on_update->decimals < length)
{
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
DBUG_RETURN(TRUE);
}
unireg_check= unireg_check == Field::NONE ? Field::TIMESTAMP_UN_FIELD
: Field::TIMESTAMP_DNUN_FIELD;
}
else if (flags & AUTO_INCREMENT_FLAG)
unireg_check= Field::NEXT_NUMBER;

sign_len= flags & UNSIGNED_FLAG ? 0 : 1;

Expand Down

0 comments on commit 266563a

Please sign in to comment.