merge from 5.1 up to rev 3471
This commit is contained in:
commit
dbbb506f42
4
README
4
README
@ -1,5 +1,5 @@
|
||||
This is a release of MySQL, a dual-license SQL database server.
|
||||
MySQL is brought to you by the MySQL team at Sun Microsystems, Inc.
|
||||
This is a release of MySQL, a dual-license SQL DBMS.
|
||||
MySQL is brought to you by the MySQL team at Oracle Corporation.
|
||||
|
||||
License information can be found in these files:
|
||||
- For GPL (free) distributions, see the COPYING file and
|
||||
|
@ -5278,10 +5278,8 @@ void do_connect(struct st_command *command)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (opt_protocol)
|
||||
mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SMEM
|
||||
if (con_shm)
|
||||
@ -8002,10 +8000,8 @@ int main(int argc, char **argv)
|
||||
mysql_options(&con->mysql, MYSQL_SET_CHARSET_DIR,
|
||||
opt_charsets_dir);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (opt_protocol)
|
||||
mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
|
@ -12,7 +12,7 @@ dnl
|
||||
dnl When changing the major version number please also check the switch
|
||||
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
||||
dnl to update version.c in ndb.
|
||||
AC_INIT([MySQL Server], [5.1.51], [], [mysql])
|
||||
AC_INIT([MySQL Server], [5.1.53], [], [mysql])
|
||||
|
||||
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
@ -26,7 +26,8 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
||||
decimal.h errmsg.h my_global.h my_net.h \
|
||||
my_getopt.h sslopt-longopts.h my_dir.h \
|
||||
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
|
||||
m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \
|
||||
m_ctype.h my_attribute.h my_compiler.h \
|
||||
$(HEADERS_GEN_CONFIGURE) \
|
||||
$(HEADERS_GEN_MAKE)
|
||||
|
||||
noinst_HEADERS = config-win.h config-netware.h my_bit.h \
|
||||
@ -37,7 +38,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \
|
||||
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
|
||||
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
|
||||
my_handler.h my_time.h my_vle.h my_user.h \
|
||||
my_libwrap.h my_stacktrace.h my_compiler.h
|
||||
my_libwrap.h my_stacktrace.h
|
||||
|
||||
EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp
|
||||
|
||||
|
@ -12,9 +12,10 @@ funcs_1.ndb* # joro : NDB tests marked as experiment
|
||||
|
||||
funcs_2.ndb_charset # joro : NDB tests marked as experimental as agreed with bochklin
|
||||
|
||||
innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests fail on Solaris
|
||||
|
||||
main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
|
||||
main.func_str @solaris # joro: Bug#40928
|
||||
main.plugin_load @solaris # Bug#42144
|
||||
main.sp @solaris # joro : Bug#54138
|
||||
main.outfile_loaddata @solaris # joro : Bug #46895
|
||||
|
||||
@ -44,3 +45,6 @@ parts.partition_syntax_ndb # joro : NDB tests marked as experiment
|
||||
parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin
|
||||
main.mysqlhotcopy_myisam # horst: due to bug#54129
|
||||
main.mysqlhotcopy_archive # horst: due to bug#54129
|
||||
main.gis-rtree # svoj: due to BUG#38965
|
||||
main.type_float # svoj: due to BUG#38965
|
||||
main.type_newdecimal # svoj: due to BUG#38965
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Requires statement logging
|
||||
-- source include/have_binlog_format_mixed_or_statement.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
|
||||
# See if replication of a "LOAD DATA in an autoincrement column"
|
||||
# Honours autoincrement values
|
||||
|
235
mysql-test/extra/rpl_tests/rpl_stm_create_if_not_exists.test
Normal file
235
mysql-test/extra/rpl_tests/rpl_stm_create_if_not_exists.test
Normal file
@ -0,0 +1,235 @@
|
||||
--echo
|
||||
--echo
|
||||
connection master;
|
||||
|
||||
if ($is_temporary)
|
||||
{
|
||||
--let $_temporary=TEMPORARY
|
||||
}
|
||||
|
||||
CREATE TABLE t2(c1 INT, c2 char(10));
|
||||
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
|
||||
|
||||
--echo
|
||||
--echo # The original query should be binlogged if the table does not exist.
|
||||
--echo # ------------------------------------------------------------------
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
|
||||
SELECT 'abc' AS c3, 1 AS c4;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # The statement should be binlogged as two events. one is
|
||||
--echo # 'CREATE $_temporary TABLE IF NOT EXISTS ..', another one is
|
||||
--echo # 'INSERT ... SELECT'.
|
||||
--echo # ------------------------------------------------------------------
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 2;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # Verify if it can be binlogged with right database name when the table
|
||||
--echo # is not in the default database
|
||||
--echo
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS db1;
|
||||
--enable_warnings
|
||||
CREATE DATABASE db1;
|
||||
USE db1;
|
||||
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS test.t1
|
||||
SELECT 'abc', 20;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
USE test;
|
||||
DROP DATABASE db1;
|
||||
|
||||
--echo
|
||||
--echo # It should be binlogged as 'REPLACE ... SELECT'
|
||||
--echo # if the original statement has option REPLACE
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
REPLACE SELECT '123', 2;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # It should be binlogged as 'INSERT IGNORE... SELECT'
|
||||
--echo # if the original statement has option IGNORE
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
IGNORE SELECT '123', 2;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # Nothing should be binlogged if error happens and no any row is inserted
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
--error ER_DUP_ENTRY
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
SELECT '123', 2;
|
||||
source include/show_binlog_events.inc;
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # Verify it can binlog well when there are some braces('(')
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
(SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
--echo
|
||||
--echo # Throw a warning that table already exists and don't insert anything
|
||||
--echo
|
||||
CREATE VIEW t3 AS SELECT * FROM t2;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t3
|
||||
SELECT '123', 2;
|
||||
source include/show_binlog_events.inc;
|
||||
DROP VIEW t3;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
|
||||
--echo
|
||||
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
--enable_warnings
|
||||
eval CREATE PROCEDURE p1(IN a INT)
|
||||
CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', a;
|
||||
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
call p1(500);
|
||||
call p1(600);
|
||||
source include/show_binlog_events.inc;
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
--echo
|
||||
--echo # The statement can be binlogged correctly when it is in a prepared statement
|
||||
--echo
|
||||
eval PREPARE stm FROM "CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', ?";
|
||||
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
SET @a= 700;
|
||||
EXECUTE stm USING @a;
|
||||
SET @a= 800;
|
||||
EXECUTE stm USING @a;
|
||||
source include/show_binlog_events.inc;
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo # The statement can be binlogged correctly when it is in a conditional comment
|
||||
--echo
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo # The whole statement in a conditional comment
|
||||
eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 900*/;
|
||||
source include/show_binlog_events.inc;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # There is an long comment before SELECT
|
||||
eval /*!CREATE $_temporary /*blabla*/ TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 901*/;
|
||||
source include/show_binlog_events.inc;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # Conditional comment starts just from SELECT
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
/*!SELECT 'abc',*/ 902;
|
||||
source include/show_binlog_events.inc;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # Only SELECT keyword is in the conditional comment
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
/*!SELECT*/ /*!'abc',*/ 904;
|
||||
source include/show_binlog_events.inc;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # Conditional comment is after SELECT keyword
|
||||
eval CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
SELECT /*!'abc',*/ 903;
|
||||
source include/show_binlog_events.inc;
|
||||
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # Conditional comment ends just before SELECT keyword
|
||||
eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1
|
||||
*/SELECT 'abc', 905;
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
if (!$is_temporary)
|
||||
{
|
||||
let $diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
}
|
||||
|
||||
DROP TABLE t2;
|
||||
eval DROP $_temporary TABLE t1;
|
||||
|
5
mysql-test/include/not_blackhole.inc
Normal file
5
mysql-test/include/not_blackhole.inc
Normal file
@ -0,0 +1,5 @@
|
||||
if (`SELECT count(*) FROM information_schema.engines WHERE
|
||||
(support = 'YES' OR support = 'DEFAULT') AND
|
||||
engine = 'blackhole'`){
|
||||
skip Blackhole engine enabled;
|
||||
}
|
@ -33,3 +33,4 @@ while (`SELECT "XX$_servers" <> "XX"`)
|
||||
--source include/diff_tables.inc
|
||||
connection $_slave;
|
||||
}
|
||||
connection $_master;
|
||||
|
@ -358,4 +358,13 @@ INDEX(a), INDEX(b), INDEX(c));
|
||||
INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9);
|
||||
DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug #53034: Multiple-table DELETE statements not accepting
|
||||
# "Access compatibility" syntax
|
||||
#
|
||||
CREATE TABLE t1 (id INT);
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
CREATE TABLE t3 LIKE t1;
|
||||
DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
|
||||
DROP TABLE t1, t2, t3;
|
||||
End of 5.1 tests
|
||||
|
@ -1713,4 +1713,15 @@ f1 f2 f3 f4 f1 = f2
|
||||
NULL NULL NULL NULL NULL
|
||||
drop table t1;
|
||||
#
|
||||
# Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
|
||||
# MYSQL_TYPE_LONGLONG
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1), (2);
|
||||
SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1
|
||||
ORDER BY t1.a;
|
||||
m
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
End of 5.1 tests
|
||||
|
@ -194,7 +194,7 @@ date("1997-12-31 23:59:59.000001") as f8,
|
||||
time("1997-12-31 23:59:59.000001") as f9;
|
||||
describe t1;
|
||||
Field Type Null Key Default Extra
|
||||
f1 date NO 0000-00-00
|
||||
f1 date YES NULL
|
||||
f2 datetime YES NULL
|
||||
f3 time YES NULL
|
||||
f4 time YES NULL
|
||||
|
@ -1335,4 +1335,12 @@ date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||
date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||
0168-12-31 23:59:59
|
||||
CREATE TABLE t1(a DOUBLE NOT NULL);
|
||||
INSERT INTO t1 VALUES (0),(9.216e-096);
|
||||
# should not crash
|
||||
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
|
||||
1
|
||||
1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -707,10 +707,7 @@ numgeometries(b) IS NULL, numinteriorrings(b) IS NULL, numpoints(b) IS NULL,
|
||||
area(b) IS NULL, glength(b) IS NULL, srid(b) IS NULL, x(b) IS NULL,
|
||||
y(b) IS NULL
|
||||
from t1;
|
||||
geometryfromtext(b) IS NULL geometryfromwkb(b) IS NULL astext(b) IS NULL aswkb(b) IS NULL geometrytype(b) IS NULL centroid(b) IS NULL envelope(b) IS NULL startpoint(b) IS NULL endpoint(b) IS NULL exteriorring(b) IS NULL pointn(b, 1) IS NULL geometryn(b, 1) IS NULL interiorringn(b, 1) IS NULL multipoint(b) IS NULL isempty(b) IS NULL issimple(b) IS NULL isclosed(b) IS NULL dimension(b) IS NULL numgeometries(b) IS NULL numinteriorrings(b) IS NULL numpoints(b) IS NULL area(b) IS NULL glength(b) IS NULL srid(b) IS NULL x(b) IS NULL y(b) IS NULL
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
ERROR 22007: Illegal non geometric '`test`.`t1`.`b`' value found during parsing
|
||||
select
|
||||
within(b, b) IS NULL, contains(b, b) IS NULL, overlaps(b, b) IS NULL,
|
||||
equals(b, b) IS NULL, disjoint(b, b) IS NULL, touches(b, b) IS NULL,
|
||||
@ -725,10 +722,7 @@ point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS
|
||||
multilinestring(b) IS NULL, multipolygon(b) IS NULL,
|
||||
geometrycollection(b) IS NULL
|
||||
from t1;
|
||||
point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NULL multilinestring(b) IS NULL multipolygon(b) IS NULL geometrycollection(b) IS NULL
|
||||
0 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1
|
||||
0 1 1 1 1 1 1
|
||||
ERROR 22007: Illegal non geometric '`test`.`t1`.`b`' value found during parsing
|
||||
drop table t1;
|
||||
CREATE TABLE t1(a POINT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
@ -1010,51 +1004,14 @@ f5 datetime YES NULL
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
SELECT MultiPoint(12345,'');
|
||||
MultiPoint(12345,'')
|
||||
NULL
|
||||
SELECT MultiPoint(123451,'');
|
||||
MultiPoint(123451,'')
|
||||
NULL
|
||||
SELECT MultiPoint(1234512,'');
|
||||
MultiPoint(1234512,'')
|
||||
NULL
|
||||
SELECT MultiPoint(12345123,'');
|
||||
MultiPoint(12345123,'')
|
||||
NULL
|
||||
SELECT MultiLineString(12345,'');
|
||||
MultiLineString(12345,'')
|
||||
NULL
|
||||
SELECT MultiLineString(123451,'');
|
||||
MultiLineString(123451,'')
|
||||
NULL
|
||||
SELECT MultiLineString(1234512,'');
|
||||
MultiLineString(1234512,'')
|
||||
NULL
|
||||
SELECT MultiLineString(12345123,'');
|
||||
MultiLineString(12345123,'')
|
||||
NULL
|
||||
SELECT LineString(12345,'');
|
||||
LineString(12345,'')
|
||||
NULL
|
||||
SELECT LineString(123451,'');
|
||||
LineString(123451,'')
|
||||
NULL
|
||||
SELECT LineString(1234512,'');
|
||||
LineString(1234512,'')
|
||||
NULL
|
||||
SELECT LineString(12345123,'');
|
||||
LineString(12345123,'')
|
||||
NULL
|
||||
SELECT Polygon(12345,'');
|
||||
Polygon(12345,'')
|
||||
NULL
|
||||
SELECT Polygon(123451,'');
|
||||
Polygon(123451,'')
|
||||
NULL
|
||||
SELECT Polygon(1234512,'');
|
||||
Polygon(1234512,'')
|
||||
NULL
|
||||
SELECT Polygon(12345123,'');
|
||||
Polygon(12345123,'')
|
||||
NULL
|
||||
ERROR 22007: Illegal non geometric '12345' value found during parsing
|
||||
SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b));
|
||||
ERROR 22007: Illegal non geometric ''00000'' value found during parsing
|
||||
#
|
||||
# BUG#51875: crash when loading data into geometry function polyfromwkb
|
||||
#
|
||||
SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
|
||||
SET @a=POLYFROMWKB(@a);
|
||||
SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
|
||||
SET @a=POLYFROMWKB(@a);
|
||||
End of 5.1 tests
|
||||
|
@ -639,3 +639,18 @@ CREATE TABLE t2(f1 CHAR(1));
|
||||
INSERT INTO t2 SELECT f1 FROM t1;
|
||||
DROP TABLE t1, t2;
|
||||
End of 5.0 tests.
|
||||
#
|
||||
# Bug#54106 assert in Protocol::end_statement,
|
||||
# INSERT IGNORE ... SELECT ... UNION SELECT ...
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 (a, a) VALUES (1, 1);
|
||||
ERROR 42000: Column 'a' specified twice
|
||||
INSERT IGNORE t1 (a, a) VALUES (1, 1);
|
||||
ERROR 42000: Column 'a' specified twice
|
||||
INSERT IGNORE t1 (a, a) SELECT 1,1;
|
||||
ERROR 42000: Column 'a' specified twice
|
||||
INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2;
|
||||
ERROR 42000: Column 'a' specified twice
|
||||
DROP TABLE t1;
|
||||
|
@ -1184,4 +1184,40 @@ NULL
|
||||
NULL
|
||||
1
|
||||
DROP TABLE t1, t2, mm1;
|
||||
#
|
||||
# Bug #54468: crash after item's print() function when ordering/grouping
|
||||
# by subquery
|
||||
#
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
INSERT INTO t1 VALUES (), ();
|
||||
SELECT 1 FROM t1
|
||||
GROUP BY
|
||||
GREATEST(t1.a,
|
||||
(SELECT 1 FROM
|
||||
(SELECT t1.b FROM t1,t1 t2
|
||||
ORDER BY t1.a, t1.a LIMIT 1) AS d)
|
||||
);
|
||||
1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug #53544: Server hangs during JOIN query in stored procedure called
|
||||
# twice in a row
|
||||
#
|
||||
CREATE TABLE t1(c INT);
|
||||
INSERT INTO t1 VALUES (1), (2);
|
||||
PREPARE stmt FROM "SELECT t2.c AS f1 FROM t1 LEFT JOIN
|
||||
t1 t2 ON t1.c=t2.c RIGHT JOIN
|
||||
t1 t3 ON t1.c=t3.c
|
||||
GROUP BY f1;";
|
||||
EXECUTE stmt;
|
||||
f1
|
||||
1
|
||||
2
|
||||
EXECUTE stmt;
|
||||
f1
|
||||
1
|
||||
2
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
16
mysql-test/r/partition_not_blackhole.result
Normal file
16
mysql-test/r/partition_not_blackhole.result
Normal file
@ -0,0 +1,16 @@
|
||||
DROP TABLE IF EXISTS t1;
|
||||
#
|
||||
# Bug#46086: crash when dropping a partitioned table and
|
||||
# the original engine is disabled
|
||||
# Copy a .frm and .par file which was created with:
|
||||
# create table `t1` (`id` int primary key) engine=blackhole
|
||||
# partition by key () partitions 1;
|
||||
SHOW TABLES;
|
||||
Tables_in_test
|
||||
t1
|
||||
SHOW CREATE TABLE t1;
|
||||
ERROR HY000: Incorrect information in file: './test/t1.frm'
|
||||
DROP TABLE t1;
|
||||
ERROR 42S02: Unknown table 't1'
|
||||
t1.frm
|
||||
t1.par
|
@ -808,3 +808,47 @@ select sum(count) from t2 ch where ch.defid in (50,52) and ch.day between 200703
|
||||
sum(count)
|
||||
579
|
||||
drop table t1, t2;
|
||||
#
|
||||
# Bug#50939: Loose Index Scan unduly relies on engine to remember range
|
||||
# endpoints
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
) PARTITION BY HASH (a) PARTITIONS 1;
|
||||
CREATE TABLE t2 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
# plans should be identical
|
||||
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
|
||||
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
DROP TABLE t1, t2;
|
||||
|
@ -1654,47 +1654,16 @@ a b
|
||||
1 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#50939: Loose Index Scan unduly relies on engine to remember range
|
||||
# endpoints
|
||||
# Bug #54802: 'NOT BETWEEN' evaluation is incorrect
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
) PARTITION BY HASH (a) PARTITIONS 1;
|
||||
CREATE TABLE t2 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
# plans should be identical
|
||||
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
|
||||
CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||
EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
|
||||
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
DROP TABLE t1, t2;
|
||||
1 SIMPLE t1 ALL c_key NULL NULL NULL 3 Using where
|
||||
SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||
c_key c_notkey
|
||||
1 1
|
||||
3 3
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -59,3 +59,24 @@ FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||
DROP TABLE t1,t2,t3;
|
||||
End of 5.0 tests.
|
||||
#
|
||||
# Bug#54568: create view cause Assertion failed: 0,
|
||||
# file .\item_subselect.cc, line 836
|
||||
#
|
||||
EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1249 Select 2 was reduced during optimization
|
||||
DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1249 Select 2 was reduced during optimization
|
||||
# None of the below should crash
|
||||
CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
||||
DROP VIEW v1, v2;
|
||||
#
|
||||
# End of 5.1 tests.
|
||||
#
|
||||
|
@ -296,4 +296,16 @@ CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL
|
||||
UPDATE t1 SET t = CONVERT_TZ(t, 'UTC', 'Europe/Moscow');
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug #55424: convert_tz crashes when fed invalid data
|
||||
#
|
||||
CREATE TABLE t1 (a SET('x') NOT NULL);
|
||||
INSERT INTO t1 VALUES ('');
|
||||
SELECT CONVERT_TZ(1, a, 1) FROM t1;
|
||||
CONVERT_TZ(1, a, 1)
|
||||
NULL
|
||||
SELECT CONVERT_TZ(1, 1, a) FROM t1;
|
||||
CONVERT_TZ(1, 1, a)
|
||||
NULL
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -1824,11 +1824,8 @@ Note 1050 Table 'v1' already exists
|
||||
set @id=last_insert_id();
|
||||
select * from t1;
|
||||
id operation
|
||||
1 CREATE TABLE ... SELECT, inserting a new key
|
||||
select * from t1_op_log;
|
||||
operation
|
||||
Before INSERT, new=CREATE TABLE ... SELECT, inserting a new key
|
||||
After INSERT, new=CREATE TABLE ... SELECT, inserting a new key
|
||||
truncate t1_op_log;
|
||||
create table if not exists v1 replace
|
||||
select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
|
||||
@ -1836,13 +1833,8 @@ Warnings:
|
||||
Note 1050 Table 'v1' already exists
|
||||
select * from t1;
|
||||
id operation
|
||||
1 CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
|
||||
select * from t1_op_log;
|
||||
operation
|
||||
Before INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
|
||||
Before DELETE, old=CREATE TABLE ... SELECT, inserting a new key
|
||||
After DELETE, old=CREATE TABLE ... SELECT, inserting a new key
|
||||
After INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
|
||||
truncate t1;
|
||||
truncate t1_op_log;
|
||||
insert into v1 (id, operation)
|
||||
|
@ -430,4 +430,21 @@ CREATE TRIGGER t_after_insert AFTER INSERT ON t1 FOR EACH ROW SET @bug42188 = 10
|
||||
INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT);
|
||||
INSERT INTO t1 VALUES (0),(0);
|
||||
# BUG#55615 : should not crash
|
||||
SELECT (@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1) FROM t1 GROUP BY @a;
|
||||
(@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1)
|
||||
1
|
||||
1
|
||||
# BUG#55564 : should not crash
|
||||
SELECT IF(
|
||||
@v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a),
|
||||
count(*), 1)
|
||||
FROM t1 GROUP BY a LIMIT 1;
|
||||
IF(
|
||||
@v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a),
|
||||
count(*), 1)
|
||||
1
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
BIN
mysql-test/std_data/parts/t1_blackhole.frm
Normal file
BIN
mysql-test/std_data/parts/t1_blackhole.frm
Normal file
Binary file not shown.
BIN
mysql-test/std_data/parts/t1_blackhole.par
Normal file
BIN
mysql-test/std_data/parts/t1_blackhole.par
Normal file
Binary file not shown.
10
mysql-test/suite/binlog/r/binlog_mixed_load_data.result
Normal file
10
mysql-test/suite/binlog/r/binlog_mixed_load_data.result
Normal file
@ -0,0 +1,10 @@
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=MYISAM;
|
||||
LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
DROP TABLE t1;
|
@ -1,5 +1,5 @@
|
||||
-- source include/have_debug.inc
|
||||
-- source include/have_binlog_format_mixed_or_statement.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
#
|
||||
# bug#27571 asynchronous setting mysql_$query()'s local error and
|
||||
# Query_log_event::error_code
|
||||
|
15
mysql-test/suite/binlog/t/binlog_mixed_load_data.test
Normal file
15
mysql-test/suite/binlog/t/binlog_mixed_load_data.test
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# Bug #34283 mysqlbinlog leaves tmpfile after termination
|
||||
# if binlog contains load data infile, so in mixed mode we
|
||||
# go to row-based for avoiding the problem.
|
||||
#
|
||||
|
||||
--source include/have_binlog_format_mixed.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=MYISAM;
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
|
||||
--source include/show_binlog_events.inc
|
||||
DROP TABLE t1;
|
@ -2,5 +2,5 @@
|
||||
# For both statement and row based bin logs 9/19/2005 [jbm]
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_binlog_format_mixed_or_statement.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
-- source extra/binlog_tests/blackhole.test
|
||||
|
@ -1244,3 +1244,16 @@ t1 CREATE TABLE `t1` (
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551615);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
@ -2507,4 +2507,96 @@ LOCK TABLES t1 READ;
|
||||
ALTER TABLE t1 COMMENT 'test';
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#55826: create table .. select crashes with when KILL_BAD_DATA
|
||||
# is returned
|
||||
#
|
||||
CREATE TABLE t1(a INT) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (0);
|
||||
SET SQL_MODE='STRICT_ALL_TABLES';
|
||||
CREATE TABLE t2
|
||||
SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
|
||||
ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE=DEFAULT;
|
||||
#
|
||||
# Bug#55580: segfault in read_view_sees_trx_id
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=Innodb;
|
||||
CREATE TABLE t2 (a INT) ENGINE=Innodb;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
INSERT INTO t2 VALUES (1),(2);
|
||||
START TRANSACTION;
|
||||
SELECT * FROM t2 LOCK IN SHARE MODE;
|
||||
a
|
||||
1
|
||||
2
|
||||
START TRANSACTION;
|
||||
SELECT * FROM t1 LOCK IN SHARE MODE;
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT * FROM t1 FOR UPDATE;
|
||||
# should not crash
|
||||
SELECT * FROM t1 GROUP BY (SELECT a FROM t2 LIMIT 1 FOR UPDATE) + t1.a;
|
||||
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug#55656: mysqldump can be slower after bug #39653 fix
|
||||
#
|
||||
CREATE TABLE t1 (a INT , b INT, c INT, d INT,
|
||||
KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
|
||||
INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
|
||||
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||
id 1
|
||||
select_type SIMPLE
|
||||
table t1
|
||||
type index
|
||||
possible_keys NULL
|
||||
key b
|
||||
key_len 4
|
||||
ref NULL
|
||||
rows 3
|
||||
Extra Using index
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b);
|
||||
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||
id 1
|
||||
select_type SIMPLE
|
||||
table t1
|
||||
type index
|
||||
possible_keys NULL
|
||||
key b
|
||||
key_len 8
|
||||
ref NULL
|
||||
rows 3
|
||||
Extra Using index
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b,c);
|
||||
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||
id 1
|
||||
select_type SIMPLE
|
||||
table t1
|
||||
type index
|
||||
possible_keys NULL
|
||||
key b
|
||||
key_len 13
|
||||
ref NULL
|
||||
rows 3
|
||||
Extra Using index
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b,c,d);
|
||||
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||
id 1
|
||||
select_type SIMPLE
|
||||
table t1
|
||||
type index
|
||||
possible_keys NULL
|
||||
key PRIMARY
|
||||
key_len 8
|
||||
ref NULL
|
||||
rows 3
|
||||
Extra Using index
|
||||
DROP TABLE t1;
|
||||
#
|
||||
End of 5.1 tests
|
||||
|
@ -662,3 +662,15 @@ INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL);
|
||||
SELECT * FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
##
|
||||
# 55277: Failing assertion: auto_inc > 0
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551615);
|
||||
# Restart the server
|
||||
-- source include/restart_mysqld.inc
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
@ -747,4 +747,83 @@ UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#55826: create table .. select crashes with when KILL_BAD_DATA
|
||||
--echo # is returned
|
||||
--echo #
|
||||
CREATE TABLE t1(a INT) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (0);
|
||||
SET SQL_MODE='STRICT_ALL_TABLES';
|
||||
--error ER_TRUNCATED_WRONG_VALUE
|
||||
CREATE TABLE t2
|
||||
SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE=DEFAULT;
|
||||
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#55580: segfault in read_view_sees_trx_id
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT) ENGINE=Innodb;
|
||||
CREATE TABLE t2 (a INT) ENGINE=Innodb;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
INSERT INTO t2 VALUES (1),(2);
|
||||
|
||||
connect (con1,localhost,root,,test);
|
||||
connect (con2,localhost,root,,test);
|
||||
|
||||
connection con1;
|
||||
START TRANSACTION;
|
||||
SELECT * FROM t2 LOCK IN SHARE MODE;
|
||||
|
||||
connection con2;
|
||||
START TRANSACTION;
|
||||
SELECT * FROM t1 LOCK IN SHARE MODE;
|
||||
|
||||
connection con1;
|
||||
let $conn_id= `SELECT CONNECTION_ID()`;
|
||||
--send SELECT * FROM t1 FOR UPDATE
|
||||
|
||||
connection con2;
|
||||
let $wait_timeout= 2;
|
||||
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||
WHERE ID=$conn_id AND STATE='Sending data';
|
||||
--source include/wait_condition.inc
|
||||
--echo # should not crash
|
||||
--error ER_LOCK_DEADLOCK
|
||||
SELECT * FROM t1 GROUP BY (SELECT a FROM t2 LIMIT 1 FOR UPDATE) + t1.a;
|
||||
|
||||
connection default;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#55656: mysqldump can be slower after bug #39653 fix
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT , b INT, c INT, d INT,
|
||||
KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
|
||||
INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
|
||||
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b);
|
||||
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b,c);
|
||||
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||
|
||||
DROP INDEX b ON t1;
|
||||
CREATE INDEX b ON t1(a,b,c,d);
|
||||
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -1244,3 +1244,16 @@ t1 CREATE TABLE `t1` (
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551615);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
@ -1,8 +1,6 @@
|
||||
-- source include/have_innodb_plugin.inc
|
||||
# embedded server ignores 'delayed', so skip this
|
||||
-- source include/not_embedded.inc
|
||||
# remove the next line after bug #55503 is fixed
|
||||
-- source include/not_valgrind.inc
|
||||
|
||||
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
-- source include/have_innodb_plugin.inc
|
||||
# embedded server ignores 'delayed', so skip this
|
||||
-- source include/not_embedded.inc
|
||||
# remove the next line after bug #55503 is fixed
|
||||
-- source include/not_valgrind.inc
|
||||
|
||||
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
|
||||
|
||||
@ -667,6 +665,18 @@ SELECT * FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
##
|
||||
# 55277: Failing assertion: auto_inc > 0
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551615);
|
||||
# Restart the server
|
||||
-- source include/restart_mysqld.inc
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# restore environment to the state it was before this test execution
|
||||
#
|
||||
|
@ -65,3 +65,12 @@ c1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
|
||||
# Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes
|
||||
# slave SQL thread abort
|
||||
|
||||
CREATE TABLE t1 ( i INT );
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
AS SELECT SLEEP(3);
|
||||
KILL QUERY master1;
|
||||
DROP TABLE t1;
|
||||
|
@ -19,4 +19,9 @@ master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `tmp2` (
|
||||
`c1` int(11) DEFAULT NULL
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`tmp2` (`c1`) SELECT * FROM tmp
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
@ -883,8 +883,8 @@ master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t2
|
||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
|
||||
master-bin.000001 # Execute_load_query # # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=#
|
||||
master-bin.000001 # Table_map # # table_id: # (test_rpl.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t1
|
||||
|
@ -467,4 +467,10 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
|
||||
DROP TEMPORARY TABLES t7;
|
||||
DROP TABLES t4, t5;
|
||||
DROP TABLES IF EXISTS bug48506_t4;
|
||||
CREATE TABLE t1 SELECT 1;
|
||||
CREATE TABLE IF NOT EXISTS t1 SELECT 1;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
DROP TABLE t1;
|
||||
end of the tests
|
||||
|
704
mysql-test/suite/rpl/r/rpl_stm_create_if_not_exists.result
Normal file
704
mysql-test/suite/rpl/r/rpl_stm_create_if_not_exists.result
Normal file
@ -0,0 +1,704 @@
|
||||
# WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT
|
||||
# EXISTS ... SELECT' behaviour
|
||||
#
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
|
||||
|
||||
CREATE TABLE t2(c1 INT, c2 char(10));
|
||||
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
|
||||
|
||||
# The original query should be binlogged if the table does not exist.
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
|
||||
SELECT 'abc' AS c3, 1 AS c4;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
|
||||
SELECT 'abc' AS c3, 1 AS c4
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# The statement should be binlogged as two events. one is
|
||||
# 'CREATE TABLE IF NOT EXISTS ..', another one is
|
||||
# 'INSERT ... SELECT'.
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Verify if it can be binlogged with right database name when the table
|
||||
# is not in the default database
|
||||
|
||||
DROP DATABASE IF EXISTS db1;
|
||||
CREATE DATABASE db1;
|
||||
USE db1;
|
||||
CREATE TABLE IF NOT EXISTS test.t1
|
||||
SELECT 'abc', 20;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `db1`; CREATE TABLE IF NOT EXISTS `test`.`t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
USE test;
|
||||
DROP DATABASE db1;
|
||||
|
||||
# It should be binlogged as 'REPLACE ... SELECT'
|
||||
# if the original statement has option REPLACE
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
REPLACE SELECT '123', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# It should be binlogged as 'INSERT IGNORE... SELECT'
|
||||
# if the original statement has option IGNORE
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
IGNORE SELECT '123', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Nothing should be binlogged if error happens and no any row is inserted
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
SELECT '123', 2;
|
||||
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Verify it can binlog well when there are some braces('(')
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
(SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Throw a warning that table already exists and don't insert anything
|
||||
|
||||
CREATE VIEW t3 AS SELECT * FROM t2;
|
||||
CREATE TABLE IF NOT EXISTS t3
|
||||
SELECT '123', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't3' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
DROP VIEW t3;
|
||||
|
||||
# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
|
||||
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
CREATE PROCEDURE p1(IN a INT)
|
||||
CREATE TABLE IF NOT EXISTS t1 SELECT '123', a;
|
||||
call p1(500);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
call p1(600);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# The statement can be binlogged correctly when it is in a prepared statement
|
||||
|
||||
PREPARE stm FROM "CREATE TABLE IF NOT EXISTS t1 SELECT '123', ?";
|
||||
SET @a= 700;
|
||||
EXECUTE stm USING @a;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
SET @a= 800;
|
||||
EXECUTE stm USING @a;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# The statement can be binlogged correctly when it is in a conditional comment
|
||||
|
||||
# The whole statement in a conditional comment
|
||||
/*!CREATE TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 900*/;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# There is an long comment before SELECT
|
||||
/*!CREATE /*blabla*/ TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 901*/;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment starts just from SELECT
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
/*!SELECT 'abc',*/ 902;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Only SELECT keyword is in the conditional comment
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
/*!SELECT*/ /*!'abc',*/ 904;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment is after SELECT keyword
|
||||
CREATE TABLE IF NOT EXISTS t1
|
||||
SELECT /*!'abc',*/ 903;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment ends just before SELECT keyword
|
||||
/*!CREATE TABLE IF NOT EXISTS t1
|
||||
*/SELECT 'abc', 905;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
CREATE TABLE t2(c1 INT, c2 char(10));
|
||||
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
|
||||
|
||||
# The original query should be binlogged if the table does not exist.
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
|
||||
SELECT 'abc' AS c3, 1 AS c4;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
|
||||
SELECT 'abc' AS c3, 1 AS c4
|
||||
|
||||
# The statement should be binlogged as two events. one is
|
||||
# 'CREATE TEMPORARY TABLE IF NOT EXISTS ..', another one is
|
||||
# 'INSERT ... SELECT'.
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Verify if it can be binlogged with right database name when the table
|
||||
# is not in the default database
|
||||
|
||||
DROP DATABASE IF EXISTS db1;
|
||||
CREATE DATABASE db1;
|
||||
USE db1;
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS test.t1
|
||||
SELECT 'abc', 20;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `db1`; CREATE TEMPORARY TABLE IF NOT EXISTS `test`.`t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
USE test;
|
||||
DROP DATABASE db1;
|
||||
|
||||
# It should be binlogged as 'REPLACE ... SELECT'
|
||||
# if the original statement has option REPLACE
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
REPLACE SELECT '123', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# It should be binlogged as 'INSERT IGNORE... SELECT'
|
||||
# if the original statement has option IGNORE
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
IGNORE SELECT '123', 2;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Nothing should be binlogged if error happens and no any row is inserted
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
SELECT '123', 2;
|
||||
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
|
||||
# Verify it can binlog well when there are some braces('(')
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
(SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
|
||||
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
CREATE PROCEDURE p1(IN a INT)
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', a;
|
||||
call p1(500);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
call p1(600);
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# The statement can be binlogged correctly when it is in a prepared statement
|
||||
|
||||
PREPARE stm FROM "CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', ?";
|
||||
SET @a= 700;
|
||||
EXECUTE stm USING @a;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
SET @a= 800;
|
||||
EXECUTE stm USING @a;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# The statement can be binlogged correctly when it is in a conditional comment
|
||||
|
||||
# The whole statement in a conditional comment
|
||||
/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 900*/;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# There is an long comment before SELECT
|
||||
/*!CREATE TEMPORARY /*blabla*/ TABLE IF NOT EXISTS t1
|
||||
SELECT 'abc', 901*/;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment starts just from SELECT
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
/*!SELECT 'abc',*/ 902;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Only SELECT keyword is in the conditional comment
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
/*!SELECT*/ /*!'abc',*/ 904;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment is after SELECT keyword
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
SELECT /*!'abc',*/ 903;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Conditional comment ends just before SELECT keyword
|
||||
/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1
|
||||
*/SELECT 'abc', 905;
|
||||
Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
|
||||
`c1` int(11) DEFAULT NULL,
|
||||
`c2` int(11) DEFAULT NULL,
|
||||
`c3` char(10) DEFAULT NULL,
|
||||
`c4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c4`)
|
||||
)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
DROP TABLE t2;
|
||||
DROP TEMPORARY TABLE t1;
|
@ -11,3 +11,4 @@
|
||||
##############################################################################
|
||||
|
||||
rpl_row_create_table : Bug#51574 Feb 27 2010 andrei failed different way than earlier with bug#45576
|
||||
rpl_log_pos : BUG#55675 Sep 10 2010 27 2010 alfranio rpl.rpl_log_pos fails sporadically with error binlog truncated in the middle
|
||||
|
@ -119,5 +119,32 @@ SELECT * FROM t2;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo
|
||||
--echo # Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes
|
||||
--echo # slave SQL thread abort
|
||||
--echo
|
||||
|
||||
--connection master1
|
||||
let $con_id = `SELECT CONNECTION_ID()`;
|
||||
|
||||
CREATE TABLE t1 ( i INT );
|
||||
send CREATE TABLE IF NOT EXISTS t1
|
||||
AS SELECT SLEEP(3);
|
||||
|
||||
connection master;
|
||||
let $wait_timeout = 3;
|
||||
let $show_statement = SHOW PROCESSLIST;
|
||||
let $field = State;
|
||||
let $condition = = 'User sleep';
|
||||
source include/wait_show_condition.inc;
|
||||
|
||||
--replace_result $con_id master1
|
||||
eval KILL QUERY $con_id;
|
||||
sync_slave_with_master;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
|
||||
source include/master-slave-end.inc;
|
||||
|
@ -1,4 +1,4 @@
|
||||
source include/have_binlog_format_mixed_or_statement.inc;
|
||||
source include/have_binlog_format_statement.inc;
|
||||
source include/have_debug.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
# BUG#33413 show binlog events fails if binlog has event size of close
|
||||
# to max_allowed_packet
|
||||
|
||||
source include/have_binlog_format_mixed_or_statement.inc;
|
||||
source include/have_binlog_format_statement.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
|
||||
|
@ -299,5 +299,18 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
|
||||
DROP TEMPORARY TABLES t7;
|
||||
DROP TABLES t4, t5;
|
||||
DROP TABLES IF EXISTS bug48506_t4;
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# Bug#55598 RBR: CREATE TABLE IF NOT EXISTS and INSERT written to binary log
|
||||
# twice
|
||||
#
|
||||
connection master;
|
||||
CREATE TABLE t1 SELECT 1;
|
||||
CREATE TABLE IF NOT EXISTS t1 SELECT 1;
|
||||
let $diff_table=test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
DROP TABLE t1;
|
||||
|
||||
source include/master-slave-end.inc;
|
||||
--echo end of the tests
|
||||
|
@ -8,7 +8,7 @@
|
||||
# 2 - Catches error.
|
||||
##########################################################################
|
||||
|
||||
--source include/have_binlog_format_mixed_or_statement.inc
|
||||
--source include/have_binlog_format_statement.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/master-slave.inc
|
||||
|
14
mysql-test/suite/rpl/t/rpl_stm_create_if_not_exists.test
Normal file
14
mysql-test/suite/rpl/t/rpl_stm_create_if_not_exists.test
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
--echo # WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT
|
||||
--echo # EXISTS ... SELECT' behaviour
|
||||
--echo #
|
||||
|
||||
source include/master-slave.inc;
|
||||
source include/have_binlog_format_statement.inc;
|
||||
|
||||
source extra/rpl_tests/rpl_stm_create_if_not_exists.test;
|
||||
|
||||
let $is_temporary=1;
|
||||
source extra/rpl_tests/rpl_stm_create_if_not_exists.test;
|
||||
|
||||
source include/master-slave-end.inc;
|
@ -1,5 +1,5 @@
|
||||
# Requires statement logging
|
||||
-- source include/have_binlog_format_mixed_or_statement.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
-- source include/master-slave.inc
|
||||
let $engine_type=MyISAM;
|
||||
-- source extra/rpl_tests/rpl_log.test
|
||||
|
@ -387,4 +387,17 @@ DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #53034: Multiple-table DELETE statements not accepting
|
||||
--echo # "Access compatibility" syntax
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (id INT);
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
CREATE TABLE t3 LIKE t1;
|
||||
|
||||
DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
|
||||
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -1082,6 +1082,20 @@ select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
|
||||
from t1 a, t1 b;
|
||||
select *, f1 = f2 from t1;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
|
||||
--echo # MYSQL_TYPE_LONGLONG
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1), (2);
|
||||
|
||||
SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1
|
||||
ORDER BY t1.a;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo End of 5.1 tests
|
||||
|
||||
|
@ -838,4 +838,15 @@ select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||
|
||||
|
||||
#
|
||||
# Bug #55565: debug assertion when ordering by expressions with user
|
||||
# variable assignments
|
||||
#
|
||||
|
||||
CREATE TABLE t1(a DOUBLE NOT NULL);
|
||||
INSERT INTO t1 VALUES (0),(9.216e-096);
|
||||
--echo # should not crash
|
||||
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -401,6 +401,7 @@ create table t1 (a int, b blob);
|
||||
insert into t1 values (1, ''), (2, NULL), (3, '1');
|
||||
select * from t1;
|
||||
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
select
|
||||
geometryfromtext(b) IS NULL, geometryfromwkb(b) IS NULL, astext(b) IS NULL,
|
||||
aswkb(b) IS NULL, geometrytype(b) IS NULL, centroid(b) IS NULL,
|
||||
@ -419,6 +420,7 @@ select
|
||||
intersects(b, b) IS NULL, crosses(b, b) IS NULL
|
||||
from t1;
|
||||
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
select
|
||||
point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS NULL,
|
||||
multilinestring(b) IS NULL, multipolygon(b) IS NULL,
|
||||
@ -702,24 +704,44 @@ drop table t1;
|
||||
# Bug#44684: valgrind reports invalid reads in
|
||||
# Item_func_spatial_collection::val_str
|
||||
#
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
SELECT MultiPoint(12345,'');
|
||||
SELECT MultiPoint(123451,'');
|
||||
SELECT MultiPoint(1234512,'');
|
||||
SELECT MultiPoint(12345123,'');
|
||||
#SELECT MultiPoint(123451,'');
|
||||
#SELECT MultiPoint(1234512,'');
|
||||
#SELECT MultiPoint(12345123,'');
|
||||
|
||||
SELECT MultiLineString(12345,'');
|
||||
SELECT MultiLineString(123451,'');
|
||||
SELECT MultiLineString(1234512,'');
|
||||
SELECT MultiLineString(12345123,'');
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
#SELECT MultiLineString(12345,'');
|
||||
#SELECT MultiLineString(123451,'');
|
||||
#SELECT MultiLineString(1234512,'');
|
||||
#SELECT MultiLineString(12345123,'');
|
||||
|
||||
SELECT LineString(12345,'');
|
||||
SELECT LineString(123451,'');
|
||||
SELECT LineString(1234512,'');
|
||||
SELECT LineString(12345123,'');
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
#SELECT LineString(12345,'');
|
||||
#SELECT LineString(123451,'');
|
||||
#SELECT LineString(1234512,'');
|
||||
#SELECT LineString(12345123,'');
|
||||
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
#SELECT Polygon(12345,'');
|
||||
#SELECT Polygon(123451,'');
|
||||
#SELECT Polygon(1234512,'');
|
||||
#SELECT Polygon(12345123,'');
|
||||
|
||||
#
|
||||
# Bug55531 crash with conversions of geometry types / strings
|
||||
#
|
||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||
SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b));
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # BUG#51875: crash when loading data into geometry function polyfromwkb
|
||||
--echo #
|
||||
SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
|
||||
SET @a=POLYFROMWKB(@a);
|
||||
SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
|
||||
SET @a=POLYFROMWKB(@a);
|
||||
|
||||
SELECT Polygon(12345,'');
|
||||
SELECT Polygon(123451,'');
|
||||
SELECT Polygon(1234512,'');
|
||||
SELECT Polygon(12345123,'');
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -499,3 +499,28 @@ DROP TABLE t1, t2;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#54106 assert in Protocol::end_statement,
|
||||
--echo # INSERT IGNORE ... SELECT ... UNION SELECT ...
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
|
||||
--error ER_FIELD_SPECIFIED_TWICE
|
||||
INSERT INTO t1 (a, a) VALUES (1, 1);
|
||||
# Verify that ER_FIELD_SPECIFIED_TWICE is not ignorable
|
||||
--error ER_FIELD_SPECIFIED_TWICE
|
||||
INSERT IGNORE t1 (a, a) VALUES (1, 1);
|
||||
|
||||
--error ER_FIELD_SPECIFIED_TWICE
|
||||
INSERT IGNORE t1 (a, a) SELECT 1,1;
|
||||
# Used to cause an assert
|
||||
--error ER_FIELD_SPECIFIED_TWICE
|
||||
INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
@ -851,4 +851,74 @@ ENGINE=MERGE UNION=(t1,t2);
|
||||
SELECT t1.a FROM mm1,t1;
|
||||
DROP TABLE t1, t2, mm1;
|
||||
|
||||
#--echo #
|
||||
#--echo # Bug #55568: user variable assignments crash server when used within
|
||||
#--echo # query
|
||||
#--echo #
|
||||
#
|
||||
#
|
||||
# This test case is invalidated because of fix of bug 55531
|
||||
# The reason is that {1} is not a valid geometric collection.
|
||||
#
|
||||
#CREATE TABLE t1 (a INT);
|
||||
|
||||
#INSERT INTO t1 VALUES (0), (1);
|
||||
|
||||
#let $i=2;
|
||||
#while ($i)
|
||||
#{
|
||||
# SELECT MULTIPOINT(
|
||||
# 1,
|
||||
# (
|
||||
# SELECT MULTIPOINT(
|
||||
# MULTIPOINT(
|
||||
# 1,
|
||||
# (SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
|
||||
# )
|
||||
# ) FROM t1
|
||||
# )
|
||||
# ) != COUNT(*) q FROM t1 GROUP BY a;
|
||||
# dec $i;
|
||||
#}
|
||||
#
|
||||
#DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #54468: crash after item's print() function when ordering/grouping
|
||||
--echo # by subquery
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
INSERT INTO t1 VALUES (), ();
|
||||
|
||||
SELECT 1 FROM t1
|
||||
GROUP BY
|
||||
GREATEST(t1.a,
|
||||
(SELECT 1 FROM
|
||||
(SELECT t1.b FROM t1,t1 t2
|
||||
ORDER BY t1.a, t1.a LIMIT 1) AS d)
|
||||
);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #53544: Server hangs during JOIN query in stored procedure called
|
||||
--echo # twice in a row
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(c INT);
|
||||
|
||||
INSERT INTO t1 VALUES (1), (2);
|
||||
|
||||
PREPARE stmt FROM "SELECT t2.c AS f1 FROM t1 LEFT JOIN
|
||||
t1 t2 ON t1.c=t2.c RIGHT JOIN
|
||||
t1 t3 ON t1.c=t3.c
|
||||
GROUP BY f1;";
|
||||
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -1,6 +1,6 @@
|
||||
# We are using .opt file since we need small binlog size
|
||||
# TODO: Need to look at making a row based version once the new row based client is completed. [jbm]
|
||||
-- source include/have_binlog_format_mixed_or_statement.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
|
||||
-- source include/have_log_bin.inc
|
||||
|
||||
|
1
mysql-test/t/partition_not_blackhole-master.opt
Normal file
1
mysql-test/t/partition_not_blackhole-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--loose-skip-blackhole
|
26
mysql-test/t/partition_not_blackhole.test
Normal file
26
mysql-test/t/partition_not_blackhole.test
Normal file
@ -0,0 +1,26 @@
|
||||
--source include/have_partition.inc
|
||||
--source include/not_blackhole.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#46086: crash when dropping a partitioned table and
|
||||
--echo # the original engine is disabled
|
||||
--echo # Copy a .frm and .par file which was created with:
|
||||
--echo # create table `t1` (`id` int primary key) engine=blackhole
|
||||
--echo # partition by key () partitions 1;
|
||||
--copy_file std_data/parts/t1_blackhole.frm $MYSQLD_DATADIR/test/t1.frm
|
||||
--copy_file std_data/parts/t1_blackhole.par $MYSQLD_DATADIR/test/t1.par
|
||||
SHOW TABLES;
|
||||
--replace_result $MYSQLD_DATADIR ./
|
||||
--error ER_NOT_FORM_FILE
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_BAD_TABLE_ERROR
|
||||
DROP TABLE t1;
|
||||
--list_files $MYSQLD_DATADIR/test t1*
|
||||
--remove_file $MYSQLD_DATADIR/test/t1.frm
|
||||
--remove_file $MYSQLD_DATADIR/test/t1.par
|
@ -846,3 +846,44 @@ insert into t2 values(52, 20070322, 456, 'filler') ;
|
||||
select sum(count) from t2 ch where ch.defid in (50,52) and ch.day between 20070320 and 20070401 group by defid;
|
||||
drop table t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#50939: Loose Index Scan unduly relies on engine to remember range
|
||||
--echo # endpoints
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
) PARTITION BY HASH (a) PARTITIONS 1;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
|
||||
INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
|
||||
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
|
||||
--echo # plans should be identical
|
||||
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
|
||||
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
|
||||
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
|
||||
--echo # Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
|
||||
--echo # Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
@ -1314,44 +1314,15 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY)
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#50939: Loose Index Scan unduly relies on engine to remember range
|
||||
--echo # endpoints
|
||||
--echo # Bug #54802: 'NOT BETWEEN' evaluation is incorrect
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
) PARTITION BY HASH (a) PARTITIONS 1;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
);
|
||||
CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||
SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||
|
||||
INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
|
||||
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
|
||||
--echo # plans should be identical
|
||||
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
|
||||
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
|
||||
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
|
||||
--echo # Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
|
||||
--echo # Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -62,3 +62,19 @@ FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
--echo #
|
||||
--echo # Bug#54568: create view cause Assertion failed: 0,
|
||||
--echo # file .\item_subselect.cc, line 836
|
||||
--echo #
|
||||
EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
--echo # None of the below should crash
|
||||
CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
||||
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
||||
DROP VIEW v1, v2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 5.1 tests.
|
||||
--echo #
|
||||
|
@ -273,5 +273,14 @@ UNLOCK TABLES;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #55424: convert_tz crashes when fed invalid data
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a SET('x') NOT NULL);
|
||||
INSERT INTO t1 VALUES ('');
|
||||
SELECT CONVERT_TZ(1, a, 1) FROM t1;
|
||||
SELECT CONVERT_TZ(1, 1, a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -328,4 +328,22 @@ INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #55615: debug assertion after using variable in assignment and
|
||||
# referred to
|
||||
# Bug #55564: crash with user variables, assignments, joins...
|
||||
#
|
||||
|
||||
CREATE TABLE t1(a INT);
|
||||
INSERT INTO t1 VALUES (0),(0);
|
||||
--echo # BUG#55615 : should not crash
|
||||
SELECT (@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1) FROM t1 GROUP BY @a;
|
||||
--echo # BUG#55564 : should not crash
|
||||
SELECT IF(
|
||||
@v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a),
|
||||
count(*), 1)
|
||||
FROM t1 GROUP BY a LIMIT 1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -656,17 +656,21 @@ static int setval(const struct my_option *opts, void *value, char *argument,
|
||||
return EXIT_OUT_OF_MEMORY;
|
||||
break;
|
||||
case GET_ENUM:
|
||||
if (((*(int*)result_pos)=
|
||||
find_type(argument, opts->typelib, 2) - 1) < 0)
|
||||
{
|
||||
/*
|
||||
Accept an integer representation of the enumerated item.
|
||||
*/
|
||||
char *endptr;
|
||||
unsigned int arg= (unsigned int) strtol(argument, &endptr, 10);
|
||||
if (*endptr || arg >= opts->typelib->count)
|
||||
return EXIT_ARGUMENT_INVALID;
|
||||
*(int*)result_pos= arg;
|
||||
int type= find_type(argument, opts->typelib, 2);
|
||||
if (type < 1)
|
||||
{
|
||||
/*
|
||||
Accept an integer representation of the enumerated item.
|
||||
*/
|
||||
char *endptr;
|
||||
ulong arg= strtoul(argument, &endptr, 10);
|
||||
if (*endptr || arg >= opts->typelib->count)
|
||||
return EXIT_ARGUMENT_INVALID;
|
||||
*((ulong*) result_pos)= arg;
|
||||
}
|
||||
else
|
||||
*((ulong*) result_pos)= type - 1;
|
||||
}
|
||||
break;
|
||||
case GET_SET:
|
||||
@ -1004,7 +1008,7 @@ static void init_one_value(const struct my_option *option, void *variable,
|
||||
*((int*) variable)= (int) getopt_ll_limit_value((int) value, option, NULL);
|
||||
break;
|
||||
case GET_ENUM:
|
||||
*((uint*) variable)= (uint) value;
|
||||
*((ulong*) variable)= (ulong) value;
|
||||
break;
|
||||
case GET_UINT:
|
||||
*((uint*) variable)= (uint) getopt_ull_limit_value((uint) value, option, NULL);
|
||||
@ -1244,7 +1248,7 @@ void my_print_variables(const struct my_option *options)
|
||||
}
|
||||
break;
|
||||
case GET_ENUM:
|
||||
printf("%s\n", get_type(optp->typelib, *(uint*) value));
|
||||
printf("%s\n", get_type(optp->typelib, *(ulong*) value));
|
||||
break;
|
||||
case GET_STR:
|
||||
case GET_STR_ALLOC: /* fall through */
|
||||
|
@ -263,6 +263,7 @@ cp include/mysql.h \
|
||||
include/keycache.h \
|
||||
include/m_ctype.h \
|
||||
include/my_attribute.h \
|
||||
include/my_compiler.h \
|
||||
include/mysqld_error.h \
|
||||
include/sql_state.h \
|
||||
include/mysqld_ername.h \
|
||||
|
@ -1535,7 +1535,7 @@ void Field::make_field(Send_field *field)
|
||||
}
|
||||
else
|
||||
field->org_table_name= field->db_name= "";
|
||||
if (orig_table)
|
||||
if (orig_table && orig_table->alias)
|
||||
{
|
||||
field->table_name= orig_table->alias;
|
||||
field->org_col_name= field_name;
|
||||
@ -4561,7 +4561,7 @@ String *Field_double::val_str(String *val_buffer,
|
||||
#endif
|
||||
doubleget(nr,ptr);
|
||||
|
||||
uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
|
||||
uint to_length= DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE;
|
||||
val_buffer->alloc(to_length);
|
||||
char *to=(char*) val_buffer->ptr();
|
||||
|
||||
|
@ -2403,9 +2403,14 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
|
||||
tot_partition_words= (m_tot_parts + 3) / 4;
|
||||
engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*));
|
||||
for (i= 0; i < m_tot_parts; i++)
|
||||
{
|
||||
engine_array[i]= ha_resolve_by_legacy_type(ha_thd(),
|
||||
(enum legacy_db_type)
|
||||
*(uchar *) ((file_buffer) + 12 + i));
|
||||
*(uchar *) ((file_buffer) +
|
||||
12 + i));
|
||||
if (!engine_array[i])
|
||||
goto err3;
|
||||
}
|
||||
address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words;
|
||||
tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4;
|
||||
if (len_words != (tot_partition_words + tot_name_words + 4))
|
||||
|
@ -4606,7 +4606,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (escape_item->const_item())
|
||||
if (escape_item->const_item() && !thd->lex->view_prepare_mode)
|
||||
{
|
||||
/* If we are on execution stage */
|
||||
String *escape_str= escape_item->val_str(&cmp.value1);
|
||||
|
@ -2263,7 +2263,7 @@ void Item_func_min_max::fix_length_and_dec()
|
||||
stored to the value pointer, if latter is provided.
|
||||
|
||||
RETURN
|
||||
0 If one of arguments is NULL
|
||||
0 If one of arguments is NULL or there was a execution error
|
||||
# index of the least/greatest argument
|
||||
*/
|
||||
|
||||
@ -2277,6 +2277,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value)
|
||||
Item **arg= args + i;
|
||||
bool is_null;
|
||||
longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
|
||||
|
||||
/* Check if we need to stop (because of error or KILL) and stop the loop */
|
||||
if (thd->is_error())
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((null_value= args[i]->null_value))
|
||||
return 0;
|
||||
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
|
||||
@ -2305,6 +2313,12 @@ String *Item_func_min_max::val_str(String *str)
|
||||
if (null_value)
|
||||
return 0;
|
||||
str_res= args[min_max_idx]->val_str(str);
|
||||
if (args[min_max_idx]->null_value)
|
||||
{
|
||||
// check if the call to val_str() above returns a NULL value
|
||||
null_value= 1;
|
||||
return NULL;
|
||||
}
|
||||
str_res->set_charset(collation.collation);
|
||||
return str_res;
|
||||
}
|
||||
@ -4263,6 +4277,14 @@ longlong Item_func_set_user_var::val_int_result()
|
||||
return entry->val_int(&null_value);
|
||||
}
|
||||
|
||||
bool Item_func_set_user_var::val_bool_result()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
check(TRUE);
|
||||
update(); // Store expression
|
||||
return entry->val_int(&null_value) != 0;
|
||||
}
|
||||
|
||||
String *Item_func_set_user_var::str_result(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
@ -1353,6 +1353,7 @@ public:
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
double val_result();
|
||||
longlong val_int_result();
|
||||
bool val_bool_result();
|
||||
String *str_result(String *str);
|
||||
my_decimal *val_decimal_result(my_decimal *);
|
||||
bool is_null_result();
|
||||
|
@ -175,6 +175,21 @@ public:
|
||||
item_type=it;
|
||||
}
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
for (unsigned int i= 0; i < arg_count; ++i)
|
||||
{
|
||||
if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
|
||||
{
|
||||
String str;
|
||||
args[i]->print(&str, QT_ORDINARY);
|
||||
str.append('\0');
|
||||
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
|
||||
str.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *func_name() const { return "multipoint"; }
|
||||
};
|
||||
|
||||
|
@ -417,26 +417,6 @@ void Item_sum::mark_as_sum_func()
|
||||
}
|
||||
|
||||
|
||||
void Item_sum::make_field(Send_field *tmp_field)
|
||||
{
|
||||
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
|
||||
{
|
||||
((Item_field*) args[0])->field->make_field(tmp_field);
|
||||
/* For expressions only col_name should be non-empty string. */
|
||||
char *empty_string= (char*)"";
|
||||
tmp_field->db_name= empty_string;
|
||||
tmp_field->org_table_name= empty_string;
|
||||
tmp_field->table_name= empty_string;
|
||||
tmp_field->org_col_name= empty_string;
|
||||
tmp_field->col_name= name;
|
||||
if (maybe_null)
|
||||
tmp_field->flags&= ~NOT_NULL_FLAG;
|
||||
}
|
||||
else
|
||||
init_make_field(tmp_field, field_type());
|
||||
}
|
||||
|
||||
|
||||
void Item_sum::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
/* orig_args is not filled with valid values until fix_fields() */
|
||||
@ -2556,7 +2536,8 @@ bool Item_sum_count_distinct::add()
|
||||
if (always_null)
|
||||
return 0;
|
||||
copy_fields(tmp_table_param);
|
||||
copy_funcs(tmp_table_param->items_to_copy);
|
||||
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
|
||||
return TRUE;
|
||||
|
||||
for (Field **field=table->field ; *field ; field++)
|
||||
if ((*field)->is_real_null(0))
|
||||
@ -3145,7 +3126,8 @@ bool Item_func_group_concat::add()
|
||||
if (always_null)
|
||||
return 0;
|
||||
copy_fields(tmp_table_param);
|
||||
copy_funcs(tmp_table_param->items_to_copy);
|
||||
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
|
||||
return TRUE;
|
||||
|
||||
for (uint i= 0; i < arg_count_field; i++)
|
||||
{
|
||||
|
@ -339,7 +339,6 @@ public:
|
||||
forced_const= TRUE;
|
||||
}
|
||||
virtual bool const_item() const { return forced_const; }
|
||||
void make_field(Send_field *field);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
void fix_num_length_and_dec();
|
||||
|
||||
|
@ -881,6 +881,8 @@ public:
|
||||
{
|
||||
decimals=0;
|
||||
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
/* It returns NULL when the second argument is less or equal to 0 */
|
||||
maybe_null= 1;
|
||||
}
|
||||
longlong val_int();
|
||||
};
|
||||
|
117
sql/log.cc
117
sql/log.cc
@ -5063,70 +5063,93 @@ void sql_perror(const char *message)
|
||||
}
|
||||
|
||||
|
||||
#ifdef __WIN__
|
||||
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||
FILE *outstream, FILE *errstream)
|
||||
{
|
||||
int handle_fd;
|
||||
int stream_fd;
|
||||
HANDLE osfh;
|
||||
|
||||
DBUG_ASSERT(filename && (outstream || errstream));
|
||||
|
||||
if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||
FILE_SHARE_DELETE, NULL,
|
||||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
|
||||
NULL)) == INVALID_HANDLE_VALUE)
|
||||
return TRUE;
|
||||
|
||||
if ((handle_fd= _open_osfhandle((intptr_t)osfh,
|
||||
_O_APPEND | _O_TEXT)) == -1)
|
||||
{
|
||||
CloseHandle(osfh);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (outstream)
|
||||
{
|
||||
stream_fd= _fileno(outstream);
|
||||
if (_dup2(handle_fd, stream_fd) < 0)
|
||||
{
|
||||
CloseHandle(osfh);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (errstream)
|
||||
{
|
||||
stream_fd= _fileno(errstream);
|
||||
if (_dup2(handle_fd, stream_fd) < 0)
|
||||
{
|
||||
CloseHandle(osfh);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
_close(handle_fd);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||
FILE *outstream, FILE *errstream)
|
||||
{
|
||||
if (outstream && !freopen(filename, "a+", outstream))
|
||||
return TRUE;
|
||||
|
||||
if (errstream && !freopen(filename, "a+", errstream))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Unfortunately, there seems to be no good way
|
||||
to restore the original streams upon failure.
|
||||
*/
|
||||
static bool redirect_std_streams(const char *file)
|
||||
{
|
||||
if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr))
|
||||
{
|
||||
setbuf(stderr, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
if (reopen_fstreams(file, stdout, stderr))
|
||||
return TRUE;
|
||||
|
||||
return TRUE;
|
||||
setbuf(stderr, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool flush_error_log()
|
||||
{
|
||||
bool result=0;
|
||||
bool result= 0;
|
||||
if (opt_error_log)
|
||||
{
|
||||
char err_renamed[FN_REFLEN], *end;
|
||||
end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
|
||||
strmov(end, "-old");
|
||||
VOID(pthread_mutex_lock(&LOCK_error_log));
|
||||
#ifdef __WIN__
|
||||
char err_temp[FN_REFLEN+5];
|
||||
/*
|
||||
On Windows is necessary a temporary file for to rename
|
||||
the current error file.
|
||||
*/
|
||||
strxmov(err_temp, err_renamed,"-tmp",NullS);
|
||||
(void) my_delete(err_temp, MYF(0));
|
||||
if (freopen(err_temp,"a+",stdout))
|
||||
{
|
||||
int fd;
|
||||
size_t bytes;
|
||||
uchar buf[IO_SIZE];
|
||||
|
||||
freopen(err_temp,"a+",stderr);
|
||||
setbuf(stderr, NULL);
|
||||
(void) my_delete(err_renamed, MYF(0));
|
||||
my_rename(log_error_file,err_renamed,MYF(0));
|
||||
redirect_std_streams(log_error_file);
|
||||
|
||||
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
|
||||
{
|
||||
while ((bytes= my_read(fd, buf, IO_SIZE, MYF(0))) &&
|
||||
bytes != MY_FILE_ERROR)
|
||||
my_fwrite(stderr, buf, bytes, MYF(0));
|
||||
my_close(fd, MYF(0));
|
||||
}
|
||||
(void) my_delete(err_temp, MYF(0));
|
||||
}
|
||||
else
|
||||
result= 1;
|
||||
#else
|
||||
my_rename(log_error_file,err_renamed,MYF(0));
|
||||
if (redirect_std_streams(log_error_file))
|
||||
result= 1;
|
||||
#endif
|
||||
if (redirect_std_streams(log_error_file))
|
||||
result= 1;
|
||||
VOID(pthread_mutex_unlock(&LOCK_error_log));
|
||||
}
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void MYSQL_BIN_LOG::signal_update()
|
||||
|
@ -199,6 +199,9 @@ typedef fp_except fp_except_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||
FILE *outstream, FILE *errstream);
|
||||
|
||||
inline void setup_fpu()
|
||||
{
|
||||
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
|
||||
@ -3821,13 +3824,15 @@ static int init_server_components()
|
||||
opt_error_log= 1; // Too long file name
|
||||
else
|
||||
{
|
||||
my_bool res;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (freopen(log_error_file, "a+", stdout))
|
||||
res= reopen_fstreams(log_error_file, stdout, stderr);
|
||||
#else
|
||||
res= reopen_fstreams(log_error_file, NULL, stderr);
|
||||
#endif
|
||||
{
|
||||
if (freopen(log_error_file, "a+", stderr))
|
||||
setbuf(stderr, NULL);
|
||||
}
|
||||
|
||||
if (!res)
|
||||
setbuf(stderr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4475,8 +4480,8 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
||||
#ifdef __WIN__
|
||||
if (!opt_console)
|
||||
{
|
||||
freopen(log_error_file,"a+",stdout);
|
||||
freopen(log_error_file,"a+",stderr);
|
||||
if (reopen_fstreams(log_error_file, stdout, stderr))
|
||||
unireg_abort(1);
|
||||
setbuf(stderr, NULL);
|
||||
FreeConsole(); // Remove window
|
||||
}
|
||||
|
@ -5526,7 +5526,11 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
|
||||
SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
|
||||
field_item, (Item*)(intptr)i, inv);
|
||||
if (inv)
|
||||
{
|
||||
tree= !tree ? tmp : tree_or(param, tree, tmp);
|
||||
if (tree == NULL)
|
||||
break;
|
||||
}
|
||||
else
|
||||
tree= tree_and(param, tree, tmp);
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len,
|
||||
n_points= wkb_get_uint(wkb, bo);
|
||||
proper_length= 4 + n_points * POINT_DATA_SIZE;
|
||||
|
||||
if (len < proper_length || res->reserve(proper_length))
|
||||
if (!n_points || len < proper_length || res->reserve(proper_length))
|
||||
return 0;
|
||||
|
||||
res->q_append(n_points);
|
||||
@ -746,7 +746,9 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
|
||||
if (len < 4)
|
||||
return 0;
|
||||
|
||||
n_linear_rings= wkb_get_uint(wkb, bo);
|
||||
if (!(n_linear_rings= wkb_get_uint(wkb, bo)))
|
||||
return 0;
|
||||
|
||||
if (res->reserve(4, 512))
|
||||
return 0;
|
||||
wkb+= 4;
|
||||
|
@ -2622,7 +2622,9 @@ public:
|
||||
|
||||
|
||||
class select_insert :public select_result_interceptor {
|
||||
public:
|
||||
protected:
|
||||
virtual int write_to_binlog(bool is_trans, int errcode);
|
||||
public:
|
||||
TABLE_LIST *table_list;
|
||||
TABLE *table;
|
||||
List<Item> *fields;
|
||||
@ -2658,6 +2660,8 @@ class select_create: public select_insert {
|
||||
MYSQL_LOCK *m_lock;
|
||||
/* m_lock or thd->extra_lock */
|
||||
MYSQL_LOCK **m_plock;
|
||||
|
||||
virtual int write_to_binlog(bool is_trans, int errcode);
|
||||
public:
|
||||
select_create (TABLE_LIST *table_arg,
|
||||
HA_CREATE_INFO *create_info_par,
|
||||
@ -2673,7 +2677,7 @@ public:
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
int binlog_show_create_table(TABLE **tables, uint count);
|
||||
int binlog_show_create_table(TABLE **tables, uint count, int errcode);
|
||||
void store_values(List<Item> &values);
|
||||
void send_error(uint errcode,const char *err);
|
||||
bool send_eof();
|
||||
|
@ -2961,6 +2961,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
we are fixing fields from insert list.
|
||||
*/
|
||||
lex->current_select= &lex->select_lex;
|
||||
|
||||
/* Errors during check_insert_fields() should not be ignored. */
|
||||
lex->current_select->no_error= FALSE;
|
||||
res= check_insert_fields(thd, table_list, *fields, values,
|
||||
!insert_into_view, &map) ||
|
||||
setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0);
|
||||
@ -3265,7 +3268,7 @@ bool select_insert::send_eof()
|
||||
|
||||
/*
|
||||
Write to binlog before commiting transaction. No statement will
|
||||
be written by the binlog_query() below in RBR mode. All the
|
||||
be written by the write_to_binlog() below in RBR mode. All the
|
||||
events are in the transaction cache and will be written when
|
||||
ha_autocommit_or_rollback() is issued below.
|
||||
*/
|
||||
@ -3277,9 +3280,8 @@ bool select_insert::send_eof()
|
||||
thd->clear_error();
|
||||
else
|
||||
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
|
||||
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
|
||||
thd->query(), thd->query_length(),
|
||||
trans_table, FALSE, errcode))
|
||||
|
||||
if (write_to_binlog(trans_table, errcode))
|
||||
{
|
||||
table->file->ha_release_auto_increment();
|
||||
DBUG_RETURN(1);
|
||||
@ -3353,9 +3355,7 @@ void select_insert::abort() {
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
|
||||
/* error of writing binary log is ignored */
|
||||
(void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
|
||||
thd->query_length(),
|
||||
transactional_table, FALSE, errcode);
|
||||
write_to_binlog(transactional_table, errcode);
|
||||
}
|
||||
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
|
||||
thd->transaction.all.modified_non_trans_table= TRUE;
|
||||
@ -3370,6 +3370,103 @@ void select_insert::abort() {
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
int select_insert::write_to_binlog(bool is_trans, int errcode)
|
||||
{
|
||||
/* It is only for statement mode */
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
return 0;
|
||||
|
||||
return thd->binlog_query(THD::ROW_QUERY_TYPE,
|
||||
thd->query(), thd->query_length(),
|
||||
is_trans, FALSE, errcode);
|
||||
}
|
||||
|
||||
/* Override the select_insert::write_to_binlog */
|
||||
int select_create::write_to_binlog(bool is_trans, int errcode)
|
||||
{
|
||||
/* It is only for statement mode */
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
WL#5370 Keep the compatibility between 5.1 master and 5.5 slave.
|
||||
Binlog a 'INSERT ... SELECT' statement only when it has the option
|
||||
'IF NOT EXISTS' and the table already exists as a base table.
|
||||
*/
|
||||
if ((create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) &&
|
||||
create_info->table_existed)
|
||||
{
|
||||
String query;
|
||||
int result;
|
||||
|
||||
thd->binlog_start_trans_and_stmt();
|
||||
/* Binlog the CREATE TABLE IF NOT EXISTS statement */
|
||||
result= binlog_show_create_table(&table, 1, 0);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
uint db_len= strlen(create_table->db);
|
||||
uint table_len= strlen(create_info->alias);
|
||||
uint select_len= thd->query_length() - thd->lex->create_select_pos;
|
||||
uint field_len= (table->s->fields - (field - table->field)) *
|
||||
(MAX_FIELD_NAME + 3);
|
||||
|
||||
/*
|
||||
pre-allocating memory reduces the times of reallocating memory,
|
||||
when calling query.appen().
|
||||
40bytes is enough for other words("INSERT IGNORE INTO", etc.).
|
||||
*/
|
||||
if (query.real_alloc(40 + db_len + table_len + field_len + select_len))
|
||||
return 1;
|
||||
|
||||
if (thd->lex->create_select_in_comment)
|
||||
query.append(STRING_WITH_LEN("/*! "));
|
||||
if (thd->lex->ignore)
|
||||
query.append(STRING_WITH_LEN("INSERT IGNORE INTO `"));
|
||||
else if (thd->lex->duplicates == DUP_REPLACE)
|
||||
query.append(STRING_WITH_LEN("REPLACE INTO `"));
|
||||
else
|
||||
query.append(STRING_WITH_LEN("INSERT INTO `"));
|
||||
|
||||
query.append(create_table->db, db_len);
|
||||
query.append(STRING_WITH_LEN("`.`"));
|
||||
query.append(create_info->alias, table_len);
|
||||
query.append(STRING_WITH_LEN("` "));
|
||||
|
||||
/*
|
||||
The insert items.
|
||||
Field is the the rightmost columns that the rows are inster in.
|
||||
*/
|
||||
query.append(STRING_WITH_LEN("("));
|
||||
for (Field **f= field ; *f ; f++)
|
||||
{
|
||||
if (f != field)
|
||||
query.append(STRING_WITH_LEN(","));
|
||||
|
||||
query.append(STRING_WITH_LEN("`"));
|
||||
query.append((*f)->field_name, strlen((*f)->field_name));
|
||||
query.append(STRING_WITH_LEN("`"));
|
||||
}
|
||||
query.append(STRING_WITH_LEN(") "));
|
||||
|
||||
/* The SELECT clause*/
|
||||
DBUG_ASSERT(thd->lex->create_select_pos);
|
||||
if (thd->lex->create_select_start_with_brace)
|
||||
query.append(STRING_WITH_LEN("("));
|
||||
if (query.append(thd->query() + thd->lex->create_select_pos, select_len))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
Avoid to use thd->binlog_query() twice, otherwise it will print the unsafe
|
||||
warning twice.
|
||||
*/
|
||||
Query_log_event ev(thd, query.c_ptr_safe(), query.length(), is_trans,
|
||||
FALSE, errcode);
|
||||
return mysql_bin_log.write(&ev);
|
||||
}
|
||||
else
|
||||
return select_insert::write_to_binlog(is_trans, errcode);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
CREATE TABLE (SELECT) ...
|
||||
@ -3610,7 +3707,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
!table->s->tmp_table &&
|
||||
!ptr->get_create_info()->table_existed)
|
||||
{
|
||||
if (int error= ptr->binlog_show_create_table(tables, count))
|
||||
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
|
||||
if (int error= ptr->binlog_show_create_table(tables, count, errcode))
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
@ -3651,7 +3749,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
||||
create_table->table_name);
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
binlog_show_create_table(&(create_table->table), 1);
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
|
||||
binlog_show_create_table(&(create_table->table), 1, errcode);
|
||||
}
|
||||
table= create_table->table;
|
||||
}
|
||||
else
|
||||
@ -3719,10 +3820,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
}
|
||||
|
||||
int
|
||||
select_create::binlog_show_create_table(TABLE **tables, uint count)
|
||||
select_create::binlog_show_create_table(TABLE **tables, uint count, int errcode)
|
||||
{
|
||||
/*
|
||||
Note 1: In RBR mode, we generate a CREATE TABLE statement for the
|
||||
Note 1: We generate a CREATE TABLE statement for the
|
||||
created table by calling store_create_info() (behaves as SHOW
|
||||
CREATE TABLE). In the event of an error, nothing should be
|
||||
written to the binary log, even if the table is non-transactional;
|
||||
@ -3738,7 +3839,6 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
|
||||
schema that will do a close_thread_tables(), destroying the
|
||||
statement transaction cache.
|
||||
*/
|
||||
DBUG_ASSERT(thd->current_stmt_binlog_row_based);
|
||||
DBUG_ASSERT(tables && *tables && count > 0);
|
||||
|
||||
char buf[2048];
|
||||
@ -3756,7 +3856,6 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
|
||||
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
|
||||
result= thd->binlog_query(THD::STMT_QUERY_TYPE,
|
||||
query.ptr(), query.length(),
|
||||
/* is_trans */ TRUE,
|
||||
|
@ -1817,6 +1817,23 @@ typedef struct st_lex : public Query_tables_list
|
||||
*/
|
||||
bool protect_against_global_read_lock;
|
||||
|
||||
/*
|
||||
The following three variables are used in 'CREATE TABLE IF NOT EXISTS ...
|
||||
SELECT' statement. They are used to binlog the statement.
|
||||
|
||||
create_select_start_with_brace will be set if there is a '(' before
|
||||
the first SELECT clause
|
||||
|
||||
create_select_pos records the relative position of the SELECT clause
|
||||
in the whole statement.
|
||||
|
||||
create_select_in_comment will be set if SELECT keyword is in conditional
|
||||
comment.
|
||||
*/
|
||||
bool create_select_start_with_brace;
|
||||
uint create_select_pos;
|
||||
bool create_select_in_comment;
|
||||
|
||||
st_lex();
|
||||
|
||||
virtual ~st_lex()
|
||||
|
@ -141,6 +141,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
bool transactional_table;
|
||||
DBUG_ENTER("mysql_load");
|
||||
|
||||
/*
|
||||
Bug #34283
|
||||
mysqlbinlog leaves tmpfile after termination if binlog contains
|
||||
load data infile, so in mixed mode we go to row-based for
|
||||
avoiding the problem.
|
||||
*/
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
read_file_from_client = 0; //server is always in the same process
|
||||
#endif
|
||||
|
@ -2717,6 +2717,25 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
TABLE_LIST *duplicate;
|
||||
create_table= lex->unlink_first_table(&link_to_local);
|
||||
|
||||
if (create_table->view)
|
||||
{
|
||||
if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_TABLE_EXISTS_ERROR,
|
||||
ER(ER_TABLE_EXISTS_ERROR),
|
||||
create_info.alias);
|
||||
my_ok(thd);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias);
|
||||
res= 1;
|
||||
}
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
|
||||
{
|
||||
update_non_unique_table_error(create_table, "CREATE", duplicate);
|
||||
|
@ -3030,12 +3030,12 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
||||
Allocate temporary space for the value of the tristate.
|
||||
This option will have a limited lifetime and is not used beyond
|
||||
server initialization.
|
||||
GET_ENUM value is an integer.
|
||||
GET_ENUM value is a unsigned long integer.
|
||||
*/
|
||||
options[0].value= options[1].value= (uchar **)alloc_root(mem_root,
|
||||
sizeof(int));
|
||||
*((uint*) options[0].value)= *((uint*) options[1].value)=
|
||||
(uint) options[0].def_value;
|
||||
sizeof(ulong));
|
||||
*((ulong*) options[0].value)= *((ulong*) options[1].value)=
|
||||
(ulong) options[0].def_value;
|
||||
|
||||
options+= 2;
|
||||
|
||||
@ -3319,7 +3319,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
Set plugin loading policy from option value. First element in the option
|
||||
list is always the <plugin name> option value.
|
||||
*/
|
||||
plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value;
|
||||
plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value;
|
||||
}
|
||||
|
||||
disable_plugin= (plugin_load_policy == PLUGIN_OFF);
|
||||
|
@ -2378,13 +2378,8 @@ JOIN::destroy()
|
||||
|
||||
cleanup(1);
|
||||
/* Cleanup items referencing temporary table columns */
|
||||
if (!tmp_all_fields3.is_empty())
|
||||
{
|
||||
List_iterator_fast<Item> it(tmp_all_fields3);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
item->cleanup();
|
||||
}
|
||||
cleanup_item_list(tmp_all_fields1);
|
||||
cleanup_item_list(tmp_all_fields3);
|
||||
if (exec_tmp_table1)
|
||||
free_tmp_table(thd, exec_tmp_table1);
|
||||
if (exec_tmp_table2)
|
||||
@ -2395,6 +2390,19 @@ JOIN::destroy()
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
void JOIN::cleanup_item_list(List<Item> &items) const
|
||||
{
|
||||
if (!items.is_empty())
|
||||
{
|
||||
List_iterator_fast<Item> it(items);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
item->cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
An entry point to single-unit select (a select without UNION).
|
||||
|
||||
@ -6819,6 +6827,8 @@ bool error_if_full_join(JOIN *join)
|
||||
{
|
||||
if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
|
||||
{
|
||||
/* This error should not be ignored. */
|
||||
join->select_lex->no_error= FALSE;
|
||||
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
|
||||
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
|
||||
return(1);
|
||||
@ -8875,10 +8885,10 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
|
||||
|
||||
/* Flatten nested joins that can be flattened. */
|
||||
TABLE_LIST *right_neighbor= NULL;
|
||||
bool fix_name_res= FALSE;
|
||||
li.rewind();
|
||||
while ((table= li++))
|
||||
{
|
||||
bool fix_name_res= FALSE;
|
||||
nested_join= table->nested_join;
|
||||
if (nested_join && !table->on_expr)
|
||||
{
|
||||
@ -12485,7 +12495,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
if (!end_of_records)
|
||||
{
|
||||
copy_fields(&join->tmp_table_param);
|
||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
||||
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
|
||||
#ifdef TO_BE_DELETED
|
||||
if (!table->uniques) // If not unique handling
|
||||
{
|
||||
@ -12591,7 +12603,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
memcpy(table->record[0]+key_part->offset, group->buff, 1);
|
||||
}
|
||||
init_tmptable_sum_functions(join->sum_funcs);
|
||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
||||
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
if ((error=table->file->ha_write_row(table->record[0])))
|
||||
{
|
||||
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
|
||||
@ -12626,7 +12639,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
|
||||
init_tmptable_sum_functions(join->sum_funcs);
|
||||
copy_fields(&join->tmp_table_param); // Groups are copied twice.
|
||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
||||
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
|
||||
if (!(error=table->file->ha_write_row(table->record[0])))
|
||||
join->send_records++; // New group
|
||||
@ -12713,7 +12727,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
if (idx < (int) join->send_group_parts)
|
||||
{
|
||||
copy_fields(&join->tmp_table_param);
|
||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
||||
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
if (join->procedure)
|
||||
@ -13010,6 +13025,34 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Find shortest key suitable for full table scan.
|
||||
|
||||
@param table Table to scan
|
||||
@param usable_keys Allowed keys
|
||||
|
||||
@note
|
||||
As far as
|
||||
1) clustered primary key entry data set is a set of all record
|
||||
fields (key fields and not key fields) and
|
||||
2) secondary index entry data is a union of its key fields and
|
||||
primary key fields (at least InnoDB and its derivatives don't
|
||||
duplicate primary key fields there, even if the primary and
|
||||
the secondary keys have a common subset of key fields),
|
||||
then secondary index entry data is always a subset of primary key entry.
|
||||
Unfortunately, key_info[nr].key_length doesn't show the length
|
||||
of key/pointer pair but a sum of key field lengths only, thus
|
||||
we can't estimate index IO volume comparing only this key_length
|
||||
value of secondary keys and clustered PK.
|
||||
So, try secondary keys first, and choose PK only if there are no
|
||||
usable secondary covering keys or found best secondary key include
|
||||
all table fields (i.e. same as PK):
|
||||
|
||||
@return
|
||||
MAX_KEY no suitable key found
|
||||
key index otherwise
|
||||
*/
|
||||
|
||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
||||
{
|
||||
uint best= MAX_KEY;
|
||||
@ -13022,23 +13065,6 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
||||
uint min_length= (uint) ~0;
|
||||
for (uint nr=0; nr < table->s->keys ; nr++)
|
||||
{
|
||||
/*
|
||||
As far as
|
||||
1) clustered primary key entry data set is a set of all record
|
||||
fields (key fields and not key fields) and
|
||||
2) secondary index entry data is a union of its key fields and
|
||||
primary key fields (at least InnoDB and its derivatives don't
|
||||
duplicate primary key fields there, even if the primary and
|
||||
the secondary keys have a common subset of key fields),
|
||||
then secondary index entry data is always a subset of primary key
|
||||
entry, and the PK is always longer.
|
||||
Unfortunately, key_info[nr].key_length doesn't show the length
|
||||
of key/pointer pair but a sum of key field lengths only, thus
|
||||
we can't estimate index IO volume comparing only this key_length
|
||||
value of seconday keys and clustered PK.
|
||||
So, try secondary keys first, and choose PK only if there are no
|
||||
usable secondary covering keys:
|
||||
*/
|
||||
if (nr == usable_clustered_pk)
|
||||
continue;
|
||||
if (usable_keys->is_set(nr))
|
||||
@ -13051,7 +13077,20 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
||||
}
|
||||
}
|
||||
}
|
||||
return best != MAX_KEY ? best : usable_clustered_pk;
|
||||
if (usable_clustered_pk != MAX_KEY)
|
||||
{
|
||||
/*
|
||||
If the primary key is clustered and found shorter key covers all table
|
||||
fields then primary key scan normally would be faster because amount of
|
||||
data to scan is the same but PK is clustered.
|
||||
It's safe to compare key parts with table fields since duplicate key
|
||||
parts aren't allowed.
|
||||
*/
|
||||
if (best == MAX_KEY ||
|
||||
table->key_info[best].key_parts >= table->s->fields)
|
||||
best= usable_clustered_pk;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15773,14 +15812,39 @@ update_sum_func(Item_sum **func_ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Copy result of functions to record in tmp_table. */
|
||||
/**
|
||||
Copy result of functions to record in tmp_table.
|
||||
|
||||
void
|
||||
copy_funcs(Item **func_ptr)
|
||||
Uses the thread pointer to check for errors in
|
||||
some of the val_xxx() methods called by the
|
||||
save_in_result_field() function.
|
||||
TODO: make the Item::val_xxx() return error code
|
||||
|
||||
@param func_ptr array of the function Items to copy to the tmp table
|
||||
@param thd pointer to the current thread for error checking
|
||||
@retval
|
||||
FALSE if OK
|
||||
@retval
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
bool
|
||||
copy_funcs(Item **func_ptr, const THD *thd)
|
||||
{
|
||||
Item *func;
|
||||
for (; (func = *func_ptr) ; func_ptr++)
|
||||
{
|
||||
func->save_in_result_field(1);
|
||||
/*
|
||||
Need to check the THD error state because Item::val_xxx() don't
|
||||
return error code, but can generate errors
|
||||
TODO: change it for a real status check when Item::val_xxx()
|
||||
are extended to return status code.
|
||||
*/
|
||||
if (thd->is_error())
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -577,6 +577,7 @@ private:
|
||||
*/
|
||||
bool implicit_grouping;
|
||||
bool make_simple_join(JOIN *join, TABLE *tmp_table);
|
||||
void cleanup_item_list(List<Item> &items) const;
|
||||
};
|
||||
|
||||
|
||||
@ -601,7 +602,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
List<Item> &new_list1, List<Item> &new_list2,
|
||||
uint elements, List<Item> &fields);
|
||||
void copy_fields(TMP_TABLE_PARAM *param);
|
||||
void copy_funcs(Item **func_ptr);
|
||||
bool copy_funcs(Item **func_ptr, const THD *thd);
|
||||
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
||||
int error, bool ignore_last_dupp_error);
|
||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
||||
|
@ -6930,13 +6930,16 @@ int finalize_schema_table(st_plugin_int *plugin)
|
||||
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
|
||||
DBUG_ENTER("finalize_schema_table");
|
||||
|
||||
if (schema_table && plugin->plugin->deinit)
|
||||
if (schema_table)
|
||||
{
|
||||
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
|
||||
if (plugin->plugin->deinit(NULL))
|
||||
if (plugin->plugin->deinit)
|
||||
{
|
||||
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
|
||||
plugin->name.str));
|
||||
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
|
||||
if (plugin->plugin->deinit(NULL))
|
||||
{
|
||||
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
|
||||
plugin->name.str));
|
||||
}
|
||||
}
|
||||
my_free(schema_table, MYF(0));
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
inline uint32 alloced_length() const { return Alloced_length;}
|
||||
inline char& operator [] (uint32 i) const { return Ptr[i]; }
|
||||
inline void length(uint32 len) { str_length=len ; }
|
||||
inline bool is_empty() { return (str_length == 0); }
|
||||
inline bool is_empty() const { return (str_length == 0); }
|
||||
inline void mark_as_const() { Alloced_length= 0;}
|
||||
inline const char *ptr() const { return Ptr; }
|
||||
inline char *c_ptr()
|
||||
|
@ -1199,56 +1199,6 @@ reopen_tables:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Implementation of the safe update options during UPDATE IGNORE. This syntax
|
||||
causes an UPDATE statement to ignore all errors. In safe update mode,
|
||||
however, we must never ignore the ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE. There
|
||||
is a special hook in my_message_sql that will otherwise delete all errors
|
||||
when the IGNORE option is specified.
|
||||
|
||||
In the future, all IGNORE handling should be used with this class and all
|
||||
traces of the hack outlined below should be removed.
|
||||
|
||||
- The parser detects IGNORE option and sets thd->lex->ignore= 1
|
||||
|
||||
- In JOIN::optimize, if this is set, then
|
||||
thd->lex->current_select->no_error gets set.
|
||||
|
||||
- In my_message_sql(), if the flag above is set then any error is
|
||||
unconditionally converted to a warning.
|
||||
|
||||
We are moving in the direction of using Internal_error_handler subclasses
|
||||
to do all such error tweaking, please continue this effort if new bugs
|
||||
appear.
|
||||
*/
|
||||
class Safe_dml_handler : public Internal_error_handler {
|
||||
|
||||
private:
|
||||
bool m_handled_error;
|
||||
|
||||
public:
|
||||
explicit Safe_dml_handler() : m_handled_error(FALSE) {}
|
||||
|
||||
bool handle_error(uint sql_errno,
|
||||
const char *message,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
THD *thd)
|
||||
{
|
||||
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR &&
|
||||
sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE)
|
||||
|
||||
{
|
||||
thd->main_da.set_error_status(thd, sql_errno, message);
|
||||
m_handled_error= TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool handled_error() { return m_handled_error; }
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
Setup multi-update handling and call SELECT to do the join
|
||||
*/
|
||||
@ -1278,11 +1228,6 @@ bool mysql_multi_update(THD *thd,
|
||||
|
||||
List<Item> total_list;
|
||||
|
||||
Safe_dml_handler handler;
|
||||
bool using_handler= thd->options & OPTION_SAFE_UPDATES;
|
||||
if (using_handler)
|
||||
thd->push_internal_handler(&handler);
|
||||
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
table_list, select_lex->with_wild,
|
||||
total_list,
|
||||
@ -1292,21 +1237,9 @@ bool mysql_multi_update(THD *thd,
|
||||
OPTION_SETUP_TABLES_DONE,
|
||||
result, unit, select_lex);
|
||||
|
||||
if (using_handler)
|
||||
{
|
||||
Internal_error_handler *top_handler;
|
||||
top_handler= thd->pop_internal_handler();
|
||||
DBUG_ASSERT(&handler == top_handler);
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error()));
|
||||
res|= thd->is_error();
|
||||
/*
|
||||
Todo: remove below code and make Safe_dml_handler do error processing
|
||||
instead. That way we can return the actual error instead of
|
||||
ER_UNKNOWN_ERROR.
|
||||
*/
|
||||
if (unlikely(res) && (!using_handler || !handler.handled_error()))
|
||||
if (unlikely(res))
|
||||
{
|
||||
/* If we had a another error reported earlier then this will be ignored */
|
||||
result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
|
||||
|
@ -1297,6 +1297,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
|
||||
%type <table>
|
||||
table_ident table_ident_nodb references xid
|
||||
table_ident_opt_wild
|
||||
|
||||
%type <simple_string>
|
||||
remember_name remember_end opt_ident opt_db text_or_password
|
||||
@ -3881,17 +3882,26 @@ create2a:
|
||||
create3 {}
|
||||
| opt_partitioning
|
||||
create_select ')'
|
||||
{ Select->set_braces(1);}
|
||||
{
|
||||
Select->set_braces(1);
|
||||
Lex->create_select_start_with_brace= TRUE;
|
||||
}
|
||||
union_opt {}
|
||||
;
|
||||
|
||||
create3:
|
||||
/* empty */ {}
|
||||
| opt_duplicate opt_as create_select
|
||||
{ Select->set_braces(0);}
|
||||
{
|
||||
Select->set_braces(0);
|
||||
Lex->create_select_start_with_brace= FALSE;
|
||||
}
|
||||
union_clause {}
|
||||
| opt_duplicate opt_as '(' create_select ')'
|
||||
{ Select->set_braces(1);}
|
||||
{
|
||||
Select->set_braces(1);
|
||||
Lex->create_select_start_with_brace= TRUE;
|
||||
}
|
||||
union_opt {}
|
||||
;
|
||||
|
||||
@ -4516,6 +4526,19 @@ create_select:
|
||||
lex->current_select->table_list.save_and_clear(&lex->save_list);
|
||||
mysql_init_select(lex);
|
||||
lex->current_select->parsing_place= SELECT_LIST;
|
||||
|
||||
if (lex->sql_command == SQLCOM_CREATE_TABLE &&
|
||||
(lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS))
|
||||
{
|
||||
Lex_input_stream *lip= YYLIP;
|
||||
|
||||
if (lex->spcont)
|
||||
lex->create_select_pos= lip->get_tok_start() -
|
||||
lex->sphead->m_tmp_query;
|
||||
else
|
||||
lex->create_select_pos= lip->get_tok_start() - lip->get_buf();
|
||||
lex->create_select_in_comment= (lip->in_comment == DISCARD_COMMENT);
|
||||
}
|
||||
}
|
||||
select_options select_item_list
|
||||
{
|
||||
@ -9600,7 +9623,7 @@ table_alias_ref_list:
|
||||
;
|
||||
|
||||
table_alias_ref:
|
||||
table_ident
|
||||
table_ident_opt_wild
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, $1, NULL,
|
||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||
@ -11383,6 +11406,21 @@ table_ident:
|
||||
}
|
||||
;
|
||||
|
||||
table_ident_opt_wild:
|
||||
ident opt_wild
|
||||
{
|
||||
$$= new Table_ident($1);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| ident '.' ident opt_wild
|
||||
{
|
||||
$$= new Table_ident(YYTHD, $1,$3,0);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
table_ident_nodb:
|
||||
ident
|
||||
{
|
||||
|
@ -2259,7 +2259,7 @@ my_tz_find(THD *thd, const String *name)
|
||||
DBUG_PRINT("enter", ("time zone name='%s'",
|
||||
name ? ((String *)name)->c_ptr_safe() : "NULL"));
|
||||
|
||||
if (!name)
|
||||
if (!name || name->is_empty())
|
||||
DBUG_RETURN(0);
|
||||
|
||||
VOID(pthread_mutex_lock(&tz_LOCK));
|
||||
|
@ -616,8 +616,7 @@ dict_table_get_on_id(
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
|
||||
|| trx->dict_operation_lock_mode == RW_X_LATCH) {
|
||||
if (trx->dict_operation_lock_mode == RW_X_LATCH) {
|
||||
|
||||
/* Note: An X latch implies that the transaction
|
||||
already owns the dictionary mutex. */
|
||||
@ -2140,7 +2139,7 @@ dict_foreign_add_to_cache(
|
||||
mem_heap_free(foreign->heap);
|
||||
}
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
return(DB_FOREIGN_NO_INDEX);
|
||||
}
|
||||
|
||||
for_in_cache->referenced_table = ref_table;
|
||||
@ -2184,7 +2183,7 @@ dict_foreign_add_to_cache(
|
||||
mem_heap_free(foreign->heap);
|
||||
}
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
return(DB_REFERENCING_NO_INDEX);
|
||||
}
|
||||
|
||||
for_in_cache->foreign_table = for_table;
|
||||
@ -3754,7 +3753,6 @@ dict_update_statistics_low(
|
||||
dictionary mutex */
|
||||
{
|
||||
dict_index_t* index;
|
||||
ulint size;
|
||||
ulint sum_of_index_sizes = 0;
|
||||
|
||||
if (table->ibd_file_missing) {
|
||||
@ -3770,14 +3768,6 @@ dict_update_statistics_low(
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have set a high innodb_force_recovery level, do not calculate
|
||||
statistics, as a badly corrupted index can cause a crash in it. */
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find out the sizes of the indexes and how many different values
|
||||
for the key they approximately have */
|
||||
|
||||
@ -3789,26 +3779,48 @@ dict_update_statistics_low(
|
||||
return;
|
||||
}
|
||||
|
||||
while (index) {
|
||||
size = btr_get_size(index, BTR_TOTAL_SIZE);
|
||||
|
||||
index->stat_index_size = size;
|
||||
do {
|
||||
if (UNIV_LIKELY
|
||||
(srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
|
||||
|| (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
|
||||
&& (index->type & DICT_CLUSTERED)))) {
|
||||
ulint size;
|
||||
size = btr_get_size(index, BTR_TOTAL_SIZE);
|
||||
|
||||
sum_of_index_sizes += size;
|
||||
index->stat_index_size = size;
|
||||
|
||||
size = btr_get_size(index, BTR_N_LEAF_PAGES);
|
||||
sum_of_index_sizes += size;
|
||||
|
||||
if (size == 0) {
|
||||
/* The root node of the tree is a leaf */
|
||||
size = 1;
|
||||
size = btr_get_size(index, BTR_N_LEAF_PAGES);
|
||||
|
||||
if (size == 0) {
|
||||
/* The root node of the tree is a leaf */
|
||||
size = 1;
|
||||
}
|
||||
|
||||
index->stat_n_leaf_pages = size;
|
||||
|
||||
btr_estimate_number_of_different_key_vals(index);
|
||||
} else {
|
||||
/* If we have set a high innodb_force_recovery
|
||||
level, do not calculate statistics, as a badly
|
||||
corrupted index can cause a crash in it.
|
||||
Initialize some bogus index cardinality
|
||||
statistics, so that the data can be queried in
|
||||
various means, also via secondary indexes. */
|
||||
ulint i;
|
||||
|
||||
sum_of_index_sizes++;
|
||||
index->stat_index_size = index->stat_n_leaf_pages = 1;
|
||||
|
||||
for (i = dict_index_get_n_unique(index); i; ) {
|
||||
index->stat_n_diff_key_vals[i--] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
index->stat_n_leaf_pages = size;
|
||||
|
||||
btr_estimate_number_of_different_key_vals(index);
|
||||
|
||||
index = dict_table_get_next_index(index);
|
||||
}
|
||||
} while (index);
|
||||
|
||||
index = dict_table_get_first_index(table);
|
||||
|
||||
|
@ -864,16 +864,27 @@ err_exit:
|
||||
|
||||
err = dict_load_indexes(table, heap);
|
||||
|
||||
/* Initialize table foreign_child value. Its value could be
|
||||
changed when dict_load_foreigns() is called below */
|
||||
table->fk_max_recusive_level = 0;
|
||||
|
||||
/* If the force recovery flag is set, we open the table irrespective
|
||||
of the error condition, since the user may want to dump data from the
|
||||
clustered index. However we load the foreign key information only if
|
||||
all indexes were loaded. */
|
||||
if (err == DB_SUCCESS) {
|
||||
err = dict_load_foreigns(table->name, TRUE);
|
||||
err = dict_load_foreigns(table->name, TRUE, TRUE);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
dict_table_remove_from_cache(table);
|
||||
table = NULL;
|
||||
}
|
||||
} else if (!srv_force_recovery) {
|
||||
dict_table_remove_from_cache(table);
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
table->fk_max_recusive_level = 0;
|
||||
#if 0
|
||||
if (err != DB_SUCCESS && table != NULL) {
|
||||
|
||||
@ -1095,8 +1106,12 @@ dict_load_foreign(
|
||||
/* out: DB_SUCCESS or error code */
|
||||
const char* id, /* in: foreign constraint id as a
|
||||
null-terminated string */
|
||||
ibool check_charsets)
|
||||
ibool check_charsets,
|
||||
/* in: TRUE=check charset compatibility */
|
||||
ibool check_recursive)
|
||||
/* in: Whether to record the foreign table
|
||||
parent count to avoid unlimited recursive
|
||||
load of chained foreign tables */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
dict_table_t* sys_foreign;
|
||||
@ -1110,6 +1125,8 @@ dict_load_foreign(
|
||||
ulint len;
|
||||
ulint n_fields_and_type;
|
||||
mtr_t mtr;
|
||||
dict_table_t* for_table;
|
||||
dict_table_t* ref_table;
|
||||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
@ -1194,11 +1211,54 @@ dict_load_foreign(
|
||||
|
||||
dict_load_foreign_cols(id, foreign);
|
||||
|
||||
/* If the foreign table is not yet in the dictionary cache, we
|
||||
have to load it so that we are able to make type comparisons
|
||||
in the next function call. */
|
||||
ref_table = dict_table_check_if_in_cache_low(
|
||||
foreign->referenced_table_name);
|
||||
|
||||
dict_table_get_low(foreign->foreign_table_name);
|
||||
/* We could possibly wind up in a deep recursive calls if
|
||||
we call dict_table_get_low() again here if there
|
||||
is a chain of tables concatenated together with
|
||||
foreign constraints. In such case, each table is
|
||||
both a parent and child of the other tables, and
|
||||
act as a "link" in such table chains.
|
||||
To avoid such scenario, we would need to check the
|
||||
number of ancesters the current table has. If that
|
||||
exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading
|
||||
the child table.
|
||||
Foreign constraints are loaded in a Breath First fashion,
|
||||
that is, the index on FOR_NAME is scanned first, and then
|
||||
index on REF_NAME. So foreign constrains in which
|
||||
current table is a child (foreign table) are loaded first,
|
||||
and then those constraints where current table is a
|
||||
parent (referenced) table.
|
||||
Thus we could check the parent (ref_table) table's
|
||||
reference count (fk_max_recusive_level) to know how deep the
|
||||
recursive call is. If the parent table (ref_table) is already
|
||||
loaded, and its fk_max_recusive_level is larger than
|
||||
DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading
|
||||
by skipping loading the child table. It will not affect foreign
|
||||
constraint check for DMLs since child table will be loaded
|
||||
at that time for the constraint check. */
|
||||
if (!ref_table
|
||||
|| ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) {
|
||||
|
||||
/* If the foreign table is not yet in the dictionary cache, we
|
||||
have to load it so that we are able to make type comparisons
|
||||
in the next function call. */
|
||||
|
||||
for_table = dict_table_get_low(foreign->foreign_table_name);
|
||||
|
||||
if (for_table && ref_table && check_recursive) {
|
||||
/* This is to record the longest chain of ancesters
|
||||
this table has, if the parent has more ancesters
|
||||
than this table has, record it after add 1 (for this
|
||||
parent */
|
||||
if (ref_table->fk_max_recusive_level
|
||||
>= for_table->fk_max_recusive_level) {
|
||||
for_table->fk_max_recusive_level =
|
||||
ref_table->fk_max_recusive_level + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that there may already be a foreign constraint object in
|
||||
the dictionary cache for this constraint: then the following
|
||||
@ -1223,6 +1283,8 @@ dict_load_foreigns(
|
||||
/*===============*/
|
||||
/* out: DB_SUCCESS or error code */
|
||||
const char* table_name, /* in: table name */
|
||||
ibool check_recursive,/* in: Whether to check recursive
|
||||
load of tables chained by FK */
|
||||
ibool check_charsets) /* in: TRUE=check charset
|
||||
compatibility */
|
||||
{
|
||||
@ -1324,7 +1386,7 @@ loop:
|
||||
|
||||
/* Load the foreign constraint definition to the dictionary cache */
|
||||
|
||||
err = dict_load_foreign(id, check_charsets);
|
||||
err = dict_load_foreign(id, check_charsets, check_recursive);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
btr_pcur_close(&pcur);
|
||||
@ -1352,6 +1414,11 @@ load_next_index:
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* Switch to scan index on REF_NAME, fk_max_recusive_level
|
||||
already been updated when scanning FOR_NAME index, no need to
|
||||
update again */
|
||||
check_recursive = FALSE;
|
||||
|
||||
goto start_load;
|
||||
}
|
||||
|
||||
|
@ -966,6 +966,8 @@ try_again:
|
||||
HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(name), space,
|
||||
0 == strcmp(name, space->name));
|
||||
if (space != NULL) {
|
||||
ibool success;
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Warning: trying to init to the"
|
||||
@ -1002,9 +1004,10 @@ try_again:
|
||||
|
||||
namesake_id = space->id;
|
||||
|
||||
mutex_exit(&(system->mutex));
|
||||
success = fil_space_free(namesake_id, FALSE);
|
||||
ut_a(success);
|
||||
|
||||
fil_space_free(namesake_id);
|
||||
mutex_exit(&(system->mutex));
|
||||
|
||||
goto try_again;
|
||||
}
|
||||
@ -1127,6 +1130,33 @@ fil_assign_new_space_id(void)
|
||||
return(id);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Check if the space id exists in the cache, complain to stderr if the
|
||||
space id cannot be found. */
|
||||
static
|
||||
fil_space_t*
|
||||
fil_space_search(
|
||||
/*=============*/
|
||||
/* out: file space instance*/
|
||||
ulint id) /* in: space id */
|
||||
{
|
||||
fil_space_t* space;
|
||||
|
||||
ut_ad(mutex_own(&fil_system->mutex));
|
||||
|
||||
HASH_SEARCH(hash, fil_system->spaces, id, space, space->id == id);
|
||||
|
||||
if (space == NULL) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: trying to remove tablespace %lu"
|
||||
" from the cache but\n"
|
||||
"InnoDB: it is not there.\n", (ulong) id);
|
||||
}
|
||||
|
||||
return(space);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Frees a space object from the tablespace memory cache. Closes the files in
|
||||
the chain but does not delete them. There must not be any pending i/o's or
|
||||
@ -1135,27 +1165,21 @@ flushes on the files. */
|
||||
ibool
|
||||
fil_space_free(
|
||||
/*===========*/
|
||||
/* out: TRUE if success */
|
||||
ulint id) /* in: space id */
|
||||
/* out: TRUE if success */
|
||||
ulint id, /* in: space id */
|
||||
ibool x_latched) /* in: TRUE if caller has space->latch
|
||||
in X mode */
|
||||
{
|
||||
fil_system_t* system = fil_system;
|
||||
fil_space_t* space;
|
||||
fil_space_t* namespace;
|
||||
fil_node_t* fil_node;
|
||||
|
||||
mutex_enter(&(system->mutex));
|
||||
ut_ad(mutex_own(&fil_system->mutex));
|
||||
|
||||
HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
|
||||
|
||||
if (!space) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: trying to remove tablespace %lu"
|
||||
" from the cache but\n"
|
||||
"InnoDB: it is not there.\n", (ulong) id);
|
||||
|
||||
mutex_exit(&(system->mutex));
|
||||
space = fil_space_search(id);
|
||||
|
||||
if (space == NULL) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
@ -1191,7 +1215,9 @@ fil_space_free(
|
||||
|
||||
ut_a(0 == UT_LIST_GET_LEN(space->chain));
|
||||
|
||||
mutex_exit(&(system->mutex));
|
||||
if (x_latched) {
|
||||
rw_lock_x_unlock(&space->latch);
|
||||
}
|
||||
|
||||
rw_lock_free(&(space->latch));
|
||||
|
||||
@ -2048,6 +2074,19 @@ try_again:
|
||||
path = mem_strdup(space->name);
|
||||
|
||||
mutex_exit(&(system->mutex));
|
||||
|
||||
/* Important: We rely on the data dictionary mutex to ensure
|
||||
that a race is not possible here. It should serialize the tablespace
|
||||
drop/free. We acquire an X latch only to avoid a race condition
|
||||
when accessing the tablespace instance via:
|
||||
|
||||
fsp_get_available_space_in_free_extents().
|
||||
|
||||
There our main motivation is to reduce the contention on the
|
||||
dictionary mutex and not correctness. */
|
||||
|
||||
rw_lock_x_lock(&space->latch);
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/* Invalidate in the buffer pool all pages belonging to the
|
||||
tablespace. Since we have set space->is_being_deleted = TRUE, readahead
|
||||
@ -2060,7 +2099,11 @@ try_again:
|
||||
#endif
|
||||
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
|
||||
|
||||
success = fil_space_free(id);
|
||||
mutex_enter(&system->mutex);
|
||||
|
||||
success = fil_space_free(id, TRUE);
|
||||
|
||||
mutex_exit(&system->mutex);
|
||||
|
||||
if (success) {
|
||||
success = os_file_delete(path);
|
||||
@ -2068,6 +2111,8 @@ try_again:
|
||||
if (!success) {
|
||||
success = os_file_delete_if_exists(path);
|
||||
}
|
||||
} else {
|
||||
rw_lock_x_unlock(&space->latch);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
@ -4569,3 +4614,28 @@ fil_page_get_type(
|
||||
|
||||
return(mach_read_from_2(page + FIL_PAGE_TYPE));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Returns TRUE if a single-table tablespace is being deleted. */
|
||||
|
||||
ibool
|
||||
fil_tablespace_is_being_deleted(
|
||||
/*============================*/
|
||||
/* out: TRUE if space is being deleted */
|
||||
ulint id) /* in: space id */
|
||||
{
|
||||
fil_space_t* space;
|
||||
ibool is_being_deleted;
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
HASH_SEARCH(hash, fil_system->spaces, id, space, space->id == id);
|
||||
|
||||
ut_a(space != NULL);
|
||||
|
||||
is_being_deleted = space->is_being_deleted;
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
return(is_being_deleted);
|
||||
}
|
||||
|
@ -2842,12 +2842,61 @@ fsp_get_available_space_in_free_extents(
|
||||
|
||||
ut_ad(!mutex_own(&kernel_mutex));
|
||||
|
||||
/* The convoluted mutex acquire is to overcome latching order
|
||||
issues: The problem is that the fil_mutex is at a lower level
|
||||
than the tablespace latch and the buffer pool mutex. We have to
|
||||
first prevent any operations on the file system by acquiring the
|
||||
dictionary mutex. Then acquire the tablespace latch to obey the
|
||||
latching order and then release the dictionary mutex. That way we
|
||||
ensure that the tablespace instance can't be freed while we are
|
||||
examining its contents (see fil_space_free()).
|
||||
|
||||
However, there is one further complication, we release the fil_mutex
|
||||
when we need to invalidate the the pages in the buffer pool and we
|
||||
reacquire the fil_mutex when deleting and freeing the tablespace
|
||||
instance in fil0fil.c. Here we need to account for that situation
|
||||
too. */
|
||||
|
||||
dict_mutex_enter_for_mysql();
|
||||
|
||||
/* At this stage there is no guarantee that the tablespace even
|
||||
exists in the cache. */
|
||||
|
||||
if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
|
||||
|
||||
dict_mutex_exit_for_mysql();
|
||||
|
||||
return(ULLINT_UNDEFINED);
|
||||
}
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
latch = fil_space_get_latch(space);
|
||||
|
||||
/* This should ensure that the tablespace instance can't be freed
|
||||
by another thread. However, the tablespace pages can still be freed
|
||||
from the buffer pool. We need to check for that again. */
|
||||
|
||||
mtr_x_lock(latch, &mtr);
|
||||
|
||||
dict_mutex_exit_for_mysql();
|
||||
|
||||
/* At this point it is possible for the tablespace to be deleted and
|
||||
its pages removed from the buffer pool. We need to check for that
|
||||
situation. However, the tablespace instance can't be deleted because
|
||||
our latching above should ensure that. */
|
||||
|
||||
if (fil_tablespace_is_being_deleted(space)) {
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
return(ULLINT_UNDEFINED);
|
||||
}
|
||||
|
||||
/* From here on even if the user has dropped the tablespace, the
|
||||
pages _must_ still exist in the buffer pool and the tablespace
|
||||
instance _must be in the file system hash table. */
|
||||
|
||||
space_header = fsp_get_space_header(space, &mtr);
|
||||
|
||||
size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr);
|
||||
|
@ -707,7 +707,9 @@ convert_error_code_to_mysql(
|
||||
|
||||
return(HA_ERR_ROW_IS_REFERENCED);
|
||||
|
||||
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
|
||||
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT
|
||||
|| error == (int) DB_FOREIGN_NO_INDEX
|
||||
|| error == (int) DB_REFERENCING_NO_INDEX) {
|
||||
|
||||
return(HA_ERR_CANNOT_ADD_FOREIGN);
|
||||
|
||||
@ -763,6 +765,16 @@ convert_error_code_to_mysql(
|
||||
|
||||
my_error(ER_QUERY_INTERRUPTED, MYF(0));
|
||||
return(-1);
|
||||
} else if (error == DB_FOREIGN_EXCEED_MAX_CASCADE) {
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
HA_ERR_ROW_IS_REFERENCED,
|
||||
"InnoDB: Cannot delete/update "
|
||||
"rows with cascading foreign key "
|
||||
"constraints that exceed max "
|
||||
"depth of %d. Please "
|
||||
"drop extra constraints and try "
|
||||
"again", DICT_FK_MAX_RECURSIVE_LOAD);
|
||||
return(-1);
|
||||
} else {
|
||||
return(-1); // Unknown error
|
||||
}
|
||||
@ -2710,12 +2722,19 @@ ha_innobase::innobase_initialize_autoinc()
|
||||
err = row_search_max_autoinc(index, col_name, &read_auto_inc);
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
/* At the this stage we do not know the increment
|
||||
or the offset, so use a default increment of 1. */
|
||||
auto_inc = read_auto_inc + 1;
|
||||
break;
|
||||
case DB_SUCCESS: {
|
||||
ulonglong col_max_value;
|
||||
|
||||
col_max_value = innobase_get_int_col_max_value(field);
|
||||
|
||||
/* At the this stage we do not know the increment
|
||||
nor the offset, so use a default increment of 1. */
|
||||
|
||||
auto_inc = innobase_next_autoinc(
|
||||
read_auto_inc, 1, 1, col_max_value);
|
||||
|
||||
break;
|
||||
}
|
||||
case DB_RECORD_NOT_FOUND:
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: MySQL and InnoDB data "
|
||||
@ -2941,8 +2960,6 @@ retry:
|
||||
/* Init table lock structure */
|
||||
thr_lock_data_init(&share->lock,&lock,(void*) 0);
|
||||
|
||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
||||
|
||||
/* Only if the table has an AUTOINC column. */
|
||||
if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
|
||||
dict_table_autoinc_lock(prebuilt->table);
|
||||
@ -2959,6 +2976,8 @@ retry:
|
||||
dict_table_autoinc_unlock(prebuilt->table);
|
||||
}
|
||||
|
||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -6099,6 +6118,8 @@ ha_innobase::rename_table(
|
||||
innobase_commit_low(trx);
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
switch (error) {
|
||||
case DB_DUPLICATE_KEY:
|
||||
/* Add a special case to handle the Duplicated Key error
|
||||
and return DB_ERROR instead.
|
||||
This is to avoid a possible SIGSEGV error from mysql error
|
||||
@ -6111,10 +6132,28 @@ ha_innobase::rename_table(
|
||||
the dup key error here is due to an existing table whose name
|
||||
is the one we are trying to rename to) and return the generic
|
||||
error code. */
|
||||
if (error == (int) DB_DUPLICATE_KEY) {
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
|
||||
|
||||
error = DB_ERROR;
|
||||
break;
|
||||
case DB_FOREIGN_NO_INDEX:
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
HA_ERR_CANNOT_ADD_FOREIGN,
|
||||
"Alter or rename of table '%s' failed"
|
||||
" because the new table is a child table"
|
||||
" in a FK relationship and it does not"
|
||||
" have an index that contains foreign"
|
||||
" keys as its prefix columns.", norm_to);
|
||||
break;
|
||||
case DB_REFERENCING_NO_INDEX:
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
HA_ERR_CANNOT_ADD_FOREIGN,
|
||||
"Alter or rename of table '%s' failed"
|
||||
" because the new table is a parent table"
|
||||
" in a FK relationship and it does not"
|
||||
" have an index that contains foreign"
|
||||
" keys as its prefix columns.", norm_to);
|
||||
break;
|
||||
}
|
||||
|
||||
error = convert_error_code_to_mysql(error, NULL);
|
||||
@ -6343,8 +6382,6 @@ ha_innobase::info(
|
||||
dict_index_t* index;
|
||||
ha_rows rec_per_key;
|
||||
ib_longlong n_rows;
|
||||
ulong j;
|
||||
ulong i;
|
||||
char path[FN_REFLEN];
|
||||
os_file_stat_t stat_info;
|
||||
|
||||
@ -6354,16 +6391,6 @@ ha_innobase::info(
|
||||
statistics calculation on tables, because that may crash the
|
||||
server if an index is badly corrupted. */
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
|
||||
/* We return success (0) instead of HA_ERR_CRASHED,
|
||||
because we want MySQL to process this query and not
|
||||
stop, like it would do if it received the error code
|
||||
HA_ERR_CRASHED. */
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* We do not know if MySQL can call this function before calling
|
||||
external_lock(). To be safe, update the thd of the current table
|
||||
handle. */
|
||||
@ -6458,25 +6485,24 @@ ha_innobase::info(
|
||||
acquiring latches inside InnoDB, we do not call it if we
|
||||
are asked by MySQL to avoid locking. Another reason to
|
||||
avoid the call is that it uses quite a lot of CPU.
|
||||
See Bug#38185.
|
||||
We do not update delete_length if no locking is requested
|
||||
so the "old" value can remain. delete_length is initialized
|
||||
to 0 in the ha_statistics' constructor. */
|
||||
if (!(flag & HA_STATUS_NO_LOCK)) {
|
||||
See Bug#38185. */
|
||||
if (flag & HA_STATUS_NO_LOCK) {
|
||||
/* We do not update delete_length if no
|
||||
locking is requested so the "old" value can
|
||||
remain. delete_length is initialized to 0 in
|
||||
the ha_statistics' constructor. */
|
||||
} else if (UNIV_UNLIKELY
|
||||
(srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
|
||||
/* Avoid accessing the tablespace if
|
||||
innodb_crash_recovery is set to a high value. */
|
||||
stats.delete_length = 0;
|
||||
} else {
|
||||
ullint avail_space;
|
||||
|
||||
/* lock the data dictionary to avoid races with
|
||||
ibd_file_missing and tablespace_discarded */
|
||||
row_mysql_lock_data_dictionary(prebuilt->trx);
|
||||
|
||||
/* ib_table->space must be an existent tablespace */
|
||||
if (!ib_table->ibd_file_missing
|
||||
&& !ib_table->tablespace_discarded) {
|
||||
|
||||
stats.delete_length =
|
||||
fsp_get_available_space_in_free_extents(
|
||||
ib_table->space) * 1024;
|
||||
} else {
|
||||
avail_space = fsp_get_available_space_in_free_extents(
|
||||
ib_table->space);
|
||||
|
||||
if (avail_space == ULLINT_UNDEFINED) {
|
||||
THD* thd;
|
||||
|
||||
thd = ha_thd();
|
||||
@ -6493,9 +6519,9 @@ ha_innobase::info(
|
||||
ib_table->name);
|
||||
|
||||
stats.delete_length = 0;
|
||||
} else {
|
||||
stats.delete_length = avail_space * 1024;
|
||||
}
|
||||
|
||||
row_mysql_unlock_data_dictionary(prebuilt->trx);
|
||||
}
|
||||
|
||||
stats.check_time = 0;
|
||||
@ -6508,6 +6534,7 @@ ha_innobase::info(
|
||||
}
|
||||
|
||||
if (flag & HA_STATUS_CONST) {
|
||||
ulong i = 0;
|
||||
index = dict_table_get_first_index_noninline(ib_table);
|
||||
|
||||
if (prebuilt->clust_index_was_generated) {
|
||||
@ -6515,6 +6542,8 @@ ha_innobase::info(
|
||||
}
|
||||
|
||||
for (i = 0; i < table->s->keys; i++) {
|
||||
ulong j;
|
||||
|
||||
if (index == NULL) {
|
||||
sql_print_error("Table %s contains fewer "
|
||||
"indexes inside InnoDB than "
|
||||
@ -6571,6 +6600,11 @@ ha_innobase::info(
|
||||
}
|
||||
}
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (flag & HA_STATUS_ERRKEY) {
|
||||
ut_a(prebuilt->trx);
|
||||
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
|
||||
@ -6583,6 +6617,7 @@ ha_innobase::info(
|
||||
stats.auto_increment_value = innobase_peek_autoinc();
|
||||
}
|
||||
|
||||
func_exit:
|
||||
prebuilt->trx->op_info = (char*)"";
|
||||
|
||||
DBUG_RETURN(0);
|
||||
@ -7814,16 +7849,17 @@ ha_innobase::store_lock(
|
||||
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
|
||||
&& (sql_command == SQLCOM_INSERT_SELECT
|
||||
|| sql_command == SQLCOM_UPDATE
|
||||
|| sql_command == SQLCOM_CREATE_TABLE)) {
|
||||
|| sql_command == SQLCOM_CREATE_TABLE
|
||||
|| sql_command == SQLCOM_SET_OPTION)) {
|
||||
|
||||
/* If we either have innobase_locks_unsafe_for_binlog
|
||||
option set or this session is using READ COMMITTED
|
||||
isolation level and isolation level of the transaction
|
||||
is not set to serializable and MySQL is doing
|
||||
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
|
||||
CREATE ... SELECT... without FOR UPDATE or
|
||||
IN SHARE MODE in select, then we use consistent
|
||||
read for select. */
|
||||
CREATE ... SELECT... or SET ... = (SELECT ...)
|
||||
without FOR UPDATE or IN SHARE MODE in select,
|
||||
then we use consistent read for select. */
|
||||
|
||||
prebuilt->select_lock_type = LOCK_NONE;
|
||||
prebuilt->stored_select_lock_type = LOCK_NONE;
|
||||
|
@ -73,6 +73,15 @@ Created 5/24/1996 Heikki Tuuri
|
||||
a later version of the engine. */
|
||||
#define DB_INTERRUPTED 49 /* the query has been interrupted with
|
||||
"KILL QUERY N;" */
|
||||
#define DB_FOREIGN_EXCEED_MAX_CASCADE 50/* Foreign key constraint related
|
||||
cascading delete/update exceeds
|
||||
maximum allowed depth */
|
||||
#define DB_FOREIGN_NO_INDEX 51 /* the child (foreign) table does not
|
||||
have an index that contains the
|
||||
foreign keys as its prefix columns */
|
||||
#define DB_REFERENCING_NO_INDEX 52 /* the parent (referencing) table does
|
||||
not have an index that contains the
|
||||
foreign keys as its prefix columns */
|
||||
|
||||
/* The following are partial failure codes */
|
||||
#define DB_FAIL 1000
|
||||
|
@ -588,6 +588,22 @@ dict_table_is_comp_noninline(
|
||||
/* out: TRUE if table uses the
|
||||
compact page format */
|
||||
const dict_table_t* table); /* in: table */
|
||||
/*********************************************************************//**
|
||||
Obtain exclusive locks on all index trees of the table. This is to prevent
|
||||
accessing index trees while InnoDB is updating internal metadata for
|
||||
operations such as truncate tables. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_x_lock_indexes(
|
||||
/*======================*/
|
||||
dict_table_t* table); /* in: table */
|
||||
/*********************************************************************//**
|
||||
Release the exclusive locks on all index tree. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_x_unlock_indexes(
|
||||
/*========================*/
|
||||
dict_table_t* table); /* in: table */
|
||||
/************************************************************************
|
||||
Checks if a column is in the ordering columns of the clustered index of a
|
||||
table. Column prefixes are treated like whole columns. */
|
||||
|
@ -298,6 +298,48 @@ dict_table_is_comp(
|
||||
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Obtain exclusive locks on all index trees of the table. This is to prevent
|
||||
accessing index trees while InnoDB is updating internal metadata for
|
||||
operations such as truncate tables. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_x_lock_indexes(
|
||||
/*======================*/
|
||||
dict_table_t* table) /* in: table */
|
||||
{
|
||||
dict_index_t* index;
|
||||
|
||||
ut_a(table);
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
/* Loop through each index of the table and lock them */
|
||||
for (index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
rw_lock_x_lock(dict_index_get_lock(index));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Release the exclusive locks on all index tree. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_x_unlock_indexes(
|
||||
/*========================*/
|
||||
dict_table_t* table) /* in: table */
|
||||
{
|
||||
dict_index_t* index;
|
||||
|
||||
ut_a(table);
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
for (index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
rw_lock_x_unlock(dict_index_get_lock(index));
|
||||
}
|
||||
}
|
||||
/************************************************************************
|
||||
Gets the number of fields in the internal representation of an index,
|
||||
including fields added by the dictionary system. */
|
||||
|
@ -82,6 +82,8 @@ dict_load_foreigns(
|
||||
/*===============*/
|
||||
/* out: DB_SUCCESS or error code */
|
||||
const char* table_name, /* in: table name */
|
||||
ibool check_recursive,/* in: Whether to check recursive
|
||||
load of tables chained by FK */
|
||||
ibool check_charsets);/* in: TRUE=check charsets
|
||||
compatibility */
|
||||
/************************************************************************
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user