MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
- Adding optional qualifiers to data types: CREATE TABLE t1 (a schema.DATE); Qualifiers now work only for three pre-defined schemas: mariadb_schema oracle_schema maxdb_schema These schemas are virtual (hard-coded) for now, but may turn into real databases on disk in the future. - mariadb_schema.TYPE now always resolves to a true MariaDB data type TYPE without sql_mode specific translations. - oracle_schema.DATE translates to MariaDB DATETIME. - maxdb_schema.TIMESTAMP translates to MariaDB DATETIME. - Fixing SHOW CREATE TABLE to use a qualifier for a data type TYPE if the current sql_mode translates TYPE to something else. The above changes fix the reported problem, so this script: SET sql_mode=ORACLE; CREATE TABLE t2 AS SELECT mariadb_date_column FROM t1; is now replicated as: SET sql_mode=ORACLE; CREATE TABLE t2 (mariadb_date_column mariadb_schema.DATE); and the slave can unambiguously treat DATE as the true MariaDB DATE without ORACLE specific translation to DATETIME. Similar, SET sql_mode=MAXDB; CREATE TABLE t2 AS SELECT mariadb_timestamp_column FROM t1; is now replicated as: SET sql_mode=MAXDB; CREATE TABLE t2 (mariadb_timestamp_column mariadb_schema.TIMESTAMP); so the slave treats TIMESTAMP as the true MariaDB TIMESTAMP without MAXDB specific translation to DATETIME.
This commit is contained in:
parent
a8458a2345
commit
d63631c3fa
@ -108,6 +108,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
||||
../sql/sql_explain.cc ../sql/sql_explain.h
|
||||
../sql/sql_analyze_stmt.cc ../sql/sql_analyze_stmt.h
|
||||
../sql/compat56.cc
|
||||
../sql/sql_schema.cc
|
||||
../sql/sql_type.cc ../sql/sql_type.h
|
||||
../sql/sql_mode.cc
|
||||
../sql/table_cache.cc ../sql/mf_iocache_encr.cc
|
||||
|
@ -158,3 +158,13 @@ show triggers like '%T1%';
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
|
||||
drop table t1;
|
||||
set GLOBAL sql_mode=default;
|
||||
#
|
||||
# MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
#
|
||||
# Compatibility schema names respect the filesystem case sensitivity
|
||||
CREATE TABLE t1 (a MARIADB_SCHEMA.date);
|
||||
ERROR HY000: Unknown data type: 'MARIADB_SCHEMA.date'
|
||||
CREATE TABLE t1 (a Mariadb_schema.date);
|
||||
ERROR HY000: Unknown data type: 'Mariadb_schema.date'
|
||||
CREATE TABLE t1 (a mariadb_schema.date);
|
||||
DROP TABLE t1;
|
||||
|
@ -129,3 +129,18 @@ let $datadir= `select @@datadir`;
|
||||
remove_file $datadir/mysql_upgrade_info;
|
||||
|
||||
set GLOBAL sql_mode=default;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
--echo #
|
||||
|
||||
--echo # Compatibility schema names respect the filesystem case sensitivity
|
||||
|
||||
--error ER_UNKNOWN_ERROR
|
||||
CREATE TABLE t1 (a MARIADB_SCHEMA.date);
|
||||
--error ER_UNKNOWN_ERROR
|
||||
CREATE TABLE t1 (a Mariadb_schema.date);
|
||||
|
||||
CREATE TABLE t1 (a mariadb_schema.date);
|
||||
DROP TABLE t1;
|
||||
|
@ -179,6 +179,7 @@ my @DEFAULT_SUITES= qw(
|
||||
binlog_encryption-
|
||||
csv-
|
||||
compat/oracle-
|
||||
compat/maxdb-
|
||||
encryption-
|
||||
federated-
|
||||
funcs_1-
|
||||
|
65
mysql-test/suite/compat/maxdb/rpl_mariadb_timestamp.result
Normal file
65
mysql-test/suite/compat/maxdb/rpl_mariadb_timestamp.result
Normal file
@ -0,0 +1,65 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
#
|
||||
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:00:00');
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (a TIMESTAMP);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
|
||||
SET sql_mode=MAXDB;
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
SET timestamp=DEFAULT;
|
||||
include/show_binlog_events.inc
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Gtid # # GTID #-#-#
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a TIMESTAMP)
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (NULL)
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES ('2001-01-01 10:20:30')
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE "t2" (
|
||||
"a" mariadb_schema.timestamp NOT NULL DEFAULT current_timestamp()
|
||||
)
|
||||
master-bin.000001 # Annotate_rows # # CREATE TABLE t2 SELECT * FROM t1
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
connection slave;
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01 10:00:00
|
||||
2001-01-01 10:20:30
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` timestamp NOT NULL DEFAULT current_timestamp()
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET sql_mode=MAXDB;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" mariadb_schema.timestamp NOT NULL DEFAULT current_timestamp()
|
||||
)
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE "t2" (
|
||||
"a" mariadb_schema.timestamp NOT NULL DEFAULT current_timestamp()
|
||||
)
|
||||
connection master;
|
||||
DROP TABLE t1, t2;
|
||||
include/rpl_end.inc
|
34
mysql-test/suite/compat/maxdb/rpl_mariadb_timestamp.test
Normal file
34
mysql-test/suite/compat/maxdb/rpl_mariadb_timestamp.test
Normal file
@ -0,0 +1,34 @@
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
--echo #
|
||||
|
||||
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:00:00');
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (a TIMESTAMP);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
|
||||
SET sql_mode=MAXDB;
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
SET timestamp=DEFAULT;
|
||||
|
||||
--let $binlog_file = LAST
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
|
||||
--sync_slave_with_master
|
||||
SELECT * FROM t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
SET sql_mode=MAXDB;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
--connection master
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--source include/rpl_end.inc
|
53
mysql-test/suite/compat/maxdb/type_timestamp.result
Normal file
53
mysql-test/suite/compat/maxdb/type_timestamp.result
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
#
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (
|
||||
def_timestamp TIMESTAMP,
|
||||
mdb_timestamp mariadb_schema.TIMESTAMP,
|
||||
ora_timestamp oracle_schema.TIMESTAMP,
|
||||
max_timestamp maxdb_schema.TIMESTAMP
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`def_timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`mdb_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`ora_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`max_timestamp` datetime DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET sql_mode=MAXDB;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"def_timestamp" mariadb_schema.timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
"mdb_timestamp" mariadb_schema.timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
"ora_timestamp" mariadb_schema.timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
"max_timestamp" datetime DEFAULT NULL
|
||||
)
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=MAXDB;
|
||||
CREATE TABLE t1 (
|
||||
def_timestamp TIMESTAMP,
|
||||
mdb_timestamp mariadb_schema.TIMESTAMP,
|
||||
ora_timestamp oracle_schema.TIMESTAMP,
|
||||
max_timestamp maxdb_schema.TIMESTAMP
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"def_timestamp" datetime DEFAULT NULL,
|
||||
"mdb_timestamp" mariadb_schema.timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
"ora_timestamp" mariadb_schema.timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
"max_timestamp" datetime DEFAULT NULL
|
||||
)
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`def_timestamp` datetime DEFAULT NULL,
|
||||
`mdb_timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`ora_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`max_timestamp` datetime DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
29
mysql-test/suite/compat/maxdb/type_timestamp.test
Normal file
29
mysql-test/suite/compat/maxdb/type_timestamp.test
Normal file
@ -0,0 +1,29 @@
|
||||
--echo #
|
||||
--echo # MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
--echo #
|
||||
|
||||
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (
|
||||
def_timestamp TIMESTAMP,
|
||||
mdb_timestamp mariadb_schema.TIMESTAMP,
|
||||
ora_timestamp oracle_schema.TIMESTAMP,
|
||||
max_timestamp maxdb_schema.TIMESTAMP
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
SET sql_mode=MAXDB;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
SET sql_mode=MAXDB;
|
||||
CREATE TABLE t1 (
|
||||
def_timestamp TIMESTAMP,
|
||||
mdb_timestamp mariadb_schema.TIMESTAMP,
|
||||
ora_timestamp oracle_schema.TIMESTAMP,
|
||||
max_timestamp maxdb_schema.TIMESTAMP
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
86
mysql-test/suite/compat/oracle/r/rpl_mariadb_date.result
Normal file
86
mysql-test/suite/compat/oracle/r/rpl_mariadb_date.result
Normal file
@ -0,0 +1,86 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
SET SQL_MODE=DEFAULT;
|
||||
CREATE TABLE t1 (a DATE);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES ('2001-01-01');
|
||||
SET SQL_MODE= ORACLE;
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
include/show_binlog_events.inc
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Gtid # # GTID #-#-#
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a DATE)
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (NULL)
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES ('2001-01-01')
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE "t2" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
master-bin.000001 # Annotate_rows # # CREATE TABLE t2 SELECT * FROM t1
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
SET SQL_MODE= DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET SQL_MODE= ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE "t2" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
connection slave;
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
NULL
|
||||
2001-01-01
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
NULL
|
||||
2001-01-01
|
||||
SET SQL_MODE= DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET SQL_MODE= ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE "t2" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
connection master;
|
||||
DROP TABLE t1, t2;
|
||||
include/rpl_end.inc
|
@ -6,3 +6,153 @@ t1 CREATE TABLE "t1" (
|
||||
"a" datetime DEFAULT NULL
|
||||
)
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
#
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (a unknown.DATE);
|
||||
ERROR HY000: Unknown data type: 'unknown.date'
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (
|
||||
def_date DATE,
|
||||
mdb_date mariadb_schema.DATE,
|
||||
ora_date oracle_schema.DATE,
|
||||
max_date maxdb_schema.DATE
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`def_date` date DEFAULT NULL,
|
||||
`mdb_date` date DEFAULT NULL,
|
||||
`ora_date` datetime DEFAULT NULL,
|
||||
`max_date` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET sql_mode=ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"def_date" mariadb_schema.date DEFAULT NULL,
|
||||
"mdb_date" mariadb_schema.date DEFAULT NULL,
|
||||
"ora_date" datetime DEFAULT NULL,
|
||||
"max_date" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=ORACLE;
|
||||
CREATE TABLE t1 (
|
||||
def_date DATE,
|
||||
mdb_date mariadb_schema.DATE,
|
||||
ora_date oracle_schema.DATE,
|
||||
max_date maxdb_schema.DATE
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"def_date" datetime DEFAULT NULL,
|
||||
"mdb_date" mariadb_schema.date DEFAULT NULL,
|
||||
"ora_date" datetime DEFAULT NULL,
|
||||
"max_date" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`def_date` datetime DEFAULT NULL,
|
||||
`mdb_date` date DEFAULT NULL,
|
||||
`ora_date` datetime DEFAULT NULL,
|
||||
`max_date` date DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# ALTER..MODIFY and ALTER..CHANGE understand qualifiers
|
||||
#
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (a DATE);
|
||||
INSERT INTO t1 VALUES ('2001-01-01');
|
||||
SET sql_mode=ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01
|
||||
ALTER TABLE t1 MODIFY a DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" datetime DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01 00:00:00
|
||||
ALTER TABLE t1 MODIFY a mariadb_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01
|
||||
ALTER TABLE t1 MODIFY a oracle_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" datetime DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01 00:00:00
|
||||
ALTER TABLE t1 CHANGE a b mariadb_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"b" mariadb_schema.date DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
b
|
||||
2001-01-01
|
||||
ALTER TABLE t1 CHANGE b a oracle_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE "t1" (
|
||||
"a" datetime DEFAULT NULL
|
||||
)
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
2001-01-01 00:00:00
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Qualified syntax is not supported yet in SP
|
||||
# See MDEV-23353 Qualified data types in SP
|
||||
#
|
||||
SET sql_mode=ORACLE;
|
||||
CREATE FUNCTION f1() RETURN mariadb_schema.DATE AS
|
||||
BEGIN
|
||||
RETURN CURRENT_DATE;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'mariadb_schema.DATE AS
|
||||
BEGIN
|
||||
RETURN CURRENT_DATE;
|
||||
END' at line 1
|
||||
CREATE PROCEDURE p1(a mariadb_schema.DATE) AS
|
||||
BEGIN
|
||||
NULL;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') AS
|
||||
BEGIN
|
||||
NULL;
|
||||
END' at line 1
|
||||
CREATE PROCEDURE p1() AS
|
||||
a mariadb_schema.DATE;
|
||||
BEGIN
|
||||
NULL;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
|
||||
BEGIN
|
||||
NULL;
|
||||
END' at line 2
|
||||
|
38
mysql-test/suite/compat/oracle/t/rpl_mariadb_date.test
Normal file
38
mysql-test/suite/compat/oracle/t/rpl_mariadb_date.test
Normal file
@ -0,0 +1,38 @@
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
SET SQL_MODE=DEFAULT;
|
||||
CREATE TABLE t1 (a DATE);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES ('2001-01-01');
|
||||
|
||||
SET SQL_MODE= ORACLE;
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
|
||||
--let $binlog_file = LAST
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
SET SQL_MODE= DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
SET SQL_MODE= ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
--sync_slave_with_master
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
SET SQL_MODE= DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
SET SQL_MODE= ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
# Cleanup
|
||||
--connection master
|
||||
DROP TABLE t1, t2;
|
||||
--source include/rpl_end.inc
|
@ -2,3 +2,102 @@ SET sql_mode=ORACLE;
|
||||
CREATE TABLE t1 (a DATE);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
|
||||
--echo #
|
||||
|
||||
SET sql_mode=DEFAULT;
|
||||
--error ER_UNKNOWN_ERROR
|
||||
CREATE TABLE t1 (a unknown.DATE);
|
||||
|
||||
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (
|
||||
def_date DATE,
|
||||
mdb_date mariadb_schema.DATE,
|
||||
ora_date oracle_schema.DATE,
|
||||
max_date maxdb_schema.DATE
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
SET sql_mode=ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
SET sql_mode=ORACLE;
|
||||
CREATE TABLE t1 (
|
||||
def_date DATE,
|
||||
mdb_date mariadb_schema.DATE,
|
||||
ora_date oracle_schema.DATE,
|
||||
max_date maxdb_schema.DATE
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # ALTER..MODIFY and ALTER..CHANGE understand qualifiers
|
||||
--echo #
|
||||
|
||||
SET sql_mode=DEFAULT;
|
||||
CREATE TABLE t1 (a DATE);
|
||||
INSERT INTO t1 VALUES ('2001-01-01');
|
||||
SET sql_mode=ORACLE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
ALTER TABLE t1 MODIFY a DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
ALTER TABLE t1 MODIFY a mariadb_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
ALTER TABLE t1 MODIFY a oracle_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
ALTER TABLE t1 CHANGE a b mariadb_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
ALTER TABLE t1 CHANGE b a oracle_schema.DATE;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Qualified syntax is not supported yet in SP
|
||||
--echo # See MDEV-23353 Qualified data types in SP
|
||||
--echo #
|
||||
|
||||
SET sql_mode=ORACLE;
|
||||
DELIMITER $$;
|
||||
# Change to this when merging to 10.5:
|
||||
#--error ER_UNKNOWN_DATA_TYPE
|
||||
--error ER_PARSE_ERROR
|
||||
CREATE FUNCTION f1() RETURN mariadb_schema.DATE AS
|
||||
BEGIN
|
||||
RETURN CURRENT_DATE;
|
||||
END;
|
||||
$$
|
||||
--error ER_PARSE_ERROR
|
||||
CREATE PROCEDURE p1(a mariadb_schema.DATE) AS
|
||||
BEGIN
|
||||
NULL;
|
||||
END;
|
||||
$$
|
||||
--error ER_PARSE_ERROR
|
||||
CREATE PROCEDURE p1() AS
|
||||
a mariadb_schema.DATE;
|
||||
BEGIN
|
||||
NULL;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
@ -127,6 +127,7 @@ SET (SQL_SOURCE
|
||||
rpl_gtid.cc rpl_parallel.cc
|
||||
semisync.cc semisync_master.cc semisync_slave.cc
|
||||
semisync_master_ack_receiver.cc
|
||||
sql_schema.cc
|
||||
sql_type.cc sql_mode.cc
|
||||
item_windowfunc.cc sql_window.cc
|
||||
sql_cte.cc
|
||||
|
13
sql/field.cc
13
sql/field.cc
@ -10407,6 +10407,19 @@ void Column_definition::set_attributes(const Lex_field_type_st &type,
|
||||
set_handler(type.type_handler());
|
||||
charset= cs;
|
||||
|
||||
#if MYSQL_VERSION_ID > 100500
|
||||
#error When merging to 10.5, please move the code below to
|
||||
#error Type_handler_timestamp_common::Column_definition_set_attributes()
|
||||
#else
|
||||
/*
|
||||
Unlike other types TIMESTAMP fields are NOT NULL by default.
|
||||
Unless --explicit-defaults-for-timestamp is given.
|
||||
*/
|
||||
if (!opt_explicit_defaults_for_timestamp &&
|
||||
type.type_handler()->field_type() == MYSQL_TYPE_TIMESTAMP)
|
||||
flags|= NOT_NULL_FLAG;
|
||||
#endif
|
||||
|
||||
if (type.length())
|
||||
{
|
||||
int err;
|
||||
|
@ -1157,10 +1157,8 @@ extern "C" my_thread_id next_thread_id_noinline()
|
||||
#endif
|
||||
|
||||
|
||||
const Type_handler *THD::type_handler_for_date() const
|
||||
const Type_handler *THD::type_handler_for_datetime() const
|
||||
{
|
||||
if (!(variables.sql_mode & MODE_ORACLE))
|
||||
return &type_handler_newdate;
|
||||
if (opt_mysql56_temporal_format)
|
||||
return &type_handler_datetime2;
|
||||
return &type_handler_datetime;
|
||||
|
@ -3422,7 +3422,7 @@ public:
|
||||
{
|
||||
return !MY_TEST(variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES);
|
||||
}
|
||||
const Type_handler *type_handler_for_date() const;
|
||||
const Type_handler *type_handler_for_datetime() const;
|
||||
bool timestamp_to_TIME(MYSQL_TIME *ltime, my_time_t ts,
|
||||
ulong sec_part, ulonglong fuzzydate);
|
||||
inline my_time_t query_start() { return start_time; }
|
||||
|
@ -237,6 +237,7 @@ void
|
||||
st_parsing_options::reset()
|
||||
{
|
||||
allows_variable= TRUE;
|
||||
lookup_keywords_after_qualifier= false;
|
||||
}
|
||||
|
||||
|
||||
@ -1539,7 +1540,10 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
|
||||
yylval->lex_str.str= (char*) get_ptr();
|
||||
yylval->lex_str.length= 1;
|
||||
c= yyGet(); // should be '.'
|
||||
next_state= MY_LEX_IDENT_START; // Next is ident (not keyword)
|
||||
if (lex->parsing_options.lookup_keywords_after_qualifier)
|
||||
next_state= MY_LEX_IDENT_OR_KEYWORD;
|
||||
else
|
||||
next_state= MY_LEX_IDENT_START; // Next is ident (not keyword)
|
||||
if (!ident_map[(uchar) yyPeek()]) // Probably ` or "
|
||||
next_state= MY_LEX_START;
|
||||
return((int) c);
|
||||
@ -8286,3 +8290,31 @@ bool LEX::tvc_finalize_derived()
|
||||
current_select->linkage= DERIVED_TABLE_TYPE;
|
||||
return tvc_finalize();
|
||||
}
|
||||
|
||||
|
||||
bool LEX::map_data_type(const Lex_ident_sys_st &schema_name,
|
||||
Lex_field_type_st *type) const
|
||||
{
|
||||
const Schema *schema= schema_name.str ?
|
||||
Schema::find_by_name(schema_name) :
|
||||
Schema::find_implied(thd);
|
||||
if (!schema)
|
||||
{
|
||||
char buf[128];
|
||||
const Name type_name= type->type_handler()->name();
|
||||
my_snprintf(buf, sizeof(buf), "%.*s.%.*s",
|
||||
(int) schema_name.length, schema_name.str,
|
||||
(int) type_name.length(), type_name.ptr());
|
||||
#if MYSQL_VERSION_ID > 100500
|
||||
#error Please remove the old code
|
||||
my_error(ER_UNKNOWN_DATA_TYPE, MYF(0), buf);
|
||||
#else
|
||||
my_printf_error(ER_UNKNOWN_ERROR, "Unknown data type: '%-.64s'",
|
||||
MYF(0), buf);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
const Type_handler *mapped= schema->map_data_type(thd, type->type_handler());
|
||||
type->set_handler(mapped);
|
||||
return false;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "sp.h" // enum stored_procedure_type
|
||||
#include "sql_tvc.h"
|
||||
#include "item.h"
|
||||
#include "sql_schema.h"
|
||||
|
||||
/* Used for flags of nesting constructs */
|
||||
#define SELECT_NESTING_MAP_SIZE 64
|
||||
@ -2144,6 +2145,7 @@ private:
|
||||
struct st_parsing_options
|
||||
{
|
||||
bool allows_variable;
|
||||
bool lookup_keywords_after_qualifier;
|
||||
|
||||
st_parsing_options() { reset(); }
|
||||
void reset();
|
||||
@ -4052,6 +4054,9 @@ public:
|
||||
bool tvc_finalize();
|
||||
bool tvc_finalize_derived();
|
||||
|
||||
bool map_data_type(const Lex_ident_sys_st &schema,
|
||||
Lex_field_type_st *type) const;
|
||||
|
||||
void mark_first_table_as_inserting();
|
||||
};
|
||||
|
||||
|
80
sql/sql_schema.cc
Normal file
80
sql/sql_schema.cc
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#include "mariadb.h"
|
||||
#include "sql_type.h"
|
||||
#include "sql_schema.h"
|
||||
#include "sql_class.h"
|
||||
|
||||
class Schema_oracle: public Schema
|
||||
{
|
||||
public:
|
||||
Schema_oracle(const LEX_CSTRING &name)
|
||||
:Schema(name)
|
||||
{ }
|
||||
const Type_handler *map_data_type(THD *thd, const Type_handler *src)
|
||||
const
|
||||
{
|
||||
if (src == &type_handler_newdate)
|
||||
return thd->type_handler_for_datetime();
|
||||
return src;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Schema_maxdb: public Schema
|
||||
{
|
||||
public:
|
||||
Schema_maxdb(const LEX_CSTRING &name)
|
||||
:Schema(name)
|
||||
{ }
|
||||
const Type_handler *map_data_type(THD *thd, const Type_handler *src)
|
||||
const
|
||||
{
|
||||
if (src == &type_handler_timestamp ||
|
||||
src == &type_handler_timestamp2)
|
||||
return thd->type_handler_for_datetime();
|
||||
return src;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Schema mariadb_schema(Lex_cstring(STRING_WITH_LEN("mariadb_schema")));
|
||||
Schema_oracle oracle_schema(Lex_cstring(STRING_WITH_LEN("oracle_schema")));
|
||||
Schema_maxdb maxdb_schema(Lex_cstring(STRING_WITH_LEN("maxdb_schema")));
|
||||
|
||||
|
||||
Schema *Schema::find_by_name(const LEX_CSTRING &name)
|
||||
{
|
||||
DBUG_ASSERT(name.str);
|
||||
if (mariadb_schema.eq_name(name))
|
||||
return &mariadb_schema;
|
||||
if (oracle_schema.eq_name(name))
|
||||
return &oracle_schema;
|
||||
if (maxdb_schema.eq_name(name))
|
||||
return &maxdb_schema;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Schema *Schema::find_implied(THD *thd)
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_ORACLE)
|
||||
return &oracle_schema;
|
||||
if (thd->variables.sql_mode & MODE_MAXDB)
|
||||
return &maxdb_schema;
|
||||
return &mariadb_schema;
|
||||
}
|
70
sql/sql_schema.h
Normal file
70
sql/sql_schema.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef SQL_SCHEMA_H_INCLUDED
|
||||
#define SQL_SCHEMA_H_INCLUDED
|
||||
/*
|
||||
Copyright (c) 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#include "mysqld.h"
|
||||
#include "lex_string.h"
|
||||
|
||||
class Schema
|
||||
{
|
||||
LEX_CSTRING m_name;
|
||||
public:
|
||||
Schema(const LEX_CSTRING &name)
|
||||
:m_name(name)
|
||||
{ }
|
||||
virtual ~Schema() { }
|
||||
const LEX_CSTRING &name() const { return m_name; }
|
||||
virtual const Type_handler *map_data_type(THD *thd, const Type_handler *src)
|
||||
const
|
||||
{
|
||||
return src;
|
||||
}
|
||||
/*
|
||||
For now we have *hard-coded* compatibility schemas:
|
||||
schema_mariadb, schema_oracle, schema_maxdb.
|
||||
But eventually we'll turn then into real databases on disk.
|
||||
So the code below compares names according to the filesystem
|
||||
case sensitivity, like it is done for regular databases.
|
||||
|
||||
Note, this is different to information_schema, whose name
|
||||
is always case insensitive. This is intentional!
|
||||
The assymetry will be gone when we'll implement SQL standard
|
||||
regular and delimited identifiers.
|
||||
*/
|
||||
bool eq_name(const LEX_CSTRING &name) const
|
||||
{
|
||||
#if MYSQL_VERSION_ID > 100500
|
||||
#error Remove the old code
|
||||
return !table_alias_charset->strnncoll(m_name.str, m_name.length,
|
||||
name.str, name.length);
|
||||
#else
|
||||
// Please remove this when merging to 10.5
|
||||
return !table_alias_charset->coll->strnncoll(table_alias_charset,
|
||||
(const uchar *) m_name.str,
|
||||
m_name.length,
|
||||
(const uchar *) name.str,
|
||||
name.length, FALSE);
|
||||
#endif
|
||||
}
|
||||
static Schema *find_by_name(const LEX_CSTRING &name);
|
||||
static Schema *find_implied(THD *thd);
|
||||
};
|
||||
|
||||
|
||||
extern Schema mariadb_schema;
|
||||
|
||||
#endif // SQL_SCHEMA_H_INCLUDED
|
@ -2224,6 +2224,13 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
append_identifier(thd, packet, &field->field_name);
|
||||
packet->append(' ');
|
||||
|
||||
const Type_handler *th= field->type_handler();
|
||||
const Schema *implied_schema= Schema::find_implied(thd);
|
||||
if (th != implied_schema->map_data_type(thd, th))
|
||||
{
|
||||
packet->append(th->schema()->name(), system_charset_info);
|
||||
packet->append(STRING_WITH_LEN("."), system_charset_info);
|
||||
}
|
||||
type.set(tmp, sizeof(tmp), system_charset_info);
|
||||
field->sql_type(type);
|
||||
packet->append(type.ptr(), type.length(), system_charset_info);
|
||||
|
@ -488,6 +488,10 @@ public:
|
||||
}
|
||||
bool append(const char *s, size_t size);
|
||||
bool append(const char *s, size_t arg_length, CHARSET_INFO *cs);
|
||||
bool append(const LEX_CSTRING &s, CHARSET_INFO *cs)
|
||||
{
|
||||
return append(s.str, s.length, cs);
|
||||
}
|
||||
bool append_ulonglong(ulonglong val);
|
||||
bool append_longlong(longlong val);
|
||||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
|
@ -69,6 +69,12 @@ Type_handler_geometry type_handler_geometry;
|
||||
#endif
|
||||
|
||||
|
||||
Schema *Type_handler::schema() const
|
||||
{
|
||||
return &mariadb_schema;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_data::init()
|
||||
{
|
||||
#ifdef HAVE_SPATIAL
|
||||
|
@ -75,6 +75,7 @@ struct Schema_specification_st;
|
||||
struct TABLE;
|
||||
struct SORT_FIELD_ATTR;
|
||||
class Vers_history_point;
|
||||
class Schema;
|
||||
|
||||
|
||||
/**
|
||||
@ -1062,6 +1063,7 @@ public:
|
||||
Type_handler *aggregate_for_num_op_traditional(const Type_handler *h1,
|
||||
const Type_handler *h2);
|
||||
|
||||
virtual Schema *schema() const;
|
||||
virtual const Name name() const= 0;
|
||||
virtual enum_field_types field_type() const= 0;
|
||||
virtual enum_field_types real_field_type() const { return field_type(); }
|
||||
|
@ -1862,6 +1862,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
%type <type_handler> int_type real_type
|
||||
|
||||
%type <Lex_field_type> type_with_opt_collate field_type
|
||||
qualified_field_type
|
||||
field_type_numeric
|
||||
field_type_string
|
||||
field_type_lob
|
||||
@ -6729,10 +6730,12 @@ field_spec:
|
||||
|
||||
lex->init_last_field(f, &$1, NULL);
|
||||
$<create_field>$= f;
|
||||
lex->parsing_options.lookup_keywords_after_qualifier= true;
|
||||
}
|
||||
field_type_or_serial opt_check_constraint
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->parsing_options.lookup_keywords_after_qualifier= false;
|
||||
$$= $<create_field>2;
|
||||
|
||||
$$->check_constraint= $4;
|
||||
@ -6751,7 +6754,7 @@ field_spec:
|
||||
;
|
||||
|
||||
field_type_or_serial:
|
||||
field_type { Lex->last_field->set_attributes($1, Lex->charset); }
|
||||
qualified_field_type { Lex->last_field->set_attributes($1, Lex->charset); }
|
||||
field_def
|
||||
| SERIAL_SYM
|
||||
{
|
||||
@ -6917,6 +6920,18 @@ column_default_expr:
|
||||
}
|
||||
;
|
||||
|
||||
qualified_field_type:
|
||||
field_type
|
||||
{
|
||||
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
|
||||
}
|
||||
| sp_decl_ident '.' field_type
|
||||
{
|
||||
if (Lex->map_data_type($1, &($$= $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
field_type:
|
||||
field_type_numeric
|
||||
| field_type_temporal
|
||||
@ -7038,7 +7053,7 @@ field_type_temporal:
|
||||
}
|
||||
$$.set(&type_handler_year, $2);
|
||||
}
|
||||
| DATE_SYM { $$.set(thd->type_handler_for_date()); }
|
||||
| DATE_SYM { $$.set(&type_handler_newdate); }
|
||||
| TIME_SYM opt_field_length
|
||||
{
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
@ -7048,31 +7063,14 @@ field_type_temporal:
|
||||
}
|
||||
| TIMESTAMP opt_field_length
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_MAXDB)
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_datetime2) :
|
||||
static_cast<const Type_handler*>(&type_handler_datetime),
|
||||
$2);
|
||||
else
|
||||
{
|
||||
/*
|
||||
Unlike other types TIMESTAMP fields are NOT NULL by default.
|
||||
Unless --explicit-defaults-for-timestamp is given.
|
||||
*/
|
||||
if (!opt_explicit_defaults_for_timestamp)
|
||||
Lex->last_field->flags|= NOT_NULL_FLAG;
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp2):
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp),
|
||||
$2);
|
||||
}
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp2):
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp),
|
||||
$2);
|
||||
}
|
||||
| DATETIME opt_field_length
|
||||
{
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_datetime2) :
|
||||
static_cast<const Type_handler*>(&type_handler_datetime),
|
||||
$2);
|
||||
$$.set(thd->type_handler_for_datetime(), $2);
|
||||
}
|
||||
;
|
||||
|
||||
@ -7400,14 +7398,14 @@ with_or_without_system:
|
||||
type_with_opt_collate:
|
||||
field_type opt_collate
|
||||
{
|
||||
$$= $1;
|
||||
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
|
||||
|
||||
if ($2)
|
||||
{
|
||||
if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Lex->last_field->set_attributes($1, Lex->charset);
|
||||
Lex->last_field->set_attributes($$, Lex->charset);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1260,6 +1260,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
%type <type_handler> int_type real_type
|
||||
|
||||
%type <Lex_field_type> type_with_opt_collate field_type
|
||||
qualified_field_type
|
||||
sp_param_type_with_opt_collate
|
||||
sp_param_field_type
|
||||
sp_param_field_type_string
|
||||
@ -6573,10 +6574,12 @@ field_spec:
|
||||
|
||||
lex->init_last_field(f, &$1, NULL);
|
||||
$<create_field>$= f;
|
||||
lex->parsing_options.lookup_keywords_after_qualifier= true;
|
||||
}
|
||||
field_type_or_serial opt_check_constraint
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->parsing_options.lookup_keywords_after_qualifier= false;
|
||||
$$= $<create_field>2;
|
||||
|
||||
$$->check_constraint= $4;
|
||||
@ -6595,7 +6598,7 @@ field_spec:
|
||||
;
|
||||
|
||||
field_type_or_serial:
|
||||
field_type { Lex->last_field->set_attributes($1, Lex->charset); }
|
||||
qualified_field_type { Lex->last_field->set_attributes($1, Lex->charset); }
|
||||
field_def
|
||||
| SERIAL_SYM
|
||||
{
|
||||
@ -6761,6 +6764,18 @@ column_default_expr:
|
||||
}
|
||||
;
|
||||
|
||||
qualified_field_type:
|
||||
field_type
|
||||
{
|
||||
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
|
||||
}
|
||||
| sp_decl_ident '.' field_type
|
||||
{
|
||||
if (Lex->map_data_type($1, &($$= $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
field_type:
|
||||
field_type_numeric
|
||||
| field_type_temporal
|
||||
@ -6934,7 +6949,7 @@ field_type_temporal:
|
||||
}
|
||||
$$.set(&type_handler_year, $2);
|
||||
}
|
||||
| DATE_SYM { $$.set(thd->type_handler_for_date()); }
|
||||
| DATE_SYM { $$.set(&type_handler_newdate); }
|
||||
| TIME_SYM opt_field_length
|
||||
{
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
@ -6944,31 +6959,14 @@ field_type_temporal:
|
||||
}
|
||||
| TIMESTAMP opt_field_length
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_MAXDB)
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_datetime2) :
|
||||
static_cast<const Type_handler*>(&type_handler_datetime),
|
||||
$2);
|
||||
else
|
||||
{
|
||||
/*
|
||||
Unlike other types TIMESTAMP fields are NOT NULL by default.
|
||||
Unless --explicit-defaults-for-timestamp is given.
|
||||
*/
|
||||
if (!opt_explicit_defaults_for_timestamp)
|
||||
Lex->last_field->flags|= NOT_NULL_FLAG;
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp2):
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp),
|
||||
$2);
|
||||
}
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp2):
|
||||
static_cast<const Type_handler*>(&type_handler_timestamp),
|
||||
$2);
|
||||
}
|
||||
| DATETIME opt_field_length
|
||||
{
|
||||
$$.set(opt_mysql56_temporal_format ?
|
||||
static_cast<const Type_handler*>(&type_handler_datetime2) :
|
||||
static_cast<const Type_handler*>(&type_handler_datetime),
|
||||
$2);
|
||||
$$.set(thd->type_handler_for_datetime(), $2);
|
||||
}
|
||||
;
|
||||
|
||||
@ -7324,27 +7322,28 @@ with_or_without_system:
|
||||
type_with_opt_collate:
|
||||
field_type opt_collate
|
||||
{
|
||||
$$= $1;
|
||||
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
|
||||
|
||||
if ($2)
|
||||
{
|
||||
if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Lex->last_field->set_attributes($1, Lex->charset);
|
||||
Lex->last_field->set_attributes($$, Lex->charset);
|
||||
}
|
||||
;
|
||||
|
||||
sp_param_type_with_opt_collate:
|
||||
sp_param_field_type opt_collate
|
||||
{
|
||||
$$= $1;
|
||||
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
|
||||
|
||||
if ($2)
|
||||
{
|
||||
if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Lex->last_field->set_attributes($1, Lex->charset);
|
||||
Lex->last_field->set_attributes($$, Lex->charset);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -610,6 +610,10 @@ public:
|
||||
{
|
||||
set(handler, 0, 0);
|
||||
}
|
||||
void set_handler(const Type_handler *handler)
|
||||
{
|
||||
m_handler= handler;
|
||||
}
|
||||
const Type_handler *type_handler() const { return m_handler; }
|
||||
};
|
||||
|
||||
|
@ -82,7 +82,7 @@ select * from t1;
|
||||
ERROR HY000: Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a uint)'
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'uint)' at line 1
|
||||
Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
|
||||
Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a uint)'
|
||||
set @@test_sql_discovery_statement='t1:create table t1 (a int)';
|
||||
select * from t1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user