1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

WL#1266 "Separate auto-set logic from TIMESTAMP type."

Final version of patch.

Adds support for specifying of DEFAULT NOW() and/or ON UPDATE NOW()
clauses for TIMESTAMP field definition.
Current implementation allows only one such field per table and
uses several unireg types for storing info about this properties of
field. It should be replaced with better implementation when new
.frm format is introduced.
This commit is contained in:
dlenev@jabberwock.localdomain
2004-04-02 10:12:53 +04:00
parent 4533338075
commit f6bff2e6c6
54 changed files with 686 additions and 178 deletions

View File

@@ -44,6 +44,12 @@ create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
create table test (a datetime default now());
ERROR 42000: Invalid default value for 'a'
create table test (a datetime on update now());
ERROR HY000: Invalid ON UPDATE clause for 'a' field
create table test (a int default 100 auto_increment);
ERROR 42000: Invalid default value for 'a'
create table 1ea10 (1a20 int,1e int);
insert into 1ea10 values(1,1);
select 1ea10.1a20,1e+ 1e+10 from 1ea10;

View File

@@ -225,7 +225,7 @@ t1 CREATE TABLE `t1` (
`empty_char` char(0) default NULL,
`type_char` char(2) default NULL,
`type_varchar` varchar(10) default NULL,
`type_timestamp` timestamp NOT NULL,
`type_timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`type_date` date NOT NULL default '0000-00-00',
`type_time` time NOT NULL default '00:00:00',
`type_datetime` datetime NOT NULL default '0000-00-00 00:00:00',

View File

@@ -103,7 +103,7 @@ tables_priv CREATE TABLE `tables_priv` (
`User` char(16) character set latin1 collate latin1_bin NOT NULL default '',
`Table_name` char(64) character set latin1 collate latin1_bin NOT NULL default '',
`Grantor` char(77) NOT NULL default '',
`Timestamp` timestamp NOT NULL,
`Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') NOT NULL default '',
`Column_priv` set('Select','Insert','Update','References') NOT NULL default '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
@@ -117,7 +117,7 @@ columns_priv CREATE TABLE `columns_priv` (
`User` char(16) character set latin1 collate latin1_bin NOT NULL default '',
`Table_name` char(64) character set latin1 collate latin1_bin NOT NULL default '',
`Column_name` char(64) character set latin1 collate latin1_bin NOT NULL default '',
`Timestamp` timestamp NOT NULL,
`Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`Column_priv` set('Select','Insert','Update','References') NOT NULL default '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`,`Column_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Column privileges'

View File

@@ -54,7 +54,7 @@ ushort smallint(5) unsigned zerofill NULL MUL 00000 select,insert,update,refer
umedium mediumint(8) unsigned NULL MUL 0 select,insert,update,references
ulong int(11) unsigned NULL MUL 0 select,insert,update,references
ulonglong bigint(13) unsigned NULL MUL 0 select,insert,update,references
time_stamp timestamp NULL YES NULL select,insert,update,references
time_stamp timestamp NULL YES CURRENT_TIMESTAMP select,insert,update,references
date_field date NULL YES NULL select,insert,update,references
time_field time NULL YES NULL select,insert,update,references
date_time datetime NULL YES NULL select,insert,update,references
@@ -222,7 +222,7 @@ ushort smallint(5) unsigned zerofill NULL 00000 select,insert,update,referenc
umedium mediumint(8) unsigned NULL MUL 0 select,insert,update,references
ulong int(11) unsigned NULL MUL 0 select,insert,update,references
ulonglong bigint(13) unsigned NULL MUL 0 select,insert,update,references
time_stamp timestamp NULL YES NULL select,insert,update,references
time_stamp timestamp NULL YES CURRENT_TIMESTAMP select,insert,update,references
date_field varchar(10) latin1_swedish_ci YES NULL select,insert,update,references
time_field time NULL YES NULL select,insert,update,references
date_time datetime NULL YES NULL select,insert,update,references
@@ -248,7 +248,7 @@ ushort smallint(5) unsigned zerofill NULL 00000 select,insert,update,referenc
umedium mediumint(8) unsigned NULL 0 select,insert,update,references
ulong int(11) unsigned NULL 0 select,insert,update,references
ulonglong bigint(13) unsigned NULL 0 select,insert,update,references
time_stamp timestamp NULL YES NULL select,insert,update,references
time_stamp timestamp NULL YES 0000-00-00 00:00:00 select,insert,update,references
date_field varchar(10) latin1_swedish_ci YES NULL select,insert,update,references
time_field time NULL YES NULL select,insert,update,references
date_time datetime NULL YES NULL select,insert,update,references

View File

@@ -128,48 +128,206 @@ t2 t4 t6 t8 t10 t12 t14
0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
drop table t1;
create table t1 (t1 timestamp default '2003-01-01 00:00:00',
t2 timestamp default '2003-01-01 00:00:00');
set TIMESTAMP=1000000000;
insert into t1 values();
create table t1 (t1 timestamp, t2 timestamp default now());
ERROR HY000: Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
create table t1 (t1 timestamp, t2 timestamp on update now());
ERROR HY000: Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
ERROR HY000: Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
ERROR HY000: Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
ERROR HY000: Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000000;
insert into t1 values ();
SET TIMESTAMP=1000000001;
update t1 set t2=now();
SET TIMESTAMP=1000000002;
insert into t1 (t1,t3) values (default, default);
select * from t1;
t1 t2
2001-09-09 04:46:40 2003-01-01 00:00:00
t1 t2 t3
2003-01-01 00:00:00 2001-09-09 04:46:41 0000-00-00 00:00:00
2003-01-01 00:00:00 NULL 0000-00-00 00:00:00
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t1` timestamp NOT NULL,
`t2` timestamp NOT NULL default '2003-01-01 00:00:00'
`t1` timestamp NOT NULL default '2003-01-01 00:00:00',
`t2` datetime default NULL,
`t3` timestamp NOT NULL default '0000-00-00 00:00:00'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES NULL
t2 timestamp YES 2003-01-01 00:00:00
show columns from t1 like 't2';
Field Type Null Key Default Extra
t2 timestamp YES 2003-01-01 00:00:00
create table t2 (select * from t1);
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`t1` timestamp NOT NULL,
`t2` timestamp NOT NULL default '2003-01-01 00:00:00'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t1 add column t0 timestamp first;
t1 timestamp YES 2003-01-01 00:00:00
t2 datetime YES NULL
t3 timestamp YES 0000-00-00 00:00:00
drop table t1;
create table t1 (t1 timestamp default now(), t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000002;
insert into t1 values ();
SET TIMESTAMP=1000000003;
update t1 set t2=now();
SET TIMESTAMP=1000000003;
insert into t1 (t1,t3) values (default, default);
select * from t1;
t1 t2 t3
2001-09-09 04:46:42 2001-09-09 04:46:43 0000-00-00 00:00:00
2001-09-09 04:46:43 NULL 0000-00-00 00:00:00
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t0` timestamp NOT NULL,
`t1` timestamp NOT NULL default '2003-01-01 00:00:00',
`t2` timestamp NOT NULL default '2003-01-01 00:00:00'
`t1` timestamp NOT NULL default CURRENT_TIMESTAMP,
`t2` datetime default NULL,
`t3` timestamp NOT NULL default '0000-00-00 00:00:00'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
create table t1 (ts1 timestamp, ts2 timestamp);
set TIMESTAMP=1000000000;
insert into t1 values ();
insert into t1 values (DEFAULT, DEFAULT);
select * from t1;
ts1 ts2
2001-09-09 04:46:40 0000-00-00 00:00:00
2001-09-09 04:46:40 0000-00-00 00:00:00
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES CURRENT_TIMESTAMP
t2 datetime YES NULL
t3 timestamp YES 0000-00-00 00:00:00
drop table t1;
create table t1 (t1 timestamp default '2003-01-01 00:00:00' on update now(), t2 datetime);
SET TIMESTAMP=1000000004;
insert into t1 values ();
select * from t1;
t1 t2
2003-01-01 00:00:00 NULL
SET TIMESTAMP=1000000005;
update t1 set t2=now();
SET TIMESTAMP=1000000005;
insert into t1 (t1) values (default);
select * from t1;
t1 t2
2001-09-09 04:46:45 2001-09-09 04:46:45
2003-01-01 00:00:00 NULL
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t1` timestamp NOT NULL default '2003-01-01 00:00:00' on update CURRENT_TIMESTAMP,
`t2` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES 2003-01-01 00:00:00
t2 datetime YES NULL
drop table t1;
create table t1 (t1 timestamp default now() on update now(), t2 datetime);
SET TIMESTAMP=1000000006;
insert into t1 values ();
select * from t1;
t1 t2
2001-09-09 04:46:46 NULL
SET TIMESTAMP=1000000007;
update t1 set t2=now();
SET TIMESTAMP=1000000007;
insert into t1 (t1) values (default);
select * from t1;
t1 t2
2001-09-09 04:46:47 2001-09-09 04:46:47
2001-09-09 04:46:47 NULL
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t1` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`t2` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES CURRENT_TIMESTAMP
t2 datetime YES NULL
drop table t1;
create table t1 (t1 timestamp, t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000007;
insert into t1 values ();
select * from t1;
t1 t2 t3
2001-09-09 04:46:47 NULL 0000-00-00 00:00:00
SET TIMESTAMP=1000000008;
update t1 set t2=now();
SET TIMESTAMP=1000000008;
insert into t1 (t1,t3) values (default, default);
select * from t1;
t1 t2 t3
2001-09-09 04:46:48 2001-09-09 04:46:48 0000-00-00 00:00:00
2001-09-09 04:46:48 NULL 0000-00-00 00:00:00
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t1` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`t2` datetime default NULL,
`t3` timestamp NOT NULL default '0000-00-00 00:00:00'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES CURRENT_TIMESTAMP
t2 datetime YES NULL
t3 timestamp YES 0000-00-00 00:00:00
drop table t1;
create table t1 (t1 timestamp default current_timestamp on update current_timestamp, t2 datetime);
SET TIMESTAMP=1000000009;
insert into t1 values ();
select * from t1;
t1 t2
2001-09-09 04:46:49 NULL
SET TIMESTAMP=1000000010;
update t1 set t2=now();
SET TIMESTAMP=1000000011;
insert into t1 (t1) values (default);
select * from t1;
t1 t2
2001-09-09 04:46:50 2001-09-09 04:46:50
2001-09-09 04:46:51 NULL
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t1` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`t2` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
t1 timestamp YES CURRENT_TIMESTAMP
t2 datetime YES NULL
delete from t1;
insert into t1 values ('2004-04-01 00:00:00', '2004-04-01 00:00:00');
SET TIMESTAMP=1000000012;
update t1 set t1= '2004-04-02 00:00:00';
select * from t1;
t1 t2
2004-04-02 00:00:00 2004-04-01 00:00:00
update t1 as ta, t1 as tb set tb.t1= '2004-04-03 00:00:00';
select * from t1;
t1 t2
2004-04-03 00:00:00 2004-04-01 00:00:00
drop table t1;
create table t1 (pk int primary key, t1 timestamp default current_timestamp on update current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000013;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
pk t1 bulk
1 2001-09-09 04:46:53 20
drop table t1;
create table t1 (pk int primary key, t1 timestamp default '2003-01-01 00:00:00' on update current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000014;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
pk t1 bulk
1 2003-01-01 00:00:00 20
drop table t1;
create table t1 (pk int primary key, t1 timestamp default current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000015;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
pk t1 bulk
1 2001-09-09 04:46:55 20
drop table t1;
create table t1 (t1 timestamp default current_timestamp on update current_timestamp);
insert into t1 values ('2004-04-01 00:00:00');
SET TIMESTAMP=1000000016;
alter table t1 add i int default 10;
select * from t1;
t1 i
2004-04-01 00:00:00 10
drop table t1;

View File

@@ -48,6 +48,16 @@ create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
--error 1059
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
#
# Some wrong defaults, so these creates should fail too
#
--error 1067
create table test (a datetime default now());
--error 1294
create table test (a datetime on update now());
--error 1067
create table test (a int default 100 auto_increment);
#
# test of dummy table names
#

View File

@@ -76,35 +76,146 @@ select * from t1;
drop table t1;
#
# Bug #1885, bug #2539.
# Not perfect but still sensible attitude towards defaults for TIMESTAMP
# We will ignore default value for first TIMESTAMP column.
# Test for TIMESTAMP column with default now() and on update now() clauses
#
create table t1 (t1 timestamp default '2003-01-01 00:00:00',
t2 timestamp default '2003-01-01 00:00:00');
set TIMESTAMP=1000000000;
insert into t1 values();
# These statements should fail.
--error 1293
create table t1 (t1 timestamp, t2 timestamp default now());
--error 1293
create table t1 (t1 timestamp, t2 timestamp on update now());
--error 1293
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
--error 1293
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
--error 1293
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
# Let us test TIMESTAMP auto-update behaviour
# Also we will test behaviour of TIMESTAMP field in SHOW CREATE TABLE and
# behaviour of DEFAULT literal for such fields
create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000000;
insert into t1 values ();
SET TIMESTAMP=1000000001;
update t1 set t2=now();
SET TIMESTAMP=1000000002;
insert into t1 (t1,t3) values (default, default);
select * from t1;
show create table t1;
show columns from t1;
show columns from t1 like 't2';
create table t2 (select * from t1);
show create table t2;
drop table t1;
# Ugly, but we can't do anything about this in 4.0
alter table t1 add column t0 timestamp first;
show create table t1;
drop table t1,t2;
#
# Test for bug 2464, DEFAULT keyword in INSERT statement should return
# default value for column.
#
create table t1 (ts1 timestamp, ts2 timestamp);
set TIMESTAMP=1000000000;
create table t1 (t1 timestamp default now(), t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000002;
insert into t1 values ();
insert into t1 values (DEFAULT, DEFAULT);
SET TIMESTAMP=1000000003;
update t1 set t2=now();
SET TIMESTAMP=1000000003;
insert into t1 (t1,t3) values (default, default);
select * from t1;
show create table t1;
show columns from t1;
drop table t1;
create table t1 (t1 timestamp default '2003-01-01 00:00:00' on update now(), t2 datetime);
SET TIMESTAMP=1000000004;
insert into t1 values ();
select * from t1;
SET TIMESTAMP=1000000005;
update t1 set t2=now();
SET TIMESTAMP=1000000005;
insert into t1 (t1) values (default);
select * from t1;
show create table t1;
show columns from t1;
drop table t1;
create table t1 (t1 timestamp default now() on update now(), t2 datetime);
SET TIMESTAMP=1000000006;
insert into t1 values ();
select * from t1;
SET TIMESTAMP=1000000007;
update t1 set t2=now();
SET TIMESTAMP=1000000007;
insert into t1 (t1) values (default);
select * from t1;
show create table t1;
show columns from t1;
drop table t1;
create table t1 (t1 timestamp, t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000007;
insert into t1 values ();
select * from t1;
SET TIMESTAMP=1000000008;
update t1 set t2=now();
SET TIMESTAMP=1000000008;
insert into t1 (t1,t3) values (default, default);
select * from t1;
show create table t1;
show columns from t1;
drop table t1;
# Let us test if CURRENT_TIMESTAMP also works well as default value
# (Of course NOW and CURRENT_TIMESTAMP are same for parser but still just
# for demonstartion.)
create table t1 (t1 timestamp default current_timestamp on update current_timestamp, t2 datetime);
SET TIMESTAMP=1000000009;
insert into t1 values ();
select * from t1;
SET TIMESTAMP=1000000010;
update t1 set t2=now();
SET TIMESTAMP=1000000011;
insert into t1 (t1) values (default);
select * from t1;
show create table t1;
show columns from t1;
delete from t1;
#
# Let us test some cases when auto-set should be disabled or influence
# on server behavior in some other way.
#
# Update statement that explicitly sets field should not auto-set it.
insert into t1 values ('2004-04-01 00:00:00', '2004-04-01 00:00:00');
SET TIMESTAMP=1000000012;
update t1 set t1= '2004-04-02 00:00:00';
select * from t1;
# The same for multi updates
update t1 as ta, t1 as tb set tb.t1= '2004-04-03 00:00:00';
select * from t1;
drop table t1;
# Now let us test replace it should behave exactly like delete+insert
# Case where optimization is possible DEFAULT = ON UPDATE
create table t1 (pk int primary key, t1 timestamp default current_timestamp on update current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000013;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
drop table t1;
# Case in which there should not be optimisation
create table t1 (pk int primary key, t1 timestamp default '2003-01-01 00:00:00' on update current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000014;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
drop table t1;
# Other similar case
create table t1 (pk int primary key, t1 timestamp default current_timestamp, bulk int);
insert into t1 values (1, '2004-04-01 00:00:00', 10);
SET TIMESTAMP=1000000015;
replace into t1 set pk = 1, bulk= 20;
select * from t1;
drop table t1;
# Let us test alter now
create table t1 (t1 timestamp default current_timestamp on update current_timestamp);
insert into t1 values ('2004-04-01 00:00:00');
SET TIMESTAMP=1000000016;
alter table t1 add i int default 10;
select * from t1;
drop table t1;