Merge from mysql-5.5.14-release
This commit is contained in:
commit
c74d844de3
@ -1,8 +1,9 @@
|
||||
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; version 2 of
|
||||
the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -1117,5 +1117,14 @@ CASE s1 WHEN 'a' THEN 'b' ELSE 'c' END
|
||||
b
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#12340997
|
||||
# DATE_ADD/DATE_SUB WITH INTERVAL CRASHES IN GET_INTERVAL_VALUE()
|
||||
#
|
||||
SELECT space(date_add(101, INTERVAL CHAR('1' USING utf16) hour_second));
|
||||
space(date_add(101, INTERVAL CHAR('1' USING utf16) hour_second))
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
|
@ -176,10 +176,12 @@ SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1
|
||||
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
|
||||
ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
|
||||
2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where 0
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
|
@ -455,4 +455,11 @@ YES plugin
|
||||
ERROR 1045 (28000): Access denied for user 'unknown'@'localhost' (using password: YES)
|
||||
# shoud contain "using password=no"
|
||||
ERROR 1045 (28000): Access denied for user 'unknown'@'localhost' (using password: NO)
|
||||
#
|
||||
# Bug #12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD
|
||||
#
|
||||
CREATE USER bug12610784@localhost;
|
||||
SET PASSWORD FOR bug12610784@localhost = PASSWORD('secret');
|
||||
ERROR 28000: Access denied for user 'bug12610784'@'localhost' (using password: NO)
|
||||
DROP USER bug12610784@localhost;
|
||||
End of 5.5 tests
|
||||
|
38
mysql-test/r/secure_file_priv_win.result
Normal file
38
mysql-test/r/secure_file_priv_win.result
Normal file
@ -0,0 +1,38 @@
|
||||
CREATE TABLE t1 (c1 longtext);
|
||||
INSERT INTO t1 values ('a');
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR/B11764517.tmp';
|
||||
show global variables like 'secure_file_priv';
|
||||
Variable_name Value
|
||||
secure_file_priv MYSQL_TMP_DIR/
|
||||
SELECT load_file('MYSQL_TMP_DIR\\B11764517.tmp') AS x;
|
||||
x
|
||||
a
|
||||
|
||||
SELECT load_file('MYSQL_TMP_DIR/B11764517.tmp') AS x;
|
||||
x
|
||||
a
|
||||
|
||||
SELECT load_file('MYSQL_TMP_DIR_UCASE/B11764517.tmp') AS x;
|
||||
x
|
||||
a
|
||||
|
||||
SELECT load_file('MYSQL_TMP_DIR_LCASE/B11764517.tmp') AS x;
|
||||
x
|
||||
a
|
||||
|
||||
SELECT load_file('MYSQL_TMP_DIR\\..a..\\..\\..\\B11764517.tmp') AS x;
|
||||
x
|
||||
NULL
|
||||
LOAD DATA INFILE 'MYSQL_TMP_DIR\\B11764517.tmp' INTO TABLE t1;
|
||||
LOAD DATA INFILE 'MYSQL_TMP_DIR/B11764517.tmp' INTO TABLE t1;
|
||||
LOAD DATA INFILE 'MYSQL_TMP_DIR_UCASE/B11764517.tmp' INTO TABLE t1;
|
||||
LOAD DATA INFILE 'MYSQL_TMP_DIR_LCASE/B11764517.tmp' INTO TABLE t1;
|
||||
LOAD DATA INFILE "MYSQL_TMP_DIR\\..a..\\..\\..\\B11764517.tmp" into table t1;
|
||||
ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR\\..a..\\..\\..\\B11764517-2.tmp';
|
||||
ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR\\B11764517-2.tmp';
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR/B11764517-3.tmp';
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR_UCASE/B11764517-4.tmp';
|
||||
SELECT * FROM t1 INTO OUTFILE 'MYSQL_TMP_DIR_LCASE/B11764517-5.tmp';
|
||||
DROP TABLE t1;
|
@ -592,3 +592,28 @@ ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' fo
|
||||
# Connection 'default'.
|
||||
drop user bug57061_user@localhost;
|
||||
drop database mysqltest_db;
|
||||
#
|
||||
# Bug#11882603 SELECT_ACL ON ANY COLUMN IN MYSQL.PROC ALLOWS TO SEE
|
||||
# DEFINITION OF ANY ROUTINE.
|
||||
#
|
||||
DROP DATABASE IF EXISTS db1;
|
||||
CREATE DATABASE db1;
|
||||
CREATE PROCEDURE db1.p1() SELECT 1;
|
||||
CREATE USER user2@localhost IDENTIFIED BY '';
|
||||
GRANT SELECT(db) ON mysql.proc TO user2@localhost;
|
||||
# Connection con2 as user2
|
||||
# The statement below before disclosed info from body_utf8 column.
|
||||
SHOW CREATE PROCEDURE db1.p1;
|
||||
ERROR 42000: PROCEDURE p1 does not exist
|
||||
# Check that SHOW works with SELECT grant on whole table
|
||||
# Connection default
|
||||
GRANT SELECT ON mysql.proc TO user2@localhost;
|
||||
# Connection con2
|
||||
# This should work
|
||||
SHOW CREATE PROCEDURE db1.p1;
|
||||
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
|
||||
SELECT 1 latin1 latin1_swedish_ci latin1_swedish_ci
|
||||
# Connection default
|
||||
DROP USER user2@localhost;
|
||||
DROP DATABASE db1;
|
||||
|
@ -7500,4 +7500,76 @@ CALL p1();
|
||||
DROP TABLE t1, t2, t3;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
|
||||
# --
|
||||
# -- Bug#12652769 - 61470: case operator in stored routine retains old
|
||||
# -- value of input parameter
|
||||
# ---
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
CREATE TABLE t1 (s1 CHAR(5) CHARACTER SET utf8);
|
||||
INSERT INTO t1 VALUES ('a');
|
||||
CREATE PROCEDURE p1(dt DATETIME, i INT)
|
||||
BEGIN
|
||||
SELECT
|
||||
CASE
|
||||
WHEN i = 1 THEN 2
|
||||
ELSE dt
|
||||
END AS x1;
|
||||
SELECT
|
||||
CASE _latin1'a'
|
||||
WHEN _utf8'a' THEN 'A'
|
||||
END AS x2;
|
||||
SELECT
|
||||
CASE _utf8'a'
|
||||
WHEN _latin1'a' THEN _utf8'A'
|
||||
END AS x3;
|
||||
SELECT
|
||||
CASE s1
|
||||
WHEN _latin1'a' THEN _latin1'b'
|
||||
ELSE _latin1'c'
|
||||
END AS x4
|
||||
FROM t1;
|
||||
END|
|
||||
|
||||
CALL p1('2011-04-03 05:14:10', 1);
|
||||
x1
|
||||
2
|
||||
x2
|
||||
A
|
||||
x3
|
||||
A
|
||||
x4
|
||||
b
|
||||
CALL p1('2011-04-03 05:14:11', 2);
|
||||
x1
|
||||
2011-04-03 05:14:11
|
||||
x2
|
||||
A
|
||||
x3
|
||||
A
|
||||
x4
|
||||
b
|
||||
CALL p1('2011-04-03 05:14:12', 2);
|
||||
x1
|
||||
2011-04-03 05:14:12
|
||||
x2
|
||||
A
|
||||
x3
|
||||
A
|
||||
x4
|
||||
b
|
||||
CALL p1('2011-04-03 05:14:13', 2);
|
||||
x1
|
||||
2011-04-03 05:14:13
|
||||
x2
|
||||
A
|
||||
x3
|
||||
A
|
||||
x4
|
||||
b
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# End of 5.5 test
|
||||
|
@ -4442,6 +4442,32 @@ pk int_key
|
||||
3 3
|
||||
7 3
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug#12329653
|
||||
# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
#
|
||||
CREATE TABLE t1(a1 int);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
|
||||
1
|
||||
1
|
||||
1
|
||||
PREPARE stmt FROM
|
||||
'SELECT 1 UNION ALL
|
||||
SELECT 1 FROM t1
|
||||
ORDER BY
|
||||
(SELECT 1 FROM t1 AS t1_0
|
||||
WHERE 1 < SOME (SELECT a1 FROM t1)
|
||||
)' ;
|
||||
EXECUTE stmt ;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
EXECUTE stmt ;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
||||
|
@ -1144,5 +1144,23 @@ SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
|
||||
UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0)
|
||||
NULL
|
||||
#
|
||||
# Bug#12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
|
||||
#
|
||||
SELECT UPDATEXML('','(a)/a','');
|
||||
UPDATEXML('','(a)/a','')
|
||||
|
||||
SELECT UPDATEXML('<a><a>x</a></a>','(a)/a','<b />');
|
||||
UPDATEXML('<a><a>x</a></a>','(a)/a','<b />')
|
||||
<a><b /></a>
|
||||
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />');
|
||||
UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />')
|
||||
<a><c><a>x</a></c></a>
|
||||
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />');
|
||||
UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />')
|
||||
<a><c><b /></c></a>
|
||||
SELECT ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b');
|
||||
ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b')
|
||||
aa bb
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
|
@ -1,3 +1,46 @@
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format='Barracuda';
|
||||
CREATE TABLE t1_purge (
|
||||
A INT,
|
||||
B BLOB, C BLOB, D BLOB, E BLOB,
|
||||
F BLOB, G BLOB, H BLOB,
|
||||
PRIMARY KEY (B(767), C(767), D(767), E(767), A),
|
||||
INDEX (A)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO t1_purge VALUES (1,
|
||||
REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766),
|
||||
REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766));
|
||||
CREATE TABLE t2_purge (
|
||||
A INT PRIMARY KEY,
|
||||
B BLOB, C BLOB, D BLOB, E BLOB,
|
||||
F BLOB, G BLOB, H BLOB, I BLOB,
|
||||
J BLOB, K BLOB, L BLOB,
|
||||
INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO t2_purge VALUES (1,
|
||||
REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766),
|
||||
REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766), REPEAT('i', 766),
|
||||
REPEAT('j', 766), REPEAT('k', 766), REPEAT('l', 766));
|
||||
CREATE TABLE t3_purge (
|
||||
A INT,
|
||||
B VARCHAR(800), C VARCHAR(800), D VARCHAR(800), E VARCHAR(800),
|
||||
F VARCHAR(800), G VARCHAR(800), H VARCHAR(800),
|
||||
PRIMARY KEY (B(767), C(767), D(767), E(767), A),
|
||||
INDEX (A)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO t3_purge SELECT * FROM t1_purge;
|
||||
CREATE TABLE t4_purge (
|
||||
A INT PRIMARY KEY,
|
||||
B VARCHAR(800), C VARCHAR(800), D VARCHAR(800), E VARCHAR(800),
|
||||
F VARCHAR(800), G VARCHAR(800), H VARCHAR(800), I VARCHAR(800),
|
||||
J VARCHAR(800), K VARCHAR(800), L VARCHAR(800),
|
||||
INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO t4_purge SELECT * FROM t2_purge;
|
||||
DELETE FROM t1_purge;
|
||||
DELETE FROM t2_purge;
|
||||
DELETE FROM t3_purge;
|
||||
DELETE FROM t4_purge;
|
||||
set global innodb_file_per_table=0;
|
||||
set global innodb_file_format=Antelope;
|
||||
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
|
||||
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
|
||||
commit;
|
||||
@ -1098,44 +1141,7 @@ t2 CREATE TABLE `t2` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
|
||||
CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
3 a
|
||||
3 b
|
||||
1 c
|
||||
0 d
|
||||
1 e
|
||||
SET lock_wait_timeout=1;
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
CREATE INDEX t2a ON t2(a);
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
3 a
|
||||
3 b
|
||||
1 c
|
||||
0 d
|
||||
1 e
|
||||
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
|
||||
ERROR HY000: Table definition has changed, please retry transaction
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
3 a
|
||||
3 b
|
||||
1 c
|
||||
0 d
|
||||
1 e
|
||||
COMMIT;
|
||||
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
|
||||
a b
|
||||
0 d
|
||||
1 c
|
||||
1 e
|
||||
3 a
|
||||
3 b
|
||||
DROP TABLE t1,t2;
|
||||
SELECT SLEEP(10);
|
||||
SLEEP(10)
|
||||
0
|
||||
DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge;
|
||||
|
@ -4,6 +4,65 @@ let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
|
||||
let $innodb_file_format_max_orig=`select @@innodb_file_format_max`;
|
||||
|
||||
let $per_table=`select @@innodb_file_per_table`;
|
||||
let $format=`select @@innodb_file_format`;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format='Barracuda';
|
||||
|
||||
# Test an assertion failure on purge.
|
||||
CREATE TABLE t1_purge (
|
||||
A INT,
|
||||
B BLOB, C BLOB, D BLOB, E BLOB,
|
||||
F BLOB, G BLOB, H BLOB,
|
||||
PRIMARY KEY (B(767), C(767), D(767), E(767), A),
|
||||
INDEX (A)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO t1_purge VALUES (1,
|
||||
REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766),
|
||||
REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766));
|
||||
|
||||
CREATE TABLE t2_purge (
|
||||
A INT PRIMARY KEY,
|
||||
B BLOB, C BLOB, D BLOB, E BLOB,
|
||||
F BLOB, G BLOB, H BLOB, I BLOB,
|
||||
J BLOB, K BLOB, L BLOB,
|
||||
INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO t2_purge VALUES (1,
|
||||
REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766),
|
||||
REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766), REPEAT('i', 766),
|
||||
REPEAT('j', 766), REPEAT('k', 766), REPEAT('l', 766));
|
||||
|
||||
CREATE TABLE t3_purge (
|
||||
A INT,
|
||||
B VARCHAR(800), C VARCHAR(800), D VARCHAR(800), E VARCHAR(800),
|
||||
F VARCHAR(800), G VARCHAR(800), H VARCHAR(800),
|
||||
PRIMARY KEY (B(767), C(767), D(767), E(767), A),
|
||||
INDEX (A)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO t3_purge SELECT * FROM t1_purge;
|
||||
|
||||
CREATE TABLE t4_purge (
|
||||
A INT PRIMARY KEY,
|
||||
B VARCHAR(800), C VARCHAR(800), D VARCHAR(800), E VARCHAR(800),
|
||||
F VARCHAR(800), G VARCHAR(800), H VARCHAR(800), I VARCHAR(800),
|
||||
J VARCHAR(800), K VARCHAR(800), L VARCHAR(800),
|
||||
INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO t4_purge SELECT * FROM t2_purge;
|
||||
|
||||
# This would trigger the failure (Bug #12429576)
|
||||
# if purge gets a chance to run before DROP TABLE t1_purge, ....
|
||||
DELETE FROM t1_purge;
|
||||
DELETE FROM t2_purge;
|
||||
DELETE FROM t3_purge;
|
||||
DELETE FROM t4_purge;
|
||||
|
||||
eval set global innodb_file_per_table=$per_table;
|
||||
eval set global innodb_file_format=$format;
|
||||
|
||||
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
|
||||
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
|
||||
commit;
|
||||
@ -357,8 +416,6 @@ explain select * from t1 where b like 'adfd%';
|
||||
# end disabled45225_1
|
||||
drop table t1;
|
||||
|
||||
let $per_table=`select @@innodb_file_per_table`;
|
||||
let $format=`select @@innodb_file_format`;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format='Barracuda';
|
||||
# Test creating a table that could lead to undo log overflow.
|
||||
@ -532,35 +589,37 @@ SHOW CREATE TABLE t2;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
|
||||
CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
connection b;
|
||||
BEGIN;
|
||||
# This acquires a MDL lock on t1 until commit.
|
||||
SELECT * FROM t1;
|
||||
connection a;
|
||||
# This times out before of the MDL lock held by connection b.
|
||||
SET lock_wait_timeout=1;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t2a ON t2(a);
|
||||
connection b;
|
||||
SELECT * FROM t2;
|
||||
--error ER_TABLE_DEF_CHANGED
|
||||
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
|
||||
SELECT * FROM t2;
|
||||
COMMIT;
|
||||
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
# The following tests are disabled because of the introduced timeouts for
|
||||
# metadata locks at the MySQL level as part of the fix for
|
||||
# Bug#45225 Locking: hang if drop table with no timeout
|
||||
# The following CREATE INDEX t1a ON t1(a); causes a lock wait timeout
|
||||
# start disabled45225_2
|
||||
#connect (a,localhost,root,,);
|
||||
#connect (b,localhost,root,,);
|
||||
#connection a;
|
||||
#CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
|
||||
#INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
|
||||
#connection b;
|
||||
#BEGIN;
|
||||
#SELECT * FROM t1;
|
||||
#connection a;
|
||||
#CREATE INDEX t1a ON t1(a);
|
||||
#connection b;
|
||||
#SELECT * FROM t1;
|
||||
#--error ER_TABLE_DEF_CHANGED
|
||||
#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
|
||||
#SELECT * FROM t1;
|
||||
#COMMIT;
|
||||
#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
|
||||
#connection default;
|
||||
#disconnect a;
|
||||
#disconnect b;
|
||||
#
|
||||
#DROP TABLE t1;
|
||||
# end disabled45225_2
|
||||
#this delay is needed because 45225_2 is disabled, to allow the purge to run
|
||||
SELECT SLEEP(10);
|
||||
DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge;
|
||||
|
||||
#
|
||||
# restore environment to the state it was before this test execution
|
||||
|
@ -755,6 +755,13 @@ INSERT INTO t1 VALUES ('a');
|
||||
SELECT CASE s1 WHEN 'a' THEN 'b' ELSE 'c' END FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#12340997
|
||||
--echo # DATE_ADD/DATE_SUB WITH INTERVAL CRASHES IN GET_INTERVAL_VALUE()
|
||||
--echo #
|
||||
|
||||
SELECT space(date_add(101, INTERVAL CHAR('1' USING utf16) hour_second));
|
||||
|
||||
#
|
||||
## TODO: add tests for all engines
|
||||
#
|
||||
|
@ -157,11 +157,12 @@ CREATE TABLE t1 (f1 INT);
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
|
||||
# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
|
||||
--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
|
||||
# EXPLAIN EXTENDED (with subselect). used to crash.
|
||||
# This is actually a valid query for this sql_mode,
|
||||
# but it was transformed in such a way that it failed, see
|
||||
# Bug#12329653 - EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1
|
||||
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
|
||||
SHOW WARNINGS;
|
||||
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
|
||||
|
@ -525,5 +525,19 @@ SELECT IS_NULLABLE, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||
--error 1
|
||||
--exec $MYSQL -uunknown 2>&1
|
||||
|
||||
--echo #
|
||||
--echo # Bug #12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD
|
||||
--echo #
|
||||
|
||||
CREATE USER bug12610784@localhost;
|
||||
SET PASSWORD FOR bug12610784@localhost = PASSWORD('secret');
|
||||
--disable_query_log
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
connect(b12610784,localhost,bug12610784,,test);
|
||||
--enable_query_log
|
||||
connect(b12610784,localhost,bug12610784,secret,test);
|
||||
connection default;
|
||||
disconnect b12610784;
|
||||
DROP USER bug12610784@localhost;
|
||||
|
||||
--echo End of 5.5 tests
|
||||
|
1
mysql-test/t/secure_file_priv_win-master.opt
Normal file
1
mysql-test/t/secure_file_priv_win-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--secure_file_priv=$MYSQL_TMP_DIR
|
79
mysql-test/t/secure_file_priv_win.test
Normal file
79
mysql-test/t/secure_file_priv_win.test
Normal file
@ -0,0 +1,79 @@
|
||||
#
|
||||
# Bug58747 breaks secure_file_priv+not secure yet+still accesses other folders
|
||||
#
|
||||
|
||||
# we do the windows specific relative directory testing
|
||||
|
||||
--source include/windows.inc
|
||||
|
||||
CREATE TABLE t1 (c1 longtext);
|
||||
INSERT INTO t1 values ('a');
|
||||
|
||||
LET $MYSQL_TMP_DIR_UCASE= `SELECT upper('$MYSQL_TMP_DIR')`;
|
||||
LET $MYSQL_TMP_DIR_LCASE= `SELECT lower('$MYSQL_TMP_DIR')`;
|
||||
|
||||
#create the file
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR/B11764517.tmp';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
show global variables like 'secure_file_priv';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT load_file('$MYSQL_TMP_DIR\\\\B11764517.tmp') AS x;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT load_file('$MYSQL_TMP_DIR/B11764517.tmp') AS x;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_UCASE MYSQL_TMP_DIR_UCASE
|
||||
eval SELECT load_file('$MYSQL_TMP_DIR_UCASE/B11764517.tmp') AS x;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_LCASE MYSQL_TMP_DIR_LCASE
|
||||
eval SELECT load_file('$MYSQL_TMP_DIR_LCASE/B11764517.tmp') AS x;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT load_file('$MYSQL_TMP_DIR\\\\..a..\\\\..\\\\..\\\\B11764517.tmp') AS x;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval LOAD DATA INFILE '$MYSQL_TMP_DIR\\\\B11764517.tmp' INTO TABLE t1;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval LOAD DATA INFILE '$MYSQL_TMP_DIR/B11764517.tmp' INTO TABLE t1;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_UCASE MYSQL_TMP_DIR_UCASE
|
||||
eval LOAD DATA INFILE '$MYSQL_TMP_DIR_UCASE/B11764517.tmp' INTO TABLE t1;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_LCASE MYSQL_TMP_DIR_LCASE
|
||||
eval LOAD DATA INFILE '$MYSQL_TMP_DIR_LCASE/B11764517.tmp' INTO TABLE t1;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
--error ER_OPTION_PREVENTS_STATEMENT
|
||||
eval LOAD DATA INFILE "$MYSQL_TMP_DIR\\\\..a..\\\\..\\\\..\\\\B11764517.tmp" into table t1;
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
--error ER_OPTION_PREVENTS_STATEMENT
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR\\\\..a..\\\\..\\\\..\\\\B11764517-2.tmp';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR\\\\B11764517-2.tmp';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR/B11764517-3.tmp';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_UCASE MYSQL_TMP_DIR_UCASE
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR_UCASE/B11764517-4.tmp';
|
||||
|
||||
--replace_result $MYSQL_TMP_DIR_LCASE MYSQL_TMP_DIR_LCASE
|
||||
eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR_LCASE/B11764517-5.tmp';
|
||||
|
||||
--error 0,1
|
||||
--remove_file $MYSQL_TMP_DIR/B11764517.tmp;
|
||||
--error 0,1
|
||||
--remove_file $MYSQL_TMP_DIR/B11764517-2.tmp;
|
||||
--error 0,1
|
||||
--remove_file $MYSQL_TMP_DIR/B11764517-3.tmp;
|
||||
--error 0,1
|
||||
--remove_file $MYSQL_TMP_DIR/B11764517-4.tmp;
|
||||
--error 0,1
|
||||
--remove_file $MYSQL_TMP_DIR/B11764517-5.tmp;
|
||||
DROP TABLE t1;
|
@ -959,6 +959,43 @@ drop user bug57061_user@localhost;
|
||||
drop database mysqltest_db;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#11882603 SELECT_ACL ON ANY COLUMN IN MYSQL.PROC ALLOWS TO SEE
|
||||
--echo # DEFINITION OF ANY ROUTINE.
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS db1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE db1;
|
||||
CREATE PROCEDURE db1.p1() SELECT 1;
|
||||
CREATE USER user2@localhost IDENTIFIED BY '';
|
||||
GRANT SELECT(db) ON mysql.proc TO user2@localhost;
|
||||
|
||||
--echo # Connection con2 as user2
|
||||
connect (con2, localhost, user2);
|
||||
--echo # The statement below before disclosed info from body_utf8 column.
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
SHOW CREATE PROCEDURE db1.p1;
|
||||
|
||||
--echo # Check that SHOW works with SELECT grant on whole table
|
||||
--echo # Connection default
|
||||
connection default;
|
||||
GRANT SELECT ON mysql.proc TO user2@localhost;
|
||||
|
||||
--echo # Connection con2
|
||||
connection con2;
|
||||
--echo # This should work
|
||||
SHOW CREATE PROCEDURE db1.p1;
|
||||
|
||||
--echo # Connection default
|
||||
connection default;
|
||||
disconnect con2;
|
||||
DROP USER user2@localhost;
|
||||
DROP DATABASE db1;
|
||||
|
||||
|
||||
# Wait till all disconnects are completed
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
|
@ -8778,4 +8778,60 @@ DROP TABLE t1, t2, t3;
|
||||
DROP PROCEDURE p1;
|
||||
--echo
|
||||
|
||||
|
||||
--echo
|
||||
--echo # --
|
||||
--echo # -- Bug#12652769 - 61470: case operator in stored routine retains old
|
||||
--echo # -- value of input parameter
|
||||
--echo # ---
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (s1 CHAR(5) CHARACTER SET utf8);
|
||||
INSERT INTO t1 VALUES ('a');
|
||||
|
||||
delimiter |;
|
||||
|
||||
CREATE PROCEDURE p1(dt DATETIME, i INT)
|
||||
BEGIN
|
||||
SELECT
|
||||
CASE
|
||||
WHEN i = 1 THEN 2
|
||||
ELSE dt
|
||||
END AS x1;
|
||||
|
||||
SELECT
|
||||
CASE _latin1'a'
|
||||
WHEN _utf8'a' THEN 'A'
|
||||
END AS x2;
|
||||
|
||||
SELECT
|
||||
CASE _utf8'a'
|
||||
WHEN _latin1'a' THEN _utf8'A'
|
||||
END AS x3;
|
||||
|
||||
SELECT
|
||||
CASE s1
|
||||
WHEN _latin1'a' THEN _latin1'b'
|
||||
ELSE _latin1'c'
|
||||
END AS x4
|
||||
FROM t1;
|
||||
END|
|
||||
|
||||
delimiter ;|
|
||||
|
||||
--echo
|
||||
CALL p1('2011-04-03 05:14:10', 1);
|
||||
CALL p1('2011-04-03 05:14:11', 2);
|
||||
CALL p1('2011-04-03 05:14:12', 2);
|
||||
CALL p1('2011-04-03 05:14:13', 2);
|
||||
|
||||
--echo
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
--echo
|
||||
|
||||
--echo # End of 5.5 test
|
||||
|
@ -3387,6 +3387,39 @@ ORDER BY outr.pk;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#12329653
|
||||
--echo # EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(a1 int);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
|
||||
## First a simpler query, illustrating the transformation
|
||||
## '1 < some (...)' => '1 < max(...)'
|
||||
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
|
||||
|
||||
## The query which made the server crash.
|
||||
PREPARE stmt FROM
|
||||
'SELECT 1 UNION ALL
|
||||
SELECT 1 FROM t1
|
||||
ORDER BY
|
||||
(SELECT 1 FROM t1 AS t1_0
|
||||
WHERE 1 < SOME (SELECT a1 FROM t1)
|
||||
)' ;
|
||||
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
EXECUTE stmt ;
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
EXECUTE stmt ;
|
||||
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
|
@ -664,6 +664,15 @@ SELECT ExtractValue(CONVERT('<\"', BINARY(10)), 1);
|
||||
SET NAMES latin1;
|
||||
SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
|
||||
|
||||
--echo #
|
||||
--echo # Bug#12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
|
||||
--echo #
|
||||
SELECT UPDATEXML('','(a)/a','');
|
||||
SELECT UPDATEXML('<a><a>x</a></a>','(a)/a','<b />');
|
||||
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />');
|
||||
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />');
|
||||
SELECT ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b');
|
||||
|
||||
--echo #
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
|
@ -144,24 +144,23 @@ int my_realpath(char *to, const char *filename, myf MyFlags)
|
||||
result= -1;
|
||||
}
|
||||
DBUG_RETURN(result);
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
int ret= GetFullPathName(filename,FN_REFLEN,
|
||||
to,
|
||||
NULL);
|
||||
#elif defined(_WIN32)
|
||||
int ret= GetFullPathName(filename,FN_REFLEN, to, NULL);
|
||||
if (ret == 0 || ret > FN_REFLEN)
|
||||
{
|
||||
if (ret > FN_REFLEN)
|
||||
my_errno= ENAMETOOLONG;
|
||||
else
|
||||
my_errno= EACCES;
|
||||
my_errno= (ret > FN_REFLEN) ? ENAMETOOLONG : GetLastError();
|
||||
if (MyFlags & MY_WME)
|
||||
my_error(EE_REALPATH, MYF(0), filename, my_errno);
|
||||
/*
|
||||
GetFullPathName didn't work : use my_load_path() which is a poor
|
||||
substitute original name but will at least be able to resolve
|
||||
paths that starts with '.'.
|
||||
*/
|
||||
my_load_path(to, filename, NullS);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
my_load_path(to, filename, NullS);
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; version 2 of
|
||||
the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -4821,14 +4821,14 @@ mark_non_agg_field:
|
||||
SELECT_LEX *select_lex= cached_table ?
|
||||
cached_table->select_lex : context->select_lex;
|
||||
if (!thd->lex->in_sum_func)
|
||||
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
select_lex->set_non_agg_field_used(true);
|
||||
else
|
||||
{
|
||||
if (outer_fixed)
|
||||
thd->lex->in_sum_func->outer_fields.push_back(this);
|
||||
else if (thd->lex->in_sum_func->nest_level !=
|
||||
thd->lex->current_select->nest_level)
|
||||
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
select_lex->set_non_agg_field_used(true);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -3007,11 +3007,35 @@ void Item_func_case::agg_num_lengths(Item *arg)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check if (*place) and new_value points to different Items and call
|
||||
THD::change_item_tree() if needed.
|
||||
|
||||
This function is a workaround for implementation deficiency in
|
||||
Item_func_case. The problem there is that the 'args' attribute contains
|
||||
Items from different expressions.
|
||||
|
||||
The function must not be used elsewhere and will be remove eventually.
|
||||
*/
|
||||
|
||||
static void change_item_tree_if_needed(THD *thd,
|
||||
Item **place,
|
||||
Item *new_value)
|
||||
{
|
||||
if (*place == new_value)
|
||||
return;
|
||||
|
||||
thd->change_item_tree(place, new_value);
|
||||
}
|
||||
|
||||
|
||||
void Item_func_case::fix_length_and_dec()
|
||||
{
|
||||
Item **agg;
|
||||
uint nagg;
|
||||
uint found_types= 0;
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
|
||||
return;
|
||||
|
||||
@ -3036,9 +3060,10 @@ void Item_func_case::fix_length_and_dec()
|
||||
Some of the items might have been changed to Item_func_conv_charset.
|
||||
*/
|
||||
for (nagg= 0 ; nagg < ncases / 2 ; nagg++)
|
||||
args[nagg * 2 + 1]= agg[nagg];
|
||||
change_item_tree_if_needed(thd, &args[nagg * 2 + 1], agg[nagg]);
|
||||
|
||||
if (else_expr_num != -1)
|
||||
args[else_expr_num]= agg[nagg++];
|
||||
change_item_tree_if_needed(thd, &args[else_expr_num], agg[nagg++]);
|
||||
}
|
||||
else
|
||||
collation.set_numeric();
|
||||
@ -3098,9 +3123,10 @@ void Item_func_case::fix_length_and_dec()
|
||||
arrray, because some of the items might have been changed to converters
|
||||
(e.g. Item_func_conv_charset, or Item_string for constants).
|
||||
*/
|
||||
args[first_expr_num]= agg[0];
|
||||
change_item_tree_if_needed(thd, &args[first_expr_num], agg[0]);
|
||||
|
||||
for (nagg= 0; nagg < ncases / 2; nagg++)
|
||||
args[nagg * 2]= agg[nagg + 1];
|
||||
change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]);
|
||||
}
|
||||
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
||||
{
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "set_var.h"
|
||||
#include "sql_select.h"
|
||||
#include "sql_parse.h" // check_stack_overrun
|
||||
#include "sql_test.h"
|
||||
|
||||
inline Item * and_items(Item* cond, Item *item)
|
||||
{
|
||||
@ -1025,6 +1026,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
it.replace(item);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE("where",
|
||||
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
{
|
||||
DBUG_ASSERT(select_lex->non_agg_field_used());
|
||||
select_lex->set_non_agg_field_used(false);
|
||||
}
|
||||
|
||||
save_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
|
||||
/*
|
||||
|
@ -259,10 +259,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
in_sum_func->outer_fields.push_back(field);
|
||||
}
|
||||
else
|
||||
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
sel->set_non_agg_field_used(true);
|
||||
}
|
||||
if (sel->nest_level > aggr_level &&
|
||||
(sel->full_group_by_flag & SUM_FUNC_USED) &&
|
||||
(sel->agg_func_used()) &&
|
||||
!sel->group_list.elements)
|
||||
{
|
||||
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
||||
@ -271,7 +271,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
|
||||
aggr_sel->set_agg_func_used(true);
|
||||
update_used_tables();
|
||||
thd->lex->in_sum_func= in_sum_func;
|
||||
return FALSE;
|
||||
|
@ -1451,7 +1451,7 @@ bool get_interval_value(Item *args,interval_type int_type,
|
||||
else
|
||||
{
|
||||
String *res;
|
||||
if (!(res=args->val_str(str_value)))
|
||||
if (!(res= args->val_str_ascii(str_value)))
|
||||
return (1);
|
||||
|
||||
/* record negative intervalls in interval->neg */
|
||||
|
@ -1973,6 +1973,9 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath)
|
||||
static int
|
||||
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
|
||||
{
|
||||
Item *context= xpath->context;
|
||||
int rc;
|
||||
|
||||
if (!my_xpath_parse_FilterExpr(xpath))
|
||||
return 0;
|
||||
|
||||
@ -1986,8 +1989,22 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH);
|
||||
return my_xpath_parse_RelativeLocationPath(xpath);
|
||||
/*
|
||||
The context for the next relative path is the nodeset
|
||||
returned by FilterExpr
|
||||
*/
|
||||
xpath->context= xpath->item;
|
||||
|
||||
/* treat double slash (//) as /descendant-or-self::node()/ */
|
||||
if (my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH))
|
||||
xpath->context= new Item_nodeset_func_descendantbyname(xpath->context,
|
||||
"*", 1, xpath->pxml, 1);
|
||||
rc= my_xpath_parse_RelativeLocationPath(xpath);
|
||||
|
||||
/* push back the context and restore the item */
|
||||
xpath->item= xpath->context;
|
||||
xpath->context= context;
|
||||
return rc;
|
||||
}
|
||||
static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
|
||||
{
|
||||
|
@ -144,8 +144,6 @@ public:
|
||||
void swap(my_decimal &rhs)
|
||||
{
|
||||
swap_variables(my_decimal, *this, rhs);
|
||||
/* Swap the buffer pointers back */
|
||||
swap_variables(decimal_digit_t *, buf, rhs.buf);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7543,12 +7543,15 @@ fn_format_relative_to_data_home(char * to, const char *name,
|
||||
bool is_secure_file_path(char *path)
|
||||
{
|
||||
char buff1[FN_REFLEN], buff2[FN_REFLEN];
|
||||
size_t opt_secure_file_priv_len;
|
||||
/*
|
||||
All paths are secure if opt_secure_file_path is 0
|
||||
*/
|
||||
if (!opt_secure_file_priv)
|
||||
return TRUE;
|
||||
|
||||
opt_secure_file_priv_len= strlen(opt_secure_file_priv);
|
||||
|
||||
if (strlen(path) >= FN_REFLEN)
|
||||
return FALSE;
|
||||
|
||||
@ -7566,11 +7569,24 @@ bool is_secure_file_path(char *path)
|
||||
return FALSE;
|
||||
}
|
||||
convert_dirname(buff2, buff1, NullS);
|
||||
if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
|
||||
if (!lower_case_file_system)
|
||||
{
|
||||
if (strncmp(opt_secure_file_priv, buff2, opt_secure_file_priv_len))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (files_charset_info->coll->strnncoll(files_charset_info,
|
||||
(uchar *) buff2, strlen(buff2),
|
||||
(uchar *) opt_secure_file_priv,
|
||||
opt_secure_file_priv_len,
|
||||
TRUE))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int fix_paths(void)
|
||||
{
|
||||
char buff[FN_REFLEN],*pos;
|
||||
|
@ -2591,8 +2591,9 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
|
||||
bzero((char*) &tables,sizeof(tables));
|
||||
tables.db= (char*) "mysql";
|
||||
tables.table_name= tables.alias= (char*) "proc";
|
||||
*full_access= (!check_table_access(thd, SELECT_ACL, &tables, FALSE,
|
||||
1, TRUE) ||
|
||||
*full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE,
|
||||
1, TRUE) &&
|
||||
(tables.grant.privilege & SELECT_ACL) != 0) ||
|
||||
(!strcmp(sp->m_definer_user.str,
|
||||
thd->security_ctx->priv_user) &&
|
||||
!strcmp(sp->m_definer_host.str,
|
||||
|
@ -825,8 +825,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
||||
|
||||
char *password= get_field(&mem, table->field[2]);
|
||||
uint password_len= password ? strlen(password) : 0;
|
||||
user.auth_string.str= password ? password : const_cast<char*>("");
|
||||
user.auth_string.length= password_len;
|
||||
set_user_salt(&user, password, password_len);
|
||||
|
||||
if (set_user_plugin(&user, password_len))
|
||||
@ -915,7 +913,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
||||
char *tmpstr= get_field(&mem, table->field[next_field++]);
|
||||
if (tmpstr)
|
||||
{
|
||||
if (user.auth_string.length)
|
||||
if (password_len)
|
||||
{
|
||||
sql_print_warning("'user' entry '%s@%s' has both a password "
|
||||
"and an authentication plugin specified. The "
|
||||
@ -1483,8 +1481,8 @@ static void acl_insert_user(const char *user, const char *host,
|
||||
{
|
||||
acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ?
|
||||
old_password_plugin_name : native_password_plugin_name;
|
||||
acl_user.auth_string.str= strmake_root(&mem, password, password_len);
|
||||
acl_user.auth_string.length= password_len;
|
||||
acl_user.auth_string.str= const_cast<char*>("");
|
||||
acl_user.auth_string.length= 0;
|
||||
}
|
||||
|
||||
acl_user.access=privileges;
|
||||
@ -8380,7 +8378,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
|
||||
old_password_plugin, otherwise MySQL will think that server
|
||||
and client plugins don't match.
|
||||
*/
|
||||
if (mpvio->acl_user->auth_string.length == 0)
|
||||
if (mpvio->acl_user->salt_len == 0)
|
||||
mpvio->acl_user_plugin= old_password_plugin_name;
|
||||
}
|
||||
}
|
||||
@ -8767,7 +8765,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
|
||||
old_password_plugin, otherwise MySQL will think that server
|
||||
and client plugins don't match.
|
||||
*/
|
||||
if (mpvio->acl_user->auth_string.length == 0)
|
||||
if (mpvio->acl_user->salt_len == 0)
|
||||
mpvio->acl_user_plugin= old_password_plugin_name;
|
||||
}
|
||||
}
|
||||
@ -9555,7 +9553,7 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
|
||||
#endif
|
||||
|
||||
if (pkt_len == 0) /* no password */
|
||||
DBUG_RETURN(info->auth_string[0] ? CR_ERROR : CR_OK);
|
||||
DBUG_RETURN(mpvio->acl_user->salt_len != 0 ? CR_ERROR : CR_OK);
|
||||
|
||||
info->password_used= PASSWORD_USED_YES;
|
||||
if (pkt_len == SCRAMBLE_LENGTH)
|
||||
@ -9604,7 +9602,7 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
|
||||
pkt_len= strnlen((char*)pkt, pkt_len);
|
||||
|
||||
if (pkt_len == 0) /* no password */
|
||||
return info->auth_string[0] ? CR_ERROR : CR_OK;
|
||||
return mpvio->acl_user->salt_len != 0 ? CR_ERROR : CR_OK;
|
||||
|
||||
if (secure_auth(mpvio))
|
||||
return CR_ERROR;
|
||||
|
@ -1755,6 +1755,8 @@ void st_select_lex::init_query()
|
||||
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
|
||||
nest_level= 0;
|
||||
link_next= 0;
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
}
|
||||
|
||||
void st_select_lex::init_select()
|
||||
@ -1785,7 +1787,8 @@ void st_select_lex::init_select()
|
||||
non_agg_fields.empty();
|
||||
cond_value= having_value= Item::COND_UNDEF;
|
||||
inner_refs_list.empty();
|
||||
full_group_by_flag= 0;
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -800,16 +800,7 @@ public:
|
||||
joins on the right.
|
||||
*/
|
||||
List<String> *prev_join_using;
|
||||
/*
|
||||
Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate
|
||||
functions and non aggregated fields when GROUP BY list is absent.
|
||||
Bits:
|
||||
0 - non aggregated fields are used in this select,
|
||||
defined as NON_AGG_FIELD_USED.
|
||||
1 - aggregate functions are used in this select,
|
||||
defined as SUM_FUNC_USED.
|
||||
*/
|
||||
uint8 full_group_by_flag;
|
||||
|
||||
void init_query();
|
||||
void init_select();
|
||||
st_select_lex_unit* master_unit();
|
||||
@ -918,7 +909,22 @@ public:
|
||||
|
||||
void clear_index_hints(void) { index_hints= NULL; }
|
||||
|
||||
/*
|
||||
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
|
||||
- Non-aggregated fields are used in this select.
|
||||
- Aggregate functions are used in this select.
|
||||
In MODE_ONLY_FULL_GROUP_BY only one of these may be true.
|
||||
*/
|
||||
bool non_agg_field_used() const { return m_non_agg_field_used; }
|
||||
bool agg_func_used() const { return m_agg_func_used; }
|
||||
|
||||
void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; }
|
||||
void set_agg_func_used(bool val) { m_agg_func_used= val; }
|
||||
|
||||
private:
|
||||
bool m_non_agg_field_used;
|
||||
bool m_agg_func_used;
|
||||
|
||||
/* current index hint kind. used in filling up index_hints */
|
||||
enum index_hint_type current_index_hint_type;
|
||||
index_clause_map current_index_hint_clause;
|
||||
|
@ -398,7 +398,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
|
||||
#if !defined(__WIN__) && ! defined(__NETWARE__)
|
||||
MY_STAT stat_info;
|
||||
if (!my_stat(name,&stat_info,MYF(MY_WME)))
|
||||
if (!my_stat(name, &stat_info, MYF(MY_WME)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
// if we are not in slave thread, the file must be:
|
||||
@ -411,7 +411,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
|
||||
is_fifo = 1;
|
||||
is_fifo= 1;
|
||||
#endif
|
||||
if ((file= mysql_file_open(key_file_load,
|
||||
name, O_RDONLY, MYF(MY_WME))) < 0)
|
||||
|
@ -1077,8 +1077,6 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||
int error;
|
||||
LEX *old_lex= thd->lex;
|
||||
LEX lex;
|
||||
uint8 saved_full_group_by_flag;
|
||||
nesting_map saved_allow_sum_func;
|
||||
DBUG_ENTER("fix_fields_part_func");
|
||||
|
||||
if (init_lex_with_single_table(thd, table, &lex))
|
||||
@ -1103,19 +1101,22 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||
This is a tricky call to prepare for since it can have a large number
|
||||
of interesting side effects, both desirable and undesirable.
|
||||
*/
|
||||
saved_full_group_by_flag= thd->lex->current_select->full_group_by_flag;
|
||||
saved_allow_sum_func= thd->lex->allow_sum_func;
|
||||
{
|
||||
const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
|
||||
const bool save_agg_func= thd->lex->current_select->agg_func_used();
|
||||
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func= 0;
|
||||
|
||||
error= func_expr->fix_fields(thd, (Item**)&func_expr);
|
||||
|
||||
/*
|
||||
Restore full_group_by_flag and allow_sum_func,
|
||||
Restore agg_field/agg_func and allow_sum_func,
|
||||
fix_fields should not affect mysql_select later, see Bug#46923.
|
||||
*/
|
||||
thd->lex->current_select->full_group_by_flag= saved_full_group_by_flag;
|
||||
thd->lex->current_select->set_non_agg_field_used(save_agg_field);
|
||||
thd->lex->current_select->set_agg_func_used(save_agg_func);
|
||||
thd->lex->allow_sum_func= saved_allow_sum_func;
|
||||
|
||||
}
|
||||
if (unlikely(error))
|
||||
{
|
||||
DBUG_PRINT("info", ("Field in partition function not part of table"));
|
||||
|
@ -260,13 +260,6 @@ enum enum_yes_no_unknown
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
/*
|
||||
A set of constants used for checking non aggregated fields and sum
|
||||
functions mixture in the ONLY_FULL_GROUP_BY_MODE.
|
||||
*/
|
||||
#define NON_AGG_FIELD_USED 1
|
||||
#define SUM_FUNC_USED 2
|
||||
|
||||
/*
|
||||
External variables
|
||||
*/
|
||||
|
@ -455,19 +455,18 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
|
||||
int res;
|
||||
nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
|
||||
/*
|
||||
Need to save the value, so we can turn off only the new NON_AGG_FIELD
|
||||
Need to save the value, so we can turn off only any new non_agg_field_used
|
||||
additions coming from the WHERE
|
||||
*/
|
||||
uint8 saved_flag= thd->lex->current_select->full_group_by_flag;
|
||||
const bool saved_non_agg_field_used=
|
||||
thd->lex->current_select->non_agg_field_used();
|
||||
DBUG_ENTER("setup_without_group");
|
||||
|
||||
thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
|
||||
res= setup_conds(thd, tables, leaves, conds);
|
||||
|
||||
/* it's not wrong to have non-aggregated columns in a WHERE */
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
thd->lex->current_select->full_group_by_flag= saved_flag |
|
||||
(thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED);
|
||||
thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used);
|
||||
|
||||
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
|
||||
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
||||
@ -673,7 +672,8 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
aggregate functions with implicit grouping (there is no GROUP BY).
|
||||
*/
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
|
||||
select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
|
||||
select_lex->non_agg_field_used() &&
|
||||
select_lex->agg_func_used())
|
||||
{
|
||||
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
||||
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
|
||||
|
@ -1,60 +0,0 @@
|
||||
-- Copyright (c) 2005 MySQL AB
|
||||
-- Use is subject to license terms.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; version 2 of the License.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS BANK default charset=latin1 default collate=latin1_bin;
|
||||
USE BANK;
|
||||
DROP TABLE IF EXISTS GL;
|
||||
CREATE TABLE GL ( TIME BIGINT UNSIGNED NOT NULL,
|
||||
ACCOUNT_TYPE INT UNSIGNED NOT NULL,
|
||||
BALANCE INT UNSIGNED NOT NULL,
|
||||
DEPOSIT_COUNT INT UNSIGNED NOT NULL,
|
||||
DEPOSIT_SUM INT UNSIGNED NOT NULL,
|
||||
WITHDRAWAL_COUNT INT UNSIGNED NOT NULL,
|
||||
WITHDRAWAL_SUM INT UNSIGNED NOT NULL,
|
||||
PURGED INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY USING HASH (TIME,ACCOUNT_TYPE))
|
||||
ENGINE = NDB;
|
||||
|
||||
DROP TABLE IF EXISTS ACCOUNT;
|
||||
CREATE TABLE ACCOUNT ( ACCOUNT_ID INT UNSIGNED NOT NULL,
|
||||
OWNER INT UNSIGNED NOT NULL,
|
||||
BALANCE INT UNSIGNED NOT NULL,
|
||||
ACCOUNT_TYPE INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY USING HASH (ACCOUNT_ID))
|
||||
ENGINE = NDB;
|
||||
|
||||
DROP TABLE IF EXISTS TRANSACTION;
|
||||
CREATE TABLE TRANSACTION ( TRANSACTION_ID BIGINT UNSIGNED NOT NULL,
|
||||
ACCOUNT INT UNSIGNED NOT NULL,
|
||||
ACCOUNT_TYPE INT UNSIGNED NOT NULL,
|
||||
OTHER_ACCOUNT INT UNSIGNED NOT NULL,
|
||||
TRANSACTION_TYPE INT UNSIGNED NOT NULL,
|
||||
TIME BIGINT UNSIGNED NOT NULL,
|
||||
AMOUNT INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY USING HASH (TRANSACTION_ID,ACCOUNT))
|
||||
ENGINE = NDB;
|
||||
|
||||
DROP TABLE IF EXISTS SYSTEM_VALUES;
|
||||
CREATE TABLE SYSTEM_VALUES ( SYSTEM_VALUES_ID INT UNSIGNED NOT NULL,
|
||||
VALUE BIGINT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY USING HASH (SYSTEM_VALUES_ID))
|
||||
ENGINE = NDB;
|
||||
|
||||
DROP TABLE IF EXISTS ACCOUNT_TYPE;
|
||||
CREATE TABLE ACCOUNT_TYPE ( ACCOUNT_TYPE_ID INT UNSIGNED NOT NULL,
|
||||
DESCRIPTION CHAR(64) NOT NULL,
|
||||
PRIMARY KEY USING HASH (ACCOUNT_TYPE_ID))
|
||||
ENGINE = NDB;
|
@ -1,25 +0,0 @@
|
||||
-- Copyright (c) 2005 MySQL AB
|
||||
-- Use is subject to license terms.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; version 2 of the License.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
create database if not exists TEST_DB;
|
||||
use TEST_DB;
|
||||
drop table if exists T1;
|
||||
create table T1 (KOL1 int unsigned not null,
|
||||
KOL2 int unsigned not null,
|
||||
KOL3 int unsigned not null,
|
||||
KOL4 int unsigned not null,
|
||||
KOL5 int unsigned not null,
|
||||
primary key using hash(KOL1)) engine=ndb;
|
@ -1,196 +0,0 @@
|
||||
# Copyright (C) 2005 MySQL AB
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public
|
||||
# License as published by the Free Software Foundation; version 2
|
||||
# of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA
|
||||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use DBI;
|
||||
|
||||
# mgm info
|
||||
my $mgmhost = "localhost";
|
||||
my $mgmport = 38101;
|
||||
|
||||
# location of ndb_x_fs
|
||||
my $datadir = "c2";
|
||||
my @schemafiles = <$datadir/ndb_*_fs/D[12]/DBDICT/P0.SchemaLog>;
|
||||
@schemafiles or die "no schemafiles in $datadir";
|
||||
|
||||
my $dsn;
|
||||
$dsn = "dbi:mysql:test:localhost;port=38100";
|
||||
|
||||
# this works better for me
|
||||
my $cnf = $ENV{MYSQL_HOME} . "/var/my.cnf";
|
||||
$dsn = "dbi:mysql:database=test;host=localhost;mysql_read_default_file=$cnf";
|
||||
|
||||
my $dbh;
|
||||
$dbh = DBI->connect($dsn, 'root', undef, { RaiseError => 0, PrintError => 0 });
|
||||
$dbh or die $DBI::errstr;
|
||||
|
||||
# mgm commands
|
||||
|
||||
my $mgm = undef;
|
||||
|
||||
sub mgmconnect {
|
||||
$mgm = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerHost => $mgmhost,
|
||||
PeerPort => $mgmport);
|
||||
$mgm or die "connect to mgm failed: $!";
|
||||
$mgm->autoflush(1);
|
||||
};
|
||||
|
||||
mgmconnect();
|
||||
warn "connected to mgm $mgmhost $mgmport\n";
|
||||
|
||||
my $nodeinfo = {};
|
||||
|
||||
sub getnodeinfo {
|
||||
$nodeinfo = {};
|
||||
$mgm->print("get status\n");
|
||||
$mgm->print("\n");
|
||||
while (defined($_ = $mgm->getline)) {
|
||||
/^node\s+status/ && last;
|
||||
}
|
||||
while (defined($_ = $mgm->getline)) {
|
||||
/^\s*$/ && last;
|
||||
/^node\.(\d+)\.(\w+):\s*(\S+)/ && ($nodeinfo->{$1}{$2} = $3);
|
||||
}
|
||||
}
|
||||
|
||||
getnodeinfo();
|
||||
|
||||
my @dbnode = ();
|
||||
for my $n (keys %$nodeinfo) {
|
||||
my $p = $nodeinfo->{$n};
|
||||
($p->{type} eq 'NDB') && push(@dbnode, $n);
|
||||
}
|
||||
@dbnode = sort { $a <=> $b } @dbnode;
|
||||
@dbnode or die "mgm error, found no db nodes";
|
||||
warn "db nodes: @dbnode\n";
|
||||
|
||||
sub restartnode {
|
||||
my($n, $initialstart) = @_;
|
||||
warn "restart node $n initialstart=$initialstart\n";
|
||||
$mgm->print("restart node\n");
|
||||
$mgm->print("node: $n\n");
|
||||
$mgm->print("initialstart: $initialstart\n");
|
||||
$mgm->print("\n");
|
||||
while (1) {
|
||||
sleep 5;
|
||||
getnodeinfo();
|
||||
my $status = $nodeinfo->{$n}{status};
|
||||
my $sp = $nodeinfo->{$n}{startphase};
|
||||
warn "node $n status: $status sp: $sp\n";
|
||||
last if $status eq 'STARTED';
|
||||
}
|
||||
}
|
||||
|
||||
sub restartall {
|
||||
warn "restart all\n";
|
||||
$mgm->print("restart all\n");
|
||||
$mgm->print("\n");
|
||||
while (1) {
|
||||
sleep 5;
|
||||
getnodeinfo();
|
||||
my $ok = 1;
|
||||
for my $n (@dbnode) {
|
||||
my $status = $nodeinfo->{$n}{status};
|
||||
my $sp = $nodeinfo->{$n}{startphase};
|
||||
warn "node $n status: $status sp: $sp\n";
|
||||
$ok = 0 if $status ne 'STARTED';
|
||||
}
|
||||
last if $ok;
|
||||
}
|
||||
}
|
||||
|
||||
# the sql stuff
|
||||
|
||||
my $maxtab = 300;
|
||||
my @tab = ();
|
||||
|
||||
sub create {
|
||||
my($n) = @_;
|
||||
my $sql = "create table t$n (a int primary key, b varchar(20), key (b)) engine=ndb";
|
||||
warn "create t$n\n";
|
||||
$dbh->do($sql) or die "$sql\n$DBI::errstr";
|
||||
}
|
||||
|
||||
sub drop {
|
||||
my($n) = @_;
|
||||
my $sql = "drop table t$n";
|
||||
warn "drop t$n\n";
|
||||
$dbh->do($sql) or die "$sql\n$DBI::errstr";
|
||||
}
|
||||
|
||||
sub dropall {
|
||||
for my $n (0..($maxtab-1)) {
|
||||
my $sql = "drop table if exists t$n";
|
||||
$dbh->do($sql) or die "$sql\n$DBI::errstr";
|
||||
}
|
||||
}
|
||||
|
||||
sub createdrop {
|
||||
my $n = int(rand($maxtab));
|
||||
if (! $tab[$n]) {
|
||||
create($n);
|
||||
$tab[$n] = 1;
|
||||
} else {
|
||||
drop($n);
|
||||
$tab[$n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub checkschemafiles {
|
||||
system("printSchemaFile -ce @schemafiles");
|
||||
$? == 0 or die "schemafiles check failed";
|
||||
}
|
||||
|
||||
sub randomrestart {
|
||||
my($k) = @_;
|
||||
my $s = int(rand(500));
|
||||
if ($s < 2) {
|
||||
my $i = $k % scalar(@dbnode);
|
||||
my $n = $dbnode[$i];
|
||||
my $initialstart = ($s < 1 ? 0 : 1);
|
||||
restartnode($n, $initialstart);
|
||||
return 1;
|
||||
}
|
||||
if ($s < 3) {
|
||||
restartall();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# deterministic
|
||||
srand(1);
|
||||
|
||||
warn "drop any old tables\n";
|
||||
dropall();
|
||||
|
||||
my $loop = 1000000;
|
||||
for my $k (0..($loop-1)) {
|
||||
warn "$k\n";
|
||||
createdrop();
|
||||
checkschemafiles();
|
||||
if (randomrestart($k)) {
|
||||
checkschemafiles();
|
||||
}
|
||||
}
|
||||
|
||||
$dbh->disconnect or die $DBI::errstr;
|
||||
|
||||
# vim: set sw=2:
|
@ -1,235 +0,0 @@
|
||||
# Copyright (C) 2005 MySQL AB
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public
|
||||
# License as published by the Free Software Foundation; version 2
|
||||
# of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA
|
||||
|
||||
#
|
||||
# test range scan bounds
|
||||
# give option --all to test all cases
|
||||
# set MYSQL_HOME to installation top
|
||||
#
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
use Getopt::Long;
|
||||
use DBI;
|
||||
|
||||
my $opt_all = 0;
|
||||
my $opt_cnt = 5;
|
||||
my $opt_verbose = 0;
|
||||
GetOptions("all" => \$opt_all, "cnt=i" => \$opt_cnt, "verbose" => \$opt_verbose)
|
||||
or die "options are: --all --cnt=N --verbose";
|
||||
|
||||
my $mysql_home = $ENV{MYSQL_HOME};
|
||||
defined($mysql_home) or die "no MYSQL_HOME";
|
||||
my $dsn = "dbi:mysql:database=test;host=localhost;mysql_read_default_file=$mysql_home/var/my.cnf";
|
||||
my $opts = { RaiseError => 0, PrintError => 0, AutoCommit => 1, };
|
||||
|
||||
my $dbh;
|
||||
my $sth;
|
||||
my $sql;
|
||||
|
||||
$dbh = DBI->connect($dsn, "root", undef, $opts) or die $DBI::errstr;
|
||||
|
||||
my $table = 't';
|
||||
|
||||
$sql = "drop table if exists $table";
|
||||
$dbh->do($sql) or die $DBI::errstr;
|
||||
|
||||
sub cut ($$$) {
|
||||
my($op, $key, $val) = @_;
|
||||
$op = '==' if $op eq '=';
|
||||
my(@w) = @$val;
|
||||
eval "\@w = grep(\$_ $op $key, \@w)";
|
||||
$@ and die $@;
|
||||
return [ @w ];
|
||||
}
|
||||
|
||||
sub mkdummy ($) {
|
||||
my ($val) = @_;
|
||||
return {
|
||||
'dummy' => 1,
|
||||
'exp' => '9 = 9',
|
||||
'res' => $val,
|
||||
};
|
||||
}
|
||||
|
||||
sub mkone ($$$$) {
|
||||
my($col, $op, $key, $val) = @_;
|
||||
my $res = cut($op, $key, $val);
|
||||
return {
|
||||
'exp' => "$col $op $key",
|
||||
'res' => $res,
|
||||
};
|
||||
}
|
||||
|
||||
sub mktwo ($$$$$$) {
|
||||
my($col, $op1, $key1, $op2, $key2, $val) = @_;
|
||||
my $res = cut($op2, $key2, cut($op1, $key1, $val));
|
||||
return {
|
||||
'exp' => "$col $op1 $key1 and $col $op2 $key2",
|
||||
'res' => $res,
|
||||
};
|
||||
}
|
||||
|
||||
sub mkall ($$$$) {
|
||||
my($col, $key1, $key2, $val) = @_;
|
||||
my @a = ();
|
||||
my $p = mkdummy($val);
|
||||
push(@a, $p) if $opt_all;
|
||||
my @ops = qw(< <= = >= >);
|
||||
for my $op (@ops) {
|
||||
my $p = mkone($col, $op, $key1, $val);
|
||||
push(@a, $p) if $opt_all || @{$p->{res}} != 0;
|
||||
}
|
||||
my @ops1 = $opt_all ? @ops : qw(= >= >);
|
||||
my @ops2 = $opt_all ? @ops : qw(<= <);
|
||||
for my $op1 (@ops1) {
|
||||
for my $op2 (@ops2) {
|
||||
my $p = mktwo($col, $op1, $key1, $op2, $key2, $val);
|
||||
push(@a, $p) if $opt_all || @{$p->{res}} != 0;
|
||||
}
|
||||
}
|
||||
warn scalar(@a)." cases\n" if $opt_verbose;
|
||||
return \@a;
|
||||
}
|
||||
|
||||
my $casecnt = 0;
|
||||
|
||||
sub verify ($$$) {
|
||||
my($sql, $ord, $res) = @_;
|
||||
warn "$sql\n" if $opt_verbose;
|
||||
$sth = $dbh->prepare($sql) or die "prepare: $sql: $DBI::errstr";
|
||||
$sth->execute() or die "execute: $sql: $DBI::errstr";
|
||||
#
|
||||
# BUG: execute can return success on error so check again
|
||||
#
|
||||
$sth->err and die "execute: $sql: $DBI::errstr";
|
||||
my @out = ();
|
||||
for my $b (@{$res->[0]}) {
|
||||
for my $c (@{$res->[1]}) {
|
||||
for my $d (@{$res->[2]}) {
|
||||
push(@out, [$b, $c, $d]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($ord) {
|
||||
@out = sort {
|
||||
$ord * ($a->[0] - $b->[0]) ||
|
||||
$ord * ($a->[1] - $b->[1]) ||
|
||||
$ord * ($a->[2] - $b->[2]) ||
|
||||
0
|
||||
} @out;
|
||||
}
|
||||
my $cnt = scalar @out;
|
||||
my $n = 0;
|
||||
while (1) {
|
||||
my $row = $sth->fetchrow_arrayref;
|
||||
$row || last;
|
||||
@$row == 3 or die "bad row: $sql: @$row";
|
||||
for my $v (@$row) {
|
||||
$v =~ s/^\s+|\s+$//g;
|
||||
$v =~ /^\d+$/ or die "bad value: $sql: $v";
|
||||
}
|
||||
if ($ord) {
|
||||
my $out = $out[$n];
|
||||
$row->[0] == $out->[0] &&
|
||||
$row->[1] == $out->[1] &&
|
||||
$row->[2] == $out->[2] or
|
||||
die "$sql: row $n: got row @$row != @$out";
|
||||
}
|
||||
$n++;
|
||||
}
|
||||
$sth->err and die "fetch: $sql: $DBI::errstr";
|
||||
$n == $cnt or die "verify: $sql: got row count $n != $cnt";
|
||||
$casecnt++;
|
||||
}
|
||||
|
||||
for my $nn ("bcd", "") {
|
||||
my %nn;
|
||||
for my $x (qw(b c d)) {
|
||||
$nn{$x} = $nn =~ /$x/ ? "not null" : "null";
|
||||
}
|
||||
warn "create table\n";
|
||||
$sql = <<EOF;
|
||||
create table $table (
|
||||
a int primary key,
|
||||
b int $nn{b},
|
||||
c int $nn{c},
|
||||
d int $nn{d},
|
||||
index (b, c, d)
|
||||
) engine=ndb
|
||||
EOF
|
||||
$dbh->do($sql) or die $DBI::errstr;
|
||||
warn "insert\n";
|
||||
$sql = "insert into $table values(?, ?, ?, ?)";
|
||||
$sth = $dbh->prepare($sql) or die $DBI::errstr;
|
||||
my @val = (0..($opt_cnt-1));
|
||||
my $v0 = 0;
|
||||
for my $v1 (@val) {
|
||||
for my $v2 (@val) {
|
||||
for my $v3 (@val) {
|
||||
$sth->bind_param(1, $v0) or die $DBI::errstr;
|
||||
$sth->bind_param(2, $v1) or die $DBI::errstr;
|
||||
$sth->bind_param(3, $v2) or die $DBI::errstr;
|
||||
$sth->bind_param(4, $v3) or die $DBI::errstr;
|
||||
$sth->execute or die $DBI::errstr;
|
||||
$v0++;
|
||||
}
|
||||
}
|
||||
}
|
||||
warn "generate cases\n";
|
||||
my $key1 = 1;
|
||||
my $key2 = 3;
|
||||
my $a1 = mkall('b', $key1, $key2, \@val);
|
||||
my $a2 = mkall('c', $key1, $key2, \@val);
|
||||
my $a3 = mkall('d', $key1, $key2, \@val);
|
||||
warn "select\n";
|
||||
for my $ord (0, +1, -1) {
|
||||
my $orderby =
|
||||
$ord == 0 ? "" :
|
||||
$ord == +1 ? " order by b, c, d" :
|
||||
$ord == -1 ? " order by b desc, c desc, d desc" : die "not here";
|
||||
for my $p1 (@$a1) {
|
||||
my $res = [ $p1->{res}, \@val, \@val ];
|
||||
$sql = "select b, c, d from $table" .
|
||||
" where $p1->{exp}" .
|
||||
$orderby;
|
||||
verify($sql, $ord, $res);
|
||||
for my $p2 (@$a2) {
|
||||
my $res = [ $p1->{res}, $p2->{res}, \@val ];
|
||||
$sql = "select b, c, d from $table" .
|
||||
" where $p1->{exp} and $p2->{exp}" .
|
||||
$orderby;
|
||||
verify($sql, $ord, $res);
|
||||
for my $p3 (@$a3) {
|
||||
my $res = [ $p1->{res}, $p2->{res}, $p3->{res} ];
|
||||
$sql = "select b, c, d from $table" .
|
||||
" where $p1->{exp} and $p2->{exp} and $p3->{exp}" .
|
||||
$orderby;
|
||||
verify($sql, $ord, $res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
warn "drop table\n";
|
||||
$sql = "drop table $table";
|
||||
$dbh->do($sql) or die $DBI::errstr;
|
||||
}
|
||||
|
||||
warn "verified $casecnt cases\n";
|
||||
warn "done\n";
|
||||
|
||||
# vim: set sw=2:
|
Loading…
x
Reference in New Issue
Block a user