mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-452 Add full support for auto-initialized/updated timestamp and datetime
Generalized support for auto-updated and/or auto-initialized timestamp and datetime columns. This patch is a reimplementation of MySQL's "WL#5874: CURRENT_TIMESTAMP as DEFAULT for DATETIME columns". In order to ease future merges, this implementation reused few function and variable names from MySQL's patch, however the implementation is quite different. TODO: The only unresolved problem in this patch is the semantics of LOAD DATA for TIMESTAMP and DATETIME columns in the cases when there are missing or NULL columns. I couldn't fully comprehend the logic behind MySQL's behavior and its relationship with their own documentation, so I left the results to be more consistent with all other LOAD cases. The problematic test cases can be seen by running the test file function_defaults, and observing the test case differences. Those were left on purpose for discussion.
This commit is contained in:
parent
620d14f8c3
commit
bc4a456758
61 changed files with 5375 additions and 540 deletions
|
@ -128,6 +128,8 @@ enum enum_server_command
|
|||
reserved by MySQL Cluster */
|
||||
#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25,
|
||||
reserved by MySQL Cluster */
|
||||
#define HAS_EXPLICIT_DEFAULT (1 << 26) /* An INSERT/UPDATE operation supplied
|
||||
an explicit default value */
|
||||
|
||||
#define REFRESH_GRANT 1 /* Refresh grant tables */
|
||||
#define REFRESH_LOG 2 /* Start on new log file */
|
||||
|
|
1166
mysql-test/include/function_defaults.inc
Normal file
1166
mysql-test/include/function_defaults.inc
Normal file
File diff suppressed because it is too large
Load diff
94
mysql-test/include/function_defaults_notembedded.inc
Normal file
94
mysql-test/include/function_defaults_notembedded.inc
Normal file
|
@ -0,0 +1,94 @@
|
|||
SET TIME_ZONE = "+00:00";
|
||||
|
||||
--echo #
|
||||
--echo # Test of INSERT DELAYED ... SET ...
|
||||
--echo #
|
||||
|
||||
--echo # 2011-04-19 08:02:40 UTC
|
||||
SET TIMESTAMP = 1303200160.123456;
|
||||
|
||||
eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
|
||||
|
||||
INSERT DELAYED INTO t1 SET a = 1;
|
||||
FLUSH TABLE t1;
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t1 WHERE b = 0;
|
||||
|
||||
INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
|
||||
FLUSH TABLE t1;
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Test of INSERT DELAYED ... VALUES ...
|
||||
--echo #
|
||||
|
||||
--echo # 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.234567;
|
||||
|
||||
eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
|
||||
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1);
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Test of a delayed insert handler servicing two insert operations
|
||||
--echo # with different sets of active defaults.
|
||||
--echo #
|
||||
eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
|
||||
|
||||
--connect(con1, localhost, root,,)
|
||||
--echo # 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.345678;
|
||||
SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
|
||||
--send INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3)
|
||||
|
||||
--connection default
|
||||
SET debug_sync = 'now WAIT_FOR parked';
|
||||
|
||||
--connect(con2, localhost, root,,)
|
||||
--echo # 2011-04-19 08:04:01 UTC
|
||||
SET TIME_ZONE="+03:00";
|
||||
SET TIMESTAMP = 1303200241.456789;
|
||||
--send INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345')
|
||||
|
||||
--connection default
|
||||
SET debug_sync = 'now SIGNAL go';
|
||||
|
||||
--let $wait_condition= SELECT COUNT(*) = 6 FROM t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--sorted_result
|
||||
SELECT * FROM t1;
|
||||
|
||||
--disconnect con1
|
||||
--disconnect con2
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Test of early activation of function defaults.
|
||||
--echo #
|
||||
|
||||
eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
|
||||
|
||||
SET TIMESTAMP = 1317235172.987654; # 2011-09-28 18:39:32 UTC
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
|
||||
|
||||
SET TIMESTAMP = 385503754.876543; # 1982-03-20 20:22:34 UTC
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
|
||||
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
|
@ -55,9 +55,9 @@ ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|||
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
|
||||
ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
|
||||
create table t1 (a datetime default now());
|
||||
ERROR 42000: Invalid default value for 'a'
|
||||
drop table t1;
|
||||
create table t1 (a datetime on update now());
|
||||
ERROR HY000: Invalid ON UPDATE clause for 'a' column
|
||||
drop table t1;
|
||||
create table t1 (a int default 100 auto_increment);
|
||||
ERROR 42000: Invalid default value for 'a'
|
||||
create table t1 (a tinyint default 1000);
|
||||
|
|
3067
mysql-test/r/function_defaults.result
Normal file
3067
mysql-test/r/function_defaults.result
Normal file
File diff suppressed because it is too large
Load diff
171
mysql-test/r/function_defaults_notembedded.result
Normal file
171
mysql-test/r/function_defaults_notembedded.result
Normal file
|
@ -0,0 +1,171 @@
|
|||
#
|
||||
# Test of function defaults for non-embedded server.
|
||||
#
|
||||
#
|
||||
# Function defaults run 1. No microsecond precision.
|
||||
#
|
||||
SET TIME_ZONE = "+00:00";
|
||||
#
|
||||
# Test of INSERT DELAYED ... SET ...
|
||||
#
|
||||
# 2011-04-19 08:02:40 UTC
|
||||
SET TIMESTAMP = 1303200160.123456;
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
|
||||
INSERT DELAYED INTO t1 SET a = 1;
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:02:40
|
||||
SELECT * FROM t1 WHERE b = 0;
|
||||
a b
|
||||
INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:02:40
|
||||
2 1980-01-02 10:20:30
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of INSERT DELAYED ... VALUES ...
|
||||
#
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.234567;
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1);
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01
|
||||
INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01
|
||||
2 1977-12-19 12:34:56
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of a delayed insert handler servicing two insert operations
|
||||
# with different sets of active defaults.
|
||||
#
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.345678;
|
||||
SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
|
||||
SET debug_sync = 'now WAIT_FOR parked';
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIME_ZONE="+03:00";
|
||||
SET TIMESTAMP = 1303200241.456789;
|
||||
INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345');
|
||||
SET debug_sync = 'now SIGNAL go';
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01
|
||||
2 2011-04-19 08:04:01
|
||||
3 2011-04-19 08:04:01
|
||||
4 1977-12-19 09:34:56
|
||||
5 1977-12-19 09:34:57
|
||||
6 1977-12-19 09:34:58
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of early activation of function defaults.
|
||||
#
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
|
||||
SET TIMESTAMP = 1317235172.987654;
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
|
||||
SET TIMESTAMP = 385503754.876543;
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-09-28 18:39:32
|
||||
2 2011-09-28 18:39:32
|
||||
3 2011-09-28 18:39:32
|
||||
4 1982-03-20 20:22:34
|
||||
5 1982-03-20 20:22:34
|
||||
6 1982-03-20 20:22:34
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Function defaults run 2. Six digits scale on seconds precision.
|
||||
#
|
||||
SET TIME_ZONE = "+00:00";
|
||||
#
|
||||
# Test of INSERT DELAYED ... SET ...
|
||||
#
|
||||
# 2011-04-19 08:02:40 UTC
|
||||
SET TIMESTAMP = 1303200160.123456;
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
|
||||
INSERT DELAYED INTO t1 SET a = 1;
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:02:40.123456
|
||||
SELECT * FROM t1 WHERE b = 0;
|
||||
a b
|
||||
INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:02:40.123456
|
||||
2 1980-01-02 10:20:30.405060
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of INSERT DELAYED ... VALUES ...
|
||||
#
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.234567;
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1);
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01.234567
|
||||
INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01.234567
|
||||
2 1977-12-19 12:34:56.789123
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of a delayed insert handler servicing two insert operations
|
||||
# with different sets of active defaults.
|
||||
#
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIMESTAMP = 1303200241.345678;
|
||||
SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
|
||||
SET debug_sync = 'now WAIT_FOR parked';
|
||||
# 2011-04-19 08:04:01 UTC
|
||||
SET TIME_ZONE="+03:00";
|
||||
SET TIMESTAMP = 1303200241.456789;
|
||||
INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345');
|
||||
SET debug_sync = 'now SIGNAL go';
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-04-19 08:04:01.345678
|
||||
2 2011-04-19 08:04:01.345678
|
||||
3 2011-04-19 08:04:01.345678
|
||||
4 1977-12-19 09:34:56.789123
|
||||
5 1977-12-19 09:34:57.891234
|
||||
6 1977-12-19 09:34:58.912345
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test of early activation of function defaults.
|
||||
#
|
||||
CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
|
||||
SET TIMESTAMP = 1317235172.987654;
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
|
||||
SET TIMESTAMP = 385503754.876543;
|
||||
INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
|
||||
FLUSH TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2011-09-28 18:39:32.987654
|
||||
2 2011-09-28 18:39:32.987654
|
||||
3 2011-09-28 18:39:32.987654
|
||||
4 1982-03-20 20:22:34.876543
|
||||
5 1982-03-20 20:22:34.876543
|
||||
6 1982-03-20 20:22:34.876543
|
||||
DROP TABLE t1;
|
|
@ -44,7 +44,7 @@ select @@log_slow_verbosity;
|
|||
innodb
|
||||
show fields from mysql.slow_log;
|
||||
Field Type Null Key Default Extra
|
||||
start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
|
||||
start_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
|
||||
user_host mediumtext NO NULL
|
||||
query_time time(6) NO NULL
|
||||
lock_time time(6) NO NULL
|
||||
|
|
|
@ -53,7 +53,7 @@ ERROR HY000: You can't use locks with log tables.
|
|||
show create table mysql.general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -62,7 +62,7 @@ general_log CREATE TABLE `general_log` (
|
|||
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
|
||||
show fields from mysql.general_log;
|
||||
Field Type Null Key Default Extra
|
||||
event_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
|
||||
event_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
|
||||
user_host mediumtext NO NULL
|
||||
thread_id int(11) NO NULL
|
||||
server_id int(10) unsigned NO NULL
|
||||
|
@ -71,7 +71,7 @@ argument mediumtext NO NULL
|
|||
show create table mysql.slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
@ -85,7 +85,7 @@ slow_log CREATE TABLE `slow_log` (
|
|||
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
|
||||
show fields from mysql.slow_log;
|
||||
Field Type Null Key Default Extra
|
||||
start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
|
||||
start_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
|
||||
user_host mediumtext NO NULL
|
||||
query_time time(6) NO NULL
|
||||
lock_time time(6) NO NULL
|
||||
|
@ -164,7 +164,7 @@ set global slow_query_log='OFF';
|
|||
show create table mysql.general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -174,7 +174,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table mysql.slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
@ -191,7 +191,7 @@ alter table mysql.slow_log engine=myisam;
|
|||
show create table mysql.general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -201,7 +201,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table mysql.slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -5239,7 +5239,7 @@ Error 1146 Table 'mysql.event' doesn't exist
|
|||
SHOW CREATE TABLE mysql.general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -5249,7 +5249,7 @@ general_log CREATE TABLE `general_log` (
|
|||
SHOW CREATE TABLE mysql.slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||
show create table general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||
show create table general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||
show create table general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||
show create table general_log;
|
||||
Table Create Table
|
||||
general_log CREATE TABLE `general_log` (
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`thread_id` int(11) NOT NULL,
|
||||
`server_id` int(10) unsigned NOT NULL,
|
||||
|
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||
show create table slow_log;
|
||||
Table Create Table
|
||||
slow_log CREATE TABLE `slow_log` (
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
`user_host` mediumtext NOT NULL,
|
||||
`query_time` time(6) NOT NULL,
|
||||
`lock_time` time(6) NOT NULL,
|
||||
|
|
|
@ -148,15 +148,15 @@ ix+0
|
|||
20030101000000
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp, t2 timestamp default now());
|
||||
ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp, t2 timestamp on update now());
|
||||
ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
|
||||
ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
|
||||
ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
|
||||
ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 datetime, t3 timestamp);
|
||||
SET TIMESTAMP=1000000000;
|
||||
insert into t1 values ();
|
||||
|
|
|
@ -63,15 +63,15 @@ a
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
`a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4) ON UPDATE CURRENT_TIMESTAMP(4)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
show columns from t1;
|
||||
Field Type Null Key Default Extra
|
||||
a timestamp(4) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
|
||||
a timestamp(4) NO CURRENT_TIMESTAMP(4) on update CURRENT_TIMESTAMP
|
||||
select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1';
|
||||
table_name t1
|
||||
column_name a
|
||||
column_default CURRENT_TIMESTAMP
|
||||
column_default CURRENT_TIMESTAMP(4)
|
||||
is_nullable NO
|
||||
data_type timestamp
|
||||
character_maximum_length NULL
|
||||
|
@ -113,7 +113,7 @@ t2 CREATE TABLE `t2` (
|
|||
show create table t3;
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
`a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4) ON UPDATE CURRENT_TIMESTAMP(4)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
drop table t2, t3;
|
||||
insert t1 values ('2010-12-13 14:15:16.222222');
|
||||
|
|
13
mysql-test/std_data/onerow.xml
Normal file
13
mysql-test/std_data/onerow.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<database name="test">
|
||||
<table_structure name="onerow">
|
||||
<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
|
||||
</table_structure>
|
||||
<table_data name="onerow">
|
||||
<row>
|
||||
<field name="a">1</field>
|
||||
</row>
|
||||
</table_data>
|
||||
</database>
|
||||
</mysqldump>
|
|
@ -59,7 +59,7 @@ def mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1) sele
|
|||
def mysql func type 4 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('function','aggregate') select,insert,update,references
|
||||
def mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
|
||||
def mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select,insert,update,references
|
||||
def mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
|
||||
def mysql general_log event_time 1 CURRENT_TIMESTAMP(6) NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
|
||||
def mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
|
||||
def mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
|
||||
def mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
|
||||
|
@ -159,7 +159,7 @@ def mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int
|
|||
def mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
|
||||
def mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
|
||||
def mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
|
||||
def mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
|
||||
def mysql slow_log start_time 1 CURRENT_TIMESTAMP(6) NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
|
||||
def mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
|
||||
def mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
|
||||
def mysql tables_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
|
||||
|
|
132
mysql-test/suite/rpl/r/rpl_function_defaults.result
Normal file
132
mysql-test/suite/rpl/r/rpl_function_defaults.result
Normal file
|
@ -0,0 +1,132 @@
|
|||
#
|
||||
# Test of function defaults on replicated tables.
|
||||
#
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
connection master
|
||||
SET TIME_ZONE="+10:30";
|
||||
SET TIMESTAMP=123456.789123;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
CURRENT_TIMESTAMP
|
||||
1970-01-02 20:47:36
|
||||
connection slave
|
||||
SET TIME_ZONE="+00:00";
|
||||
SET TIMESTAMP=987654321.123456;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
CURRENT_TIMESTAMP
|
||||
2001-04-19 04:25:21
|
||||
connection master
|
||||
CREATE TABLE t1 (
|
||||
a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
b TIMESTAMP(1) NOT NULL DEFAULT CURRENT_TIMESTAMP(1),
|
||||
c TIMESTAMP(2) NOT NULL DEFAULT CURRENT_TIMESTAMP(2),
|
||||
d TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
e TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4),
|
||||
f TIMESTAMP(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5),
|
||||
g TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
h DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
i DATETIME(1) DEFAULT CURRENT_TIMESTAMP(1),
|
||||
j DATETIME(2) DEFAULT CURRENT_TIMESTAMP(2),
|
||||
k DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
|
||||
l DATETIME(4) DEFAULT CURRENT_TIMESTAMP(4),
|
||||
m DATETIME(5) DEFAULT CURRENT_TIMESTAMP(5),
|
||||
n DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
||||
o INT
|
||||
);
|
||||
INSERT INTO t1 ( o ) VALUES ( 1 );
|
||||
CREATE TABLE t2 (
|
||||
a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
|
||||
b TIMESTAMP(1) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(1),
|
||||
c TIMESTAMP(2) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(2),
|
||||
d TIMESTAMP(3) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
e TIMESTAMP(4) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(4),
|
||||
f TIMESTAMP(5) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(5),
|
||||
g TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
h DATETIME ON UPDATE CURRENT_TIMESTAMP,
|
||||
i DATETIME(1) ON UPDATE CURRENT_TIMESTAMP(1),
|
||||
j DATETIME(2) ON UPDATE CURRENT_TIMESTAMP(2),
|
||||
k DATETIME(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
l DATETIME(4) ON UPDATE CURRENT_TIMESTAMP(4),
|
||||
m DATETIME(5) ON UPDATE CURRENT_TIMESTAMP(5),
|
||||
n DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
o INT
|
||||
);
|
||||
INSERT INTO t2 ( o ) VALUES ( 1 );
|
||||
sync_slave_with_master
|
||||
connection slave
|
||||
SELECT * FROM t1;
|
||||
a 1970-01-02 10:17:36
|
||||
b 1970-01-02 10:17:36.7
|
||||
c 1970-01-02 10:17:36.78
|
||||
d 1970-01-02 10:17:36.789
|
||||
e 1970-01-02 10:17:36.7891
|
||||
f 1970-01-02 10:17:36.78912
|
||||
g 1970-01-02 10:17:36.789123
|
||||
h 1970-01-02 20:47:36
|
||||
i 1970-01-02 20:47:36.7
|
||||
j 1970-01-02 20:47:36.78
|
||||
k 1970-01-02 20:47:36.789
|
||||
l 1970-01-02 20:47:36.7891
|
||||
m 1970-01-02 20:47:36.78912
|
||||
n 1970-01-02 20:47:36.789123
|
||||
o 1
|
||||
SELECT * FROM t2;
|
||||
a 0000-00-00 00:00:00
|
||||
b 0000-00-00 00:00:00.0
|
||||
c 0000-00-00 00:00:00.00
|
||||
d 0000-00-00 00:00:00.000
|
||||
e 0000-00-00 00:00:00.0000
|
||||
f 0000-00-00 00:00:00.00000
|
||||
g 0000-00-00 00:00:00.000000
|
||||
h NULL
|
||||
i NULL
|
||||
j NULL
|
||||
k NULL
|
||||
l NULL
|
||||
m NULL
|
||||
n NULL
|
||||
o 1
|
||||
connection master
|
||||
SET TIMESTAMP=1234567890.123456;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
CURRENT_TIMESTAMP
|
||||
2009-02-14 10:01:30
|
||||
UPDATE t1 SET o = 2;
|
||||
UPDATE t2 SET o = 2;
|
||||
sync_slave_with_master
|
||||
connection slave
|
||||
SELECT * FROM t1;
|
||||
a 1970-01-02 10:17:36
|
||||
b 1970-01-02 10:17:36.7
|
||||
c 1970-01-02 10:17:36.78
|
||||
d 1970-01-02 10:17:36.789
|
||||
e 1970-01-02 10:17:36.7891
|
||||
f 1970-01-02 10:17:36.78912
|
||||
g 1970-01-02 10:17:36.789123
|
||||
h 1970-01-02 20:47:36
|
||||
i 1970-01-02 20:47:36.7
|
||||
j 1970-01-02 20:47:36.78
|
||||
k 1970-01-02 20:47:36.789
|
||||
l 1970-01-02 20:47:36.7891
|
||||
m 1970-01-02 20:47:36.78912
|
||||
n 1970-01-02 20:47:36.789123
|
||||
o 2
|
||||
SELECT * FROM t2;
|
||||
a 2009-02-13 23:31:30
|
||||
b 2009-02-13 23:31:30.1
|
||||
c 2009-02-13 23:31:30.12
|
||||
d 2009-02-13 23:31:30.123
|
||||
e 2009-02-13 23:31:30.1234
|
||||
f 2009-02-13 23:31:30.12345
|
||||
g 2009-02-13 23:31:30.123456
|
||||
h 2009-02-14 10:01:30
|
||||
i 2009-02-14 10:01:30.1
|
||||
j 2009-02-14 10:01:30.12
|
||||
k 2009-02-14 10:01:30.123
|
||||
l 2009-02-14 10:01:30.1234
|
||||
m 2009-02-14 10:01:30.12345
|
||||
n 2009-02-14 10:01:30.123456
|
||||
o 2
|
||||
connection master
|
||||
DROP TABLE t1, t2;
|
||||
include/rpl_end.inc
|
93
mysql-test/suite/rpl/t/rpl_function_defaults.test
Normal file
93
mysql-test/suite/rpl/t/rpl_function_defaults.test
Normal file
|
@ -0,0 +1,93 @@
|
|||
--echo #
|
||||
--echo # Test of function defaults on replicated tables.
|
||||
--echo #
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
--echo connection master
|
||||
connection master;
|
||||
SET TIME_ZONE="+10:30";
|
||||
SET TIMESTAMP=123456.789123;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
|
||||
--echo connection slave
|
||||
connection slave;
|
||||
SET TIME_ZONE="+00:00";
|
||||
SET TIMESTAMP=987654321.123456;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
|
||||
--echo connection master
|
||||
connection master;
|
||||
CREATE TABLE t1 (
|
||||
a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
b TIMESTAMP(1) NOT NULL DEFAULT CURRENT_TIMESTAMP(1),
|
||||
c TIMESTAMP(2) NOT NULL DEFAULT CURRENT_TIMESTAMP(2),
|
||||
d TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
e TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4),
|
||||
f TIMESTAMP(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5),
|
||||
g TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
h DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
i DATETIME(1) DEFAULT CURRENT_TIMESTAMP(1),
|
||||
j DATETIME(2) DEFAULT CURRENT_TIMESTAMP(2),
|
||||
k DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
|
||||
l DATETIME(4) DEFAULT CURRENT_TIMESTAMP(4),
|
||||
m DATETIME(5) DEFAULT CURRENT_TIMESTAMP(5),
|
||||
n DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
||||
o INT
|
||||
);
|
||||
|
||||
INSERT INTO t1 ( o ) VALUES ( 1 );
|
||||
|
||||
CREATE TABLE t2 (
|
||||
a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
|
||||
b TIMESTAMP(1) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(1),
|
||||
c TIMESTAMP(2) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(2),
|
||||
d TIMESTAMP(3) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
e TIMESTAMP(4) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(4),
|
||||
f TIMESTAMP(5) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(5),
|
||||
g TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
h DATETIME ON UPDATE CURRENT_TIMESTAMP,
|
||||
i DATETIME(1) ON UPDATE CURRENT_TIMESTAMP(1),
|
||||
j DATETIME(2) ON UPDATE CURRENT_TIMESTAMP(2),
|
||||
k DATETIME(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
l DATETIME(4) ON UPDATE CURRENT_TIMESTAMP(4),
|
||||
m DATETIME(5) ON UPDATE CURRENT_TIMESTAMP(5),
|
||||
n DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
o INT
|
||||
);
|
||||
|
||||
INSERT INTO t2 ( o ) VALUES ( 1 );
|
||||
|
||||
--echo sync_slave_with_master
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo connection slave
|
||||
connection slave;
|
||||
|
||||
query_vertical SELECT * FROM t1;
|
||||
query_vertical SELECT * FROM t2;
|
||||
|
||||
--echo connection master
|
||||
connection master;
|
||||
|
||||
SET TIMESTAMP=1234567890.123456;
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
|
||||
UPDATE t1 SET o = 2;
|
||||
UPDATE t2 SET o = 2;
|
||||
|
||||
--echo sync_slave_with_master
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo connection slave
|
||||
connection slave;
|
||||
|
||||
query_vertical SELECT * FROM t1;
|
||||
query_vertical SELECT * FROM t2;
|
||||
|
||||
--echo connection master
|
||||
connection master;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--source include/rpl_end.inc
|
|
@ -55,10 +55,10 @@ create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|||
#
|
||||
# Some wrong defaults, so these creates should fail too (Bug #5902)
|
||||
#
|
||||
--error 1067
|
||||
create table t1 (a datetime default now());
|
||||
--error 1294
|
||||
drop table t1;
|
||||
create table t1 (a datetime on update now());
|
||||
drop table t1;
|
||||
--error 1067
|
||||
create table t1 (a int default 100 auto_increment);
|
||||
--error 1067
|
||||
|
|
23
mysql-test/t/function_defaults.test
Normal file
23
mysql-test/t/function_defaults.test
Normal file
|
@ -0,0 +1,23 @@
|
|||
--echo #
|
||||
--echo # Test of function defaults for any server, including embedded.
|
||||
--echo #
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo #
|
||||
--echo # Function defaults run 1. No microsecond precision.
|
||||
--echo #
|
||||
let $current_timestamp=CURRENT_TIMESTAMP;
|
||||
let $now=NOW();
|
||||
let $timestamp=TIMESTAMP;
|
||||
let $datetime=DATETIME;
|
||||
source 'include/function_defaults.inc';
|
||||
|
||||
--echo #
|
||||
--echo # Function defaults run 2. Six digits scale on seconds precision.
|
||||
--echo #
|
||||
let $current_timestamp=CURRENT_TIMESTAMP(6);
|
||||
let $now=NOW(6);
|
||||
let $timestamp=TIMESTAMP(6);
|
||||
let $datetime=DATETIME(6);
|
||||
source 'include/function_defaults.inc';
|
18
mysql-test/t/function_defaults_notembedded.test
Normal file
18
mysql-test/t/function_defaults_notembedded.test
Normal file
|
@ -0,0 +1,18 @@
|
|||
--echo #
|
||||
--echo # Test of function defaults for non-embedded server.
|
||||
--echo #
|
||||
|
||||
--source include/not_embedded.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
--echo #
|
||||
--echo # Function defaults run 1. No microsecond precision.
|
||||
--echo #
|
||||
let $timestamp=TIMESTAMP;
|
||||
--source include/function_defaults_notembedded.inc
|
||||
|
||||
--echo #
|
||||
--echo # Function defaults run 2. Six digits scale on seconds precision.
|
||||
--echo #
|
||||
let $timestamp=TIMESTAMP(6);
|
||||
--source include/function_defaults_notembedded.inc
|
|
@ -86,17 +86,16 @@ drop table t1;
|
|||
# Test for TIMESTAMP column with default now() and on update now() clauses
|
||||
#
|
||||
|
||||
# These statements should fail.
|
||||
--error 1293
|
||||
create table t1 (t1 timestamp, t2 timestamp default now());
|
||||
--error 1293
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp, t2 timestamp on update now());
|
||||
--error 1293
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
|
||||
--error 1293
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
|
||||
--error 1293
|
||||
drop table t1;
|
||||
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
|
||||
drop table t1;
|
||||
|
||||
# Let us test TIMESTAMP auto-update behaviour
|
||||
# Also we will test behaviour of TIMESTAMP field in SHOW CREATE TABLE and
|
||||
|
|
|
@ -829,9 +829,6 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
|
|||
(int) table->field[ET_FIELD_ON_COMPLETION]->val_int()))
|
||||
goto end;
|
||||
|
||||
/* Don't update create on row update. */
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
/*
|
||||
mysql_event_fill_row() calls my_error() in case of error so no need to
|
||||
handle it here
|
||||
|
@ -1133,8 +1130,6 @@ update_timing_fields_for_event(THD *thd,
|
|||
goto end;
|
||||
|
||||
store_record(table, record[1]);
|
||||
/* Don't update create on row update. */
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
|
||||
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
|
||||
|
|
157
sql/field.cc
157
sql/field.cc
|
@ -4419,10 +4419,12 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
|
|||
{
|
||||
/* For 4.0 MYD and 4.0 InnoDB compatibility */
|
||||
flags|= UNSIGNED_FLAG | BINARY_FLAG;
|
||||
if (unireg_check != NONE && !share->timestamp_field)
|
||||
if (unireg_check != NONE)
|
||||
{
|
||||
/* This timestamp has auto-update */
|
||||
share->timestamp_field= this;
|
||||
/*
|
||||
This TIMESTAMP column is hereby quietly assumed to have an insert or
|
||||
update default function.
|
||||
*/
|
||||
flags|= TIMESTAMP_FLAG;
|
||||
if (unireg_check != TIMESTAMP_DN_FIELD)
|
||||
flags|= ON_UPDATE_NOW_FLAG;
|
||||
|
@ -4430,40 +4432,6 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Get auto-set type for TIMESTAMP field.
|
||||
|
||||
Returns value indicating during which operations this TIMESTAMP field
|
||||
should be auto-set to current timestamp.
|
||||
*/
|
||||
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
|
||||
{
|
||||
switch (unireg_check)
|
||||
{
|
||||
case TIMESTAMP_DN_FIELD:
|
||||
return TIMESTAMP_AUTO_SET_ON_INSERT;
|
||||
case TIMESTAMP_UN_FIELD:
|
||||
return TIMESTAMP_AUTO_SET_ON_UPDATE;
|
||||
case TIMESTAMP_OLD_FIELD:
|
||||
/*
|
||||
Although we can have several such columns in legacy tables this
|
||||
function should be called only for first of them (i.e. the one
|
||||
having auto-set property).
|
||||
*/
|
||||
DBUG_ASSERT(table->timestamp_field == this);
|
||||
/* Fall-through */
|
||||
case TIMESTAMP_DNUN_FIELD:
|
||||
return TIMESTAMP_AUTO_SET_ON_BOTH;
|
||||
default:
|
||||
/*
|
||||
Normally this function should not be called for TIMESTAMPs without
|
||||
auto-set property.
|
||||
*/
|
||||
DBUG_ASSERT(0);
|
||||
return TIMESTAMP_NO_AUTO_SET;
|
||||
}
|
||||
}
|
||||
|
||||
my_time_t Field_timestamp::get_timestamp(ulong *sec_part) const
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
|
@ -4713,6 +4681,16 @@ int Field_timestamp::set_time()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Field_timestamp::set_explicit_default(Item *value)
|
||||
{
|
||||
if (value &&
|
||||
((value->type() == Item::DEFAULT_VALUE_ITEM &&
|
||||
!((Item_default_value*)value)->arg) ||
|
||||
(!maybe_null() && value->is_null())))
|
||||
return;
|
||||
flags|= HAS_EXPLICIT_DEFAULT;
|
||||
}
|
||||
|
||||
void Field_timestamp_hires::sql_type(String &res) const
|
||||
{
|
||||
CHARSET_INFO *cs=res.charset();
|
||||
|
@ -5836,6 +5814,20 @@ void Field_datetime::sql_type(String &res) const
|
|||
res.set_ascii(STRING_WITH_LEN("datetime"));
|
||||
}
|
||||
|
||||
|
||||
int Field_datetime::set_time()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
MYSQL_TIME now_time;
|
||||
thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start());
|
||||
now_time.second_part= thd->query_start_sec_part();
|
||||
set_notnull();
|
||||
store_TIME(&now_time);
|
||||
thd->time_zone_used= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
|
||||
{
|
||||
ulonglong packed= sec_part_shift(pack_time(ltime), dec);
|
||||
|
@ -8857,16 +8849,37 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||
{
|
||||
uint sign_len, allowed_type_modifier= 0;
|
||||
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
||||
const bool on_update_is_function=
|
||||
(fld_on_update_value != NULL &&
|
||||
fld_on_update_value->type() == Item::FUNC_ITEM);
|
||||
|
||||
DBUG_ENTER("Create_field::init()");
|
||||
|
||||
field= 0;
|
||||
field_name= fld_name;
|
||||
def= fld_default_value;
|
||||
flags= fld_type_modifier;
|
||||
option_list= create_opt;
|
||||
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
|
||||
Field::NEXT_NUMBER : Field::NONE);
|
||||
|
||||
if (fld_default_value != NULL && fld_default_value->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
/* We have a function default for insertions. */
|
||||
def= NULL;
|
||||
unireg_check= on_update_is_function ?
|
||||
Field::TIMESTAMP_DNUN_FIELD : // for insertions and for updates.
|
||||
Field::TIMESTAMP_DN_FIELD; // only for insertions.
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No function default for insertions. Either NULL or a constant. */
|
||||
def= fld_default_value;
|
||||
if (on_update_is_function)
|
||||
unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
|
||||
else
|
||||
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG) != 0 ?
|
||||
Field::NEXT_NUMBER : // Automatic increment.
|
||||
Field::NONE;
|
||||
}
|
||||
|
||||
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
|
||||
if (decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
|
@ -9089,44 +9102,6 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||
}
|
||||
length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
|
||||
flags|= UNSIGNED_FLAG;
|
||||
|
||||
if (fld_default_value)
|
||||
{
|
||||
/* Grammar allows only NOW() value for ON UPDATE clause */
|
||||
if (fld_default_value->type() == Item::FUNC_ITEM &&
|
||||
((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
|
||||
{
|
||||
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
|
||||
Field::TIMESTAMP_DN_FIELD);
|
||||
/*
|
||||
We don't need default value any longer moreover it is dangerous.
|
||||
Everything handled by unireg_check further.
|
||||
*/
|
||||
def= 0;
|
||||
}
|
||||
else
|
||||
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
|
||||
Field::NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
|
||||
or ON UPDATE values then for the sake of compatiblity we should treat
|
||||
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
|
||||
have another TIMESTAMP column with auto-set option before this one)
|
||||
or DEFAULT 0 (in other cases).
|
||||
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
|
||||
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
|
||||
information about all TIMESTAMP fields in table will be availiable.
|
||||
|
||||
If we have TIMESTAMP NULL column without explicit DEFAULT value
|
||||
we treat it as having DEFAULT NULL attribute.
|
||||
*/
|
||||
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
|
||||
(flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
|
||||
Field::NONE));
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
/* We don't support creation of MYSQL_TYPE_DATE anymore */
|
||||
|
@ -9592,11 +9567,18 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
|
|||
def=0;
|
||||
char_length= length;
|
||||
|
||||
if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
|
||||
old_field->ptr && orig_field &&
|
||||
(sql_type != MYSQL_TYPE_TIMESTAMP || /* set def only if */
|
||||
old_field->table->timestamp_field != old_field || /* timestamp field */
|
||||
unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
|
||||
/*
|
||||
Copy the default value from the column object orig_field, if:
|
||||
1) The column has a constant default value.
|
||||
2) The column type is not a BLOB type.
|
||||
3) The original column (old_field) was properly initialized with a record
|
||||
buffer pointer.
|
||||
4) The original column doesn't have a default function to auto-initialize
|
||||
the column on INSERT
|
||||
*/
|
||||
if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) && // 1) 2)
|
||||
old_field->ptr && orig_field && // 3)
|
||||
!old_field->has_insert_default_function()) // 4)
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff), charset);
|
||||
|
@ -9780,3 +9762,12 @@ key_map Field::get_possible_keys()
|
|||
return (table->pos_in_table_list->is_materialized_derived() ?
|
||||
part_of_key : key_start);
|
||||
}
|
||||
|
||||
|
||||
void Field::set_explicit_default(Item *value)
|
||||
{
|
||||
if (value && value->type() == Item::DEFAULT_VALUE_ITEM &&
|
||||
!((Item_default_value*)value)->arg)
|
||||
return;
|
||||
flags|= HAS_EXPLICIT_DEFAULT;
|
||||
}
|
||||
|
|
72
sql/field.h
72
sql/field.h
|
@ -329,6 +329,37 @@ public:
|
|||
*null_ptr= ((*null_ptr & (uchar) ~null_bit) |
|
||||
(null_ptr[l_offset] & null_bit));
|
||||
}
|
||||
|
||||
bool has_insert_default_function() const
|
||||
{
|
||||
return unireg_check == TIMESTAMP_DN_FIELD ||
|
||||
unireg_check == TIMESTAMP_DNUN_FIELD;
|
||||
}
|
||||
|
||||
bool has_update_default_function() const
|
||||
{
|
||||
return unireg_check == TIMESTAMP_UN_FIELD ||
|
||||
unireg_check == TIMESTAMP_DNUN_FIELD;
|
||||
}
|
||||
|
||||
virtual void set_explicit_default(Item *value);
|
||||
|
||||
/**
|
||||
Evaluates the @c INSERT default function and stores the result in the
|
||||
field. If no such function exists for the column, or the function is not
|
||||
valid for the column's data type, invoking this function has no effect.
|
||||
*/
|
||||
virtual int evaluate_insert_default_function() { return 0; }
|
||||
|
||||
|
||||
/**
|
||||
Evaluates the @c UPDATE default function, if one exists, and stores the
|
||||
result in the record buffer. If no such function exists for the column,
|
||||
or the function is not valid for the column's data type, invoking this
|
||||
function has no effect.
|
||||
*/
|
||||
virtual int evaluate_update_default_function() { return 0; }
|
||||
|
||||
virtual bool binary() const { return 1; }
|
||||
virtual bool zero_pack() const { return 1; }
|
||||
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||
|
@ -1239,12 +1270,26 @@ public:
|
|||
virtual int set_time();
|
||||
virtual void set_default()
|
||||
{
|
||||
if (table->timestamp_field == this &&
|
||||
unireg_check != TIMESTAMP_UN_FIELD)
|
||||
if (has_insert_default_function())
|
||||
set_time();
|
||||
else
|
||||
Field::set_default();
|
||||
}
|
||||
virtual void set_explicit_default(Item *value);
|
||||
virtual int evaluate_insert_default_function()
|
||||
{
|
||||
int res= 0;
|
||||
if (has_insert_default_function())
|
||||
res= set_time();
|
||||
return res;
|
||||
}
|
||||
virtual int evaluate_update_default_function()
|
||||
{
|
||||
int res= 0;
|
||||
if (has_update_default_function())
|
||||
res= set_time();
|
||||
return res;
|
||||
}
|
||||
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
|
||||
virtual my_time_t get_timestamp(ulong *sec_part) const;
|
||||
virtual void store_TIME(my_time_t timestamp, ulong sec_part)
|
||||
|
@ -1252,7 +1297,6 @@ public:
|
|||
int4store(ptr,timestamp);
|
||||
}
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
timestamp_auto_set_type get_auto_set_type() const;
|
||||
uchar *pack(uchar *to, const uchar *from,
|
||||
uint max_length __attribute__((unused)))
|
||||
{
|
||||
|
@ -1503,6 +1547,28 @@ public:
|
|||
void sql_type(String &str) const;
|
||||
bool zero_pack() const { return 1; }
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
virtual int set_time();
|
||||
virtual void set_default()
|
||||
{
|
||||
if (has_insert_default_function())
|
||||
set_time();
|
||||
else
|
||||
Field::set_default();
|
||||
}
|
||||
virtual int evaluate_insert_default_function()
|
||||
{
|
||||
int res= 0;
|
||||
if (has_insert_default_function())
|
||||
res= set_time();
|
||||
return res;
|
||||
}
|
||||
virtual int evaluate_update_default_function()
|
||||
{
|
||||
int res= 0;
|
||||
if (has_update_default_function())
|
||||
res= set_time();
|
||||
return res;
|
||||
}
|
||||
uchar *pack(uchar* to, const uchar *from,
|
||||
uint max_length __attribute__((unused)))
|
||||
{
|
||||
|
|
|
@ -2906,8 +2906,6 @@ int ha_ndbcluster::write_row(uchar *record)
|
|||
}
|
||||
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
if (!(op= trans->getNdbOperation(m_table)))
|
||||
ERR_RETURN(trans->getNdbError());
|
||||
|
@ -3146,11 +3144,6 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
|
|||
}
|
||||
|
||||
ha_statistic_increment(&SSV::ha_update_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
{
|
||||
table->timestamp_field->set_time();
|
||||
bitmap_set_bit(table->write_set, table->timestamp_field->field_index);
|
||||
}
|
||||
|
||||
if (m_use_partition_function &&
|
||||
(error= get_parts_for_update(old_data, new_data, table->record[0],
|
||||
|
|
|
@ -3451,8 +3451,8 @@ void ha_partition::try_semi_consistent_read(bool yes)
|
|||
|
||||
ADDITIONAL INFO:
|
||||
|
||||
We have to set timestamp fields and auto_increment fields, because those
|
||||
may be used in determining which partition the row should be written to.
|
||||
We have to set auto_increment fields, because those may be used in
|
||||
determining which partition the row should be written to.
|
||||
*/
|
||||
|
||||
int ha_partition::write_row(uchar * buf)
|
||||
|
@ -3463,7 +3463,6 @@ int ha_partition::write_row(uchar * buf)
|
|||
bool have_auto_increment= table->next_number_field && buf == table->record[0];
|
||||
my_bitmap_map *old_map;
|
||||
THD *thd= ha_thd();
|
||||
timestamp_auto_set_type saved_timestamp_type= table->timestamp_field_type;
|
||||
ulonglong saved_sql_mode= thd->variables.sql_mode;
|
||||
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
|
||||
#ifdef NOT_NEEDED
|
||||
|
@ -3472,11 +3471,6 @@ int ha_partition::write_row(uchar * buf)
|
|||
DBUG_ENTER("ha_partition::write_row");
|
||||
DBUG_ASSERT(buf == m_rec0);
|
||||
|
||||
/* If we have a timestamp column, update it to the current time */
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
/*
|
||||
If we have an auto_increment column and we are writing a changed row
|
||||
or a new row, then update the auto_increment value in the record.
|
||||
|
@ -3552,7 +3546,6 @@ int ha_partition::write_row(uchar * buf)
|
|||
exit:
|
||||
thd->variables.sql_mode= saved_sql_mode;
|
||||
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
|
||||
table->timestamp_field_type= saved_timestamp_type;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
@ -3587,18 +3580,8 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
|
|||
uint32 new_part_id, old_part_id;
|
||||
int error= 0;
|
||||
longlong func_value;
|
||||
timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
|
||||
DBUG_ENTER("ha_partition::update_row");
|
||||
|
||||
/*
|
||||
We need to set timestamp field once before we calculate
|
||||
the partition. Then we disable timestamp calculations
|
||||
inside m_file[*]->update_row() methods
|
||||
*/
|
||||
if (orig_timestamp_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
if ((error= get_parts_for_update(old_data, new_data, table->record[0],
|
||||
m_part_info, &old_part_id, &new_part_id,
|
||||
&func_value)))
|
||||
|
@ -3672,7 +3655,6 @@ exit:
|
|||
info(HA_STATUS_AUTO);
|
||||
set_auto_increment_if_higher(table->found_next_number_field);
|
||||
}
|
||||
table->timestamp_field_type= orig_timestamp_type;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
|
@ -9885,23 +9885,6 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
|
|||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
|
||||
any TIMESTAMP column with data from the row but instead will use
|
||||
the event's current time.
|
||||
As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
|
||||
columns, we know that all TIMESTAMP columns on slave will receive explicit
|
||||
data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
|
||||
When we allow a table without TIMESTAMP to be replicated to a table having
|
||||
more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
|
||||
column to be replicated into a BIGINT column and the slave's table has a
|
||||
TIMESTAMP column, then the slave's TIMESTAMP column will take its value
|
||||
from set_time() which we called earlier (consistent with SBR). And then in
|
||||
some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
|
||||
analyze if explicit data is provided for slave's TIMESTAMP columns).
|
||||
*/
|
||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
/* Honor next number column if present */
|
||||
m_table->next_number_field= m_table->found_next_number_field;
|
||||
/*
|
||||
|
@ -10984,8 +10967,6 @@ Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability
|
|||
if ((err= find_key()))
|
||||
return err;
|
||||
|
||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -924,22 +924,6 @@ int Write_rows_log_event_old::do_before_row_operations(TABLE *table)
|
|||
from the start.
|
||||
*/
|
||||
table->file->ha_start_bulk_insert(0);
|
||||
/*
|
||||
We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
|
||||
any TIMESTAMP column with data from the row but instead will use
|
||||
the event's current time.
|
||||
As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
|
||||
columns, we know that all TIMESTAMP columns on slave will receive explicit
|
||||
data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
|
||||
When we allow a table without TIMESTAMP to be replicated to a table having
|
||||
more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
|
||||
column to be replicated into a BIGINT column and the slave's table has a
|
||||
TIMESTAMP column, then the slave's TIMESTAMP column will take its value
|
||||
from set_time() which we called earlier (consistent with SBR). And then in
|
||||
some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
|
||||
analyze if explicit data is provided for slave's TIMESTAMP columns).
|
||||
*/
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1128,8 +1112,6 @@ int Update_rows_log_event_old::do_before_row_operations(TABLE *table)
|
|||
if (!m_memory)
|
||||
return HA_ERR_OUT_OF_MEM;
|
||||
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2589,22 +2571,6 @@ Write_rows_log_event_old::do_before_row_operations(const Slave_reporting_capabil
|
|||
from the start.
|
||||
*/
|
||||
m_table->file->ha_start_bulk_insert(0);
|
||||
/*
|
||||
We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
|
||||
any TIMESTAMP column with data from the row but instead will use
|
||||
the event's current time.
|
||||
As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
|
||||
columns, we know that all TIMESTAMP columns on slave will receive explicit
|
||||
data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
|
||||
When we allow a table without TIMESTAMP to be replicated to a table having
|
||||
more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
|
||||
column to be replicated into a BIGINT column and the slave's table has a
|
||||
TIMESTAMP column, then the slave's TIMESTAMP column will take its value
|
||||
from set_time() which we called earlier (consistent with SBR). And then in
|
||||
some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
|
||||
analyze if explicit data is provided for slave's TIMESTAMP columns).
|
||||
*/
|
||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2814,8 +2780,6 @@ Update_rows_log_event_old::do_before_row_operations(const Slave_reporting_capabi
|
|||
return HA_ERR_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1350,7 +1350,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
|
|||
}
|
||||
|
||||
store_record(table,record[1]);
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
||||
if (chistics->suid != SP_IS_DEFAULT_SUID)
|
||||
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
|
||||
|
|
|
@ -2426,7 +2426,6 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
|
|||
{
|
||||
LEX_STRING cmt = { 0, 0 };
|
||||
uint unused1= 0;
|
||||
int unused2= 0;
|
||||
|
||||
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
|
||||
lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
|
||||
|
@ -2443,8 +2442,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
|
|||
|
||||
sp_prepare_create_field(thd, field_def);
|
||||
|
||||
if (prepare_create_field(field_def, &unused1, &unused2, &unused2,
|
||||
HA_CAN_GEOMETRY))
|
||||
if (prepare_create_field(field_def, &unused1, HA_CAN_GEOMETRY))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -8800,13 +8800,13 @@ err_no_arena:
|
|||
*/
|
||||
|
||||
static bool
|
||||
fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
||||
fill_record(THD * thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
|
||||
bool ignore_errors)
|
||||
{
|
||||
List_iterator_fast<Item> f(fields),v(values);
|
||||
Item *value, *fld;
|
||||
Item_field *field;
|
||||
TABLE *table= 0, *vcol_table= 0;
|
||||
TABLE *vcol_table= 0;
|
||||
bool save_abort_on_warning= thd->abort_on_warning;
|
||||
bool save_no_errors= thd->no_errors;
|
||||
DBUG_ENTER("fill_record");
|
||||
|
@ -8828,12 +8828,13 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
|
||||
goto err;
|
||||
}
|
||||
table= field->field->table;
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
DBUG_ASSERT(field->field->table == table_arg);
|
||||
table_arg->auto_increment_field_not_null= FALSE;
|
||||
f.rewind();
|
||||
}
|
||||
else if (thd->lex->unit.insert_table_with_stored_vcol)
|
||||
vcol_table= thd->lex->unit.insert_table_with_stored_vcol;
|
||||
|
||||
while ((fld= f++))
|
||||
{
|
||||
if (!(field= fld->filed_for_view_update()))
|
||||
|
@ -8843,7 +8844,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||
}
|
||||
value=v++;
|
||||
Field *rfield= field->field;
|
||||
table= rfield->table;
|
||||
TABLE* table= rfield->table;
|
||||
if (rfield == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
if (rfield->vcol_info &&
|
||||
|
@ -8861,6 +8862,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
|
||||
goto err;
|
||||
}
|
||||
rfield->set_explicit_default(value);
|
||||
DBUG_ASSERT(vcol_table == 0 || vcol_table == table);
|
||||
vcol_table= table;
|
||||
}
|
||||
|
@ -8875,8 +8877,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||
err:
|
||||
thd->abort_on_warning= save_abort_on_warning;
|
||||
thd->no_errors= save_no_errors;
|
||||
if (table)
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
if (fields.elements)
|
||||
table_arg->auto_increment_field_not_null= FALSE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
@ -8905,13 +8907,13 @@ err:
|
|||
*/
|
||||
|
||||
bool
|
||||
fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
||||
fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, List<Item> &fields,
|
||||
List<Item> &values, bool ignore_errors,
|
||||
Table_triggers_list *triggers,
|
||||
enum trg_event_type event)
|
||||
{
|
||||
bool result;
|
||||
result= (fill_record(thd, fields, values, ignore_errors) ||
|
||||
Table_triggers_list *triggers= table->triggers;
|
||||
result= (fill_record(thd, table, fields, values, ignore_errors) ||
|
||||
(triggers && triggers->process_triggers(thd, event,
|
||||
TRG_ACTION_BEFORE, TRUE)));
|
||||
/*
|
||||
|
@ -8920,7 +8922,6 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||
*/
|
||||
if (!result && triggers)
|
||||
{
|
||||
TABLE *table= 0;
|
||||
List_iterator_fast<Item> f(fields);
|
||||
Item *fld;
|
||||
Item_field *item_field;
|
||||
|
@ -8928,9 +8929,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||
{
|
||||
fld= (Item_field*)f++;
|
||||
item_field= fld->filed_for_view_update();
|
||||
if (item_field && item_field->field &&
|
||||
(table= item_field->field->table) &&
|
||||
table->vfield)
|
||||
if (item_field && item_field->field && table && table->vfield)
|
||||
result= update_virtual_fields(thd, table, TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -8960,13 +8959,12 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||
*/
|
||||
|
||||
bool
|
||||
fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
|
||||
bool use_value)
|
||||
fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
||||
bool ignore_errors, bool use_value)
|
||||
{
|
||||
List_iterator_fast<Item> v(values);
|
||||
List<TABLE> tbl_list;
|
||||
Item *value;
|
||||
TABLE *table= 0;
|
||||
Field *field;
|
||||
bool abort_on_warning_saved= thd->abort_on_warning;
|
||||
DBUG_ENTER("fill_record");
|
||||
|
@ -8981,7 +8979,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
|
|||
On INSERT or UPDATE fields are checked to be from the same table,
|
||||
thus we safely can take table from the first field.
|
||||
*/
|
||||
table= (*ptr)->table;
|
||||
DBUG_ASSERT((*ptr)->table == table);
|
||||
|
||||
/*
|
||||
Reset the table->auto_increment_field_not_null as it is valid for
|
||||
|
@ -9012,6 +9010,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
|
|||
else
|
||||
if (value->save_in_field(field, 0) < 0)
|
||||
goto err;
|
||||
field->set_explicit_default(value);
|
||||
}
|
||||
/* Update virtual fields*/
|
||||
thd->abort_on_warning= FALSE;
|
||||
|
@ -9051,13 +9050,13 @@ err:
|
|||
*/
|
||||
|
||||
bool
|
||||
fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
|
||||
fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr,
|
||||
List<Item> &values, bool ignore_errors,
|
||||
Table_triggers_list *triggers,
|
||||
enum trg_event_type event)
|
||||
{
|
||||
bool result;
|
||||
result= (fill_record(thd, ptr, values, ignore_errors, FALSE) ||
|
||||
Table_triggers_list *triggers= table->triggers;
|
||||
result= (fill_record(thd, table, ptr, values, ignore_errors, FALSE) ||
|
||||
(triggers && triggers->process_triggers(thd, event,
|
||||
TRG_ACTION_BEFORE, TRUE)));
|
||||
/*
|
||||
|
@ -9066,7 +9065,6 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
|
|||
*/
|
||||
if (!result && triggers && *ptr)
|
||||
{
|
||||
TABLE *table= (*ptr)->table;
|
||||
if (table->vfield)
|
||||
result= update_virtual_fields(thd, table, TRUE);
|
||||
}
|
||||
|
@ -9706,11 +9704,6 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
|
|||
/* Make sure all columns get assigned to a default value */
|
||||
table->use_all_columns();
|
||||
table->no_replicate= 1;
|
||||
/*
|
||||
Don't set automatic timestamps as we may want to use time of logging,
|
||||
not from query start
|
||||
*/
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
}
|
||||
else
|
||||
thd->restore_backup_open_tables_state(backup);
|
||||
|
|
|
@ -170,15 +170,15 @@ TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
|||
TABLE *find_temporary_table(THD *thd, const char *table_key,
|
||||
uint table_key_length);
|
||||
void close_thread_tables(THD *thd);
|
||||
bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
||||
bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
||||
List<Item> &fields,
|
||||
List<Item> &values,
|
||||
bool ignore_errors,
|
||||
Table_triggers_list *triggers,
|
||||
enum trg_event_type event);
|
||||
bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
|
||||
bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
||||
Field **field,
|
||||
List<Item> &values,
|
||||
bool ignore_errors,
|
||||
Table_triggers_list *triggers,
|
||||
enum trg_event_type event);
|
||||
bool insert_fields(THD *thd, Name_resolution_context *context,
|
||||
const char *db_name, const char *table_name,
|
||||
|
@ -191,7 +191,7 @@ bool setup_fields(THD *thd, Item** ref_pointer_array,
|
|||
List<Item> &item, enum_mark_columns mark_used_columns,
|
||||
List<Item> *sum_func_list, bool allow_sum_func);
|
||||
void unfix_fields(List<Item> &items);
|
||||
bool fill_record(THD *thd, Field **field, List<Item> &values,
|
||||
bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
|
||||
bool ignore_errors, bool use_value);
|
||||
|
||||
Field *
|
||||
|
@ -304,6 +304,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
|
|||
void mark_tmp_table_for_reuse(TABLE *table);
|
||||
bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
|
||||
int update_virtual_fields(THD *thd, TABLE *table, bool ignore_stored= FALSE);
|
||||
int update_default_fields(TABLE *table);
|
||||
int dynamic_column_error_message(enum_dyncol_func_result rc);
|
||||
|
||||
extern TABLE *unused_tables;
|
||||
|
|
|
@ -4120,6 +4120,16 @@ public:
|
|||
*/
|
||||
#define CF_FORCE_ORIGINAL_BINLOG_FORMAT (1U << 10)
|
||||
|
||||
/**
|
||||
Statement that inserts new rows (INSERT, REPLACE, LOAD)
|
||||
*/
|
||||
#define CF_INSERTS_DATA (1U << 11)
|
||||
|
||||
/**
|
||||
Statement that updates existing rows (UPDATE, multi-update)
|
||||
*/
|
||||
#define CF_UPDATES_DATA (1U << 12)
|
||||
|
||||
/* Bits in server_command_flags */
|
||||
|
||||
/**
|
||||
|
|
|
@ -257,7 +257,7 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
|
|||
}
|
||||
|
||||
*(items.head_ref())= value;
|
||||
fill_record(table_thd, cache_table->field, items, TRUE, TRUE);
|
||||
fill_record(table_thd, cache_table, cache_table->field, items, TRUE, TRUE);
|
||||
if (table_thd->is_error())
|
||||
goto err;;
|
||||
|
||||
|
|
|
@ -191,11 +191,6 @@ error:
|
|||
different table maps, like on select ... insert
|
||||
map Store here table map for used fields
|
||||
|
||||
NOTE
|
||||
Clears TIMESTAMP_AUTO_SET_ON_INSERT from table->timestamp_field_type
|
||||
or leaves it as is, depending on if timestamp should be updated or
|
||||
not.
|
||||
|
||||
RETURN
|
||||
0 OK
|
||||
-1 Error
|
||||
|
@ -234,8 +229,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||
if (check_grant_all_columns(thd, INSERT_ACL, &field_it))
|
||||
return -1;
|
||||
#endif
|
||||
clear_timestamp_auto_bits(table->timestamp_field_type,
|
||||
TIMESTAMP_AUTO_SET_ON_INSERT);
|
||||
/*
|
||||
No fields are provided so all fields must be provided in the values.
|
||||
Thus we set all bits in the write set.
|
||||
|
@ -295,18 +288,8 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dup_field->field_name);
|
||||
return -1;
|
||||
}
|
||||
if (table->timestamp_field) // Don't automaticly set timestamp if used
|
||||
{
|
||||
if (bitmap_is_set(table->write_set,
|
||||
table->timestamp_field->field_index))
|
||||
clear_timestamp_auto_bits(table->timestamp_field_type,
|
||||
TIMESTAMP_AUTO_SET_ON_INSERT);
|
||||
else
|
||||
{
|
||||
bitmap_set_bit(table->write_set,
|
||||
table->timestamp_field->field_index);
|
||||
}
|
||||
}
|
||||
if (table->default_field)
|
||||
table->mark_default_fields_for_write();
|
||||
}
|
||||
/* Mark virtual columns used in the insert statement */
|
||||
if (table->vfield)
|
||||
|
@ -339,9 +322,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||
update_fields The update fields.
|
||||
|
||||
NOTE
|
||||
If the update fields include the timestamp field,
|
||||
remove TIMESTAMP_AUTO_SET_ON_UPDATE from table->timestamp_field_type.
|
||||
|
||||
If the update fields include an autoinc field, set the
|
||||
table->next_number_field_updated flag.
|
||||
|
||||
|
@ -355,21 +335,9 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
|||
List<Item> &update_values, table_map *map)
|
||||
{
|
||||
TABLE *table= insert_table_list->table;
|
||||
my_bool timestamp_mark;
|
||||
my_bool autoinc_mark;
|
||||
LINT_INIT(timestamp_mark);
|
||||
LINT_INIT(autoinc_mark);
|
||||
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
/*
|
||||
Unmark the timestamp field so that we can check if this is modified
|
||||
by update_fields
|
||||
*/
|
||||
timestamp_mark= bitmap_test_and_clear(table->write_set,
|
||||
table->timestamp_field->field_index);
|
||||
}
|
||||
|
||||
table->next_number_field_updated= FALSE;
|
||||
|
||||
if (table->found_next_number_field)
|
||||
|
@ -393,17 +361,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
|||
insert_table_list, map, false))
|
||||
return -1;
|
||||
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
/* Don't set timestamp column if this is modified. */
|
||||
if (bitmap_is_set(table->write_set,
|
||||
table->timestamp_field->field_index))
|
||||
clear_timestamp_auto_bits(table->timestamp_field_type,
|
||||
TIMESTAMP_AUTO_SET_ON_UPDATE);
|
||||
if (timestamp_mark)
|
||||
bitmap_set_bit(table->write_set,
|
||||
table->timestamp_field->field_index);
|
||||
}
|
||||
if (table->default_field)
|
||||
table->mark_default_fields_for_write();
|
||||
|
||||
if (table->found_next_number_field)
|
||||
{
|
||||
|
@ -709,7 +668,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
int error, res;
|
||||
bool transactional_table, joins_freed= FALSE;
|
||||
bool changed;
|
||||
bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED);
|
||||
const bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED);
|
||||
bool using_bulk_insert= 0;
|
||||
uint value_count;
|
||||
ulong counter = 1;
|
||||
|
@ -913,8 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
if (fields.elements || !value_count)
|
||||
{
|
||||
restore_record(table,s->default_values); // Get empty record
|
||||
if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0,
|
||||
table->triggers,
|
||||
if (fill_record_n_invoke_before_triggers(thd, table, fields, *values, 0,
|
||||
TRG_EVENT_INSERT))
|
||||
{
|
||||
if (values_list.elements != 1 && ! thd->is_error())
|
||||
|
@ -958,8 +916,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
share->default_values[share->null_bytes - 1];
|
||||
}
|
||||
}
|
||||
if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0,
|
||||
table->triggers,
|
||||
if (fill_record_n_invoke_before_triggers(thd, table, table->field, *values, 0,
|
||||
TRG_EVENT_INSERT))
|
||||
{
|
||||
if (values_list.elements != 1 && ! thd->is_error())
|
||||
|
@ -971,6 +928,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (table->default_field && table->update_default_fields())
|
||||
{
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((res= table_list->view_check_option(thd,
|
||||
(values_list.elements == 1 ?
|
||||
|
@ -987,7 +949,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
if (lock_type == TL_WRITE_DELAYED)
|
||||
{
|
||||
LEX_STRING const st_query = { query, thd->query_length() };
|
||||
DEBUG_SYNC(thd, "before_write_delayed");
|
||||
error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
|
||||
DEBUG_SYNC(thd, "after_write_delayed");
|
||||
query=0;
|
||||
}
|
||||
else
|
||||
|
@ -1696,13 +1660,32 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
restore_record(table,record[1]);
|
||||
DBUG_ASSERT(info->update_fields->elements ==
|
||||
info->update_values->elements);
|
||||
if (fill_record_n_invoke_before_triggers(thd, *info->update_fields,
|
||||
if (fill_record_n_invoke_before_triggers(thd, table, *info->update_fields,
|
||||
*info->update_values,
|
||||
info->ignore,
|
||||
table->triggers,
|
||||
TRG_EVENT_UPDATE))
|
||||
goto before_trg_err;
|
||||
|
||||
bool different_records= (!records_are_comparable(table) ||
|
||||
compare_record(table));
|
||||
/*
|
||||
Default fields must be updated before checking view updateability.
|
||||
This branch of INSERT is executed only when a UNIQUE key was violated
|
||||
with the ON DUPLICATE KEY UPDATE option. In this case the INSERT
|
||||
operation is transformed to an UPDATE, and the default fields must
|
||||
be updated as this is an UPDATE.
|
||||
*/
|
||||
if (different_records && table->default_field)
|
||||
{
|
||||
bool res;
|
||||
enum_sql_command cmd= thd->lex->sql_command;
|
||||
thd->lex->sql_command= SQLCOM_UPDATE;
|
||||
res= table->update_default_fields();
|
||||
thd->lex->sql_command= cmd;
|
||||
if (res)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
|
||||
if (info->view &&
|
||||
(res= info->view->view_check_option(current_thd, info->ignore)) ==
|
||||
|
@ -1713,7 +1696,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
|
||||
table->file->restore_auto_increment(prev_insert_id);
|
||||
info->touched++;
|
||||
if (!records_are_comparable(table) || compare_record(table))
|
||||
if (different_records)
|
||||
{
|
||||
if ((error=table->file->ha_update_row(table->record[1],
|
||||
table->record[0])) &&
|
||||
|
@ -1784,8 +1767,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
*/
|
||||
if (last_uniq_key(table,key_nr) &&
|
||||
!table->file->referenced_by_foreign_key() &&
|
||||
(table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
|
||||
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
{
|
||||
if ((error=table->file->ha_update_row(table->record[1],
|
||||
|
@ -1948,7 +1929,6 @@ public:
|
|||
ulonglong forced_insert_id;
|
||||
ulong auto_increment_increment;
|
||||
ulong auto_increment_offset;
|
||||
timestamp_auto_set_type timestamp_field_type;
|
||||
LEX_STRING query;
|
||||
Time_zone *time_zone;
|
||||
|
||||
|
@ -2321,7 +2301,7 @@ end_create:
|
|||
TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
||||
{
|
||||
my_ptrdiff_t adjust_ptrs;
|
||||
Field **field,**org_field, *found_next_number_field;
|
||||
Field **field,**org_field, *found_next_number_field, **dfield_ptr;
|
||||
TABLE *copy;
|
||||
TABLE_SHARE *share;
|
||||
uchar *bitmap;
|
||||
|
@ -2390,6 +2370,12 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||
bitmap= (uchar*) (field + share->fields + 1);
|
||||
copy->record[0]= (bitmap + share->column_bitmap_size*3);
|
||||
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
|
||||
if (share->default_fields)
|
||||
{
|
||||
copy->default_field= (Field**) client_thd->alloc((share->default_fields+1)*
|
||||
sizeof(Field**));
|
||||
dfield_ptr= copy->default_field;
|
||||
}
|
||||
/*
|
||||
Make a copy of all fields.
|
||||
The copied fields need to point into the copied record. This is done
|
||||
|
@ -2407,18 +2393,19 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
|
||||
if (*org_field == found_next_number_field)
|
||||
(*field)->table->found_next_number_field= *field;
|
||||
if (share->default_fields &&
|
||||
((*org_field)->has_insert_default_function() ||
|
||||
(*org_field)->has_update_default_function()))
|
||||
{
|
||||
/* Put the newly copied field into the set of default fields. */
|
||||
*dfield_ptr= *field;
|
||||
(*dfield_ptr)->unireg_check= (*org_field)->unireg_check;
|
||||
dfield_ptr++;
|
||||
}
|
||||
}
|
||||
*field=0;
|
||||
|
||||
/* Adjust timestamp */
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
/* Restore offset as this may have been reset in handle_inserts */
|
||||
copy->timestamp_field=
|
||||
(Field_timestamp*) copy->field[share->timestamp_field_offset];
|
||||
copy->timestamp_field->unireg_check= table->timestamp_field->unireg_check;
|
||||
copy->timestamp_field_type= copy->timestamp_field->get_auto_set_type();
|
||||
}
|
||||
if (share->default_fields)
|
||||
*dfield_ptr= NULL;
|
||||
|
||||
/* Adjust in_use for pointing to client thread */
|
||||
copy->in_use= client_thd;
|
||||
|
@ -2508,7 +2495,6 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
|||
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
|
||||
row->first_successful_insert_id_in_prev_stmt=
|
||||
thd->first_successful_insert_id_in_prev_stmt;
|
||||
row->timestamp_field_type= table->timestamp_field_type;
|
||||
|
||||
/* Add session variable timezone
|
||||
Time_zone object will not be freed even the thread is ended.
|
||||
|
@ -3051,7 +3037,6 @@ bool Delayed_insert::handle_inserts(void)
|
|||
row->first_successful_insert_id_in_prev_stmt;
|
||||
thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
|
||||
row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
|
||||
table->timestamp_field_type= row->timestamp_field_type;
|
||||
table->auto_increment_field_not_null= row->auto_increment_field_not_null;
|
||||
|
||||
/* Copy the session variables. */
|
||||
|
@ -3527,6 +3512,8 @@ int select_insert::send_data(List<Item> &values)
|
|||
|
||||
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
|
||||
store_values(values);
|
||||
if (table->default_field && table->update_default_fields())
|
||||
DBUG_RETURN(1);
|
||||
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
|
||||
if (thd->is_error())
|
||||
{
|
||||
|
@ -3586,11 +3573,11 @@ int select_insert::send_data(List<Item> &values)
|
|||
void select_insert::store_values(List<Item> &values)
|
||||
{
|
||||
if (fields->elements)
|
||||
fill_record_n_invoke_before_triggers(thd, *fields, values, 1,
|
||||
table->triggers, TRG_EVENT_INSERT);
|
||||
fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1,
|
||||
TRG_EVENT_INSERT);
|
||||
else
|
||||
fill_record_n_invoke_before_triggers(thd, table->field, values, 1,
|
||||
table->triggers, TRG_EVENT_INSERT);
|
||||
fill_record_n_invoke_before_triggers(thd, table, table->field, values, 1,
|
||||
TRG_EVENT_INSERT);
|
||||
}
|
||||
|
||||
void select_insert::send_error(uint errcode,const char *err)
|
||||
|
@ -3808,7 +3795,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
DBUG_ENTER("create_table_from_items");
|
||||
|
||||
tmp_table.alias= 0;
|
||||
tmp_table.timestamp_field= 0;
|
||||
tmp_table.s= &share;
|
||||
init_tmp_table_share(thd, &share, "", 0, "", "");
|
||||
|
||||
|
@ -3817,6 +3803,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
tmp_table.null_row= 0;
|
||||
tmp_table.maybe_null= 0;
|
||||
|
||||
promote_first_timestamp_column(&alter_info->create_list);
|
||||
|
||||
while ((item=it++))
|
||||
{
|
||||
Create_field *cr_field;
|
||||
|
@ -4056,8 +4044,6 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||
for (Field **f= field ; *f ; f++)
|
||||
bitmap_set_bit(table->write_set, (*f)->field_index);
|
||||
|
||||
/* Don't set timestamp if used */
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
|
||||
restore_record(table,s->default_values); // Get empty record
|
||||
|
@ -4133,8 +4119,8 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
|
|||
|
||||
void select_create::store_values(List<Item> &values)
|
||||
{
|
||||
fill_record_n_invoke_before_triggers(thd, field, values, 1,
|
||||
table->triggers, TRG_EVENT_INSERT);
|
||||
fill_record_n_invoke_before_triggers(thd, table, field, values, 1,
|
||||
TRG_EVENT_INSERT);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -273,7 +273,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
for (field=table->field; *field ; field++)
|
||||
fields_vars.push_back(new Item_field(*field));
|
||||
bitmap_set_all(table->write_set);
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
/*
|
||||
Let us also prepare SET clause, altough it is probably empty
|
||||
in this case.
|
||||
|
@ -289,21 +288,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
|
||||
check_that_all_fields_are_given_values(thd, table, table_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
/*
|
||||
Check whenever TIMESTAMP field with auto-set feature specified
|
||||
explicitly.
|
||||
*/
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
if (bitmap_is_set(table->write_set,
|
||||
table->timestamp_field->field_index))
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
else
|
||||
{
|
||||
bitmap_set_bit(table->write_set,
|
||||
table->timestamp_field->field_index);
|
||||
}
|
||||
}
|
||||
/* Add all fields with default functions to table->write_set. */
|
||||
if (table->default_field)
|
||||
table->mark_default_fields_for_write();
|
||||
/* Fix the expressions in SET clause */
|
||||
if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
@ -850,7 +837,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
ER(ER_WARN_TOO_FEW_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
||||
((Field_timestamp*) field)->set_time();
|
||||
field->set_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -864,6 +851,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
pos[length]=save_chr;
|
||||
if ((pos+=length) > read_info.row_end)
|
||||
pos= read_info.row_end; /* Fills rest with space */
|
||||
field->set_explicit_default(NULL);
|
||||
}
|
||||
}
|
||||
if (pos != read_info.row_end)
|
||||
|
@ -876,10 +864,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
}
|
||||
|
||||
if (thd->killed ||
|
||||
fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
|
||||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
|
||||
ignore_check_option_errors,
|
||||
table->triggers,
|
||||
TRG_EVENT_INSERT))
|
||||
TRG_EVENT_INSERT) ||
|
||||
(table->default_field && table->update_default_fields()))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
switch (table_list->view_check_option(thd,
|
||||
|
@ -994,10 +982,11 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
field->set_null();
|
||||
field->set_explicit_default(NULL);
|
||||
if (!field->maybe_null())
|
||||
{
|
||||
if (field->type() == MYSQL_TYPE_TIMESTAMP)
|
||||
((Field_timestamp*) field)->set_time();
|
||||
field->set_time();
|
||||
else if (field != table->next_number_field)
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
||||
|
@ -1025,6 +1014,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
field->store((char*) pos, length, read_info.read_charset);
|
||||
field->set_explicit_default(NULL);
|
||||
}
|
||||
else if (item->type() == Item::STRING_ITEM)
|
||||
{
|
||||
|
@ -1066,7 +1056,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
||||
((Field_timestamp*) field)->set_time();
|
||||
field->set_time();
|
||||
/*
|
||||
TODO: We probably should not throw warning for each field.
|
||||
But how about intention to always have the same number
|
||||
|
@ -1093,10 +1083,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
}
|
||||
|
||||
if (thd->killed ||
|
||||
fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
|
||||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
|
||||
ignore_check_option_errors,
|
||||
table->triggers,
|
||||
TRG_EVENT_INSERT))
|
||||
TRG_EVENT_INSERT) ||
|
||||
(table->default_field && table->update_default_fields()))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
switch (table_list->view_check_option(thd,
|
||||
|
@ -1206,7 +1196,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (!field->maybe_null())
|
||||
{
|
||||
if (field->type() == FIELD_TYPE_TIMESTAMP)
|
||||
((Field_timestamp *) field)->set_time();
|
||||
field->set_time();
|
||||
else if (field != table->next_number_field)
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
||||
|
@ -1225,6 +1215,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
|
||||
field->set_explicit_default(NULL);
|
||||
}
|
||||
else
|
||||
((Item_user_var_as_out_param *) item)->set_value(
|
||||
|
@ -1269,10 +1260,10 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
}
|
||||
|
||||
if (thd->killed ||
|
||||
fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
|
||||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
|
||||
ignore_check_option_errors,
|
||||
table->triggers,
|
||||
TRG_EVENT_INSERT))
|
||||
TRG_EVENT_INSERT) ||
|
||||
(table->default_field && table->update_default_fields()))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
switch (table_list->view_check_option(thd,
|
||||
|
|
|
@ -268,12 +268,14 @@ void init_update_queries(void)
|
|||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
|
||||
CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS ;
|
||||
CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
|
||||
CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
|
||||
CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_REPORT_PROGRESS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_REPORT_PROGRESS |
|
||||
CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
|
||||
|
@ -290,21 +292,21 @@ void init_update_queries(void)
|
|||
sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
|
||||
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_UPDATES_DATA;
|
||||
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_UPDATES_DATA;
|
||||
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
|
||||
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
|
||||
|
@ -5881,11 +5883,11 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
|||
no need fix_fields()
|
||||
|
||||
We allow only one function as part of default value -
|
||||
NOW() as default for TIMESTAMP type.
|
||||
NOW() as default for TIMESTAMP and DATETIME type.
|
||||
*/
|
||||
if (default_value->type() == Item::FUNC_ITEM &&
|
||||
!(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
|
||||
type == MYSQL_TYPE_TIMESTAMP))
|
||||
(type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_DATETIME)))
|
||||
{
|
||||
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
|
||||
DBUG_RETURN(1);
|
||||
|
@ -5907,7 +5909,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
|||
}
|
||||
}
|
||||
|
||||
if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
|
||||
if (on_update_value &&
|
||||
!(type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_DATETIME))
|
||||
{
|
||||
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
|
||||
DBUG_RETURN(1);
|
||||
|
|
|
@ -6526,9 +6526,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||
lpt->pack_frm_data= NULL;
|
||||
lpt->pack_frm_len= 0;
|
||||
|
||||
/* Never update timestamp columns when alter */
|
||||
lpt->table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
if (table->file->alter_table_flags(alter_info->flags) &
|
||||
HA_PARTITION_ONE_PHASE)
|
||||
{
|
||||
|
|
|
@ -9463,7 +9463,7 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
|||
if (item->is_null())
|
||||
DBUG_RETURN(NESTED_LOOP_OK);
|
||||
}
|
||||
fill_record(thd, table->field, sjm->sjm_table_cols, TRUE, FALSE);
|
||||
fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE);
|
||||
if (thd->is_error())
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
if ((error= table->file->ha_write_tmp_row(table->record[0])))
|
||||
|
|
|
@ -1108,8 +1108,35 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
|
|||
|
||||
#define LIST_PROCESS_HOST_LEN 64
|
||||
|
||||
static bool get_field_default_value(THD *thd, Field *timestamp_field,
|
||||
Field *field, String *def_value,
|
||||
|
||||
/**
|
||||
Print "ON UPDATE" clause of a field into a string.
|
||||
|
||||
@param timestamp_field Pointer to timestamp field of a table.
|
||||
@param field The field to generate ON UPDATE clause for.
|
||||
@bool lcase Whether to print in lower case.
|
||||
@return false on success, true on error.
|
||||
*/
|
||||
static bool print_on_update_clause(Field *field, String *val, bool lcase)
|
||||
{
|
||||
DBUG_ASSERT(val->charset()->mbminlen == 1);
|
||||
val->length(0);
|
||||
if (field->has_update_default_function())
|
||||
{
|
||||
if (lcase)
|
||||
val->append(STRING_WITH_LEN("on update "));
|
||||
else
|
||||
val->append(STRING_WITH_LEN("ON UPDATE "));
|
||||
val->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
|
||||
if (field->decimals() > 0)
|
||||
val->append_parenthesized(field->decimals());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool get_field_default_value(THD *thd, Field *field, String *def_value,
|
||||
bool quoted)
|
||||
{
|
||||
bool has_default;
|
||||
|
@ -1120,8 +1147,7 @@ static bool get_field_default_value(THD *thd, Field *timestamp_field,
|
|||
We are using CURRENT_TIMESTAMP instead of NOW because it is
|
||||
more standard
|
||||
*/
|
||||
has_now_default= (timestamp_field == field &&
|
||||
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
|
||||
has_now_default= field->has_insert_default_function();
|
||||
|
||||
has_default= (field_type != FIELD_TYPE_BLOB &&
|
||||
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
||||
|
@ -1133,7 +1159,11 @@ static bool get_field_default_value(THD *thd, Field *timestamp_field,
|
|||
if (has_default)
|
||||
{
|
||||
if (has_now_default)
|
||||
{
|
||||
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
|
||||
if (field->decimals() > 0)
|
||||
def_value->append_parenthesized(field->decimals());
|
||||
}
|
||||
else if (!field->is_null())
|
||||
{ // Not null by default
|
||||
char tmp[MAX_FIELD_WIDTH];
|
||||
|
@ -1365,16 +1395,18 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||
}
|
||||
|
||||
if (!field->vcol_info &&
|
||||
get_field_default_value(thd, table->timestamp_field,
|
||||
field, &def_value, 1))
|
||||
get_field_default_value(thd, field, &def_value, 1))
|
||||
{
|
||||
packet->append(STRING_WITH_LEN(" DEFAULT "));
|
||||
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
||||
}
|
||||
|
||||
if (!limited_mysql_mode && table->timestamp_field == field &&
|
||||
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
|
||||
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
|
||||
if (!limited_mysql_mode && print_on_update_clause(field, &def_value, false))
|
||||
{
|
||||
packet->append(STRING_WITH_LEN(" "));
|
||||
packet->append(def_value);
|
||||
}
|
||||
|
||||
|
||||
if (field->unireg_check == Field::NEXT_NUMBER &&
|
||||
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
|
||||
|
@ -4758,7 +4790,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
TABLE *show_table;
|
||||
Field **ptr, *field, *timestamp_field;
|
||||
Field **ptr, *field;
|
||||
int count;
|
||||
DBUG_ENTER("get_schema_column_record");
|
||||
|
||||
|
@ -4782,7 +4814,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
show_table= tables->table;
|
||||
count= 0;
|
||||
ptr= show_table->field;
|
||||
timestamp_field= show_table->timestamp_field;
|
||||
show_table->use_all_columns(); // Required for default
|
||||
restore_record(show_table, s->default_values);
|
||||
|
||||
|
@ -4830,7 +4861,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
cs);
|
||||
table->field[4]->store((longlong) count, TRUE);
|
||||
|
||||
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
|
||||
if (get_field_default_value(thd, field, &type, 0))
|
||||
{
|
||||
table->field[5]->store(type.ptr(), type.length(), cs);
|
||||
table->field[5]->set_notnull();
|
||||
|
@ -4847,10 +4878,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
|
||||
if (field->unireg_check == Field::NEXT_NUMBER)
|
||||
table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
|
||||
if (timestamp_field == field &&
|
||||
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
|
||||
table->field[17]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
|
||||
cs);
|
||||
if (print_on_update_clause(field, &type, true))
|
||||
table->field[17]->store(type.ptr(), type.length(), cs);
|
||||
if (field->vcol_info)
|
||||
{
|
||||
if (field->stored_in_db)
|
||||
|
|
|
@ -502,6 +502,24 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Append a parenthesized number to String.
|
||||
Used in various pieces of SHOW related code.
|
||||
|
||||
@param nr Number
|
||||
@param radix Radix, optional parameter, 10 by default.
|
||||
*/
|
||||
bool String::append_parenthesized(long nr, int radix)
|
||||
{
|
||||
char buff[64], *end;
|
||||
buff[0]= '(';
|
||||
end= int10_to_str(nr, buff + 1, radix);
|
||||
*end++ = ')';
|
||||
return append(buff, (uint) (end - buff));
|
||||
}
|
||||
|
||||
|
||||
bool String::append_with_prefill(const char *s,uint32 arg_length,
|
||||
uint32 full_length, char fill_char)
|
||||
{
|
||||
|
|
|
@ -343,6 +343,7 @@ public:
|
|||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
bool append_with_prefill(const char *s, uint32 arg_length,
|
||||
uint32 full_length, char fill_char);
|
||||
bool append_parenthesized(long nr, int radix= 10);
|
||||
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
|
||||
|
|
|
@ -2607,7 +2607,6 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||
prepare_create_field()
|
||||
sql_field field to prepare for packing
|
||||
blob_columns count for BLOBs
|
||||
timestamps count for timestamps
|
||||
table_flags table flags
|
||||
|
||||
DESCRIPTION
|
||||
|
@ -2621,7 +2620,6 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||
|
||||
int prepare_create_field(Create_field *sql_field,
|
||||
uint *blob_columns,
|
||||
int *timestamps, int *timestamps_with_niladic,
|
||||
longlong table_flags)
|
||||
{
|
||||
unsigned int dup_val_count;
|
||||
|
@ -2743,21 +2741,6 @@ int prepare_create_field(Create_field *sql_field,
|
|||
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
||||
break;
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
/* We should replace old TIMESTAMP fields with their newer analogs */
|
||||
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
|
||||
{
|
||||
if (!*timestamps)
|
||||
{
|
||||
sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
||||
(*timestamps_with_niladic)++;
|
||||
}
|
||||
else
|
||||
sql_field->unireg_check= Field::NONE;
|
||||
}
|
||||
else if (sql_field->unireg_check != Field::NONE)
|
||||
(*timestamps_with_niladic)++;
|
||||
|
||||
(*timestamps)++;
|
||||
/* fall-through */
|
||||
default:
|
||||
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
||||
|
@ -2829,6 +2812,40 @@ bool check_duplicate_warning(THD *thd, char *msg, ulong length)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Modifies the first column definition whose SQL type is TIMESTAMP
|
||||
by adding the features DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
|
||||
|
||||
@param column_definitions The list of column definitions, in the physical
|
||||
order in which they appear in the table.
|
||||
*/
|
||||
void promote_first_timestamp_column(List<Create_field> *column_definitions)
|
||||
{
|
||||
List_iterator<Create_field> it(*column_definitions);
|
||||
Create_field *column_definition;
|
||||
|
||||
while ((column_definition= it++) != NULL)
|
||||
{
|
||||
if (column_definition->sql_type == MYSQL_TYPE_TIMESTAMP || // TIMESTAMP
|
||||
column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
|
||||
{
|
||||
if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
|
||||
column_definition->def == NULL && // no constant default,
|
||||
column_definition->unireg_check == Field::NONE) // no function default
|
||||
{
|
||||
DBUG_PRINT("info", ("First TIMESTAMP column '%s' was promoted to "
|
||||
"DEFAULT CURRENT_TIMESTAMP ON UPDATE "
|
||||
"CURRENT_TIMESTAMP",
|
||||
column_definition->field_name
|
||||
));
|
||||
column_definition->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Preparation for table creation
|
||||
|
||||
|
@ -2869,7 +2886,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
ulong record_offset= 0;
|
||||
KEY *key_info;
|
||||
KEY_PART_INFO *key_part_info;
|
||||
int timestamps= 0, timestamps_with_niladic= 0;
|
||||
int field_no,dup_no;
|
||||
int select_field_pos,auto_increment=0;
|
||||
List_iterator<Create_field> it(alter_info->create_list);
|
||||
|
@ -3153,7 +3169,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
DBUG_ASSERT(sql_field->charset != 0);
|
||||
|
||||
if (prepare_create_field(sql_field, &blob_columns,
|
||||
×tamps, ×tamps_with_niladic,
|
||||
file->ha_table_flags()))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
|
||||
|
@ -3184,12 +3199,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
record_offset+= sql_field->pack_length;
|
||||
}
|
||||
}
|
||||
if (timestamps_with_niladic > 1)
|
||||
{
|
||||
my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
|
||||
ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (auto_increment > 1)
|
||||
{
|
||||
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
|
||||
|
@ -4558,6 +4567,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
|||
/* Got lock. */
|
||||
DEBUG_SYNC(thd, "locked_table_name");
|
||||
|
||||
promote_first_timestamp_column(&alter_info->create_list);
|
||||
|
||||
result= mysql_create_table_no_lock(thd, create_table->db,
|
||||
create_table->table_name, create_info,
|
||||
alter_info, FALSE, 0, &is_trans);
|
||||
|
@ -6371,6 +6382,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
need_copy_table= alter_info->change_level;
|
||||
|
||||
set_table_default_charset(thd, create_info, db);
|
||||
promote_first_timestamp_column(&alter_info->create_list);
|
||||
|
||||
if (thd->variables.old_alter_table
|
||||
|| (table->s->db_type() != create_info->db_type)
|
||||
|
@ -6668,6 +6680,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
|
||||
DBUG_EXECUTE_IF("sleep_before_create_table_no_lock",
|
||||
my_sleep(100000););
|
||||
|
||||
/*
|
||||
Create a table with a temporary name.
|
||||
With create_info->frm_only == 1 this creates a .frm file only.
|
||||
|
@ -6738,8 +6751,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
*/
|
||||
if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
|
||||
{
|
||||
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
|
||||
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
new_table->next_number_field=new_table->found_next_number_field;
|
||||
DBUG_EXECUTE_IF("abort_copy_table", {
|
||||
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
|
||||
|
@ -7316,6 +7327,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||
ulonglong prev_insert_id, time_to_report_progress;
|
||||
List_iterator<Create_field> it(create);
|
||||
Create_field *def;
|
||||
Field **dfield_ptr= to->default_field;
|
||||
DBUG_ENTER("copy_data_between_tables");
|
||||
|
||||
/* Two or 3 stages; Sorting, copying data and update indexes */
|
||||
|
@ -7345,6 +7357,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||
errpos= 3;
|
||||
|
||||
copy_end=copy;
|
||||
to->s->default_fields= 0;
|
||||
for (Field **ptr=to->field ; *ptr ; ptr++)
|
||||
{
|
||||
def=it++;
|
||||
|
@ -7364,8 +7377,23 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||
}
|
||||
(copy_end++)->set(*ptr,def->field,0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/*
|
||||
Update the set of auto-update fields to contain only the newly added
|
||||
fields. Only these fields should be updated automatically. Old fields
|
||||
keep their current values, and therefore should not be present in the
|
||||
set of autoupdate fields.
|
||||
*/
|
||||
if ((*ptr)->has_insert_default_function())
|
||||
{
|
||||
*(dfield_ptr++)= *ptr;
|
||||
++to->s->default_fields;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dfield_ptr)
|
||||
*dfield_ptr= NULL;
|
||||
|
||||
if (order)
|
||||
{
|
||||
|
@ -7456,6 +7484,11 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||
prev_insert_id= to->file->next_insert_id;
|
||||
if (to->vfield)
|
||||
update_virtual_fields(thd, to, TRUE);
|
||||
if (to->default_field && to->update_default_fields())
|
||||
{
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
if (thd->is_error())
|
||||
{
|
||||
error= 1;
|
||||
|
|
|
@ -187,7 +187,6 @@ void close_cached_table(THD *thd, TABLE *table);
|
|||
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
|
||||
int prepare_create_field(Create_field *sql_field,
|
||||
uint *blob_columns,
|
||||
int *timestamps, int *timestamps_with_niladic,
|
||||
longlong table_flags);
|
||||
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
|
||||
HA_CREATE_INFO *create_info);
|
||||
|
@ -208,6 +207,9 @@ void execute_ddl_log_recovery();
|
|||
bool execute_ddl_log_entry(THD *thd, uint first_entry);
|
||||
bool check_duplicate_warning(THD *thd, char *msg, ulong length);
|
||||
|
||||
template<typename T> class List;
|
||||
void promote_first_timestamp_column(List<Create_field> *column_definitions);
|
||||
|
||||
/*
|
||||
These prototypes where under INNODB_COMPATIBILITY_HOOKS.
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ int select_union::send_data(List<Item> &values)
|
|||
return 0;
|
||||
if (table->no_rows_with_nulls)
|
||||
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
|
||||
fill_record(thd, table->field, values, TRUE, FALSE);
|
||||
fill_record(thd, table, table->field, values, TRUE, FALSE);
|
||||
if (thd->is_error())
|
||||
return 1;
|
||||
if (table->no_rows_with_nulls)
|
||||
|
|
|
@ -342,19 +342,8 @@ int mysql_update(THD *thd,
|
|||
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
// Don't set timestamp column if this is modified
|
||||
if (bitmap_is_set(table->write_set,
|
||||
table->timestamp_field->field_index))
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
else
|
||||
{
|
||||
if (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
bitmap_set_bit(table->write_set,
|
||||
table->timestamp_field->field_index);
|
||||
}
|
||||
}
|
||||
if (table->default_field)
|
||||
table->mark_default_fields_for_write();
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* Check values */
|
||||
|
@ -389,7 +378,7 @@ int mysql_update(THD *thd,
|
|||
to compare records and detect data change.
|
||||
*/
|
||||
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
|
||||
(((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE))
|
||||
table->default_field && table->has_default_function(true))
|
||||
bitmap_union(table->read_set, table->write_set);
|
||||
// Don't count on usage of 'only index' when calculating which key to use
|
||||
table->covering_keys.clear_all();
|
||||
|
@ -686,8 +675,7 @@ int mysql_update(THD *thd,
|
|||
continue; /* repeat the read of the same row if it still exists */
|
||||
|
||||
store_record(table,record[1]);
|
||||
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
|
||||
table->triggers,
|
||||
if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
|
||||
TRG_EVENT_UPDATE))
|
||||
break; /* purecov: inspected */
|
||||
|
||||
|
@ -695,6 +683,11 @@ int mysql_update(THD *thd,
|
|||
|
||||
if (!can_compare_record || compare_record(table))
|
||||
{
|
||||
if (table->default_field && table->update_default_fields())
|
||||
{
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
if ((res= table_list->view_check_option(thd, ignore)) !=
|
||||
VIEW_CHECK_OK)
|
||||
{
|
||||
|
@ -1241,11 +1234,6 @@ int mysql_multi_update_prepare(THD *thd)
|
|||
while ((tl= ti++))
|
||||
{
|
||||
TABLE *table= tl->table;
|
||||
/* Only set timestamp column if this is not modified */
|
||||
if (table->timestamp_field &&
|
||||
bitmap_is_set(table->write_set,
|
||||
table->timestamp_field->field_index))
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
/* if table will be updated then check that it is unique */
|
||||
if (table->map & tables_for_update)
|
||||
|
@ -1495,8 +1483,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||
to compare records and detect data change.
|
||||
*/
|
||||
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
|
||||
(((uint) table->timestamp_field_type) &
|
||||
TIMESTAMP_AUTO_SET_ON_UPDATE))
|
||||
table->default_field && table->has_default_function(true))
|
||||
bitmap_union(table->read_set, table->write_set);
|
||||
}
|
||||
}
|
||||
|
@ -1875,10 +1862,10 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||
|
||||
table->status|= STATUS_UPDATED;
|
||||
store_record(table,record[1]);
|
||||
if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset],
|
||||
if (fill_record_n_invoke_before_triggers(thd, table, *fields_for_table[offset],
|
||||
*values_for_table[offset], 0,
|
||||
table->triggers,
|
||||
TRG_EVENT_UPDATE))
|
||||
TRG_EVENT_UPDATE) ||
|
||||
(table->default_field && table->update_default_fields()))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
|
@ -1979,7 +1966,7 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||
} while ((tbl= tbl_it++));
|
||||
|
||||
/* Store regular updated fields in the row. */
|
||||
fill_record(thd,
|
||||
fill_record(thd, tmp_table,
|
||||
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
||||
*values_for_table[offset], TRUE, FALSE);
|
||||
|
||||
|
@ -2169,7 +2156,10 @@ int multi_update::do_updates()
|
|||
for (copy_field_ptr=copy_field;
|
||||
copy_field_ptr != copy_field_end;
|
||||
copy_field_ptr++)
|
||||
{
|
||||
(*copy_field_ptr->do_copy)(copy_field_ptr);
|
||||
copy_field_ptr->to_field->set_explicit_default(NULL);
|
||||
}
|
||||
|
||||
if (table->triggers &&
|
||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||
|
@ -2179,6 +2169,8 @@ int multi_update::do_updates()
|
|||
if (!can_compare_record || compare_record(table))
|
||||
{
|
||||
int error;
|
||||
if (table->default_field && (error= table->update_default_fields()))
|
||||
goto err2;
|
||||
if ((error= cur_table->view_check_option(thd, ignore)) !=
|
||||
VIEW_CHECK_OK)
|
||||
{
|
||||
|
|
|
@ -5873,9 +5873,9 @@ attribute:
|
|||
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
|
||||
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
|
||||
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
|
||||
| ON UPDATE_SYM NOW_SYM optional_braces
|
||||
| ON UPDATE_SYM NOW_SYM opt_time_precision
|
||||
{
|
||||
Item *item= new (YYTHD->mem_root) Item_func_now_local(6);
|
||||
Item *item= new (YYTHD->mem_root) Item_func_now_local($4);
|
||||
if (item == NULL)
|
||||
MYSQL_YYABORT;
|
||||
Lex->on_update_value= item;
|
||||
|
@ -5967,9 +5967,9 @@ type_with_opt_collate:
|
|||
|
||||
|
||||
now_or_signed_literal:
|
||||
NOW_SYM optional_braces
|
||||
NOW_SYM opt_time_precision
|
||||
{
|
||||
$$= new (YYTHD->mem_root) Item_func_now_local(6);
|
||||
$$= new (YYTHD->mem_root) Item_func_now_local($2);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
|
129
sql/table.cc
129
sql/table.cc
|
@ -1250,6 +1250,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
com_length= uint2korr(forminfo+284);
|
||||
vcol_screen_length= uint2korr(forminfo+286);
|
||||
share->vfields= 0;
|
||||
share->default_fields= 0;
|
||||
share->stored_fields= share->fields;
|
||||
if (forminfo[46] != (uchar)255)
|
||||
{
|
||||
|
@ -1581,8 +1582,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
|
||||
if (reg_field->unireg_check == Field::NEXT_NUMBER)
|
||||
share->found_next_number_field= field_ptr;
|
||||
if (share->timestamp_field == reg_field)
|
||||
share->timestamp_field_offset= i;
|
||||
|
||||
if (use_hash)
|
||||
{
|
||||
|
@ -1604,6 +1603,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
if (share->stored_rec_length>=recpos)
|
||||
share->stored_rec_length= recpos-1;
|
||||
}
|
||||
if (reg_field->has_insert_default_function() ||
|
||||
reg_field->has_update_default_function())
|
||||
++share->default_fields;
|
||||
}
|
||||
*field_ptr=0; // End marker
|
||||
/* Sanity checks: */
|
||||
|
@ -2315,7 +2317,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
uint records, i, bitmap_size;
|
||||
bool error_reported= FALSE;
|
||||
uchar *record, *bitmaps;
|
||||
Field **field_ptr, **vfield_ptr;
|
||||
Field **field_ptr, **vfield_ptr, **dfield_ptr;
|
||||
uint8 save_context_analysis_only= thd->lex->context_analysis_only;
|
||||
DBUG_ENTER("open_table_from_share");
|
||||
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
|
||||
|
@ -2419,9 +2421,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
if (share->found_next_number_field)
|
||||
outparam->found_next_number_field=
|
||||
outparam->field[(uint) (share->found_next_number_field - share->field)];
|
||||
if (share->timestamp_field)
|
||||
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
|
||||
|
||||
|
||||
/* Fix key->name and key_part->field */
|
||||
if (share->key_parts)
|
||||
|
@ -2472,7 +2471,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
}
|
||||
|
||||
/*
|
||||
Process virtual columns, if any.
|
||||
Process virtual and default columns, if any.
|
||||
*/
|
||||
if (!share->vfields)
|
||||
outparam->vfield= NULL;
|
||||
|
@ -2484,10 +2483,26 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
goto err;
|
||||
|
||||
outparam->vfield= vfield_ptr;
|
||||
}
|
||||
|
||||
if (!share->default_fields)
|
||||
outparam->default_field= NULL;
|
||||
else
|
||||
{
|
||||
if (!(dfield_ptr = (Field **) alloc_root(&outparam->mem_root,
|
||||
(uint) ((share->default_fields+1)*
|
||||
sizeof(Field*)))))
|
||||
goto err;
|
||||
|
||||
outparam->default_field= dfield_ptr;
|
||||
}
|
||||
|
||||
if (share->vfields || share->default_fields)
|
||||
{
|
||||
/* Reuse the same loop both for virtual and default fields. */
|
||||
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
|
||||
{
|
||||
if ((*field_ptr)->vcol_info)
|
||||
if (share->vfields && (*field_ptr)->vcol_info)
|
||||
{
|
||||
if (unpack_vcol_info_from_frm(thd,
|
||||
outparam,
|
||||
|
@ -2500,8 +2515,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
}
|
||||
*(vfield_ptr++)= *field_ptr;
|
||||
}
|
||||
if (share->default_fields &&
|
||||
((*field_ptr)->has_insert_default_function() ||
|
||||
(*field_ptr)->has_update_default_function()))
|
||||
*(dfield_ptr++)= *field_ptr;
|
||||
}
|
||||
*vfield_ptr= 0; // End marker
|
||||
if (share->vfields)
|
||||
*vfield_ptr= 0; // End marker
|
||||
if (share->default_fields)
|
||||
*dfield_ptr= 0; // End marker
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
|
@ -3924,9 +3946,6 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
|
|||
DBUG_ASSERT(!auto_increment_field_not_null);
|
||||
auto_increment_field_not_null= FALSE;
|
||||
|
||||
if (timestamp_field)
|
||||
timestamp_field_type= timestamp_field->get_auto_set_type();
|
||||
|
||||
pos_in_table_list= tl;
|
||||
|
||||
clear_column_bitmaps();
|
||||
|
@ -5842,6 +5861,48 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
bool TABLE::has_default_function(bool is_update)
|
||||
{
|
||||
Field **dfield_ptr, *dfield;
|
||||
bool res= false;
|
||||
for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
|
||||
{
|
||||
dfield= (*dfield_ptr);
|
||||
if (is_update)
|
||||
res= dfield->has_update_default_function();
|
||||
else
|
||||
res= dfield->has_insert_default_function();
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
void TABLE::mark_default_fields_for_write()
|
||||
{
|
||||
Field **dfield_ptr, *dfield;
|
||||
enum_sql_command cmd= in_use->lex->sql_command;
|
||||
for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
|
||||
{
|
||||
dfield= (*dfield_ptr);
|
||||
if (((cmd == SQLCOM_INSERT || cmd == SQLCOM_INSERT_SELECT ||
|
||||
cmd == SQLCOM_REPLACE || cmd == SQLCOM_REPLACE_SELECT ||
|
||||
cmd == SQLCOM_LOAD) &&
|
||||
dfield->has_insert_default_function()) ||
|
||||
((cmd == SQLCOM_UPDATE || cmd == SQLCOM_UPDATE_MULTI) &&
|
||||
dfield->has_update_default_function()))
|
||||
bitmap_set_bit(write_set, dfield->field_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Allocate space for keys
|
||||
|
@ -6448,6 +6509,50 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Update all DEFAULT and/or ON INSERT fields.
|
||||
|
||||
@details
|
||||
|
||||
@retval
|
||||
0 Success
|
||||
@retval
|
||||
>0 Error occurred when storing a virtual field value
|
||||
*/
|
||||
|
||||
int TABLE::update_default_fields()
|
||||
{
|
||||
DBUG_ENTER("update_default_fields");
|
||||
Field **dfield_ptr, *dfield;
|
||||
int res= 0;
|
||||
enum_sql_command cmd= in_use->lex->sql_command;
|
||||
|
||||
DBUG_ASSERT(default_field);
|
||||
/* Iterate over virtual fields in the table */
|
||||
for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
|
||||
{
|
||||
dfield= (*dfield_ptr);
|
||||
/*
|
||||
If an explicit default value for a filed overrides the default,
|
||||
do not update the field with its automatic default value.
|
||||
*/
|
||||
if (!(dfield->flags & HAS_EXPLICIT_DEFAULT))
|
||||
{
|
||||
if (sql_command_flags[cmd] & CF_INSERTS_DATA)
|
||||
res= dfield->evaluate_insert_default_function();
|
||||
if (sql_command_flags[cmd] & CF_UPDATES_DATA)
|
||||
res= dfield->evaluate_update_default_function();
|
||||
if (res)
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
/* Unset the explicit default flag for the next record. */
|
||||
dfield->flags&= ~HAS_EXPLICIT_DEFAULT;
|
||||
}
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@brief Reset const_table flag
|
||||
|
||||
|
|
41
sql/table.h
41
sql/table.h
|
@ -350,25 +350,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
Values in this enum are used to indicate how a tables TIMESTAMP field
|
||||
should be treated. It can be set to the current timestamp on insert or
|
||||
update or both.
|
||||
WARNING: The values are used for bit operations. If you change the
|
||||
enum, you must keep the bitwise relation of the values. For example:
|
||||
(int) TIMESTAMP_AUTO_SET_ON_BOTH must be equal to
|
||||
(int) TIMESTAMP_AUTO_SET_ON_INSERT | (int) TIMESTAMP_AUTO_SET_ON_UPDATE.
|
||||
We use an enum here so that the debugger can display the value names.
|
||||
*/
|
||||
enum timestamp_auto_set_type
|
||||
{
|
||||
TIMESTAMP_NO_AUTO_SET= 0, TIMESTAMP_AUTO_SET_ON_INSERT= 1,
|
||||
TIMESTAMP_AUTO_SET_ON_UPDATE= 2, TIMESTAMP_AUTO_SET_ON_BOTH= 3
|
||||
};
|
||||
#define clear_timestamp_auto_bits(_target_, _bits_) \
|
||||
(_target_)= (enum timestamp_auto_set_type)((int)(_target_) & ~(int)(_bits_))
|
||||
|
||||
class Field_timestamp;
|
||||
class Field_blob;
|
||||
class Table_triggers_list;
|
||||
|
||||
|
@ -608,7 +589,6 @@ struct TABLE_SHARE
|
|||
/* The following is copied to each TABLE on OPEN */
|
||||
Field **field;
|
||||
Field **found_next_number_field;
|
||||
Field *timestamp_field; /* Used only during open */
|
||||
KEY *key_info; /* data of keys in database */
|
||||
uint *blob_field; /* Index to blobs in Field arrray*/
|
||||
|
||||
|
@ -680,7 +660,6 @@ struct TABLE_SHARE
|
|||
uint uniques; /* Number of UNIQUE index */
|
||||
uint null_fields; /* number of null fields */
|
||||
uint blob_fields; /* number of blob fields */
|
||||
uint timestamp_field_offset; /* Field number for timestamp field */
|
||||
uint varchar_fields; /* number of varchar fields */
|
||||
uint db_create_options; /* Create options from database */
|
||||
uint db_options_in_use; /* Options in use */
|
||||
|
@ -695,6 +674,7 @@ struct TABLE_SHARE
|
|||
uint column_bitmap_size;
|
||||
uchar frm_version;
|
||||
uint vfields; /* Number of computed (virtual) fields */
|
||||
uint default_fields; /* Number of default fields in */
|
||||
bool use_ext_keys; /* Extended keys can be used */
|
||||
bool null_field_first;
|
||||
bool system; /* Set if system table (one record) */
|
||||
|
@ -1007,8 +987,9 @@ public:
|
|||
|
||||
Field *next_number_field; /* Set if next_number is activated */
|
||||
Field *found_next_number_field; /* Set on open */
|
||||
Field_timestamp *timestamp_field;
|
||||
Field **vfield; /* Pointer to virtual fields*/
|
||||
/* Fields that are updated automatically on INSERT or UPDATE. */
|
||||
Field **default_field;
|
||||
|
||||
/* Table's triggers, 0 if there are no of them */
|
||||
Table_triggers_list *triggers;
|
||||
|
@ -1064,19 +1045,6 @@ public:
|
|||
*/
|
||||
ha_rows quick_condition_rows;
|
||||
|
||||
/*
|
||||
If this table has TIMESTAMP field with auto-set property (pointed by
|
||||
timestamp_field member) then this variable indicates during which
|
||||
operations (insert only/on update/in both cases) we should set this
|
||||
field to current timestamp. If there are no such field in this table
|
||||
or we should not automatically set its value during execution of current
|
||||
statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0).
|
||||
|
||||
Value of this variable is set for each statement in open_table() and
|
||||
if needed cleared later in statement processing code (see mysql_update()
|
||||
as example).
|
||||
*/
|
||||
timestamp_auto_set_type timestamp_field_type;
|
||||
table_map map; /* ID bit of table (1,2,4,8,16...) */
|
||||
|
||||
uint lock_position; /* Position in MYSQL_LOCK.table */
|
||||
|
@ -1207,6 +1175,8 @@ public:
|
|||
void mark_columns_needed_for_insert(void);
|
||||
bool mark_virtual_col(Field *field);
|
||||
void mark_virtual_columns_for_write(bool insert_fl);
|
||||
void mark_default_fields_for_write();
|
||||
bool has_default_function(bool is_update);
|
||||
inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
|
||||
MY_BITMAP *write_set_arg)
|
||||
{
|
||||
|
@ -1293,6 +1263,7 @@ public:
|
|||
bool update_const_key_parts(COND *conds);
|
||||
uint actual_n_key_parts(KEY *keyinfo);
|
||||
ulong actual_key_flags(KEY *keyinfo);
|
||||
int update_default_fields();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -905,8 +905,6 @@ int ha_archive::write_row(uchar *buf)
|
|||
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
|
||||
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
mysql_mutex_lock(&share->mutex);
|
||||
|
||||
if (!share->archive_write_open)
|
||||
|
|
|
@ -999,9 +999,6 @@ int ha_tina::write_row(uchar * buf)
|
|||
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
size= encode_quote(buf);
|
||||
|
||||
if (!share->tina_write_opened)
|
||||
|
@ -1064,9 +1061,6 @@ int ha_tina::update_row(const uchar * old_data, uchar * new_data)
|
|||
|
||||
ha_statistic_increment(&SSV::ha_update_count);
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
size= encode_quote(new_data);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1849,8 +1849,6 @@ int ha_federated::write_row(uchar *buf)
|
|||
values_string.length(0);
|
||||
insert_field_value_string.length(0);
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
/*
|
||||
start both our field and field values strings
|
||||
|
|
|
@ -1993,8 +1993,6 @@ int ha_federatedx::write_row(uchar *buf)
|
|||
|
||||
values_string.length(0);
|
||||
insert_field_value_string.length(0);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
/*
|
||||
start both our field and field values strings
|
||||
|
|
|
@ -241,8 +241,6 @@ void ha_heap::update_key_stats()
|
|||
int ha_heap::write_row(uchar * buf)
|
||||
{
|
||||
int res;
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
if (table->next_number_field && buf == table->record[0])
|
||||
{
|
||||
if ((res= update_auto_increment()))
|
||||
|
@ -264,8 +262,6 @@ int ha_heap::write_row(uchar * buf)
|
|||
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
|
||||
{
|
||||
int res;
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
res= heap_update(file,old_data,new_data);
|
||||
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||
file->s->records)
|
||||
|
|
|
@ -5163,9 +5163,6 @@ ha_innobase::write_row(
|
|||
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
sql_command = thd_sql_command(user_thd);
|
||||
|
||||
if ((sql_command == SQLCOM_ALTER_TABLE
|
||||
|
@ -5573,9 +5570,6 @@ ha_innobase::update_row(
|
|||
|
||||
ha_statistic_increment(&SSV::ha_update_count);
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
if (prebuilt->upd_node) {
|
||||
uvect = prebuilt->upd_node->update;
|
||||
} else {
|
||||
|
|
|
@ -1248,10 +1248,6 @@ int ha_maria::close(void)
|
|||
|
||||
int ha_maria::write_row(uchar * buf)
|
||||
{
|
||||
/* If we have a timestamp column, update it to the current time */
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
/*
|
||||
If we have an auto_increment column and we are writing a changed row
|
||||
or a new row, then update the auto_increment value in the record.
|
||||
|
@ -2245,8 +2241,6 @@ bool ha_maria::is_crashed() const
|
|||
int ha_maria::update_row(const uchar * old_data, uchar * new_data)
|
||||
{
|
||||
CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("UPDATE in WRITE CONCURRENT");
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
return maria_update(file, old_data, new_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -832,10 +832,6 @@ int ha_myisam::close(void)
|
|||
|
||||
int ha_myisam::write_row(uchar *buf)
|
||||
{
|
||||
/* If we have a timestamp column, update it to the current time */
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
/*
|
||||
If we have an auto_increment column and we are writing a changed row
|
||||
or a new row, then update the auto_increment value in the record.
|
||||
|
@ -1656,8 +1652,6 @@ bool ha_myisam::is_crashed() const
|
|||
|
||||
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
|
||||
{
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
return mi_update(file,old_data,new_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -1078,8 +1078,6 @@ int ha_myisammrg::write_row(uchar * buf)
|
|||
if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
|
||||
DBUG_RETURN(HA_ERR_TABLE_READONLY);
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
if (table->next_number_field && buf == table->record[0])
|
||||
{
|
||||
int error;
|
||||
|
@ -1093,8 +1091,6 @@ int ha_myisammrg::update_row(const uchar * old_data, uchar * new_data)
|
|||
{
|
||||
DBUG_ASSERT(this->file->children_attached);
|
||||
ha_statistic_increment(&SSV::ha_update_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
return myrg_update(file,old_data,new_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -5933,9 +5933,6 @@ ha_innobase::write_row(
|
|||
DBUG_RETURN(HA_ERR_CRASHED);
|
||||
}
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
sql_command = thd_sql_command(user_thd);
|
||||
|
||||
if ((sql_command == SQLCOM_ALTER_TABLE
|
||||
|
@ -6359,9 +6356,6 @@ ha_innobase::update_row(
|
|||
DBUG_RETURN(HA_ERR_CRASHED);
|
||||
}
|
||||
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
|
||||
if (prebuilt->upd_node) {
|
||||
uvect = prebuilt->upd_node->update;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue