mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge from mysql-5.1-bugteam
This commit is contained in:
commit
37072db77b
62 changed files with 1435 additions and 284 deletions
|
@ -3063,3 +3063,4 @@ sql/share/slovak
|
||||||
sql/share/spanish
|
sql/share/spanish
|
||||||
sql/share/swedish
|
sql/share/swedish
|
||||||
sql/share/ukrainian
|
sql/share/ukrainian
|
||||||
|
libmysqld/examples/mysqltest.cc
|
||||||
|
|
|
@ -2,12 +2,5 @@ funcs_1.charset_collation_1 # depends on compile-time decisions
|
||||||
binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
|
binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
|
||||||
main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
|
main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
|
||||||
rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2
|
rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2
|
||||||
rpl.rpl_extraColmaster_myisam # Bug#46013: rpl_extraColmaster_myisam fails on pb2
|
|
||||||
rpl.rpl_stm_reset_slave # Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2
|
|
||||||
rpl.rpl_extraCol_myisam # Bug#40796
|
|
||||||
rpl.rpl_extraColmaster_innodb # Bug#40796
|
|
||||||
rpl.rpl_extraCol_innodb # Bug#40796
|
|
||||||
rpl_ndb.rpl_ndb_log # Bug#38998
|
rpl_ndb.rpl_ndb_log # Bug#38998
|
||||||
rpl.rpl_innodb_bug28430 # Bug#46029
|
rpl.rpl_innodb_bug28430 # Bug#46029
|
||||||
rpl.rpl_row_basic_3innodb # Bug#45243
|
|
||||||
rpl.rpl_truncate_3innodb # Bug#46030
|
|
||||||
|
|
35
mysql-test/include/rpl_loaddata_charset.inc
Normal file
35
mysql-test/include/rpl_loaddata_charset.inc
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
connection master;
|
||||||
|
--disable_warnings
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE DATABASE mysqltest CHARSET UTF8;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
|
||||||
|
|
||||||
|
if (!$LOAD_LOCAL)
|
||||||
|
{
|
||||||
|
LOAD DATA INFILE '../../std_data/loaddata_utf8.dat' INTO TABLE t
|
||||||
|
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
|
||||||
|
}
|
||||||
|
if ($LOAD_LOCAL)
|
||||||
|
{
|
||||||
|
LOAD DATA LOCAL INFILE './std_data/loaddata_utf8.dat' INTO TABLE t
|
||||||
|
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
save_master_pos;
|
||||||
|
echo ----------content on master----------;
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
echo ----------content on slave----------;
|
||||||
|
USE mysqltest;
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP DATABASE mysqltest;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
|
@ -462,3 +462,17 @@ select last_insert_id();
|
||||||
last_insert_id()
|
last_insert_id()
|
||||||
3
|
3
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# Bug#46616: Assertion `!table->auto_increment_field_not_null' on view
|
||||||
|
# manipulations
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
INSERT INTO t1 VALUES (1), (1);
|
||||||
|
CREATE TABLE t2 ( a INT AUTO_INCREMENT KEY );
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 AS SELECT a FROM t1;
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
UPDATE t2 SET a = 2;
|
||||||
|
SELECT a FROM t2;
|
||||||
|
a
|
||||||
|
2
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
2
mysql-test/r/disabled_partition.require
Normal file
2
mysql-test/r/disabled_partition.require
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Variable_name Value
|
||||||
|
have_partitioning DISABLED
|
|
@ -741,3 +741,19 @@ USE information_schema;
|
||||||
HANDLER COLUMNS OPEN;
|
HANDLER COLUMNS OPEN;
|
||||||
ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
|
ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
|
||||||
USE test;
|
USE test;
|
||||||
|
#
|
||||||
|
# BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 AS SELECT 1 AS f1;
|
||||||
|
HANDLER t1 OPEN;
|
||||||
|
TRUNCATE t1;
|
||||||
|
HANDLER t1 READ FIRST;
|
||||||
|
ERROR 42S02: Unknown table 't1' in HANDLER
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TEMPORARY TABLE t1 AS SELECT 1 AS f1;
|
||||||
|
HANDLER t1 OPEN;
|
||||||
|
TRUNCATE t1;
|
||||||
|
HANDLER t1 READ FIRST;
|
||||||
|
ERROR 42S02: Unknown table 't1' in HANDLER
|
||||||
|
DROP TABLE t1;
|
||||||
|
End of 5.1 tests
|
||||||
|
|
|
@ -2207,4 +2207,16 @@ ERROR HY000: Table storage engine for 'm1' doesn't have this option
|
||||||
DROP TABLE m1,t1,t2,t3,t4,t5,t6,t7;
|
DROP TABLE m1,t1,t2,t3,t4,t5,t6,t7;
|
||||||
SELECT 1 FROM m1;
|
SELECT 1 FROM m1;
|
||||||
ERROR 42S02: Table 'test.m1' doesn't exist
|
ERROR 42S02: Table 'test.m1' doesn't exist
|
||||||
|
#
|
||||||
|
# Bug #46614: Assertion in show_create_trigger()
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
CREATE TABLE t2(a int);
|
||||||
|
CREATE TABLE t3(a int) ENGINE = MERGE UNION(t1, t2);
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo();
|
||||||
|
SHOW CREATE TRIGGER tr1;
|
||||||
|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
|
||||||
|
tr1 CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo() latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
DROP TRIGGER tr1;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
|
|
@ -1,3 +1,48 @@
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
FLUSH TABLES;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR 42000: Unknown table engine 'partition'
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ERROR 42000: Unknown table engine 'partition'
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze Error Unknown table engine 'partition'
|
||||||
|
test.t1 analyze error Corrupt
|
||||||
|
CHECK TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check Error Unknown table engine 'partition'
|
||||||
|
test.t1 check error Corrupt
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize Error Unknown table engine 'partition'
|
||||||
|
test.t1 optimize error Corrupt
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair Error Unknown table engine 'partition'
|
||||||
|
test.t1 repair error Corrupt
|
||||||
|
ALTER TABLE t1 REPAIR PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair Error Unknown table engine 'partition'
|
||||||
|
test.t1 repair error Corrupt
|
||||||
|
ALTER TABLE t1 CHECK PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check Error Unknown table engine 'partition'
|
||||||
|
test.t1 check error Corrupt
|
||||||
|
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize Error Unknown table engine 'partition'
|
||||||
|
test.t1 optimize error Corrupt
|
||||||
|
ALTER TABLE t1 ANALYZE PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze Error Unknown table engine 'partition'
|
||||||
|
test.t1 analyze error Corrupt
|
||||||
|
ALTER TABLE t1 REBUILD PARTITION ALL;
|
||||||
|
ERROR 42000: Unknown table engine 'partition'
|
||||||
|
ALTER TABLE t1 ENGINE Memory;
|
||||||
|
ERROR 42000: Unknown table engine 'partition'
|
||||||
|
ALTER TABLE t1 ADD (new INT);
|
||||||
|
ERROR 42000: Unknown table engine 'partition'
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
firstname VARCHAR(25) NOT NULL,
|
firstname VARCHAR(25) NOT NULL,
|
||||||
lastname VARCHAR(25) NOT NULL,
|
lastname VARCHAR(25) NOT NULL,
|
||||||
|
|
|
@ -1,4 +1,55 @@
|
||||||
drop table if exists t1, t2;
|
drop table if exists t1, t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int NOT NULL,
|
||||||
|
b int NOT NULL);
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
a int NOT NULL,
|
||||||
|
b int NOT NULL,
|
||||||
|
INDEX(b)
|
||||||
|
)
|
||||||
|
PARTITION BY HASH(a) PARTITIONS 2;
|
||||||
|
INSERT INTO t1 VALUES (399, 22);
|
||||||
|
INSERT INTO t2 VALUES (1, 22), (1, 42);
|
||||||
|
INSERT INTO t2 SELECT 1, 399 FROM t2, t1
|
||||||
|
WHERE t1.b = t2.b;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
b varchar(10),
|
||||||
|
PRIMARY KEY (a)
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE (to_days(a)) (
|
||||||
|
PARTITION p1 VALUES LESS THAN (733407),
|
||||||
|
PARTITION pmax VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES ('2007-07-30 17:35:48', 'p1');
|
||||||
|
INSERT INTO t1 VALUES ('2009-07-14 17:35:55', 'pmax');
|
||||||
|
INSERT INTO t1 VALUES ('2009-09-21 17:31:42', 'pmax');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
2007-07-30 17:35:48 p1
|
||||||
|
2009-07-14 17:35:55 pmax
|
||||||
|
2009-09-21 17:31:42 pmax
|
||||||
|
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
|
||||||
|
PARTITION p3 VALUES LESS THAN (733969),
|
||||||
|
PARTITION pmax VALUES LESS THAN MAXVALUE);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
2007-07-30 17:35:48 p1
|
||||||
|
2009-07-14 17:35:55 pmax
|
||||||
|
2009-09-21 17:31:42 pmax
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`b` varchar(10) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`a`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
/*!50100 PARTITION BY RANGE (to_days(a))
|
||||||
|
(PARTITION p1 VALUES LESS THAN (733407) ENGINE = MyISAM,
|
||||||
|
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
|
||||||
|
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
|
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
|
||||||
ENGINE=MyISAM
|
ENGINE=MyISAM
|
||||||
PARTITION BY HASH (a);
|
PARTITION BY HASH (a);
|
||||||
|
|
93
mysql-test/r/partition_disabled.result
Normal file
93
mysql-test/r/partition_disabled.result
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
FLUSH TABLES;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 analyze error Corrupt
|
||||||
|
CHECK TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 check error Corrupt
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 optimize error Corrupt
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 repair error Corrupt
|
||||||
|
ALTER TABLE t1 REPAIR PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 repair error Corrupt
|
||||||
|
ALTER TABLE t1 CHECK PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 check error Corrupt
|
||||||
|
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 optimize error Corrupt
|
||||||
|
ALTER TABLE t1 ANALYZE PARTITION ALL;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
test.t1 analyze error Corrupt
|
||||||
|
ALTER TABLE t1 REBUILD PARTITION ALL;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
ALTER TABLE t1 ENGINE Memory;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
ALTER TABLE t1 ADD (new INT);
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
firstname VARCHAR(25) NOT NULL,
|
||||||
|
lastname VARCHAR(25) NOT NULL,
|
||||||
|
username VARCHAR(16) NOT NULL,
|
||||||
|
email VARCHAR(35),
|
||||||
|
joined DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY KEY(joined)
|
||||||
|
PARTITIONS 6;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
drop table t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
firstname VARCHAR(25) NOT NULL,
|
||||||
|
lastname VARCHAR(25) NOT NULL,
|
||||||
|
username VARCHAR(16) NOT NULL,
|
||||||
|
email VARCHAR(35),
|
||||||
|
joined DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE( YEAR(joined) ) (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1960),
|
||||||
|
PARTITION p1 VALUES LESS THAN (1970),
|
||||||
|
PARTITION p2 VALUES LESS THAN (1980),
|
||||||
|
PARTITION p3 VALUES LESS THAN (1990),
|
||||||
|
PARTITION p4 VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
drop table t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
CREATE TABLE t1 (id INT, purchased DATE)
|
||||||
|
PARTITION BY RANGE( YEAR(purchased) )
|
||||||
|
SUBPARTITION BY HASH( TO_DAYS(purchased) )
|
||||||
|
SUBPARTITIONS 2 (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1990),
|
||||||
|
PARTITION p1 VALUES LESS THAN (2000),
|
||||||
|
PARTITION p2 VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
|
||||||
|
drop table t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
|
||||||
|
insert into t1 values (''),(' '),('a'),('a '),('a ');
|
||||||
|
explain partitions select * from t1 where a='a ' OR a='a';
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 5 Using where
|
||||||
|
drop table t1;
|
|
@ -1495,9 +1495,9 @@ CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
|
||||||
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
|
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
|
||||||
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
||||||
aa SUM(b)
|
aa SUM(b)
|
||||||
2.000000000000000000000000000000 10
|
2.00000000000000000000000000000 10
|
||||||
3.000000000000000000000000000000 10
|
3.00000000000000000000000000000 10
|
||||||
4.000000000000000000000000000000 30
|
4.00000000000000000000000000000 30
|
||||||
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
||||||
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
|
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -1521,13 +1521,13 @@ f1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
|
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1264 Out of range value for column 'f1' at row 1
|
Note 1265 Data truncated for column 'f1' at row 1
|
||||||
DESC t1;
|
DESC t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
f1 decimal(65,30) NO 0.000000000000000000000000000000
|
f1 decimal(65,20) NO 0.00000000000000000000
|
||||||
SELECT f1 FROM t1;
|
SELECT f1 FROM t1;
|
||||||
f1
|
f1
|
||||||
99999999999999999999999999999999999.999999999999999999999999999999
|
123451234512345123451234512345123451234512345.67890678906789067891
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
||||||
1.01500000 * 1.01500000 * 0.99500000);
|
1.01500000 * 1.01500000 * 0.99500000);
|
||||||
|
@ -1595,7 +1595,7 @@ Warnings:
|
||||||
Note 1265 Data truncated for column 'my_col' at row 1
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
my_col decimal(65,30) NO 0.000000000000000000000000000000
|
my_col decimal(32,30) NO 0.000000000000000000000000000000
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
my_col
|
my_col
|
||||||
1.123456789123456789123456789123
|
1.123456789123456789123456789123
|
||||||
|
@ -1625,8 +1625,212 @@ Warnings:
|
||||||
Note 1265 Data truncated for column 'my_col' at row 1
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
my_col decimal(65,30) YES NULL
|
my_col decimal(30,30) YES NULL
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
my_col
|
my_col
|
||||||
0.012345687012345687012345687012
|
0.012345687012345687012345687012
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#45261: Crash, stored procedure + decimal
|
||||||
|
#
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
99999999999999999999999999999999999999999999999999999999999999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
99999999999999999999999999999999999999999999999999999999999999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
99999999999999999999999999999999999999999999999999999999999999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
99999999999999999999999999999999999999999999999999999999999999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,25) NO 0.0000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
1000000000000000000000000000000000000001.1000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(31,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
1.100000000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(31,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
1.100000000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(30,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
0.100000000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,20) NO 0.00000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
123456789012345678901234567890123456789012345.12345678901234567890
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
12345678901234567890123456789012345678901234567890123456789012345
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,0) NO 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
99999999999999999999999999999999999999999999999999999999999999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
|
||||||
|
AS c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(30,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
0.123456789012345678901234567890
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(33,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
123.123456789012345678901234567890
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,29) NO 0.00000000000000000000000000000
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
2.10000000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Test that the integer and decimal parts are properly calculated.
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 3
|
||||||
|
DESC t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(32,30) YES NULL
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 2
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 3
|
||||||
|
DESC t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(32,30) YES NULL
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'c1' at row 1
|
||||||
|
DESC t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(31,30) YES NULL
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
#
|
||||||
|
# Test that variables get maximum precision.
|
||||||
|
#
|
||||||
|
SET @decimal= 1.1;
|
||||||
|
CREATE TABLE t1 SELECT @decimal AS c1;
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
c1 decimal(65,30) YES NULL
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
1.100000000000000000000000000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
|
@ -3699,25 +3699,6 @@ SELECT * FROM v1 IGNORE INDEX (c2) WHERE c2=2;
|
||||||
ERROR 42000: Key 'c2' doesn't exist in table 'v1'
|
ERROR 42000: Key 'c2' doesn't exist in table 'v1'
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# -----------------------------------------------------------------
|
|
||||||
# -- Bug#40825: Error 1356 while selecting from a view
|
|
||||||
# -- with a "HAVING" clause though query works
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE TABLE t1 (c INT);
|
|
||||||
|
|
||||||
CREATE VIEW v1 (view_column) AS SELECT c AS alias FROM t1 HAVING alias;
|
|
||||||
SHOW CREATE VIEW v1;
|
|
||||||
View Create View character_set_client collation_connection
|
|
||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`c` AS `view_column` from `t1` having `view_column` latin1 latin1_swedish_ci
|
|
||||||
SELECT * FROM v1;
|
|
||||||
view_column
|
|
||||||
|
|
||||||
DROP VIEW v1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
# -- End of test case for Bug#40825
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #45806 crash when replacing into a view with a join!
|
# Bug #45806 crash when replacing into a view with a join!
|
||||||
#
|
#
|
||||||
|
@ -3829,6 +3810,25 @@ DROP VIEW v1;
|
||||||
DROP VIEW v2;
|
DROP VIEW v2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# -- End of test case for Bug#45806
|
# -- End of test case for Bug#45806
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# -- Bug#40825: Error 1356 while selecting from a view
|
||||||
|
# -- with a "HAVING" clause though query works
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c INT);
|
||||||
|
|
||||||
|
CREATE VIEW v1 (view_column) AS SELECT c AS alias FROM t1 HAVING alias;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`c` AS `view_column` from `t1` having `view_column` latin1 latin1_swedish_ci
|
||||||
|
SELECT * FROM v1;
|
||||||
|
view_column
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# -- End of test case for Bug#40825
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
# -- End of 5.0 tests.
|
# -- End of 5.0 tests.
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
|
|
3
mysql-test/std_data/loaddata_utf8.dat
Normal file
3
mysql-test/std_data/loaddata_utf8.dat
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
一二三
|
||||||
|
四五六
|
||||||
|
七八九
|
BIN
mysql-test/std_data/parts/t1.frm
Normal file
BIN
mysql-test/std_data/parts/t1.frm
Normal file
Binary file not shown.
|
@ -101,6 +101,8 @@ master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'dark blue 1' WHERE f
|
||||||
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (1 * 10),"brown")
|
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (1 * 10),"brown")
|
||||||
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
||||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
source include/diff_master_slave.inc;
|
||||||
|
source include/diff_master_slave.inc;
|
||||||
########################################################################
|
########################################################################
|
||||||
# Cleanup
|
# Cleanup
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
33
mysql-test/suite/rpl/r/rpl_create_if_not_exists.result
Normal file
33
mysql-test/suite/rpl/r/rpl_create_if_not_exists.result
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
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;
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
CREATE DATABASE IF NOT EXISTS mysqltest;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE IF NOT EXISTS t(c1 int);
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 LIKE t;
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t;
|
||||||
|
CREATE EVENT IF NOT EXISTS e
|
||||||
|
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
|
||||||
|
DO SELECT now();
|
||||||
|
DROP DATABASE mysqltest;
|
||||||
|
CREATE DATABASE IF NOT EXISTS mysqltest;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE IF NOT EXISTS t(c1 int);
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 LIKE t;
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t;
|
||||||
|
CREATE EVENT IF NOT EXISTS e
|
||||||
|
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
|
||||||
|
DO SELECT now();
|
||||||
|
SHOW TABLES in mysqltest;
|
||||||
|
Tables_in_mysqltest
|
||||||
|
t
|
||||||
|
t1
|
||||||
|
t2
|
||||||
|
SHOW EVENTS in mysqltest;
|
||||||
|
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
|
||||||
|
mysqltest e @ SYSTEM ONE TIME # NULL NULL NULL NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
|
@ -0,0 +1,22 @@
|
||||||
|
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;
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int);
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int);
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # DROP DATABASE IF EXISTS mysqltest
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int)
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int)
|
||||||
|
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
|
|
@ -35,3 +35,44 @@ C3BF
|
||||||
D0AA
|
D0AA
|
||||||
D0AA
|
D0AA
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
-------------test bug#45516------------------
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
CREATE DATABASE mysqltest CHARSET UTF8;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
|
||||||
|
LOAD DATA LOCAL INFILE './std_data/loaddata_utf8.dat' INTO TABLE t
|
||||||
|
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
|
||||||
|
----------content on master----------
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
hex(cl)
|
||||||
|
E4B880E4BA8CE4B889
|
||||||
|
E59B9BE4BA94E585AD
|
||||||
|
E4B883E585ABE4B99D
|
||||||
|
----------content on slave----------
|
||||||
|
USE mysqltest;
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
hex(cl)
|
||||||
|
E4B880E4BA8CE4B889
|
||||||
|
E59B9BE4BA94E585AD
|
||||||
|
E4B883E585ABE4B99D
|
||||||
|
DROP DATABASE mysqltest;
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
CREATE DATABASE mysqltest CHARSET UTF8;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
|
||||||
|
LOAD DATA INFILE '../../std_data/loaddata_utf8.dat' INTO TABLE t
|
||||||
|
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
|
||||||
|
----------content on master----------
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
hex(cl)
|
||||||
|
E4B880E4BA8CE4B889
|
||||||
|
E59B9BE4BA94E585AD
|
||||||
|
E4B883E585ABE4B99D
|
||||||
|
----------content on slave----------
|
||||||
|
USE mysqltest;
|
||||||
|
SELECT hex(cl) FROM t;
|
||||||
|
hex(cl)
|
||||||
|
E4B880E4BA8CE4B889
|
||||||
|
E59B9BE4BA94E585AD
|
||||||
|
E4B883E585ABE4B99D
|
||||||
|
DROP DATABASE mysqltest;
|
||||||
|
|
|
@ -125,14 +125,13 @@ while ($type)
|
||||||
connection master;
|
connection master;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
# Re-enable this after fixing BUG#46130
|
connection master;
|
||||||
#connection master;
|
let $diff_statement= SELECT * FROM t order by i;
|
||||||
#let $diff_statement= SELECT * FROM t order by i;
|
source include/diff_master_slave.inc;
|
||||||
#source include/diff_master_slave.inc;
|
|
||||||
|
|
||||||
#connection master;
|
connection master;
|
||||||
#let $diff_statement= SELECT * FROM n order by d, f;
|
let $diff_statement= SELECT * FROM n order by d, f;
|
||||||
#source include/diff_master_slave.inc;
|
source include/diff_master_slave.inc;
|
||||||
|
|
||||||
--echo ########################################################################
|
--echo ########################################################################
|
||||||
--echo # Cleanup
|
--echo # Cleanup
|
||||||
|
|
70
mysql-test/suite/rpl/t/rpl_create_if_not_exists.test
Normal file
70
mysql-test/suite/rpl/t/rpl_create_if_not_exists.test
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# BUG#45574:
|
||||||
|
# SP: CREATE DATABASE|TABLE IF NOT EXISTS not binlogged if routine exists.
|
||||||
|
#
|
||||||
|
# There is an inconsistency with DROP DATABASE|TABLE|EVENT IF EXISTS and
|
||||||
|
# CREATE DATABASE|TABLE|EVENT IF NOT EXISTS. DROP IF EXISTS statements are
|
||||||
|
# binlogged even if either the DB, TABLE or EVENT does not exist. In
|
||||||
|
# contrast, Only the CREATE EVENT IF NOT EXISTS is binlogged when the EVENT
|
||||||
|
# exists.
|
||||||
|
#
|
||||||
|
# This problem caused some of the tests to fail randomly on PB or PB2.
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
# Fixed this bug by adding calls to write_bin_log in:
|
||||||
|
# mysql_create_db
|
||||||
|
# mysql_create_table_no_lock
|
||||||
|
# mysql_create_like_table
|
||||||
|
# create_table_from_items
|
||||||
|
#
|
||||||
|
# Test is implemented as follows:
|
||||||
|
# i) test each "CREATE IF NOT EXISTS" (DDL), found in MySQL 5.1 manual
|
||||||
|
# exclude CREATE TEMPORARY TABLE, on existent objects;
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# rpl_create_tmp_table_if_not_exists.test tests CREATE TEMPORARY TABLE cases.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-data-definition.html
|
||||||
|
#
|
||||||
|
|
||||||
|
source include/master-slave.inc;
|
||||||
|
disable_warnings;
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
|
||||||
|
CREATE DATABASE IF NOT EXISTS mysqltest;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE IF NOT EXISTS t(c1 int);
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 LIKE t;
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t;
|
||||||
|
CREATE EVENT IF NOT EXISTS e
|
||||||
|
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
|
||||||
|
DO SELECT now();
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
#DROP database from slave.
|
||||||
|
#The database and all tables can be recreated in slave
|
||||||
|
#if binlog of the second CREATE command is recorded and sent from master to slave.
|
||||||
|
DROP DATABASE mysqltest;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
CREATE DATABASE IF NOT EXISTS mysqltest;
|
||||||
|
USE mysqltest;
|
||||||
|
CREATE TABLE IF NOT EXISTS t(c1 int);
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 LIKE t;
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t;
|
||||||
|
CREATE EVENT IF NOT EXISTS e
|
||||||
|
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
|
||||||
|
DO SELECT now();
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
SHOW TABLES in mysqltest;
|
||||||
|
#Execution time changes in each run. So we disregard it by calling replace_column.
|
||||||
|
replace_column 6 #;
|
||||||
|
SHOW EVENTS in mysqltest;
|
||||||
|
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
source include/master-slave-end.inc;
|
|
@ -0,0 +1,41 @@
|
||||||
|
# BUG#45574:
|
||||||
|
# SP: CREATE DATABASE|TABLE IF NOT EXISTS not binlogged if routine exists.
|
||||||
|
#
|
||||||
|
# There is an inconsistency with DROP DATABASE|TABLE|EVENT IF EXISTS and
|
||||||
|
# CREATE DATABASE|TABLE|EVENT IF NOT EXISTS. DROP IF EXISTS statements are
|
||||||
|
# binlogged even if either the DB, TABLE or EVENT does not exist. In
|
||||||
|
# contrast, Only the CREATE EVENT IF NOT EXISTS is binlogged when the EVENT
|
||||||
|
# exists.
|
||||||
|
#
|
||||||
|
# This problem caused some of the tests to fail randomly on PB or PB2.
|
||||||
|
#
|
||||||
|
# Test is implemented as follows:
|
||||||
|
#
|
||||||
|
# i) test each "CREATE TEMPORARY TABLE IF EXISTS" (DDL), found in MySQL
|
||||||
|
# 5.1 manual, on existent objects;
|
||||||
|
# ii) show binlog events;
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# rpl_create_if_not_exists.test tests other cases.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-data-definition.html
|
||||||
|
#
|
||||||
|
|
||||||
|
source include/master-slave.inc;
|
||||||
|
#CREATE TEMPORARY TABLE statements are not binlogged in row mode,
|
||||||
|
#So it must be test by itself.
|
||||||
|
source include/have_binlog_format_mixed_or_statement.inc;
|
||||||
|
disable_warnings;
|
||||||
|
|
||||||
|
DROP DATABASE IF EXISTS mysqltest;
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int);
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int);
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp;
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp;
|
||||||
|
source include/show_binlog_events.inc;
|
||||||
|
|
||||||
|
source include/master-slave-end.inc;
|
|
@ -31,3 +31,20 @@ select hex(a) from t1;
|
||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#45516
|
||||||
|
# When slave SQL thread executing LOAD DATA command, the
|
||||||
|
# thd->variables.collation_database was not set properly to the default
|
||||||
|
# database charset
|
||||||
|
#
|
||||||
|
|
||||||
|
echo -------------test bug#45516------------------;
|
||||||
|
|
||||||
|
# LOAD DATA INFILE
|
||||||
|
let $LOAD_LOCAL=1;
|
||||||
|
source include/rpl_loaddata_charset.inc;
|
||||||
|
|
||||||
|
# LOAD DATA LOCAL INFILE
|
||||||
|
let $LOAD_LOCAL=0;
|
||||||
|
source include/rpl_loaddata_charset.inc;
|
||||||
|
|
|
@ -324,3 +324,21 @@ insert into t1 values(null,0,0,0,null);
|
||||||
replace into t1 values(null,1,0,2,null);
|
replace into t1 values(null,1,0,2,null);
|
||||||
select last_insert_id();
|
select last_insert_id();
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#46616: Assertion `!table->auto_increment_field_not_null' on view
|
||||||
|
--echo # manipulations
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
INSERT INTO t1 VALUES (1), (1);
|
||||||
|
|
||||||
|
CREATE TABLE t2 ( a INT AUTO_INCREMENT KEY );
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
CREATE TABLE IF NOT EXISTS t2 AS SELECT a FROM t1;
|
||||||
|
|
||||||
|
UPDATE t2 SET a = 2;
|
||||||
|
|
||||||
|
SELECT a FROM t2;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
|
@ -19,3 +19,22 @@ let $other_engine_type= MEMORY;
|
||||||
let $other_handler_engine_type= MyISAM;
|
let $other_handler_engine_type= MyISAM;
|
||||||
|
|
||||||
--source include/handler.inc
|
--source include/handler.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 AS SELECT 1 AS f1;
|
||||||
|
HANDLER t1 OPEN;
|
||||||
|
TRUNCATE t1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
HANDLER t1 READ FIRST;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE t1 AS SELECT 1 AS f1;
|
||||||
|
HANDLER t1 OPEN;
|
||||||
|
TRUNCATE t1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
HANDLER t1 READ FIRST;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
|
|
@ -1622,4 +1622,15 @@ DROP TABLE m1,t1,t2,t3,t4,t5,t6,t7;
|
||||||
--error ER_NO_SUCH_TABLE
|
--error ER_NO_SUCH_TABLE
|
||||||
SELECT 1 FROM m1; # Should not hang!
|
SELECT 1 FROM m1; # Should not hang!
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #46614: Assertion in show_create_trigger()
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
CREATE TABLE t2(a int);
|
||||||
|
CREATE TABLE t3(a int) ENGINE = MERGE UNION(t1, t2);
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo();
|
||||||
|
SHOW CREATE TRIGGER tr1;
|
||||||
|
DROP TRIGGER tr1;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
|
@ -1,12 +1,35 @@
|
||||||
--disable_abort_on_error
|
--disable_abort_on_error
|
||||||
# Run this tets only when mysqld don't has partitioning
|
# Run this test only when mysqld don't has partitioning (not compiled with)
|
||||||
# the statements are not expected to work, just check that we
|
# the statements are not expected to work, just check that we
|
||||||
# can't crash the server
|
# can't crash the server
|
||||||
-- require r/not_partition.require
|
-- require r/not_partition.require
|
||||||
disable_query_log;
|
disable_query_log;
|
||||||
show variables like "have_partitioning";
|
show variables like "have_partitioning";
|
||||||
enable_query_log;
|
enable_query_log;
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#39893: Crash if select on a partitioned table,
|
||||||
|
# when partitioning is disabled
|
||||||
|
FLUSH TABLES;
|
||||||
|
--copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
|
||||||
|
SELECT * FROM t1;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
CHECK TABLE t1;
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
ALTER TABLE t1 REPAIR PARTITION ALL;
|
||||||
|
ALTER TABLE t1 CHECK PARTITION ALL;
|
||||||
|
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
|
||||||
|
ALTER TABLE t1 ANALYZE PARTITION ALL;
|
||||||
|
ALTER TABLE t1 REBUILD PARTITION ALL;
|
||||||
|
ALTER TABLE t1 ENGINE Memory;
|
||||||
|
ALTER TABLE t1 ADD (new INT);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--error ER_FEATURE_DISABLED
|
--error ER_FEATURE_DISABLED
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
|
|
|
@ -14,6 +14,53 @@
|
||||||
drop table if exists t1, t2;
|
drop table if exists t1, t2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#46639: 1030 (HY000): Got error 124 from storage engine on
|
||||||
|
# INSERT ... SELECT ...
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int NOT NULL,
|
||||||
|
b int NOT NULL);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
a int NOT NULL,
|
||||||
|
b int NOT NULL,
|
||||||
|
INDEX(b)
|
||||||
|
)
|
||||||
|
PARTITION BY HASH(a) PARTITIONS 2;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (399, 22);
|
||||||
|
INSERT INTO t2 VALUES (1, 22), (1, 42);
|
||||||
|
|
||||||
|
INSERT INTO t2 SELECT 1, 399 FROM t2, t1
|
||||||
|
WHERE t1.b = t2.b;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#46478: timestamp field incorrectly defaulted when partition is reorganized
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
b varchar(10),
|
||||||
|
PRIMARY KEY (a)
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE (to_days(a)) (
|
||||||
|
PARTITION p1 VALUES LESS THAN (733407),
|
||||||
|
PARTITION pmax VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES ('2007-07-30 17:35:48', 'p1');
|
||||||
|
INSERT INTO t1 VALUES ('2009-07-14 17:35:55', 'pmax');
|
||||||
|
INSERT INTO t1 VALUES ('2009-09-21 17:31:42', 'pmax');
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
|
||||||
|
PARTITION p3 VALUES LESS THAN (733969),
|
||||||
|
PARTITION pmax VALUES LESS THAN MAXVALUE);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#36001: Partitions: spelling and using some error messages
|
# Bug#36001: Partitions: spelling and using some error messages
|
||||||
#
|
#
|
||||||
|
|
1
mysql-test/t/partition_disabled-master.opt
Normal file
1
mysql-test/t/partition_disabled-master.opt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--loose-skip-partition
|
85
mysql-test/t/partition_disabled.test
Normal file
85
mysql-test/t/partition_disabled.test
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
--disable_abort_on_error
|
||||||
|
# Run this test only when mysqld has partitioning, but it is disabled.
|
||||||
|
# The statements are not expected to work, just check that we
|
||||||
|
# can't crash the server.
|
||||||
|
--require r/disabled_partition.require
|
||||||
|
--disable_query_log
|
||||||
|
show variables like "have_partitioning";
|
||||||
|
--enable_query_log
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#39893: Crash if select on a partitioned table,
|
||||||
|
# when partitioning is disabled
|
||||||
|
FLUSH TABLES;
|
||||||
|
--copy_file $MYSQLTEST_VARDIR/std_data/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
|
||||||
|
SELECT * FROM t1;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
CHECK TABLE t1;
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
ALTER TABLE t1 REPAIR PARTITION ALL;
|
||||||
|
ALTER TABLE t1 CHECK PARTITION ALL;
|
||||||
|
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
|
||||||
|
ALTER TABLE t1 ANALYZE PARTITION ALL;
|
||||||
|
ALTER TABLE t1 REBUILD PARTITION ALL;
|
||||||
|
ALTER TABLE t1 ENGINE Memory;
|
||||||
|
ALTER TABLE t1 ADD (new INT);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--error ER_OPTION_PREVENTS_STATEMENT
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
firstname VARCHAR(25) NOT NULL,
|
||||||
|
lastname VARCHAR(25) NOT NULL,
|
||||||
|
username VARCHAR(16) NOT NULL,
|
||||||
|
email VARCHAR(35),
|
||||||
|
joined DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY KEY(joined)
|
||||||
|
PARTITIONS 6;
|
||||||
|
|
||||||
|
--error ER_OPTION_PREVENTS_STATEMENT
|
||||||
|
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
|
||||||
|
|
||||||
|
--error ER_BAD_TABLE_ERROR
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--error ER_OPTION_PREVENTS_STATEMENT
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
firstname VARCHAR(25) NOT NULL,
|
||||||
|
lastname VARCHAR(25) NOT NULL,
|
||||||
|
username VARCHAR(16) NOT NULL,
|
||||||
|
email VARCHAR(35),
|
||||||
|
joined DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE( YEAR(joined) ) (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1960),
|
||||||
|
PARTITION p1 VALUES LESS THAN (1970),
|
||||||
|
PARTITION p2 VALUES LESS THAN (1980),
|
||||||
|
PARTITION p3 VALUES LESS THAN (1990),
|
||||||
|
PARTITION p4 VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
--error ER_BAD_TABLE_ERROR
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--error ER_OPTION_PREVENTS_STATEMENT
|
||||||
|
CREATE TABLE t1 (id INT, purchased DATE)
|
||||||
|
PARTITION BY RANGE( YEAR(purchased) )
|
||||||
|
SUBPARTITION BY HASH( TO_DAYS(purchased) )
|
||||||
|
SUBPARTITIONS 2 (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1990),
|
||||||
|
PARTITION p1 VALUES LESS THAN (2000),
|
||||||
|
PARTITION p2 VALUES LESS THAN MAXVALUE
|
||||||
|
);
|
||||||
|
--error ER_BAD_TABLE_ERROR
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# Create a table without partitions to test "EXPLAIN PARTITIONS"
|
||||||
|
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
|
||||||
|
insert into t1 values (''),(' '),('a'),('a '),('a ');
|
||||||
|
explain partitions select * from t1 where a='a ' OR a='a';
|
||||||
|
drop table t1;
|
|
@ -1286,3 +1286,137 @@ CREATE TABLE t1 SELECT 1 % .1234567891234567891234567891234567891234567891234567
|
||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#45261: Crash, stored procedure + decimal
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT
|
||||||
|
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
|
||||||
|
AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test that the integer and decimal parts are properly calculated.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
|
||||||
|
DESC t2;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
|
||||||
|
DESC t2;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(30,30));
|
||||||
|
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
||||||
|
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
|
||||||
|
DESC t2;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test that variables get maximum precision.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @decimal= 1.1;
|
||||||
|
CREATE TABLE t1 SELECT @decimal AS c1;
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
|
@ -3680,29 +3680,6 @@ SELECT * FROM v1 IGNORE INDEX (c2) WHERE c2=2;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo # -----------------------------------------------------------------
|
|
||||||
--echo # -- Bug#40825: Error 1356 while selecting from a view
|
|
||||||
--echo # -- with a "HAVING" clause though query works
|
|
||||||
--echo # -----------------------------------------------------------------
|
|
||||||
--echo
|
|
||||||
|
|
||||||
CREATE TABLE t1 (c INT);
|
|
||||||
|
|
||||||
--echo
|
|
||||||
|
|
||||||
CREATE VIEW v1 (view_column) AS SELECT c AS alias FROM t1 HAVING alias;
|
|
||||||
SHOW CREATE VIEW v1;
|
|
||||||
SELECT * FROM v1;
|
|
||||||
|
|
||||||
--echo
|
|
||||||
|
|
||||||
DROP VIEW v1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
--echo
|
|
||||||
--echo # -- End of test case for Bug#40825
|
|
||||||
--echo
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug #45806 crash when replacing into a view with a join!
|
--echo # Bug #45806 crash when replacing into a view with a join!
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -3735,6 +3712,29 @@ DROP TABLE t1;
|
||||||
|
|
||||||
--echo # -- End of test case for Bug#45806
|
--echo # -- End of test case for Bug#45806
|
||||||
|
|
||||||
|
--echo # -----------------------------------------------------------------
|
||||||
|
--echo # -- Bug#40825: Error 1356 while selecting from a view
|
||||||
|
--echo # -- with a "HAVING" clause though query works
|
||||||
|
--echo # -----------------------------------------------------------------
|
||||||
|
--echo
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c INT);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
|
||||||
|
CREATE VIEW v1 (view_column) AS SELECT c AS alias FROM t1 HAVING alias;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # -- End of test case for Bug#40825
|
||||||
|
--echo
|
||||||
|
|
||||||
--echo # -----------------------------------------------------------------
|
--echo # -----------------------------------------------------------------
|
||||||
--echo # -- End of 5.0 tests.
|
--echo # -- End of 5.0 tests.
|
||||||
--echo # -----------------------------------------------------------------
|
--echo # -----------------------------------------------------------------
|
||||||
|
|
|
@ -70,6 +70,18 @@ void my_net_local_init(NET *net)
|
||||||
|
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unused stub hook required for linking the client API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
C_MODE_START
|
||||||
|
|
||||||
|
void slave_io_thread_detach_vio()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
C_MODE_END
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Every resource, which we can fail to acquire, is allocated in init().
|
Every resource, which we can fail to acquire, is allocated in init().
|
||||||
|
|
|
@ -933,6 +933,9 @@ void end_server(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
init_sigpipe_variables
|
init_sigpipe_variables
|
||||||
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
|
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
|
||||||
|
#ifdef MYSQL_SERVER
|
||||||
|
slave_io_thread_detach_vio();
|
||||||
|
#endif
|
||||||
set_sigpipe(mysql);
|
set_sigpipe(mysql);
|
||||||
vio_delete(mysql->net.vio);
|
vio_delete(mysql->net.vio);
|
||||||
reset_sigpipe(mysql);
|
reset_sigpipe(mysql);
|
||||||
|
|
|
@ -33,3 +33,11 @@
|
||||||
|
|
||||||
#define mysql_server_init(a,b,c) 0
|
#define mysql_server_init(a,b,c) 0
|
||||||
|
|
||||||
|
#ifdef HAVE_REPLICATION
|
||||||
|
C_MODE_START
|
||||||
|
void slave_io_thread_detach_vio();
|
||||||
|
C_MODE_END
|
||||||
|
#else
|
||||||
|
#define slave_io_thread_detach_vio()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
85
sql/field.cc
85
sql/field.cc
|
@ -2485,12 +2485,97 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
|
||||||
{
|
{
|
||||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||||
|
DBUG_ASSERT(precision >= dec);
|
||||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
||||||
(dec <= DECIMAL_MAX_SCALE));
|
(dec <= DECIMAL_MAX_SCALE));
|
||||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a field to hold a decimal value from an item.
|
||||||
|
|
||||||
|
@remark The MySQL DECIMAL data type has a characteristic that needs to be
|
||||||
|
taken into account when deducing the type from a Item_decimal.
|
||||||
|
|
||||||
|
But first, let's briefly recap what is the new MySQL DECIMAL type:
|
||||||
|
|
||||||
|
The declaration syntax for a decimal is DECIMAL(M,D), where:
|
||||||
|
|
||||||
|
* M is the maximum number of digits (the precision).
|
||||||
|
It has a range of 1 to 65.
|
||||||
|
* D is the number of digits to the right of the decimal separator (the scale).
|
||||||
|
It has a range of 0 to 30 and must be no larger than M.
|
||||||
|
|
||||||
|
D and M are used to determine the storage requirements for the integer
|
||||||
|
and fractional parts of each value. The integer part is to the left of
|
||||||
|
the decimal separator and to the right is the fractional part. Hence:
|
||||||
|
|
||||||
|
M is the number of digits for the integer and fractional part.
|
||||||
|
D is the number of digits for the fractional part.
|
||||||
|
|
||||||
|
Consequently, M - D is the number of digits for the integer part. For
|
||||||
|
example, a DECIMAL(20,10) column has ten digits on either side of
|
||||||
|
the decimal separator.
|
||||||
|
|
||||||
|
The characteristic that needs to be taken into account is that the
|
||||||
|
backing type for Item_decimal is a my_decimal that has a higher
|
||||||
|
precision (DECIMAL_MAX_POSSIBLE_PRECISION, see my_decimal.h) than
|
||||||
|
DECIMAL.
|
||||||
|
|
||||||
|
Drawing a comparison between my_decimal and DECIMAL:
|
||||||
|
|
||||||
|
* M has a range of 1 to 81.
|
||||||
|
* D has a range of 0 to 81.
|
||||||
|
|
||||||
|
There can be a difference in range if the decimal contains a integer
|
||||||
|
part. This is because the fractional part must always be on a group
|
||||||
|
boundary, leaving at least one group for the integer part. Since each
|
||||||
|
group is 9 (DIG_PER_DEC1) digits and there are 9 (DECIMAL_BUFF_LENGTH)
|
||||||
|
groups, the fractional part is limited to 72 digits if there is at
|
||||||
|
least one digit in the integral part.
|
||||||
|
|
||||||
|
Although the backing type for a DECIMAL is also my_decimal, every
|
||||||
|
time a my_decimal is stored in a DECIMAL field, the precision and
|
||||||
|
scale are explicitly capped at 65 (DECIMAL_MAX_PRECISION) and 30
|
||||||
|
(DECIMAL_MAX_SCALE) digits, following my_decimal truncation procedure
|
||||||
|
(FIX_INTG_FRAC_ERROR).
|
||||||
|
*/
|
||||||
|
|
||||||
|
Field_new_decimal *
|
||||||
|
Field_new_decimal::new_decimal_field(const Item *item)
|
||||||
|
{
|
||||||
|
uint32 len;
|
||||||
|
uint intg= item->decimal_int_part(), scale= item->decimals;
|
||||||
|
|
||||||
|
DBUG_ASSERT(item->decimal_precision() >= item->decimals);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Employ a procedure along the lines of the my_decimal truncation process:
|
||||||
|
- If the integer part is equal to or bigger than the maximum precision:
|
||||||
|
Truncate integer part to fit and the fractional becomes zero.
|
||||||
|
- Otherwise:
|
||||||
|
Truncate fractional part to fit.
|
||||||
|
*/
|
||||||
|
if (intg >= DECIMAL_MAX_PRECISION)
|
||||||
|
{
|
||||||
|
intg= DECIMAL_MAX_PRECISION;
|
||||||
|
scale= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint room= min(DECIMAL_MAX_PRECISION - intg, DECIMAL_MAX_SCALE);
|
||||||
|
if (scale > room)
|
||||||
|
scale= room;
|
||||||
|
}
|
||||||
|
|
||||||
|
len= my_decimal_precision_to_length(intg + scale, scale, item->unsigned_flag);
|
||||||
|
|
||||||
|
return new Field_new_decimal(len, item->maybe_null, item->name, scale,
|
||||||
|
item->unsigned_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_new_decimal::reset(void)
|
int Field_new_decimal::reset(void)
|
||||||
{
|
{
|
||||||
store_value(&decimal_zero);
|
store_value(&decimal_zero);
|
||||||
|
|
|
@ -608,6 +608,10 @@ protected:
|
||||||
|
|
||||||
class Field_num :public Field {
|
class Field_num :public Field {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
The scale of the Field's value, i.e. the number of digits to the right
|
||||||
|
of the decimal point.
|
||||||
|
*/
|
||||||
const uint8 dec;
|
const uint8 dec;
|
||||||
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
|
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
|
||||||
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||||
|
@ -766,6 +770,11 @@ public:
|
||||||
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
|
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
|
||||||
const char *field_name_arg, uint8 dec_arg,
|
const char *field_name_arg, uint8 dec_arg,
|
||||||
bool unsigned_arg);
|
bool unsigned_arg);
|
||||||
|
/*
|
||||||
|
Create a field to hold a decimal value from an item.
|
||||||
|
Truncates the precision and/or scale if necessary.
|
||||||
|
*/
|
||||||
|
static Field_new_decimal *new_decimal_field(const Item *item);
|
||||||
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
|
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||||
Item_result result_type () const { return DECIMAL_RESULT; }
|
Item_result result_type () const { return DECIMAL_RESULT; }
|
||||||
|
|
|
@ -4414,17 +4414,6 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
|
||||||
break;
|
break;
|
||||||
case partition_index_first:
|
case partition_index_first:
|
||||||
DBUG_PRINT("info", ("index_first on partition %d", i));
|
DBUG_PRINT("info", ("index_first on partition %d", i));
|
||||||
/* MyISAM engine can fail if we call index_first() when indexes disabled */
|
|
||||||
/* that happens if the table is empty. */
|
|
||||||
/* Here we use file->stats.records instead of file->records() because */
|
|
||||||
/* file->records() is supposed to return an EXACT count, and it can be */
|
|
||||||
/* possibly slow. We don't need an exact number, an approximate one- from*/
|
|
||||||
/* the last ::info() call - is sufficient. */
|
|
||||||
if (file->stats.records == 0)
|
|
||||||
{
|
|
||||||
error= HA_ERR_END_OF_FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error= file->index_first(buf);
|
error= file->index_first(buf);
|
||||||
break;
|
break;
|
||||||
case partition_index_first_unordered:
|
case partition_index_first_unordered:
|
||||||
|
@ -4512,32 +4501,10 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
|
||||||
m_start_key.flag);
|
m_start_key.flag);
|
||||||
break;
|
break;
|
||||||
case partition_index_first:
|
case partition_index_first:
|
||||||
/* MyISAM engine can fail if we call index_first() when indexes disabled */
|
|
||||||
/* that happens if the table is empty. */
|
|
||||||
/* Here we use file->stats.records instead of file->records() because */
|
|
||||||
/* file->records() is supposed to return an EXACT count, and it can be */
|
|
||||||
/* possibly slow. We don't need an exact number, an approximate one- from*/
|
|
||||||
/* the last ::info() call - is sufficient. */
|
|
||||||
if (file->stats.records == 0)
|
|
||||||
{
|
|
||||||
error= HA_ERR_END_OF_FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error= file->index_first(rec_buf_ptr);
|
error= file->index_first(rec_buf_ptr);
|
||||||
reverse_order= FALSE;
|
reverse_order= FALSE;
|
||||||
break;
|
break;
|
||||||
case partition_index_last:
|
case partition_index_last:
|
||||||
/* MyISAM engine can fail if we call index_last() when indexes disabled */
|
|
||||||
/* that happens if the table is empty. */
|
|
||||||
/* Here we use file->stats.records instead of file->records() because */
|
|
||||||
/* file->records() is supposed to return an EXACT count, and it can be */
|
|
||||||
/* possibly slow. We don't need an exact number, an approximate one- from*/
|
|
||||||
/* the last ::info() call - is sufficient. */
|
|
||||||
if (file->stats.records == 0)
|
|
||||||
{
|
|
||||||
error= HA_ERR_END_OF_FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error= file->index_last(rec_buf_ptr);
|
error= file->index_last(rec_buf_ptr);
|
||||||
reverse_order= TRUE;
|
reverse_order= TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -895,7 +895,7 @@ class partition_info;
|
||||||
struct st_partition_iter;
|
struct st_partition_iter;
|
||||||
#define NOT_A_PARTITION_ID ((uint32)-1)
|
#define NOT_A_PARTITION_ID ((uint32)-1)
|
||||||
|
|
||||||
enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
|
enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
|
||||||
|
|
||||||
typedef struct st_ha_create_information
|
typedef struct st_ha_create_information
|
||||||
{
|
{
|
||||||
|
@ -918,14 +918,12 @@ typedef struct st_ha_create_information
|
||||||
uint options; /* OR of HA_CREATE_ options */
|
uint options; /* OR of HA_CREATE_ options */
|
||||||
uint merge_insert_method;
|
uint merge_insert_method;
|
||||||
uint extra_size; /* length of extra data segment */
|
uint extra_size; /* length of extra data segment */
|
||||||
/** Transactional or not. Unused; reserved for future versions. */
|
enum enum_ha_unused unused1;
|
||||||
enum ha_choice transactional;
|
|
||||||
bool table_existed; /* 1 in create if table existed */
|
bool table_existed; /* 1 in create if table existed */
|
||||||
bool frm_only; /* 1 if no ha_create_table() */
|
bool frm_only; /* 1 if no ha_create_table() */
|
||||||
bool varchar; /* 1 if table has a VARCHAR */
|
bool varchar; /* 1 if table has a VARCHAR */
|
||||||
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
|
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
|
||||||
/** Per-page checksums or not. Unused; reserved for future versions. */
|
enum enum_ha_unused unused2;
|
||||||
enum ha_choice page_checksum;
|
|
||||||
} HA_CREATE_INFO;
|
} HA_CREATE_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
25
sql/item.cc
25
sql/item.cc
|
@ -435,17 +435,26 @@ Item::Item(THD *thd, Item *item):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decimal precision of the item.
|
||||||
|
|
||||||
|
@remark The precision must not be capped as it can be used in conjunction
|
||||||
|
with Item::decimals to determine the size of the integer part when
|
||||||
|
constructing a decimal data type.
|
||||||
|
|
||||||
|
@see Item::decimal_int_part()
|
||||||
|
@see Item::decimals
|
||||||
|
*/
|
||||||
|
|
||||||
uint Item::decimal_precision() const
|
uint Item::decimal_precision() const
|
||||||
{
|
{
|
||||||
|
uint precision= max_length;
|
||||||
Item_result restype= result_type();
|
Item_result restype= result_type();
|
||||||
|
|
||||||
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
||||||
{
|
precision= my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
|
||||||
uint prec=
|
|
||||||
my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
|
return precision;
|
||||||
return min(prec, DECIMAL_MAX_PRECISION);
|
|
||||||
}
|
|
||||||
return min(max_length, DECIMAL_MAX_PRECISION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4902,9 +4911,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
|
||||||
switch (field_type()) {
|
switch (field_type()) {
|
||||||
case MYSQL_TYPE_DECIMAL:
|
case MYSQL_TYPE_DECIMAL:
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
|
field= Field_new_decimal::new_decimal_field(this);
|
||||||
Field::NONE, name, decimals, 0,
|
|
||||||
unsigned_flag);
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
|
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
|
||||||
|
|
|
@ -755,9 +755,10 @@ public:
|
||||||
virtual cond_result eq_cmp_result() const { return COND_OK; }
|
virtual cond_result eq_cmp_result() const { return COND_OK; }
|
||||||
inline uint float_length(uint decimals_par) const
|
inline uint float_length(uint decimals_par) const
|
||||||
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
|
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
|
||||||
|
/** Returns the uncapped decimal precision of this item. */
|
||||||
virtual uint decimal_precision() const;
|
virtual uint decimal_precision() const;
|
||||||
inline int decimal_int_part() const
|
inline int decimal_int_part() const
|
||||||
{ return my_decimal_int_part(decimal_precision(), decimals); }
|
{ return decimal_precision() - decimals; }
|
||||||
/*
|
/*
|
||||||
Returns true if this is constant (during query execution, i.e. its value
|
Returns true if this is constant (during query execution, i.e. its value
|
||||||
will not change until next fix_fields) and its value is known.
|
will not change until next fix_fields) and its value is known.
|
||||||
|
|
|
@ -2183,7 +2183,7 @@ uint Item_func_ifnull::decimal_precision() const
|
||||||
int arg1_int_part= args[1]->decimal_int_part();
|
int arg1_int_part= args[1]->decimal_int_part();
|
||||||
int max_int_part= max(arg0_int_part, arg1_int_part);
|
int max_int_part= max(arg0_int_part, arg1_int_part);
|
||||||
int precision= max_int_part + decimals;
|
int precision= max_int_part + decimals;
|
||||||
return min(precision, DECIMAL_MAX_PRECISION);
|
return precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2367,7 +2367,7 @@ uint Item_func_if::decimal_precision() const
|
||||||
int arg1_prec= args[1]->decimal_int_part();
|
int arg1_prec= args[1]->decimal_int_part();
|
||||||
int arg2_prec= args[2]->decimal_int_part();
|
int arg2_prec= args[2]->decimal_int_part();
|
||||||
int precision=max(arg1_prec,arg2_prec) + decimals;
|
int precision=max(arg1_prec,arg2_prec) + decimals;
|
||||||
return min(precision, DECIMAL_MAX_PRECISION);
|
return precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2775,7 +2775,7 @@ uint Item_func_case::decimal_precision() const
|
||||||
|
|
||||||
if (else_expr_num != -1)
|
if (else_expr_num != -1)
|
||||||
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
|
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
|
||||||
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
return max_int_part + decimals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -452,45 +452,8 @@ Field *Item_func::tmp_table_field(TABLE *table)
|
||||||
return make_string_field(table);
|
return make_string_field(table);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
field= Field_new_decimal::new_decimal_field(this);
|
||||||
uint8 dec= decimals;
|
|
||||||
uint8 intg= decimal_precision() - dec;
|
|
||||||
uint32 len= max_length;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
|
||||||
will always throw a warning. We must limit dec to
|
|
||||||
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (dec > 0)
|
|
||||||
{
|
|
||||||
int overflow;
|
|
||||||
|
|
||||||
dec= min(dec, DECIMAL_MAX_SCALE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the value still overflows the field with the corrected dec,
|
|
||||||
we'll throw out decimals rather than integers. This is still
|
|
||||||
bad and of course throws a truncation warning.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const int required_length=
|
|
||||||
my_decimal_precision_to_length(intg + dec, dec,
|
|
||||||
unsigned_flag);
|
|
||||||
|
|
||||||
overflow= required_length - len;
|
|
||||||
|
|
||||||
if (overflow > 0)
|
|
||||||
dec= max(0, dec - overflow); // too long, discard fract
|
|
||||||
else
|
|
||||||
/* Corrected value fits. */
|
|
||||||
len= required_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
// This case should never be chosen
|
// This case should never be chosen
|
||||||
|
@ -4781,6 +4744,19 @@ void Item_func_get_user_var::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint Item_func_get_user_var::decimal_precision() const
|
||||||
|
{
|
||||||
|
uint precision= max_length;
|
||||||
|
Item_result restype= result_type();
|
||||||
|
|
||||||
|
/* Default to maximum as the precision is unknown a priori. */
|
||||||
|
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
||||||
|
precision= DECIMAL_MAX_PRECISION;
|
||||||
|
|
||||||
|
return precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_get_user_var::const_item() const
|
bool Item_func_get_user_var::const_item() const
|
||||||
{
|
{
|
||||||
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
|
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
|
||||||
|
|
|
@ -1393,6 +1393,7 @@ public:
|
||||||
table_map used_tables() const
|
table_map used_tables() const
|
||||||
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
|
uint decimal_precision() const;
|
||||||
private:
|
private:
|
||||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||||
|
|
||||||
|
|
|
@ -517,8 +517,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
|
||||||
name, table->s, collation.collation);
|
name, table->s, collation.collation);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
field= new Field_new_decimal(max_length, maybe_null, name,
|
field= Field_new_decimal::new_decimal_field(this);
|
||||||
decimals, unsigned_flag);
|
|
||||||
break;
|
break;
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -2949,6 +2949,8 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
||||||
{
|
{
|
||||||
LEX_STRING new_db;
|
LEX_STRING new_db;
|
||||||
int expected_error,actual_error= 0;
|
int expected_error,actual_error= 0;
|
||||||
|
HA_CREATE_INFO db_options;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Colleagues: please never free(thd->catalog) in MySQL. This would
|
Colleagues: please never free(thd->catalog) in MySQL. This would
|
||||||
lead to bugs as here thd->catalog is a part of an alloced block,
|
lead to bugs as here thd->catalog is a part of an alloced block,
|
||||||
|
@ -2960,6 +2962,13 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
||||||
new_db.length= db_len;
|
new_db.length= db_len;
|
||||||
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
|
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
|
||||||
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
|
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Setting the character set and collation of the current database thd->db.
|
||||||
|
*/
|
||||||
|
load_db_opt_by_name(thd, thd->db, &db_options);
|
||||||
|
if (db_options.default_table_charset)
|
||||||
|
thd->db_charset= db_options.default_table_charset;
|
||||||
thd->variables.auto_increment_increment= auto_increment_increment;
|
thd->variables.auto_increment_increment= auto_increment_increment;
|
||||||
thd->variables.auto_increment_offset= auto_increment_offset;
|
thd->variables.auto_increment_offset= auto_increment_offset;
|
||||||
|
|
||||||
|
@ -3160,7 +3169,7 @@ compare_errors:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we expected a non-zero error code, and we don't get the same error
|
If we expected a non-zero error code, and we don't get the same error
|
||||||
code, and none of them should be ignored.
|
code, and it should be ignored or is related to a concurrency issue.
|
||||||
*/
|
*/
|
||||||
actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
|
actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
|
||||||
DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
|
DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
|
||||||
|
@ -3183,7 +3192,8 @@ Default database: '%s'. Query: '%s'",
|
||||||
thd->is_slave_error= 1;
|
thd->is_slave_error= 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
If we get the same error code as expected, or they should be ignored.
|
If we get the same error code as expected and it is not a concurrency
|
||||||
|
issue, or should be ignored.
|
||||||
*/
|
*/
|
||||||
else if ((expected_error == actual_error &&
|
else if ((expected_error == actual_error &&
|
||||||
!concurrency_error_code(expected_error)) ||
|
!concurrency_error_code(expected_error)) ||
|
||||||
|
@ -3193,6 +3203,14 @@ Default database: '%s'. Query: '%s'",
|
||||||
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
|
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
|
||||||
thd->killed= THD::NOT_KILLED;
|
thd->killed= THD::NOT_KILLED;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
If we expected a non-zero error code and get nothing and, it is a concurrency
|
||||||
|
issue or should be ignored.
|
||||||
|
*/
|
||||||
|
else if (expected_error && !actual_error &&
|
||||||
|
(concurrency_error_code(expected_error) ||
|
||||||
|
ignored_error_code(expected_error)))
|
||||||
|
ha_autocommit_or_rollback(thd, TRUE);
|
||||||
/*
|
/*
|
||||||
Other cases: mostly we expected no error and get one.
|
Other cases: mostly we expected no error and get one.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,10 +48,12 @@ C_MODE_END
|
||||||
digits * number of decimal digits in one our big digit - number of decimal
|
digits * number of decimal digits in one our big digit - number of decimal
|
||||||
digits in one our big digit decreased by 1 (because we always put decimal
|
digits in one our big digit decreased by 1 (because we always put decimal
|
||||||
point on the border of our big digits))
|
point on the border of our big digits))
|
||||||
|
|
||||||
|
This value is 65 due to historical reasons partly due to it being used
|
||||||
|
as the maximum allowed precision and not the actual maximum precision.
|
||||||
*/
|
*/
|
||||||
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
|
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
|
||||||
#define DECIMAL_MAX_SCALE 30
|
#define DECIMAL_MAX_SCALE 30
|
||||||
#define DECIMAL_NOT_SPECIFIED 31
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
maximum length of string representation (number of maximum decimal
|
maximum length of string representation (number of maximum decimal
|
||||||
|
@ -75,12 +77,6 @@ inline uint my_decimal_size(uint precision, uint scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline int my_decimal_int_part(uint precision, uint decimals)
|
|
||||||
{
|
|
||||||
return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
||||||
|
|
||||||
|
@ -184,7 +180,7 @@ inline uint my_decimal_length_to_precision(uint length, uint scale,
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
||||||
uint8 scale,
|
uint scale,
|
||||||
bool unsigned_flag)
|
bool unsigned_flag)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -196,7 +192,7 @@ inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
||||||
(unsigned_flag || !precision ? 0 : 1));
|
(unsigned_flag || !precision ? 0 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
|
inline uint32 my_decimal_precision_to_length(uint precision, uint scale,
|
||||||
bool unsigned_flag)
|
bool unsigned_flag)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -8065,7 +8065,10 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
|
||||||
if (cur_quick->file->inited != handler::NONE)
|
if (cur_quick->file->inited != handler::NONE)
|
||||||
cur_quick->file->ha_index_end();
|
cur_quick->file->ha_index_end();
|
||||||
if (cur_quick->init() || cur_quick->reset())
|
if (cur_quick->init() || cur_quick->reset())
|
||||||
|
{
|
||||||
|
delete unique;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
|
@ -8073,13 +8076,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
|
||||||
if (result != HA_ERR_END_OF_FILE)
|
if (result != HA_ERR_END_OF_FILE)
|
||||||
{
|
{
|
||||||
cur_quick->range_end();
|
cur_quick->range_end();
|
||||||
|
delete unique;
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
|
{
|
||||||
|
delete unique;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* skip row if it will be retrieved by clustered PK scan */
|
/* skip row if it will be retrieved by clustered PK scan */
|
||||||
if (pk_quick_select && pk_quick_select->row_in_ranges())
|
if (pk_quick_select && pk_quick_select->row_in_ranges())
|
||||||
|
@ -8088,8 +8095,10 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
|
||||||
cur_quick->file->position(cur_quick->record);
|
cur_quick->file->position(cur_quick->record);
|
||||||
result= unique->unique_add((char*)cur_quick->file->ref);
|
result= unique->unique_add((char*)cur_quick->file->ref);
|
||||||
if (result)
|
if (result)
|
||||||
|
{
|
||||||
|
delete unique;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
28
sql/slave.cc
28
sql/slave.cc
|
@ -2010,9 +2010,6 @@ static int has_temporary_error(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("has_temporary_error");
|
DBUG_ENTER("has_temporary_error");
|
||||||
|
|
||||||
if (thd->is_fatal_error)
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
|
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
|
||||||
if (thd->main_da.is_error())
|
if (thd->main_da.is_error())
|
||||||
{
|
{
|
||||||
|
@ -3738,6 +3735,31 @@ void end_relay_log_info(Relay_log_info* rli)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Hook to detach the active VIO before closing a connection handle.
|
||||||
|
|
||||||
|
The client API might close the connection (and associated data)
|
||||||
|
in case it encounters a unrecoverable (network) error. This hook
|
||||||
|
is called from the client code before the VIO handle is deleted
|
||||||
|
allows the thread to detach the active vio so it does not point
|
||||||
|
to freed memory.
|
||||||
|
|
||||||
|
Other calls to THD::clear_active_vio throughout this module are
|
||||||
|
redundant due to the hook but are left in place for illustrative
|
||||||
|
purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C" void slave_io_thread_detach_vio()
|
||||||
|
{
|
||||||
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
|
THD *thd= current_thd;
|
||||||
|
if (thd->slave_thread)
|
||||||
|
thd->clear_active_vio();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to connect until successful or slave killed
|
Try to connect until successful or slave killed
|
||||||
|
|
||||||
|
|
|
@ -658,10 +658,8 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
|
||||||
}
|
}
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
|
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
|
||||||
if (!silent)
|
|
||||||
my_ok(thd);
|
|
||||||
error= 0;
|
error= 0;
|
||||||
goto exit;
|
goto not_silent;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -698,7 +696,8 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
|
||||||
happened. (This is a very unlikely senario)
|
happened. (This is a very unlikely senario)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_silent:
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
char *query;
|
char *query;
|
||||||
|
|
|
@ -1066,6 +1066,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
|
||||||
DBUG_ENTER("mysql_truncate");
|
DBUG_ENTER("mysql_truncate");
|
||||||
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
bzero((char*) &create_info,sizeof(create_info));
|
||||||
|
|
||||||
|
/* Remove tables from the HANDLER's hash. */
|
||||||
|
mysql_ha_rm_tables(thd, table_list, FALSE);
|
||||||
|
|
||||||
/* If it is a temporary table, close and regenerate it */
|
/* If it is a temporary table, close and regenerate it */
|
||||||
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
|
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -3392,25 +3392,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||||
bool not_used;
|
bool not_used;
|
||||||
DBUG_ENTER("create_table_from_items");
|
DBUG_ENTER("create_table_from_items");
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000););
|
|
||||||
|
|
||||||
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
|
||||||
create_table->table->db_stat)
|
|
||||||
{
|
|
||||||
/* Table already exists and was open at open_and_lock_tables() stage. */
|
|
||||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
|
||||||
{
|
|
||||||
create_info->table_existed= 1; // Mark that table existed
|
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
||||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
|
||||||
create_table->table_name);
|
|
||||||
DBUG_RETURN(create_table->table);
|
|
||||||
}
|
|
||||||
|
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_table.alias= 0;
|
tmp_table.alias= 0;
|
||||||
tmp_table.timestamp_field= 0;
|
tmp_table.timestamp_field= 0;
|
||||||
tmp_table.s= &share;
|
tmp_table.s= &share;
|
||||||
|
@ -3612,10 +3593,35 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||||
thd->binlog_start_trans_and_stmt();
|
thd->binlog_start_trans_and_stmt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(table= create_table_from_items(thd, create_info, create_table,
|
DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000););
|
||||||
alter_info, &values,
|
|
||||||
&extra_lock, hook_ptr)))
|
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||||
DBUG_RETURN(-1); // abort() deletes table
|
create_table->table->db_stat)
|
||||||
|
{
|
||||||
|
/* Table already exists and was open at open_and_lock_tables() stage. */
|
||||||
|
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||||
|
{
|
||||||
|
/* Mark that table existed */
|
||||||
|
create_info->table_existed= 1;
|
||||||
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
|
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);
|
||||||
|
table= create_table->table;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!(table= create_table_from_items(thd, create_info, create_table,
|
||||||
|
alter_info, &values,
|
||||||
|
&extra_lock, hook_ptr)))
|
||||||
|
/* abort() deletes table */
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
if (extra_lock)
|
if (extra_lock)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6077,6 +6077,9 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||||
lpt->pack_frm_len= 0;
|
lpt->pack_frm_len= 0;
|
||||||
thd->work_part_info= part_info;
|
thd->work_part_info= part_info;
|
||||||
|
|
||||||
|
/* Never update timestamp columns when alter */
|
||||||
|
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||||
|
|
||||||
if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
|
if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -9380,47 +9380,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
||||||
new_field->set_derivation(item->collation.derivation);
|
new_field->set_derivation(item->collation.derivation);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
new_field= Field_new_decimal::new_decimal_field(item);
|
||||||
uint8 dec= item->decimals;
|
|
||||||
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
|
|
||||||
uint32 len= item->max_length;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
|
||||||
will always throw a warning. We must limit dec to
|
|
||||||
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (dec > 0)
|
|
||||||
{
|
|
||||||
signed int overflow;
|
|
||||||
|
|
||||||
dec= min(dec, DECIMAL_MAX_SCALE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the value still overflows the field with the corrected dec,
|
|
||||||
we'll throw out decimals rather than integers. This is still
|
|
||||||
bad and of course throws a truncation warning.
|
|
||||||
+1: for decimal point
|
|
||||||
*/
|
|
||||||
|
|
||||||
const int required_length=
|
|
||||||
my_decimal_precision_to_length(intg + dec, dec,
|
|
||||||
item->unsigned_flag);
|
|
||||||
|
|
||||||
overflow= required_length - len;
|
|
||||||
|
|
||||||
if (overflow > 0)
|
|
||||||
dec= max(0, dec - overflow); // too long, discard fract
|
|
||||||
else
|
|
||||||
/* Corrected value fits. */
|
|
||||||
len= required_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_field= new Field_new_decimal(len, maybe_null, item->name,
|
|
||||||
dec, item->unsigned_flag);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
// This case should never be choosen
|
// This case should never be choosen
|
||||||
|
|
|
@ -7071,8 +7071,6 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
|
||||||
/* Perform closing actions and return error status. */
|
/* Perform closing actions and return error status. */
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_ASSERT(num_tables == 1);
|
|
||||||
|
|
||||||
Table_triggers_list *triggers= lst->table->triggers;
|
Table_triggers_list *triggers= lst->table->triggers;
|
||||||
|
|
||||||
if (!triggers)
|
if (!triggers)
|
||||||
|
|
|
@ -3475,6 +3475,41 @@ void sp_prepare_create_field(THD *thd, Create_field *sql_field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write CREATE TABLE binlog
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
write_create_table_bin_log()
|
||||||
|
thd Thread object
|
||||||
|
create_info Create information
|
||||||
|
internal_tmp_table Set to 1 if this is an internal temporary table
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function only is called in mysql_create_table_no_lock and
|
||||||
|
mysql_create_table
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
NONE
|
||||||
|
*/
|
||||||
|
static inline void write_create_table_bin_log(THD *thd,
|
||||||
|
const HA_CREATE_INFO *create_info,
|
||||||
|
bool internal_tmp_table)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Don't write statement if:
|
||||||
|
- It is an internal temporary table,
|
||||||
|
- Row-based logging is used and it we are creating a temporary table, or
|
||||||
|
- The binary log is not open.
|
||||||
|
Otherwise, the statement shall be binlogged.
|
||||||
|
*/
|
||||||
|
if (!internal_tmp_table &&
|
||||||
|
(!thd->current_stmt_binlog_row_based ||
|
||||||
|
(thd->current_stmt_binlog_row_based &&
|
||||||
|
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
|
||||||
|
write_bin_log(thd, TRUE, thd->query, thd->query_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a table
|
Create a table
|
||||||
|
|
||||||
|
@ -3738,6 +3773,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
||||||
alias);
|
alias);
|
||||||
error= 0;
|
error= 0;
|
||||||
|
write_create_table_bin_log(thd, create_info, internal_tmp_table);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
|
||||||
|
@ -3858,18 +3894,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||||
thd->thread_specific_used= TRUE;
|
thd->thread_specific_used= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
write_create_table_bin_log(thd, create_info, internal_tmp_table);
|
||||||
Don't write statement if:
|
|
||||||
- It is an internal temporary table,
|
|
||||||
- Row-based logging is used and it we are creating a temporary table, or
|
|
||||||
- The binary log is not open.
|
|
||||||
Otherwise, the statement shall be binlogged.
|
|
||||||
*/
|
|
||||||
if (!internal_tmp_table &&
|
|
||||||
(!thd->current_stmt_binlog_row_based ||
|
|
||||||
(thd->current_stmt_binlog_row_based &&
|
|
||||||
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
|
|
||||||
write_bin_log(thd, TRUE, thd->query, thd->query_length);
|
|
||||||
error= FALSE;
|
error= FALSE;
|
||||||
unlock_and_end:
|
unlock_and_end:
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
|
@ -3885,6 +3910,7 @@ warn:
|
||||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
||||||
alias);
|
alias);
|
||||||
create_info->table_existed= 1; // Mark that table existed
|
create_info->table_existed= 1; // Mark that table existed
|
||||||
|
write_create_table_bin_log(thd, create_info, internal_tmp_table);
|
||||||
goto unlock_and_end;
|
goto unlock_and_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3936,6 +3962,7 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
|
||||||
table_name);
|
table_name);
|
||||||
create_info->table_existed= 1;
|
create_info->table_existed= 1;
|
||||||
result= FALSE;
|
result= FALSE;
|
||||||
|
write_create_table_bin_log(thd, create_info, internal_tmp_table);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5276,6 +5303,24 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goto binlog;
|
||||||
|
|
||||||
|
table_exists:
|
||||||
|
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||||
|
{
|
||||||
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||||
|
my_snprintf(warn_buff, sizeof(warn_buff),
|
||||||
|
ER(ER_TABLE_EXISTS_ERROR), table_name);
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
|
ER_TABLE_EXISTS_ERROR,warn_buff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
binlog:
|
||||||
DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
|
DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5339,20 +5384,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||||
write_bin_log(thd, TRUE, thd->query, thd->query_length);
|
write_bin_log(thd, TRUE, thd->query, thd->query_length);
|
||||||
|
|
||||||
res= FALSE;
|
res= FALSE;
|
||||||
goto err;
|
|
||||||
|
|
||||||
table_exists:
|
|
||||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
|
||||||
{
|
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
|
||||||
my_snprintf(warn_buff, sizeof(warn_buff),
|
|
||||||
ER(ER_TABLE_EXISTS_ERROR), table_name);
|
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
||||||
ER_TABLE_EXISTS_ERROR,warn_buff);
|
|
||||||
res= FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (name_lock)
|
if (name_lock)
|
||||||
|
|
|
@ -732,6 +732,7 @@ int mysql_update(THD *thd,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table->auto_increment_field_not_null= FALSE;
|
||||||
dup_key_found= 0;
|
dup_key_found= 0;
|
||||||
/*
|
/*
|
||||||
Caching the killed status to pass as the arg to query event constuctor;
|
Caching the killed status to pass as the arg to query event constuctor;
|
||||||
|
|
|
@ -494,7 +494,6 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
|
||||||
enum enum_tx_isolation tx_isolation;
|
enum enum_tx_isolation tx_isolation;
|
||||||
enum Cast_target cast_type;
|
enum Cast_target cast_type;
|
||||||
enum Item_udftype udf_type;
|
enum Item_udftype udf_type;
|
||||||
enum ha_choice choice;
|
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
thr_lock_type lock_type;
|
thr_lock_type lock_type;
|
||||||
interval_type interval, interval_time_st;
|
interval_type interval, interval_time_st;
|
||||||
|
@ -1164,8 +1163,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%type <ulonglong_number>
|
%type <ulonglong_number>
|
||||||
ulonglong_num real_ulonglong_num size_number
|
ulonglong_num real_ulonglong_num size_number
|
||||||
|
|
||||||
%type <choice> choice
|
|
||||||
|
|
||||||
%type <p_elem_value>
|
%type <p_elem_value>
|
||||||
part_bit_expr
|
part_bit_expr
|
||||||
|
|
||||||
|
@ -3757,8 +3754,8 @@ partitioning:
|
||||||
LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
|
LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
|
||||||
if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
|
if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
|
||||||
{
|
{
|
||||||
my_error(ER_FEATURE_DISABLED, MYF(0),
|
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
|
||||||
"partitioning", "--with-partition");
|
"--skip-partition");
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
lex->part_info= new partition_info();
|
lex->part_info= new partition_info();
|
||||||
|
@ -9066,11 +9063,6 @@ dec_num:
|
||||||
| FLOAT_NUM
|
| FLOAT_NUM
|
||||||
;
|
;
|
||||||
|
|
||||||
choice:
|
|
||||||
ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; }
|
|
||||||
| DEFAULT { $$= HA_CHOICE_UNDEF; }
|
|
||||||
;
|
|
||||||
|
|
||||||
procedure_clause:
|
procedure_clause:
|
||||||
/* empty */
|
/* empty */
|
||||||
| PROCEDURE ident /* Procedure name */
|
| PROCEDURE ident /* Procedure name */
|
||||||
|
|
|
@ -913,6 +913,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||||
we unlock the old value of share->db_plugin before
|
we unlock the old value of share->db_plugin before
|
||||||
replacing it with a globally locked version of tmp_plugin
|
replacing it with a globally locked version of tmp_plugin
|
||||||
*/
|
*/
|
||||||
|
/* Check if the partitioning engine is ready */
|
||||||
|
if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
|
||||||
|
{
|
||||||
|
error= 8;
|
||||||
|
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
|
||||||
|
"--skip-partition");
|
||||||
|
my_free(buff, MYF(0));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
plugin_unlock(NULL, share->db_plugin);
|
plugin_unlock(NULL, share->db_plugin);
|
||||||
share->db_plugin= ha_lock_engine(NULL, partition_hton);
|
share->db_plugin= ha_lock_engine(NULL, partition_hton);
|
||||||
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
|
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
|
||||||
|
|
|
@ -361,10 +361,8 @@ typedef struct st_table_share
|
||||||
}
|
}
|
||||||
enum row_type row_type; /* How rows are stored */
|
enum row_type row_type; /* How rows are stored */
|
||||||
enum tmp_table_type tmp_table;
|
enum tmp_table_type tmp_table;
|
||||||
/** Transactional or not. Unused; reserved for future versions. */
|
enum enum_ha_unused unused1;
|
||||||
enum ha_choice transactional;
|
enum enum_ha_unused unused2;
|
||||||
/** Per-page checksums or not. Unused; reserved for future versions. */
|
|
||||||
enum ha_choice page_checksum;
|
|
||||||
|
|
||||||
uint ref_count; /* How many TABLE objects uses this */
|
uint ref_count; /* How many TABLE objects uses this */
|
||||||
uint open_count; /* Number of tables in open list */
|
uint open_count; /* Number of tables in open list */
|
||||||
|
|
|
@ -618,7 +618,7 @@ enum btr_cur_method {
|
||||||
hash_node, and might be necessary to
|
hash_node, and might be necessary to
|
||||||
update */
|
update */
|
||||||
BTR_CUR_BINARY, /*!< success using the binary search */
|
BTR_CUR_BINARY, /*!< success using the binary search */
|
||||||
BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
|
BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to
|
||||||
the insert buffer */
|
the insert buffer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ typedef struct trx_named_savept_struct trx_named_savept_t;
|
||||||
enum trx_rb_ctx {
|
enum trx_rb_ctx {
|
||||||
RB_NONE = 0, /*!< no rollback */
|
RB_NONE = 0, /*!< no rollback */
|
||||||
RB_NORMAL, /*!< normal rollback */
|
RB_NORMAL, /*!< normal rollback */
|
||||||
RB_RECOVERY, /*!< rolling back an incomplete transaction,
|
RB_RECOVERY /*!< rolling back an incomplete transaction,
|
||||||
in crash recovery */
|
in crash recovery */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,15 @@ int _mi_check_index(MI_INFO *info, int inx)
|
||||||
{
|
{
|
||||||
if (inx == -1) /* Use last index */
|
if (inx == -1) /* Use last index */
|
||||||
inx=info->lastinx;
|
inx=info->lastinx;
|
||||||
if (inx < 0 || ! mi_is_key_active(info->s->state.key_map, inx))
|
if (inx < 0)
|
||||||
{
|
{
|
||||||
my_errno=HA_ERR_WRONG_INDEX;
|
my_errno= HA_ERR_WRONG_INDEX;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!mi_is_key_active(info->s->state.key_map, inx))
|
||||||
|
{
|
||||||
|
my_errno= info->s->state.state.records ? HA_ERR_WRONG_INDEX :
|
||||||
|
HA_ERR_END_OF_FILE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (info->lastinx != inx) /* Index changed */
|
if (info->lastinx != inx) /* Index changed */
|
||||||
|
|
Loading…
Reference in a new issue