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
@ -128,6 +128,8 @@ enum enum_server_command
|
|||||||
reserved by MySQL Cluster */
|
reserved by MySQL Cluster */
|
||||||
#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25,
|
#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25,
|
||||||
reserved by MySQL Cluster */
|
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_GRANT 1 /* Refresh grant tables */
|
||||||
#define REFRESH_LOG 2 /* Start on new log file */
|
#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);
|
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
|
||||||
ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
|
ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
|
||||||
create table t1 (a datetime default now());
|
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());
|
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);
|
create table t1 (a int default 100 auto_increment);
|
||||||
ERROR 42000: Invalid default value for 'a'
|
ERROR 42000: Invalid default value for 'a'
|
||||||
create table t1 (a tinyint default 1000);
|
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
|
innodb
|
||||||
show fields from mysql.slow_log;
|
show fields from mysql.slow_log;
|
||||||
Field Type Null Key Default Extra
|
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
|
user_host mediumtext NO NULL
|
||||||
query_time time(6) NO NULL
|
query_time time(6) NO NULL
|
||||||
lock_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;
|
show create table mysql.general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned 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'
|
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
|
||||||
show fields from mysql.general_log;
|
show fields from mysql.general_log;
|
||||||
Field Type Null Key Default Extra
|
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
|
user_host mediumtext NO NULL
|
||||||
thread_id int(11) NO NULL
|
thread_id int(11) NO NULL
|
||||||
server_id int(10) unsigned NO NULL
|
server_id int(10) unsigned NO NULL
|
||||||
@ -71,7 +71,7 @@ argument mediumtext NO NULL
|
|||||||
show create table mysql.slow_log;
|
show create table mysql.slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_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'
|
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
|
||||||
show fields from mysql.slow_log;
|
show fields from mysql.slow_log;
|
||||||
Field Type Null Key Default Extra
|
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
|
user_host mediumtext NO NULL
|
||||||
query_time time(6) NO NULL
|
query_time time(6) NO NULL
|
||||||
lock_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;
|
show create table mysql.general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned 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;
|
show create table mysql.slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_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;
|
show create table mysql.general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned 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;
|
show create table mysql.slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_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;
|
SHOW CREATE TABLE mysql.general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned 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;
|
SHOW CREATE TABLE mysql.slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_time` time(6) NOT NULL,
|
`lock_time` time(6) NOT NULL,
|
||||||
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||||||
show create table general_log;
|
show create table general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned NOT NULL,
|
`server_id` int(10) unsigned NOT NULL,
|
||||||
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||||||
show create table slow_log;
|
show create table slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_time` time(6) NOT NULL,
|
`lock_time` time(6) NOT NULL,
|
||||||
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||||||
show create table general_log;
|
show create table general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned NOT NULL,
|
`server_id` int(10) unsigned NOT NULL,
|
||||||
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||||||
show create table slow_log;
|
show create table slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_time` time(6) NOT NULL,
|
`lock_time` time(6) NOT NULL,
|
||||||
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||||||
show create table general_log;
|
show create table general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned NOT NULL,
|
`server_id` int(10) unsigned NOT NULL,
|
||||||
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||||||
show create table slow_log;
|
show create table slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_time` time(6) NOT NULL,
|
`lock_time` time(6) NOT NULL,
|
||||||
|
@ -242,7 +242,7 @@ event CREATE TABLE `event` (
|
|||||||
show create table general_log;
|
show create table general_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
general_log CREATE TABLE `general_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`thread_id` int(11) NOT NULL,
|
`thread_id` int(11) NOT NULL,
|
||||||
`server_id` int(10) unsigned NOT NULL,
|
`server_id` int(10) unsigned NOT NULL,
|
||||||
@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
|
|||||||
show create table slow_log;
|
show create table slow_log;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
slow_log CREATE TABLE `slow_log` (
|
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,
|
`user_host` mediumtext NOT NULL,
|
||||||
`query_time` time(6) NOT NULL,
|
`query_time` time(6) NOT NULL,
|
||||||
`lock_time` time(6) NOT NULL,
|
`lock_time` time(6) NOT NULL,
|
||||||
|
@ -148,15 +148,15 @@ ix+0
|
|||||||
20030101000000
|
20030101000000
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (t1 timestamp, t2 timestamp default now());
|
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());
|
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());
|
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());
|
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());
|
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);
|
create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 datetime, t3 timestamp);
|
||||||
SET TIMESTAMP=1000000000;
|
SET TIMESTAMP=1000000000;
|
||||||
insert into t1 values ();
|
insert into t1 values ();
|
||||||
|
@ -63,15 +63,15 @@ a
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
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
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
show columns from t1;
|
show columns from t1;
|
||||||
Field Type Null Key Default Extra
|
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';
|
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
|
table_name t1
|
||||||
column_name a
|
column_name a
|
||||||
column_default CURRENT_TIMESTAMP
|
column_default CURRENT_TIMESTAMP(4)
|
||||||
is_nullable NO
|
is_nullable NO
|
||||||
data_type timestamp
|
data_type timestamp
|
||||||
character_maximum_length NULL
|
character_maximum_length NULL
|
||||||
@ -113,7 +113,7 @@ t2 CREATE TABLE `t2` (
|
|||||||
show create table t3;
|
show create table t3;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t3 CREATE TABLE `t3` (
|
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
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
drop table t2, t3;
|
drop table t2, t3;
|
||||||
insert t1 values ('2010-12-13 14:15:16.222222');
|
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 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 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 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 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 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
|
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 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 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 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 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 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
|
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)
|
# Some wrong defaults, so these creates should fail too (Bug #5902)
|
||||||
#
|
#
|
||||||
--error 1067
|
|
||||||
create table t1 (a datetime default now());
|
create table t1 (a datetime default now());
|
||||||
--error 1294
|
drop table t1;
|
||||||
create table t1 (a datetime on update now());
|
create table t1 (a datetime on update now());
|
||||||
|
drop table t1;
|
||||||
--error 1067
|
--error 1067
|
||||||
create table t1 (a int default 100 auto_increment);
|
create table t1 (a int default 100 auto_increment);
|
||||||
--error 1067
|
--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
|
# 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());
|
create table t1 (t1 timestamp, t2 timestamp default now());
|
||||||
--error 1293
|
drop table t1;
|
||||||
create table t1 (t1 timestamp, t2 timestamp on update now());
|
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());
|
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());
|
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());
|
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
|
# Let us test TIMESTAMP auto-update behaviour
|
||||||
# Also we will test behaviour of TIMESTAMP field in SHOW CREATE TABLE and
|
# 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()))
|
(int) table->field[ET_FIELD_ON_COMPLETION]->val_int()))
|
||||||
goto end;
|
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
|
mysql_event_fill_row() calls my_error() in case of error so no need to
|
||||||
handle it here
|
handle it here
|
||||||
@ -1133,8 +1130,6 @@ update_timing_fields_for_event(THD *thd,
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
store_record(table, record[1]);
|
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);
|
my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
|
||||||
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
|
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 */
|
/* For 4.0 MYD and 4.0 InnoDB compatibility */
|
||||||
flags|= UNSIGNED_FLAG | BINARY_FLAG;
|
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;
|
flags|= TIMESTAMP_FLAG;
|
||||||
if (unireg_check != TIMESTAMP_DN_FIELD)
|
if (unireg_check != TIMESTAMP_DN_FIELD)
|
||||||
flags|= ON_UPDATE_NOW_FLAG;
|
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
|
my_time_t Field_timestamp::get_timestamp(ulong *sec_part) const
|
||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
@ -4713,6 +4681,16 @@ int Field_timestamp::set_time()
|
|||||||
return 0;
|
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
|
void Field_timestamp_hires::sql_type(String &res) const
|
||||||
{
|
{
|
||||||
CHARSET_INFO *cs=res.charset();
|
CHARSET_INFO *cs=res.charset();
|
||||||
@ -5836,6 +5814,20 @@ void Field_datetime::sql_type(String &res) const
|
|||||||
res.set_ascii(STRING_WITH_LEN("datetime"));
|
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)
|
void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
|
||||||
{
|
{
|
||||||
ulonglong packed= sec_part_shift(pack_time(ltime), dec);
|
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;
|
uint sign_len, allowed_type_modifier= 0;
|
||||||
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
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()");
|
DBUG_ENTER("Create_field::init()");
|
||||||
|
|
||||||
field= 0;
|
field= 0;
|
||||||
field_name= fld_name;
|
field_name= fld_name;
|
||||||
def= fld_default_value;
|
|
||||||
flags= fld_type_modifier;
|
flags= fld_type_modifier;
|
||||||
option_list= create_opt;
|
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;
|
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
|
||||||
if (decimals >= NOT_FIXED_DEC)
|
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);
|
length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
|
||||||
flags|= UNSIGNED_FLAG;
|
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;
|
break;
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
/* We don't support creation of MYSQL_TYPE_DATE anymore */
|
/* 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;
|
def=0;
|
||||||
char_length= length;
|
char_length= length;
|
||||||
|
|
||||||
if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
|
/*
|
||||||
old_field->ptr && orig_field &&
|
Copy the default value from the column object orig_field, if:
|
||||||
(sql_type != MYSQL_TYPE_TIMESTAMP || /* set def only if */
|
1) The column has a constant default value.
|
||||||
old_field->table->timestamp_field != old_field || /* timestamp field */
|
2) The column type is not a BLOB type.
|
||||||
unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
|
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];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String tmp(buff,sizeof(buff), charset);
|
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() ?
|
return (table->pos_in_table_list->is_materialized_derived() ?
|
||||||
part_of_key : key_start);
|
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= ((*null_ptr & (uchar) ~null_bit) |
|
||||||
(null_ptr[l_offset] & 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 binary() const { return 1; }
|
||||||
virtual bool zero_pack() const { return 1; }
|
virtual bool zero_pack() const { return 1; }
|
||||||
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||||
@ -1239,12 +1270,26 @@ public:
|
|||||||
virtual int set_time();
|
virtual int set_time();
|
||||||
virtual void set_default()
|
virtual void set_default()
|
||||||
{
|
{
|
||||||
if (table->timestamp_field == this &&
|
if (has_insert_default_function())
|
||||||
unireg_check != TIMESTAMP_UN_FIELD)
|
|
||||||
set_time();
|
set_time();
|
||||||
else
|
else
|
||||||
Field::set_default();
|
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 */
|
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
|
||||||
virtual my_time_t get_timestamp(ulong *sec_part) const;
|
virtual my_time_t get_timestamp(ulong *sec_part) const;
|
||||||
virtual void store_TIME(my_time_t timestamp, ulong sec_part)
|
virtual void store_TIME(my_time_t timestamp, ulong sec_part)
|
||||||
@ -1252,7 +1297,6 @@ public:
|
|||||||
int4store(ptr,timestamp);
|
int4store(ptr,timestamp);
|
||||||
}
|
}
|
||||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||||
timestamp_auto_set_type get_auto_set_type() const;
|
|
||||||
uchar *pack(uchar *to, const uchar *from,
|
uchar *pack(uchar *to, const uchar *from,
|
||||||
uint max_length __attribute__((unused)))
|
uint max_length __attribute__((unused)))
|
||||||
{
|
{
|
||||||
@ -1503,6 +1547,28 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool zero_pack() const { return 1; }
|
bool zero_pack() const { return 1; }
|
||||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
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,
|
uchar *pack(uchar* to, const uchar *from,
|
||||||
uint max_length __attribute__((unused)))
|
uint max_length __attribute__((unused)))
|
||||||
{
|
{
|
||||||
|
@ -2906,8 +2906,6 @@ int ha_ndbcluster::write_row(uchar *record)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ha_statistic_increment(&SSV::ha_write_count);
|
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)))
|
if (!(op= trans->getNdbOperation(m_table)))
|
||||||
ERR_RETURN(trans->getNdbError());
|
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);
|
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 &&
|
if (m_use_partition_function &&
|
||||||
(error= get_parts_for_update(old_data, new_data, table->record[0],
|
(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:
|
ADDITIONAL INFO:
|
||||||
|
|
||||||
We have to set timestamp fields and auto_increment fields, because those
|
We have to set auto_increment fields, because those may be used in
|
||||||
may be used in determining which partition the row should be written to.
|
determining which partition the row should be written to.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ha_partition::write_row(uchar * buf)
|
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];
|
bool have_auto_increment= table->next_number_field && buf == table->record[0];
|
||||||
my_bitmap_map *old_map;
|
my_bitmap_map *old_map;
|
||||||
THD *thd= ha_thd();
|
THD *thd= ha_thd();
|
||||||
timestamp_auto_set_type saved_timestamp_type= table->timestamp_field_type;
|
|
||||||
ulonglong saved_sql_mode= thd->variables.sql_mode;
|
ulonglong saved_sql_mode= thd->variables.sql_mode;
|
||||||
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
|
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
|
||||||
#ifdef NOT_NEEDED
|
#ifdef NOT_NEEDED
|
||||||
@ -3472,11 +3471,6 @@ int ha_partition::write_row(uchar * buf)
|
|||||||
DBUG_ENTER("ha_partition::write_row");
|
DBUG_ENTER("ha_partition::write_row");
|
||||||
DBUG_ASSERT(buf == m_rec0);
|
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
|
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.
|
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:
|
exit:
|
||||||
thd->variables.sql_mode= saved_sql_mode;
|
thd->variables.sql_mode= saved_sql_mode;
|
||||||
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
|
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
|
||||||
table->timestamp_field_type= saved_timestamp_type;
|
|
||||||
DBUG_RETURN(error);
|
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;
|
uint32 new_part_id, old_part_id;
|
||||||
int error= 0;
|
int error= 0;
|
||||||
longlong func_value;
|
longlong func_value;
|
||||||
timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
|
|
||||||
DBUG_ENTER("ha_partition::update_row");
|
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],
|
if ((error= get_parts_for_update(old_data, new_data, table->record[0],
|
||||||
m_part_info, &old_part_id, &new_part_id,
|
m_part_info, &old_part_id, &new_part_id,
|
||||||
&func_value)))
|
&func_value)))
|
||||||
@ -3672,7 +3655,6 @@ exit:
|
|||||||
info(HA_STATUS_AUTO);
|
info(HA_STATUS_AUTO);
|
||||||
set_auto_increment_if_higher(table->found_next_number_field);
|
set_auto_increment_if_higher(table->found_next_number_field);
|
||||||
}
|
}
|
||||||
table->timestamp_field_type= orig_timestamp_type;
|
|
||||||
DBUG_RETURN(error);
|
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 */
|
/* Honor next number column if present */
|
||||||
m_table->next_number_field= m_table->found_next_number_field;
|
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()))
|
if ((err= find_key()))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,22 +924,6 @@ int Write_rows_log_event_old::do_before_row_operations(TABLE *table)
|
|||||||
from the start.
|
from the start.
|
||||||
*/
|
*/
|
||||||
table->file->ha_start_bulk_insert(0);
|
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,8 +1112,6 @@ int Update_rows_log_event_old::do_before_row_operations(TABLE *table)
|
|||||||
if (!m_memory)
|
if (!m_memory)
|
||||||
return HA_ERR_OUT_OF_MEM;
|
return HA_ERR_OUT_OF_MEM;
|
||||||
|
|
||||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2589,22 +2571,6 @@ Write_rows_log_event_old::do_before_row_operations(const Slave_reporting_capabil
|
|||||||
from the start.
|
from the start.
|
||||||
*/
|
*/
|
||||||
m_table->file->ha_start_bulk_insert(0);
|
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;
|
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;
|
return HA_ERR_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,7 +1350,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
store_record(table,record[1]);
|
store_record(table,record[1]);
|
||||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
|
||||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
||||||
if (chistics->suid != SP_IS_DEFAULT_SUID)
|
if (chistics->suid != SP_IS_DEFAULT_SUID)
|
||||||
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
|
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 };
|
LEX_STRING cmt = { 0, 0 };
|
||||||
uint unused1= 0;
|
uint unused1= 0;
|
||||||
int unused2= 0;
|
|
||||||
|
|
||||||
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
|
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
|
||||||
lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
|
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);
|
sp_prepare_create_field(thd, field_def);
|
||||||
|
|
||||||
if (prepare_create_field(field_def, &unused1, &unused2, &unused2,
|
if (prepare_create_field(field_def, &unused1, HA_CAN_GEOMETRY))
|
||||||
HA_CAN_GEOMETRY))
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -8800,13 +8800,13 @@ err_no_arena:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
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)
|
bool ignore_errors)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> f(fields),v(values);
|
List_iterator_fast<Item> f(fields),v(values);
|
||||||
Item *value, *fld;
|
Item *value, *fld;
|
||||||
Item_field *field;
|
Item_field *field;
|
||||||
TABLE *table= 0, *vcol_table= 0;
|
TABLE *vcol_table= 0;
|
||||||
bool save_abort_on_warning= thd->abort_on_warning;
|
bool save_abort_on_warning= thd->abort_on_warning;
|
||||||
bool save_no_errors= thd->no_errors;
|
bool save_no_errors= thd->no_errors;
|
||||||
DBUG_ENTER("fill_record");
|
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);
|
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
table= field->field->table;
|
DBUG_ASSERT(field->field->table == table_arg);
|
||||||
table->auto_increment_field_not_null= FALSE;
|
table_arg->auto_increment_field_not_null= FALSE;
|
||||||
f.rewind();
|
f.rewind();
|
||||||
}
|
}
|
||||||
else if (thd->lex->unit.insert_table_with_stored_vcol)
|
else if (thd->lex->unit.insert_table_with_stored_vcol)
|
||||||
vcol_table= thd->lex->unit.insert_table_with_stored_vcol;
|
vcol_table= thd->lex->unit.insert_table_with_stored_vcol;
|
||||||
|
|
||||||
while ((fld= f++))
|
while ((fld= f++))
|
||||||
{
|
{
|
||||||
if (!(field= fld->filed_for_view_update()))
|
if (!(field= fld->filed_for_view_update()))
|
||||||
@ -8843,7 +8844,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||||||
}
|
}
|
||||||
value=v++;
|
value=v++;
|
||||||
Field *rfield= field->field;
|
Field *rfield= field->field;
|
||||||
table= rfield->table;
|
TABLE* table= rfield->table;
|
||||||
if (rfield == table->next_number_field)
|
if (rfield == table->next_number_field)
|
||||||
table->auto_increment_field_not_null= TRUE;
|
table->auto_increment_field_not_null= TRUE;
|
||||||
if (rfield->vcol_info &&
|
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));
|
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
rfield->set_explicit_default(value);
|
||||||
DBUG_ASSERT(vcol_table == 0 || vcol_table == table);
|
DBUG_ASSERT(vcol_table == 0 || vcol_table == table);
|
||||||
vcol_table= table;
|
vcol_table= table;
|
||||||
}
|
}
|
||||||
@ -8875,8 +8877,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||||||
err:
|
err:
|
||||||
thd->abort_on_warning= save_abort_on_warning;
|
thd->abort_on_warning= save_abort_on_warning;
|
||||||
thd->no_errors= save_no_errors;
|
thd->no_errors= save_no_errors;
|
||||||
if (table)
|
if (fields.elements)
|
||||||
table->auto_increment_field_not_null= FALSE;
|
table_arg->auto_increment_field_not_null= FALSE;
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8905,13 +8907,13 @@ err:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
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,
|
List<Item> &values, bool ignore_errors,
|
||||||
Table_triggers_list *triggers,
|
|
||||||
enum trg_event_type event)
|
enum trg_event_type event)
|
||||||
{
|
{
|
||||||
bool result;
|
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,
|
(triggers && triggers->process_triggers(thd, event,
|
||||||
TRG_ACTION_BEFORE, TRUE)));
|
TRG_ACTION_BEFORE, TRUE)));
|
||||||
/*
|
/*
|
||||||
@ -8920,7 +8922,6 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||||||
*/
|
*/
|
||||||
if (!result && triggers)
|
if (!result && triggers)
|
||||||
{
|
{
|
||||||
TABLE *table= 0;
|
|
||||||
List_iterator_fast<Item> f(fields);
|
List_iterator_fast<Item> f(fields);
|
||||||
Item *fld;
|
Item *fld;
|
||||||
Item_field *item_field;
|
Item_field *item_field;
|
||||||
@ -8928,9 +8929,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||||||
{
|
{
|
||||||
fld= (Item_field*)f++;
|
fld= (Item_field*)f++;
|
||||||
item_field= fld->filed_for_view_update();
|
item_field= fld->filed_for_view_update();
|
||||||
if (item_field && item_field->field &&
|
if (item_field && item_field->field && table && table->vfield)
|
||||||
(table= item_field->field->table) &&
|
|
||||||
table->vfield)
|
|
||||||
result= update_virtual_fields(thd, table, TRUE);
|
result= update_virtual_fields(thd, table, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8960,13 +8959,12 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
|
fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
||||||
bool use_value)
|
bool ignore_errors, bool use_value)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> v(values);
|
List_iterator_fast<Item> v(values);
|
||||||
List<TABLE> tbl_list;
|
List<TABLE> tbl_list;
|
||||||
Item *value;
|
Item *value;
|
||||||
TABLE *table= 0;
|
|
||||||
Field *field;
|
Field *field;
|
||||||
bool abort_on_warning_saved= thd->abort_on_warning;
|
bool abort_on_warning_saved= thd->abort_on_warning;
|
||||||
DBUG_ENTER("fill_record");
|
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,
|
On INSERT or UPDATE fields are checked to be from the same table,
|
||||||
thus we safely can take table from the first field.
|
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
|
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
|
else
|
||||||
if (value->save_in_field(field, 0) < 0)
|
if (value->save_in_field(field, 0) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
field->set_explicit_default(value);
|
||||||
}
|
}
|
||||||
/* Update virtual fields*/
|
/* Update virtual fields*/
|
||||||
thd->abort_on_warning= FALSE;
|
thd->abort_on_warning= FALSE;
|
||||||
@ -9051,13 +9050,13 @@ err:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
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,
|
List<Item> &values, bool ignore_errors,
|
||||||
Table_triggers_list *triggers,
|
|
||||||
enum trg_event_type event)
|
enum trg_event_type event)
|
||||||
{
|
{
|
||||||
bool result;
|
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,
|
(triggers && triggers->process_triggers(thd, event,
|
||||||
TRG_ACTION_BEFORE, TRUE)));
|
TRG_ACTION_BEFORE, TRUE)));
|
||||||
/*
|
/*
|
||||||
@ -9066,7 +9065,6 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
|
|||||||
*/
|
*/
|
||||||
if (!result && triggers && *ptr)
|
if (!result && triggers && *ptr)
|
||||||
{
|
{
|
||||||
TABLE *table= (*ptr)->table;
|
|
||||||
if (table->vfield)
|
if (table->vfield)
|
||||||
result= update_virtual_fields(thd, table, TRUE);
|
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 */
|
/* Make sure all columns get assigned to a default value */
|
||||||
table->use_all_columns();
|
table->use_all_columns();
|
||||||
table->no_replicate= 1;
|
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
|
else
|
||||||
thd->restore_backup_open_tables_state(backup);
|
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,
|
TABLE *find_temporary_table(THD *thd, const char *table_key,
|
||||||
uint table_key_length);
|
uint table_key_length);
|
||||||
void close_thread_tables(THD *thd);
|
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,
|
List<Item> &values,
|
||||||
bool ignore_errors,
|
bool ignore_errors,
|
||||||
Table_triggers_list *triggers,
|
|
||||||
enum trg_event_type event);
|
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,
|
List<Item> &values,
|
||||||
bool ignore_errors,
|
bool ignore_errors,
|
||||||
Table_triggers_list *triggers,
|
|
||||||
enum trg_event_type event);
|
enum trg_event_type event);
|
||||||
bool insert_fields(THD *thd, Name_resolution_context *context,
|
bool insert_fields(THD *thd, Name_resolution_context *context,
|
||||||
const char *db_name, const char *table_name,
|
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> &item, enum_mark_columns mark_used_columns,
|
||||||
List<Item> *sum_func_list, bool allow_sum_func);
|
List<Item> *sum_func_list, bool allow_sum_func);
|
||||||
void unfix_fields(List<Item> &items);
|
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);
|
bool ignore_errors, bool use_value);
|
||||||
|
|
||||||
Field *
|
Field *
|
||||||
@ -304,6 +304,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
|
|||||||
void mark_tmp_table_for_reuse(TABLE *table);
|
void mark_tmp_table_for_reuse(TABLE *table);
|
||||||
bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
|
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_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);
|
int dynamic_column_error_message(enum_dyncol_func_result rc);
|
||||||
|
|
||||||
extern TABLE *unused_tables;
|
extern TABLE *unused_tables;
|
||||||
|
@ -4120,6 +4120,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
#define CF_FORCE_ORIGINAL_BINLOG_FORMAT (1U << 10)
|
#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 */
|
/* Bits in server_command_flags */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,7 +257,7 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*(items.head_ref())= 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())
|
if (table_thd->is_error())
|
||||||
goto err;;
|
goto err;;
|
||||||
|
|
||||||
|
@ -191,11 +191,6 @@ error:
|
|||||||
different table maps, like on select ... insert
|
different table maps, like on select ... insert
|
||||||
map Store here table map for used fields
|
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
|
RETURN
|
||||||
0 OK
|
0 OK
|
||||||
-1 Error
|
-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))
|
if (check_grant_all_columns(thd, INSERT_ACL, &field_it))
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#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.
|
No fields are provided so all fields must be provided in the values.
|
||||||
Thus we set all bits in the write set.
|
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);
|
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dup_field->field_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (table->timestamp_field) // Don't automaticly set timestamp if used
|
if (table->default_field)
|
||||||
{
|
table->mark_default_fields_for_write();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Mark virtual columns used in the insert statement */
|
/* Mark virtual columns used in the insert statement */
|
||||||
if (table->vfield)
|
if (table->vfield)
|
||||||
@ -339,9 +322,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||||||
update_fields The update fields.
|
update_fields The update fields.
|
||||||
|
|
||||||
NOTE
|
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
|
If the update fields include an autoinc field, set the
|
||||||
table->next_number_field_updated flag.
|
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)
|
List<Item> &update_values, table_map *map)
|
||||||
{
|
{
|
||||||
TABLE *table= insert_table_list->table;
|
TABLE *table= insert_table_list->table;
|
||||||
my_bool timestamp_mark;
|
|
||||||
my_bool autoinc_mark;
|
my_bool autoinc_mark;
|
||||||
LINT_INIT(timestamp_mark);
|
|
||||||
LINT_INIT(autoinc_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;
|
table->next_number_field_updated= FALSE;
|
||||||
|
|
||||||
if (table->found_next_number_field)
|
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))
|
insert_table_list, map, false))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (table->timestamp_field)
|
if (table->default_field)
|
||||||
{
|
table->mark_default_fields_for_write();
|
||||||
/* 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->found_next_number_field)
|
if (table->found_next_number_field)
|
||||||
{
|
{
|
||||||
@ -709,7 +668,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
int error, res;
|
int error, res;
|
||||||
bool transactional_table, joins_freed= FALSE;
|
bool transactional_table, joins_freed= FALSE;
|
||||||
bool changed;
|
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;
|
bool using_bulk_insert= 0;
|
||||||
uint value_count;
|
uint value_count;
|
||||||
ulong counter = 1;
|
ulong counter = 1;
|
||||||
@ -913,8 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
if (fields.elements || !value_count)
|
if (fields.elements || !value_count)
|
||||||
{
|
{
|
||||||
restore_record(table,s->default_values); // Get empty record
|
restore_record(table,s->default_values); // Get empty record
|
||||||
if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0,
|
if (fill_record_n_invoke_before_triggers(thd, table, fields, *values, 0,
|
||||||
table->triggers,
|
|
||||||
TRG_EVENT_INSERT))
|
TRG_EVENT_INSERT))
|
||||||
{
|
{
|
||||||
if (values_list.elements != 1 && ! thd->is_error())
|
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];
|
share->default_values[share->null_bytes - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0,
|
if (fill_record_n_invoke_before_triggers(thd, table, table->field, *values, 0,
|
||||||
table->triggers,
|
|
||||||
TRG_EVENT_INSERT))
|
TRG_EVENT_INSERT))
|
||||||
{
|
{
|
||||||
if (values_list.elements != 1 && ! thd->is_error())
|
if (values_list.elements != 1 && ! thd->is_error())
|
||||||
@ -971,6 +928,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (table->default_field && table->update_default_fields())
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((res= table_list->view_check_option(thd,
|
if ((res= table_list->view_check_option(thd,
|
||||||
(values_list.elements == 1 ?
|
(values_list.elements == 1 ?
|
||||||
@ -987,7 +949,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
if (lock_type == TL_WRITE_DELAYED)
|
if (lock_type == TL_WRITE_DELAYED)
|
||||||
{
|
{
|
||||||
LEX_STRING const st_query = { query, thd->query_length() };
|
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);
|
error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
|
||||||
|
DEBUG_SYNC(thd, "after_write_delayed");
|
||||||
query=0;
|
query=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1696,13 +1660,32 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
restore_record(table,record[1]);
|
restore_record(table,record[1]);
|
||||||
DBUG_ASSERT(info->update_fields->elements ==
|
DBUG_ASSERT(info->update_fields->elements ==
|
||||||
info->update_values->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->update_values,
|
||||||
info->ignore,
|
info->ignore,
|
||||||
table->triggers,
|
|
||||||
TRG_EVENT_UPDATE))
|
TRG_EVENT_UPDATE))
|
||||||
goto before_trg_err;
|
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 ... */
|
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
|
||||||
if (info->view &&
|
if (info->view &&
|
||||||
(res= info->view->view_check_option(current_thd, info->ignore)) ==
|
(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);
|
table->file->restore_auto_increment(prev_insert_id);
|
||||||
info->touched++;
|
info->touched++;
|
||||||
if (!records_are_comparable(table) || compare_record(table))
|
if (different_records)
|
||||||
{
|
{
|
||||||
if ((error=table->file->ha_update_row(table->record[1],
|
if ((error=table->file->ha_update_row(table->record[1],
|
||||||
table->record[0])) &&
|
table->record[0])) &&
|
||||||
@ -1784,8 +1767,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
*/
|
*/
|
||||||
if (last_uniq_key(table,key_nr) &&
|
if (last_uniq_key(table,key_nr) &&
|
||||||
!table->file->referenced_by_foreign_key() &&
|
!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()))
|
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||||
{
|
{
|
||||||
if ((error=table->file->ha_update_row(table->record[1],
|
if ((error=table->file->ha_update_row(table->record[1],
|
||||||
@ -1948,7 +1929,6 @@ public:
|
|||||||
ulonglong forced_insert_id;
|
ulonglong forced_insert_id;
|
||||||
ulong auto_increment_increment;
|
ulong auto_increment_increment;
|
||||||
ulong auto_increment_offset;
|
ulong auto_increment_offset;
|
||||||
timestamp_auto_set_type timestamp_field_type;
|
|
||||||
LEX_STRING query;
|
LEX_STRING query;
|
||||||
Time_zone *time_zone;
|
Time_zone *time_zone;
|
||||||
|
|
||||||
@ -2321,7 +2301,7 @@ end_create:
|
|||||||
TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
||||||
{
|
{
|
||||||
my_ptrdiff_t adjust_ptrs;
|
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 *copy;
|
||||||
TABLE_SHARE *share;
|
TABLE_SHARE *share;
|
||||||
uchar *bitmap;
|
uchar *bitmap;
|
||||||
@ -2390,6 +2370,12 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||||||
bitmap= (uchar*) (field + share->fields + 1);
|
bitmap= (uchar*) (field + share->fields + 1);
|
||||||
copy->record[0]= (bitmap + share->column_bitmap_size*3);
|
copy->record[0]= (bitmap + share->column_bitmap_size*3);
|
||||||
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
|
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.
|
Make a copy of all fields.
|
||||||
The copied fields need to point into the copied record. This is done
|
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]
|
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
|
||||||
if (*org_field == found_next_number_field)
|
if (*org_field == found_next_number_field)
|
||||||
(*field)->table->found_next_number_field= *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;
|
*field=0;
|
||||||
|
if (share->default_fields)
|
||||||
/* Adjust timestamp */
|
*dfield_ptr= NULL;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust in_use for pointing to client thread */
|
/* Adjust in_use for pointing to client thread */
|
||||||
copy->in_use= client_thd;
|
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;
|
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
|
||||||
row->first_successful_insert_id_in_prev_stmt=
|
row->first_successful_insert_id_in_prev_stmt=
|
||||||
thd->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
|
/* Add session variable timezone
|
||||||
Time_zone object will not be freed even the thread is ended.
|
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;
|
row->first_successful_insert_id_in_prev_stmt;
|
||||||
thd.stmt_depends_on_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;
|
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;
|
table->auto_increment_field_not_null= row->auto_increment_field_not_null;
|
||||||
|
|
||||||
/* Copy the session variables. */
|
/* 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
|
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
|
||||||
store_values(values);
|
store_values(values);
|
||||||
|
if (table->default_field && table->update_default_fields())
|
||||||
|
DBUG_RETURN(1);
|
||||||
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
|
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
|
||||||
if (thd->is_error())
|
if (thd->is_error())
|
||||||
{
|
{
|
||||||
@ -3586,11 +3573,11 @@ int select_insert::send_data(List<Item> &values)
|
|||||||
void select_insert::store_values(List<Item> &values)
|
void select_insert::store_values(List<Item> &values)
|
||||||
{
|
{
|
||||||
if (fields->elements)
|
if (fields->elements)
|
||||||
fill_record_n_invoke_before_triggers(thd, *fields, values, 1,
|
fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1,
|
||||||
table->triggers, TRG_EVENT_INSERT);
|
TRG_EVENT_INSERT);
|
||||||
else
|
else
|
||||||
fill_record_n_invoke_before_triggers(thd, table->field, values, 1,
|
fill_record_n_invoke_before_triggers(thd, table, table->field, values, 1,
|
||||||
table->triggers, TRG_EVENT_INSERT);
|
TRG_EVENT_INSERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void select_insert::send_error(uint errcode,const char *err)
|
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");
|
DBUG_ENTER("create_table_from_items");
|
||||||
|
|
||||||
tmp_table.alias= 0;
|
tmp_table.alias= 0;
|
||||||
tmp_table.timestamp_field= 0;
|
|
||||||
tmp_table.s= &share;
|
tmp_table.s= &share;
|
||||||
init_tmp_table_share(thd, &share, "", 0, "", "");
|
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.null_row= 0;
|
||||||
tmp_table.maybe_null= 0;
|
tmp_table.maybe_null= 0;
|
||||||
|
|
||||||
|
promote_first_timestamp_column(&alter_info->create_list);
|
||||||
|
|
||||||
while ((item=it++))
|
while ((item=it++))
|
||||||
{
|
{
|
||||||
Create_field *cr_field;
|
Create_field *cr_field;
|
||||||
@ -4056,8 +4044,6 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
for (Field **f= field ; *f ; f++)
|
for (Field **f= field ; *f ; f++)
|
||||||
bitmap_set_bit(table->write_set, (*f)->field_index);
|
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;
|
table->next_number_field=table->found_next_number_field;
|
||||||
|
|
||||||
restore_record(table,s->default_values); // Get empty record
|
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)
|
void select_create::store_values(List<Item> &values)
|
||||||
{
|
{
|
||||||
fill_record_n_invoke_before_triggers(thd, field, values, 1,
|
fill_record_n_invoke_before_triggers(thd, table, field, values, 1,
|
||||||
table->triggers, TRG_EVENT_INSERT);
|
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++)
|
for (field=table->field; *field ; field++)
|
||||||
fields_vars.push_back(new Item_field(*field));
|
fields_vars.push_back(new Item_field(*field));
|
||||||
bitmap_set_all(table->write_set);
|
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
|
Let us also prepare SET clause, altough it is probably empty
|
||||||
in this case.
|
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) ||
|
setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
|
||||||
check_that_all_fields_are_given_values(thd, table, table_list))
|
check_that_all_fields_are_given_values(thd, table, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/* Add all fields with default functions to table->write_set. */
|
||||||
Check whenever TIMESTAMP field with auto-set feature specified
|
if (table->default_field)
|
||||||
explicitly.
|
table->mark_default_fields_for_write();
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Fix the expressions in SET clause */
|
/* Fix the expressions in SET clause */
|
||||||
if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
|
if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
|
||||||
DBUG_RETURN(TRUE);
|
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),
|
ER(ER_WARN_TOO_FEW_RECORDS),
|
||||||
thd->warning_info->current_row_for_warning());
|
thd->warning_info->current_row_for_warning());
|
||||||
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
||||||
((Field_timestamp*) field)->set_time();
|
field->set_time();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -864,6 +851,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
pos[length]=save_chr;
|
pos[length]=save_chr;
|
||||||
if ((pos+=length) > read_info.row_end)
|
if ((pos+=length) > read_info.row_end)
|
||||||
pos= read_info.row_end; /* Fills rest with space */
|
pos= read_info.row_end; /* Fills rest with space */
|
||||||
|
field->set_explicit_default(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != read_info.row_end)
|
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 ||
|
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,
|
ignore_check_option_errors,
|
||||||
table->triggers,
|
TRG_EVENT_INSERT) ||
|
||||||
TRG_EVENT_INSERT))
|
(table->default_field && table->update_default_fields()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
switch (table_list->view_check_option(thd,
|
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);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
field->set_null();
|
field->set_null();
|
||||||
|
field->set_explicit_default(NULL);
|
||||||
if (!field->maybe_null())
|
if (!field->maybe_null())
|
||||||
{
|
{
|
||||||
if (field->type() == MYSQL_TYPE_TIMESTAMP)
|
if (field->type() == MYSQL_TYPE_TIMESTAMP)
|
||||||
((Field_timestamp*) field)->set_time();
|
field->set_time();
|
||||||
else if (field != table->next_number_field)
|
else if (field != table->next_number_field)
|
||||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
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)
|
if (field == table->next_number_field)
|
||||||
table->auto_increment_field_not_null= TRUE;
|
table->auto_increment_field_not_null= TRUE;
|
||||||
field->store((char*) pos, length, read_info.read_charset);
|
field->store((char*) pos, length, read_info.read_charset);
|
||||||
|
field->set_explicit_default(NULL);
|
||||||
}
|
}
|
||||||
else if (item->type() == Item::STRING_ITEM)
|
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);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
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.
|
TODO: We probably should not throw warning for each field.
|
||||||
But how about intention to always have the same number
|
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 ||
|
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,
|
ignore_check_option_errors,
|
||||||
table->triggers,
|
TRG_EVENT_INSERT) ||
|
||||||
TRG_EVENT_INSERT))
|
(table->default_field && table->update_default_fields()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
switch (table_list->view_check_option(thd,
|
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->maybe_null())
|
||||||
{
|
{
|
||||||
if (field->type() == FIELD_TYPE_TIMESTAMP)
|
if (field->type() == FIELD_TYPE_TIMESTAMP)
|
||||||
((Field_timestamp *) field)->set_time();
|
field->set_time();
|
||||||
else if (field != table->next_number_field)
|
else if (field != table->next_number_field)
|
||||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
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)
|
if (field == table->next_number_field)
|
||||||
table->auto_increment_field_not_null= TRUE;
|
table->auto_increment_field_not_null= TRUE;
|
||||||
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
|
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
|
||||||
|
field->set_explicit_default(NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
((Item_user_var_as_out_param *) item)->set_value(
|
((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 ||
|
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,
|
ignore_check_option_errors,
|
||||||
table->triggers,
|
TRG_EVENT_INSERT) ||
|
||||||
TRG_EVENT_INSERT))
|
(table->default_field && table->update_default_fields()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
switch (table_list->view_check_option(thd,
|
switch (table_list->view_check_option(thd,
|
||||||
|
@ -268,12 +268,14 @@ void init_update_queries(void)
|
|||||||
CF_CAN_GENERATE_ROW_EVENTS;
|
CF_CAN_GENERATE_ROW_EVENTS;
|
||||||
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
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 |
|
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 |
|
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
|
||||||
CF_AUTO_COMMIT_TRANS;
|
CF_AUTO_COMMIT_TRANS;
|
||||||
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | 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 |
|
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_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_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||||
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= 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_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||||
|
|
||||||
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
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 |
|
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 |
|
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 |
|
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 |
|
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||||
CF_CAN_GENERATE_ROW_EVENTS;
|
CF_CAN_GENERATE_ROW_EVENTS;
|
||||||
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||||
CF_CAN_GENERATE_ROW_EVENTS;
|
CF_CAN_GENERATE_ROW_EVENTS;
|
||||||
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
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 |
|
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 |
|
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE |
|
||||||
CF_CAN_GENERATE_ROW_EVENTS;
|
CF_CAN_GENERATE_ROW_EVENTS;
|
||||||
sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
|
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()
|
no need fix_fields()
|
||||||
|
|
||||||
We allow only one function as part of default value -
|
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 &&
|
if (default_value->type() == Item::FUNC_ITEM &&
|
||||||
!(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
|
!(((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);
|
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
|
||||||
DBUG_RETURN(1);
|
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);
|
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@ -6526,9 +6526,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
lpt->pack_frm_data= NULL;
|
lpt->pack_frm_data= NULL;
|
||||||
lpt->pack_frm_len= 0;
|
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) &
|
if (table->file->alter_table_flags(alter_info->flags) &
|
||||||
HA_PARTITION_ONE_PHASE)
|
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())
|
if (item->is_null())
|
||||||
DBUG_RETURN(NESTED_LOOP_OK);
|
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())
|
if (thd->is_error())
|
||||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||||
if ((error= table->file->ha_write_tmp_row(table->record[0])))
|
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
|
#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 quoted)
|
||||||
{
|
{
|
||||||
bool has_default;
|
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
|
We are using CURRENT_TIMESTAMP instead of NOW because it is
|
||||||
more standard
|
more standard
|
||||||
*/
|
*/
|
||||||
has_now_default= (timestamp_field == field &&
|
has_now_default= field->has_insert_default_function();
|
||||||
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
|
|
||||||
|
|
||||||
has_default= (field_type != FIELD_TYPE_BLOB &&
|
has_default= (field_type != FIELD_TYPE_BLOB &&
|
||||||
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
!(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_default)
|
||||||
{
|
{
|
||||||
if (has_now_default)
|
if (has_now_default)
|
||||||
|
{
|
||||||
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
|
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
|
||||||
|
if (field->decimals() > 0)
|
||||||
|
def_value->append_parenthesized(field->decimals());
|
||||||
|
}
|
||||||
else if (!field->is_null())
|
else if (!field->is_null())
|
||||||
{ // Not null by default
|
{ // Not null by default
|
||||||
char tmp[MAX_FIELD_WIDTH];
|
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 &&
|
if (!field->vcol_info &&
|
||||||
get_field_default_value(thd, table->timestamp_field,
|
get_field_default_value(thd, field, &def_value, 1))
|
||||||
field, &def_value, 1))
|
|
||||||
{
|
{
|
||||||
packet->append(STRING_WITH_LEN(" DEFAULT "));
|
packet->append(STRING_WITH_LEN(" DEFAULT "));
|
||||||
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!limited_mysql_mode && table->timestamp_field == field &&
|
if (!limited_mysql_mode && print_on_update_clause(field, &def_value, false))
|
||||||
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
|
{
|
||||||
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
|
packet->append(STRING_WITH_LEN(" "));
|
||||||
|
packet->append(def_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (field->unireg_check == Field::NEXT_NUMBER &&
|
if (field->unireg_check == Field::NEXT_NUMBER &&
|
||||||
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
|
!(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;
|
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
|
||||||
CHARSET_INFO *cs= system_charset_info;
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
TABLE *show_table;
|
TABLE *show_table;
|
||||||
Field **ptr, *field, *timestamp_field;
|
Field **ptr, *field;
|
||||||
int count;
|
int count;
|
||||||
DBUG_ENTER("get_schema_column_record");
|
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;
|
show_table= tables->table;
|
||||||
count= 0;
|
count= 0;
|
||||||
ptr= show_table->field;
|
ptr= show_table->field;
|
||||||
timestamp_field= show_table->timestamp_field;
|
|
||||||
show_table->use_all_columns(); // Required for default
|
show_table->use_all_columns(); // Required for default
|
||||||
restore_record(show_table, s->default_values);
|
restore_record(show_table, s->default_values);
|
||||||
|
|
||||||
@ -4830,7 +4861,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||||||
cs);
|
cs);
|
||||||
table->field[4]->store((longlong) count, TRUE);
|
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]->store(type.ptr(), type.length(), cs);
|
||||||
table->field[5]->set_notnull();
|
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)
|
if (field->unireg_check == Field::NEXT_NUMBER)
|
||||||
table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
|
table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
|
||||||
if (timestamp_field == field &&
|
if (print_on_update_clause(field, &type, true))
|
||||||
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
|
table->field[17]->store(type.ptr(), type.length(), cs);
|
||||||
table->field[17]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
|
|
||||||
cs);
|
|
||||||
if (field->vcol_info)
|
if (field->vcol_info)
|
||||||
{
|
{
|
||||||
if (field->stored_in_db)
|
if (field->stored_in_db)
|
||||||
|
@ -502,6 +502,24 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
|
|||||||
return FALSE;
|
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,
|
bool String::append_with_prefill(const char *s,uint32 arg_length,
|
||||||
uint32 full_length, char fill_char)
|
uint32 full_length, char fill_char)
|
||||||
{
|
{
|
||||||
|
@ -343,6 +343,7 @@ public:
|
|||||||
bool append(IO_CACHE* file, uint32 arg_length);
|
bool append(IO_CACHE* file, uint32 arg_length);
|
||||||
bool append_with_prefill(const char *s, uint32 arg_length,
|
bool append_with_prefill(const char *s, uint32 arg_length,
|
||||||
uint32 full_length, char fill_char);
|
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 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
|
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);
|
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()
|
prepare_create_field()
|
||||||
sql_field field to prepare for packing
|
sql_field field to prepare for packing
|
||||||
blob_columns count for BLOBs
|
blob_columns count for BLOBs
|
||||||
timestamps count for timestamps
|
|
||||||
table_flags table flags
|
table_flags table flags
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@ -2621,7 +2620,6 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||||||
|
|
||||||
int prepare_create_field(Create_field *sql_field,
|
int prepare_create_field(Create_field *sql_field,
|
||||||
uint *blob_columns,
|
uint *blob_columns,
|
||||||
int *timestamps, int *timestamps_with_niladic,
|
|
||||||
longlong table_flags)
|
longlong table_flags)
|
||||||
{
|
{
|
||||||
unsigned int dup_val_count;
|
unsigned int dup_val_count;
|
||||||
@ -2743,21 +2741,6 @@ int prepare_create_field(Create_field *sql_field,
|
|||||||
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
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 */
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
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
|
Preparation for table creation
|
||||||
|
|
||||||
@ -2869,7 +2886,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
ulong record_offset= 0;
|
ulong record_offset= 0;
|
||||||
KEY *key_info;
|
KEY *key_info;
|
||||||
KEY_PART_INFO *key_part_info;
|
KEY_PART_INFO *key_part_info;
|
||||||
int timestamps= 0, timestamps_with_niladic= 0;
|
|
||||||
int field_no,dup_no;
|
int field_no,dup_no;
|
||||||
int select_field_pos,auto_increment=0;
|
int select_field_pos,auto_increment=0;
|
||||||
List_iterator<Create_field> it(alter_info->create_list);
|
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);
|
DBUG_ASSERT(sql_field->charset != 0);
|
||||||
|
|
||||||
if (prepare_create_field(sql_field, &blob_columns,
|
if (prepare_create_field(sql_field, &blob_columns,
|
||||||
×tamps, ×tamps_with_niladic,
|
|
||||||
file->ha_table_flags()))
|
file->ha_table_flags()))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
|
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;
|
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)
|
if (auto_increment > 1)
|
||||||
{
|
{
|
||||||
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
|
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. */
|
/* Got lock. */
|
||||||
DEBUG_SYNC(thd, "locked_table_name");
|
DEBUG_SYNC(thd, "locked_table_name");
|
||||||
|
|
||||||
|
promote_first_timestamp_column(&alter_info->create_list);
|
||||||
|
|
||||||
result= mysql_create_table_no_lock(thd, create_table->db,
|
result= mysql_create_table_no_lock(thd, create_table->db,
|
||||||
create_table->table_name, create_info,
|
create_table->table_name, create_info,
|
||||||
alter_info, FALSE, 0, &is_trans);
|
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;
|
need_copy_table= alter_info->change_level;
|
||||||
|
|
||||||
set_table_default_charset(thd, create_info, db);
|
set_table_default_charset(thd, create_info, db);
|
||||||
|
promote_first_timestamp_column(&alter_info->create_list);
|
||||||
|
|
||||||
if (thd->variables.old_alter_table
|
if (thd->variables.old_alter_table
|
||||||
|| (table->s->db_type() != create_info->db_type)
|
|| (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");
|
DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
|
||||||
DBUG_EXECUTE_IF("sleep_before_create_table_no_lock",
|
DBUG_EXECUTE_IF("sleep_before_create_table_no_lock",
|
||||||
my_sleep(100000););
|
my_sleep(100000););
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a table with a temporary name.
|
Create a table with a temporary name.
|
||||||
With create_info->frm_only == 1 this creates a .frm file only.
|
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))
|
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;
|
new_table->next_number_field=new_table->found_next_number_field;
|
||||||
DBUG_EXECUTE_IF("abort_copy_table", {
|
DBUG_EXECUTE_IF("abort_copy_table", {
|
||||||
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
|
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;
|
ulonglong prev_insert_id, time_to_report_progress;
|
||||||
List_iterator<Create_field> it(create);
|
List_iterator<Create_field> it(create);
|
||||||
Create_field *def;
|
Create_field *def;
|
||||||
|
Field **dfield_ptr= to->default_field;
|
||||||
DBUG_ENTER("copy_data_between_tables");
|
DBUG_ENTER("copy_data_between_tables");
|
||||||
|
|
||||||
/* Two or 3 stages; Sorting, copying data and update indexes */
|
/* 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;
|
errpos= 3;
|
||||||
|
|
||||||
copy_end=copy;
|
copy_end=copy;
|
||||||
|
to->s->default_fields= 0;
|
||||||
for (Field **ptr=to->field ; *ptr ; ptr++)
|
for (Field **ptr=to->field ; *ptr ; ptr++)
|
||||||
{
|
{
|
||||||
def=it++;
|
def=it++;
|
||||||
@ -7364,8 +7377,23 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||||||
}
|
}
|
||||||
(copy_end++)->set(*ptr,def->field,0);
|
(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)
|
if (order)
|
||||||
{
|
{
|
||||||
@ -7456,6 +7484,11 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
|
|||||||
prev_insert_id= to->file->next_insert_id;
|
prev_insert_id= to->file->next_insert_id;
|
||||||
if (to->vfield)
|
if (to->vfield)
|
||||||
update_virtual_fields(thd, to, TRUE);
|
update_virtual_fields(thd, to, TRUE);
|
||||||
|
if (to->default_field && to->update_default_fields())
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (thd->is_error())
|
if (thd->is_error())
|
||||||
{
|
{
|
||||||
error= 1;
|
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);
|
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
|
||||||
int prepare_create_field(Create_field *sql_field,
|
int prepare_create_field(Create_field *sql_field,
|
||||||
uint *blob_columns,
|
uint *blob_columns,
|
||||||
int *timestamps, int *timestamps_with_niladic,
|
|
||||||
longlong table_flags);
|
longlong table_flags);
|
||||||
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
|
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
|
||||||
HA_CREATE_INFO *create_info);
|
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 execute_ddl_log_entry(THD *thd, uint first_entry);
|
||||||
bool check_duplicate_warning(THD *thd, char *msg, ulong length);
|
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.
|
These prototypes where under INNODB_COMPATIBILITY_HOOKS.
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ int select_union::send_data(List<Item> &values)
|
|||||||
return 0;
|
return 0;
|
||||||
if (table->no_rows_with_nulls)
|
if (table->no_rows_with_nulls)
|
||||||
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
|
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())
|
if (thd->is_error())
|
||||||
return 1;
|
return 1;
|
||||||
if (table->no_rows_with_nulls)
|
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");
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (table->timestamp_field)
|
if (table->default_field)
|
||||||
{
|
table->mark_default_fields_for_write();
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/* Check values */
|
/* Check values */
|
||||||
@ -389,7 +378,7 @@ int mysql_update(THD *thd,
|
|||||||
to compare records and detect data change.
|
to compare records and detect data change.
|
||||||
*/
|
*/
|
||||||
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
|
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);
|
bitmap_union(table->read_set, table->write_set);
|
||||||
// Don't count on usage of 'only index' when calculating which key to use
|
// Don't count on usage of 'only index' when calculating which key to use
|
||||||
table->covering_keys.clear_all();
|
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 */
|
continue; /* repeat the read of the same row if it still exists */
|
||||||
|
|
||||||
store_record(table,record[1]);
|
store_record(table,record[1]);
|
||||||
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
|
if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
|
||||||
table->triggers,
|
|
||||||
TRG_EVENT_UPDATE))
|
TRG_EVENT_UPDATE))
|
||||||
break; /* purecov: inspected */
|
break; /* purecov: inspected */
|
||||||
|
|
||||||
@ -695,6 +683,11 @@ int mysql_update(THD *thd,
|
|||||||
|
|
||||||
if (!can_compare_record || compare_record(table))
|
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)) !=
|
if ((res= table_list->view_check_option(thd, ignore)) !=
|
||||||
VIEW_CHECK_OK)
|
VIEW_CHECK_OK)
|
||||||
{
|
{
|
||||||
@ -1241,11 +1234,6 @@ int mysql_multi_update_prepare(THD *thd)
|
|||||||
while ((tl= ti++))
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
TABLE *table= tl->table;
|
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 will be updated then check that it is unique */
|
||||||
if (table->map & tables_for_update)
|
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.
|
to compare records and detect data change.
|
||||||
*/
|
*/
|
||||||
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
|
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
|
||||||
(((uint) table->timestamp_field_type) &
|
table->default_field && table->has_default_function(true))
|
||||||
TIMESTAMP_AUTO_SET_ON_UPDATE))
|
|
||||||
bitmap_union(table->read_set, table->write_set);
|
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;
|
table->status|= STATUS_UPDATED;
|
||||||
store_record(table,record[1]);
|
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,
|
*values_for_table[offset], 0,
|
||||||
table->triggers,
|
TRG_EVENT_UPDATE) ||
|
||||||
TRG_EVENT_UPDATE))
|
(table->default_field && table->update_default_fields()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1979,7 +1966,7 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
} while ((tbl= tbl_it++));
|
} while ((tbl= tbl_it++));
|
||||||
|
|
||||||
/* Store regular updated fields in the row. */
|
/* Store regular updated fields in the row. */
|
||||||
fill_record(thd,
|
fill_record(thd, tmp_table,
|
||||||
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
||||||
*values_for_table[offset], TRUE, FALSE);
|
*values_for_table[offset], TRUE, FALSE);
|
||||||
|
|
||||||
@ -2169,7 +2156,10 @@ int multi_update::do_updates()
|
|||||||
for (copy_field_ptr=copy_field;
|
for (copy_field_ptr=copy_field;
|
||||||
copy_field_ptr != copy_field_end;
|
copy_field_ptr != copy_field_end;
|
||||||
copy_field_ptr++)
|
copy_field_ptr++)
|
||||||
|
{
|
||||||
(*copy_field_ptr->do_copy)(copy_field_ptr);
|
(*copy_field_ptr->do_copy)(copy_field_ptr);
|
||||||
|
copy_field_ptr->to_field->set_explicit_default(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||||
@ -2179,6 +2169,8 @@ int multi_update::do_updates()
|
|||||||
if (!can_compare_record || compare_record(table))
|
if (!can_compare_record || compare_record(table))
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
if (table->default_field && (error= table->update_default_fields()))
|
||||||
|
goto err2;
|
||||||
if ((error= cur_table->view_check_option(thd, ignore)) !=
|
if ((error= cur_table->view_check_option(thd, ignore)) !=
|
||||||
VIEW_CHECK_OK)
|
VIEW_CHECK_OK)
|
||||||
{
|
{
|
||||||
|
@ -5873,9 +5873,9 @@ attribute:
|
|||||||
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
|
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
|
||||||
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
|
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
|
||||||
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
|
| 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)
|
if (item == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->on_update_value= item;
|
Lex->on_update_value= item;
|
||||||
@ -5967,9 +5967,9 @@ type_with_opt_collate:
|
|||||||
|
|
||||||
|
|
||||||
now_or_signed_literal:
|
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)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
127
sql/table.cc
127
sql/table.cc
@ -1250,6 +1250,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
com_length= uint2korr(forminfo+284);
|
com_length= uint2korr(forminfo+284);
|
||||||
vcol_screen_length= uint2korr(forminfo+286);
|
vcol_screen_length= uint2korr(forminfo+286);
|
||||||
share->vfields= 0;
|
share->vfields= 0;
|
||||||
|
share->default_fields= 0;
|
||||||
share->stored_fields= share->fields;
|
share->stored_fields= share->fields;
|
||||||
if (forminfo[46] != (uchar)255)
|
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)
|
if (reg_field->unireg_check == Field::NEXT_NUMBER)
|
||||||
share->found_next_number_field= field_ptr;
|
share->found_next_number_field= field_ptr;
|
||||||
if (share->timestamp_field == reg_field)
|
|
||||||
share->timestamp_field_offset= i;
|
|
||||||
|
|
||||||
if (use_hash)
|
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)
|
if (share->stored_rec_length>=recpos)
|
||||||
share->stored_rec_length= recpos-1;
|
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
|
*field_ptr=0; // End marker
|
||||||
/* Sanity checks: */
|
/* Sanity checks: */
|
||||||
@ -2315,7 +2317,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
uint records, i, bitmap_size;
|
uint records, i, bitmap_size;
|
||||||
bool error_reported= FALSE;
|
bool error_reported= FALSE;
|
||||||
uchar *record, *bitmaps;
|
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;
|
uint8 save_context_analysis_only= thd->lex->context_analysis_only;
|
||||||
DBUG_ENTER("open_table_from_share");
|
DBUG_ENTER("open_table_from_share");
|
||||||
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
|
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)
|
if (share->found_next_number_field)
|
||||||
outparam->found_next_number_field=
|
outparam->found_next_number_field=
|
||||||
outparam->field[(uint) (share->found_next_number_field - share->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 */
|
/* Fix key->name and key_part->field */
|
||||||
if (share->key_parts)
|
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)
|
if (!share->vfields)
|
||||||
outparam->vfield= NULL;
|
outparam->vfield= NULL;
|
||||||
@ -2484,10 +2483,26 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
outparam->vfield= vfield_ptr;
|
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++)
|
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,
|
if (unpack_vcol_info_from_frm(thd,
|
||||||
outparam,
|
outparam,
|
||||||
@ -2500,8 +2515,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
}
|
}
|
||||||
*(vfield_ptr++)= *field_ptr;
|
*(vfield_ptr++)= *field_ptr;
|
||||||
}
|
}
|
||||||
|
if (share->default_fields &&
|
||||||
|
((*field_ptr)->has_insert_default_function() ||
|
||||||
|
(*field_ptr)->has_update_default_function()))
|
||||||
|
*(dfield_ptr++)= *field_ptr;
|
||||||
}
|
}
|
||||||
|
if (share->vfields)
|
||||||
*vfield_ptr= 0; // End marker
|
*vfield_ptr= 0; // End marker
|
||||||
|
if (share->default_fields)
|
||||||
|
*dfield_ptr= 0; // End marker
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
@ -3924,9 +3946,6 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
|
|||||||
DBUG_ASSERT(!auto_increment_field_not_null);
|
DBUG_ASSERT(!auto_increment_field_not_null);
|
||||||
auto_increment_field_not_null= FALSE;
|
auto_increment_field_not_null= FALSE;
|
||||||
|
|
||||||
if (timestamp_field)
|
|
||||||
timestamp_field_type= timestamp_field->get_auto_set_type();
|
|
||||||
|
|
||||||
pos_in_table_list= tl;
|
pos_in_table_list= tl;
|
||||||
|
|
||||||
clear_column_bitmaps();
|
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
|
@brief
|
||||||
Allocate space for keys
|
Allocate space for keys
|
||||||
@ -6448,6 +6509,50 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
|
|||||||
DBUG_RETURN(0);
|
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
|
@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 Field_blob;
|
||||||
class Table_triggers_list;
|
class Table_triggers_list;
|
||||||
|
|
||||||
@ -608,7 +589,6 @@ struct TABLE_SHARE
|
|||||||
/* The following is copied to each TABLE on OPEN */
|
/* The following is copied to each TABLE on OPEN */
|
||||||
Field **field;
|
Field **field;
|
||||||
Field **found_next_number_field;
|
Field **found_next_number_field;
|
||||||
Field *timestamp_field; /* Used only during open */
|
|
||||||
KEY *key_info; /* data of keys in database */
|
KEY *key_info; /* data of keys in database */
|
||||||
uint *blob_field; /* Index to blobs in Field arrray*/
|
uint *blob_field; /* Index to blobs in Field arrray*/
|
||||||
|
|
||||||
@ -680,7 +660,6 @@ struct TABLE_SHARE
|
|||||||
uint uniques; /* Number of UNIQUE index */
|
uint uniques; /* Number of UNIQUE index */
|
||||||
uint null_fields; /* number of null fields */
|
uint null_fields; /* number of null fields */
|
||||||
uint blob_fields; /* number of blob 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 varchar_fields; /* number of varchar fields */
|
||||||
uint db_create_options; /* Create options from database */
|
uint db_create_options; /* Create options from database */
|
||||||
uint db_options_in_use; /* Options in use */
|
uint db_options_in_use; /* Options in use */
|
||||||
@ -695,6 +674,7 @@ struct TABLE_SHARE
|
|||||||
uint column_bitmap_size;
|
uint column_bitmap_size;
|
||||||
uchar frm_version;
|
uchar frm_version;
|
||||||
uint vfields; /* Number of computed (virtual) fields */
|
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 use_ext_keys; /* Extended keys can be used */
|
||||||
bool null_field_first;
|
bool null_field_first;
|
||||||
bool system; /* Set if system table (one record) */
|
bool system; /* Set if system table (one record) */
|
||||||
@ -1007,8 +987,9 @@ public:
|
|||||||
|
|
||||||
Field *next_number_field; /* Set if next_number is activated */
|
Field *next_number_field; /* Set if next_number is activated */
|
||||||
Field *found_next_number_field; /* Set on open */
|
Field *found_next_number_field; /* Set on open */
|
||||||
Field_timestamp *timestamp_field;
|
|
||||||
Field **vfield; /* Pointer to virtual fields*/
|
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's triggers, 0 if there are no of them */
|
||||||
Table_triggers_list *triggers;
|
Table_triggers_list *triggers;
|
||||||
@ -1064,19 +1045,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
ha_rows quick_condition_rows;
|
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...) */
|
table_map map; /* ID bit of table (1,2,4,8,16...) */
|
||||||
|
|
||||||
uint lock_position; /* Position in MYSQL_LOCK.table */
|
uint lock_position; /* Position in MYSQL_LOCK.table */
|
||||||
@ -1207,6 +1175,8 @@ public:
|
|||||||
void mark_columns_needed_for_insert(void);
|
void mark_columns_needed_for_insert(void);
|
||||||
bool mark_virtual_col(Field *field);
|
bool mark_virtual_col(Field *field);
|
||||||
void mark_virtual_columns_for_write(bool insert_fl);
|
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,
|
inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
|
||||||
MY_BITMAP *write_set_arg)
|
MY_BITMAP *write_set_arg)
|
||||||
{
|
{
|
||||||
@ -1293,6 +1263,7 @@ public:
|
|||||||
bool update_const_key_parts(COND *conds);
|
bool update_const_key_parts(COND *conds);
|
||||||
uint actual_n_key_parts(KEY *keyinfo);
|
uint actual_n_key_parts(KEY *keyinfo);
|
||||||
ulong actual_key_flags(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);
|
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
|
||||||
|
|
||||||
ha_statistic_increment(&SSV::ha_write_count);
|
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);
|
mysql_mutex_lock(&share->mutex);
|
||||||
|
|
||||||
if (!share->archive_write_open)
|
if (!share->archive_write_open)
|
||||||
|
@ -999,9 +999,6 @@ int ha_tina::write_row(uchar * buf)
|
|||||||
|
|
||||||
ha_statistic_increment(&SSV::ha_write_count);
|
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);
|
size= encode_quote(buf);
|
||||||
|
|
||||||
if (!share->tina_write_opened)
|
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);
|
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);
|
size= encode_quote(new_data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1849,8 +1849,6 @@ int ha_federated::write_row(uchar *buf)
|
|||||||
values_string.length(0);
|
values_string.length(0);
|
||||||
insert_field_value_string.length(0);
|
insert_field_value_string.length(0);
|
||||||
ha_statistic_increment(&SSV::ha_write_count);
|
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
|
start both our field and field values strings
|
||||||
|
@ -1993,8 +1993,6 @@ int ha_federatedx::write_row(uchar *buf)
|
|||||||
|
|
||||||
values_string.length(0);
|
values_string.length(0);
|
||||||
insert_field_value_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
|
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 ha_heap::write_row(uchar * buf)
|
||||||
{
|
{
|
||||||
int res;
|
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 (table->next_number_field && buf == table->record[0])
|
||||||
{
|
{
|
||||||
if ((res= update_auto_increment()))
|
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 ha_heap::update_row(const uchar * old_data, uchar * new_data)
|
||||||
{
|
{
|
||||||
int res;
|
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);
|
res= heap_update(file,old_data,new_data);
|
||||||
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||||
file->s->records)
|
file->s->records)
|
||||||
|
@ -5163,9 +5163,6 @@ ha_innobase::write_row(
|
|||||||
|
|
||||||
ha_statistic_increment(&SSV::ha_write_count);
|
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);
|
sql_command = thd_sql_command(user_thd);
|
||||||
|
|
||||||
if ((sql_command == SQLCOM_ALTER_TABLE
|
if ((sql_command == SQLCOM_ALTER_TABLE
|
||||||
@ -5573,9 +5570,6 @@ ha_innobase::update_row(
|
|||||||
|
|
||||||
ha_statistic_increment(&SSV::ha_update_count);
|
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) {
|
if (prebuilt->upd_node) {
|
||||||
uvect = prebuilt->upd_node->update;
|
uvect = prebuilt->upd_node->update;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1248,10 +1248,6 @@ int ha_maria::close(void)
|
|||||||
|
|
||||||
int ha_maria::write_row(uchar * buf)
|
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
|
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.
|
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)
|
int ha_maria::update_row(const uchar * old_data, uchar * new_data)
|
||||||
{
|
{
|
||||||
CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("UPDATE in WRITE CONCURRENT");
|
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);
|
return maria_update(file, old_data, new_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,10 +832,6 @@ int ha_myisam::close(void)
|
|||||||
|
|
||||||
int ha_myisam::write_row(uchar *buf)
|
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
|
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.
|
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)
|
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);
|
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)
|
if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
|
||||||
DBUG_RETURN(HA_ERR_TABLE_READONLY);
|
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])
|
if (table->next_number_field && buf == table->record[0])
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -1093,8 +1091,6 @@ int ha_myisammrg::update_row(const uchar * old_data, uchar * new_data)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(this->file->children_attached);
|
DBUG_ASSERT(this->file->children_attached);
|
||||||
ha_statistic_increment(&SSV::ha_update_count);
|
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);
|
return myrg_update(file,old_data,new_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5933,9 +5933,6 @@ ha_innobase::write_row(
|
|||||||
DBUG_RETURN(HA_ERR_CRASHED);
|
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);
|
sql_command = thd_sql_command(user_thd);
|
||||||
|
|
||||||
if ((sql_command == SQLCOM_ALTER_TABLE
|
if ((sql_command == SQLCOM_ALTER_TABLE
|
||||||
@ -6359,9 +6356,6 @@ ha_innobase::update_row(
|
|||||||
DBUG_RETURN(HA_ERR_CRASHED);
|
DBUG_RETURN(HA_ERR_CRASHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
|
||||||
table->timestamp_field->set_time();
|
|
||||||
|
|
||||||
if (prebuilt->upd_node) {
|
if (prebuilt->upd_node) {
|
||||||
uvect = prebuilt->upd_node->update;
|
uvect = prebuilt->upd_node->update;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user