Commit 3213d510 authored by Staale Smedseng's avatar Staale Smedseng

Commit after merge from 5.1-bugteam

parents 0b46a263 f075494e
...@@ -1295,6 +1295,8 @@ mysql-test/linux_sys_vars.inc ...@@ -1295,6 +1295,8 @@ mysql-test/linux_sys_vars.inc
mysql-test/load_sysvars.inc mysql-test/load_sysvars.inc
mysql-test/mtr mysql-test/mtr
mysql-test/mysql-test-run mysql-test/mysql-test-run
mysql-test/mysql-test-gcov.err
mysql-test/mysql-test-gcov.msg
mysql-test/mysql-test-run-shell mysql-test/mysql-test-run-shell
mysql-test/mysql-test-run.log mysql-test/mysql-test-run.log
mysql-test/mysql_test_run_new mysql-test/mysql_test_run_new
......
...@@ -22,40 +22,46 @@ use strict; ...@@ -22,40 +22,46 @@ use strict;
sub gcov_prepare ($) { sub gcov_prepare ($) {
my ($dir)= @_; my ($dir)= @_;
print "Purging gcov information from '$dir'...\n";
`find $dir -name \*.gcov \ system("find $dir -name \*.gcov -o -name \*.da"
-or -name \*.da | xargs rm`; . " -o -name \*.gcda | grep -v 'README.gcov\$' | xargs rm");
} }
my @mysqld_src_dirs= #
( # Collect gcov statistics.
"strings", # Arguments:
"mysys", # $dir basedir, normally source directory
"include", # $gcov gcov utility program [path] name
"extra", # $gcov_msg message file name
"regex", # $gcov_err error file name
"isam", #
"merge",
"myisam",
"myisammrg",
"heap",
"sql",
);
sub gcov_collect ($$$) { sub gcov_collect ($$$) {
my ($dir, $gcov, $gcov_msg, $gcov_err)= @_; my ($dir, $gcov, $gcov_msg, $gcov_err)= @_;
# Get current directory to return to later.
my $start_dir= cwd(); my $start_dir= cwd();
print "Collecting source coverage info...\n"; print "Collecting source coverage info using '$gcov'...\n";
-f $gcov_msg and unlink($gcov_msg); -f "$start_dir/$gcov_msg" and unlink("$start_dir/$gcov_msg");
-f $gcov_err and unlink($gcov_err); -f "$start_dir/$gcov_err" and unlink("$start_dir/$gcov_err");
foreach my $d ( @mysqld_src_dirs )
{ my @dirs= `find "$dir" -type d -print | sort`;
chdir("$dir/$d"); #print "List of directories:\n@dirs\n";
foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) )
{ foreach my $d ( @dirs ) {
`$gcov $f 2>>$gcov_err >>$gcov_msg`; my $dir_reported= 0;
chomp($d);
chdir($d) or next;
foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) ) {
$f =~ /(.*)\.[ch]c?/;
-f "$1.gcno" or next;
if (!$dir_reported) {
print "Collecting in '$d'...\n";
$dir_reported= 1;
}
system("$gcov $f 2>>$start_dir/$gcov_err >>$start_dir/$gcov_msg");
} }
chdir($start_dir); chdir($start_dir);
} }
......
...@@ -163,8 +163,9 @@ our $opt_force; ...@@ -163,8 +163,9 @@ our $opt_force;
our $opt_mem= $ENV{'MTR_MEM'}; our $opt_mem= $ENV{'MTR_MEM'};
our $opt_gcov; our $opt_gcov;
our $opt_gcov_err; our $opt_gcov_exe= "gcov";
our $opt_gcov_msg; our $opt_gcov_err= "mysql-test-gcov.msg";
our $opt_gcov_msg= "mysql-test-gcov.err";
our $glob_debugger= 0; our $glob_debugger= 0;
our $opt_gdb; our $opt_gdb;
...@@ -396,7 +397,7 @@ sub main { ...@@ -396,7 +397,7 @@ sub main {
mtr_print_line(); mtr_print_line();
if ( $opt_gcov ) { if ( $opt_gcov ) {
gcov_collect($basedir, $opt_gcov, gcov_collect($basedir, $opt_gcov_exe,
$opt_gcov_msg, $opt_gcov_err); $opt_gcov_msg, $opt_gcov_err);
} }
...@@ -5057,6 +5058,8 @@ Misc options ...@@ -5057,6 +5058,8 @@ Misc options
to turn off. to turn off.
sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
gcov Collect coverage information after the test.
The result is a gcov file per source and header file.
HERE HERE
exit(1); exit(1);
......
...@@ -1691,3 +1691,15 @@ FROM t1; ...@@ -1691,3 +1691,15 @@ FROM t1;
ERROR 21000: Subquery returns more than 1 row ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1; DROP TABLE t1;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(i INT);
INSERT INTO t1 VALUES (1), (10);
SELECT COUNT(i) FROM t1;
COUNT(i)
2
SELECT COUNT(i) FROM t1 WHERE i > 1;
COUNT(i)
1
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;
...@@ -2448,3 +2448,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -2448,3 +2448,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a` Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a`
drop table t1; drop table t1;
CREATE TABLE t1 (a int, b int, c int, d int,
KEY foo (c,d,a,b), KEY bar (c,a,b,d));
INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4);
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT a,b,c+1,d FROM t1;
EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL foo 10 NULL 9 Using where; Using index for group-by
SELECT DISTINCT c FROM t1 WHERE d=4;
c
1
2
DROP TABLE t1;
End of 5.0 tests
...@@ -299,59 +299,107 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000; ...@@ -299,59 +299,107 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5); select ROUND(RAND(),5);
ROUND(RAND(),5) ROUND(RAND(),5)
0.02887 0.02887
show variables like '%alloc%';
==+ Testing %alloc% system variables +==
==+ NOTE: These values *must* be a multiple of 1024 +==
==+ Other values will be rounded down to nearest multiple +==
==+ Show initial values +==
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
Variable_name Value Variable_name Value
query_alloc_block_size 8192 query_alloc_block_size 8192
query_prealloc_size 8192 query_prealloc_size 8192
range_alloc_block_size 4096 range_alloc_block_size 4096
transaction_alloc_block_size 8192 transaction_alloc_block_size 8192
transaction_prealloc_size 4096 transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; ==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192 QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192 QUERY_PREALLOC_SIZE 8192
RANGE_ALLOC_BLOCK_SIZE 4096 RANGE_ALLOC_BLOCK_SIZE 4096
TRANSACTION_ALLOC_BLOCK_SIZE 8192 TRANSACTION_ALLOC_BLOCK_SIZE 8192
TRANSACTION_PREALLOC_SIZE 4096 TRANSACTION_PREALLOC_SIZE 4096
set @@range_alloc_block_size=1024*16; Testing values that are multiples of 1024
set @@range_alloc_block_size=1024*15+1024;
set @@query_alloc_block_size=1024*15+1024*2;
set @@query_prealloc_size=1024*18-1024;
set @@transaction_alloc_block_size=1024*21-1024*1;
set @@transaction_prealloc_size=1024*21-2048;
==+ Check manipulated values ==+
select @@query_alloc_block_size;
@@query_alloc_block_size
17408
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
Variable_name Value
query_alloc_block_size 17408
query_prealloc_size 17408
range_alloc_block_size 16384
transaction_alloc_block_size 20480
transaction_prealloc_size 19456
==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 17408
QUERY_PREALLOC_SIZE 17408
RANGE_ALLOC_BLOCK_SIZE 16384
TRANSACTION_ALLOC_BLOCK_SIZE 20480
TRANSACTION_PREALLOC_SIZE 19456
==+ Manipulate variable values +==
Testing values that are not 1024 multiples
set @@range_alloc_block_size=1024*16+1023;
set @@query_alloc_block_size=1024*17+2; set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18; set @@query_prealloc_size=1024*18-1023;
set @@transaction_alloc_block_size=1024*20-1; set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1; set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size; select @@query_alloc_block_size;
@@query_alloc_block_size @@query_alloc_block_size
17408 17408
show variables like '%alloc%'; ==+ Check manipulated values ==+
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
Variable_name Value Variable_name Value
query_alloc_block_size 17408 query_alloc_block_size 17408
query_prealloc_size 18432 query_prealloc_size 17408
range_alloc_block_size 16384 range_alloc_block_size 16384
transaction_alloc_block_size 19456 transaction_alloc_block_size 19456
transaction_prealloc_size 20480 transaction_prealloc_size 20480
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; ==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 17408 QUERY_ALLOC_BLOCK_SIZE 17408
QUERY_PREALLOC_SIZE 18432 QUERY_PREALLOC_SIZE 17408
RANGE_ALLOC_BLOCK_SIZE 16384 RANGE_ALLOC_BLOCK_SIZE 16384
TRANSACTION_ALLOC_BLOCK_SIZE 19456 TRANSACTION_ALLOC_BLOCK_SIZE 19456
TRANSACTION_PREALLOC_SIZE 20480 TRANSACTION_PREALLOC_SIZE 20480
==+ Set values back to the default values +==
set @@range_alloc_block_size=default; set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%'; ==+ Check the values now that they are reset +==
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
Variable_name Value Variable_name Value
query_alloc_block_size 8192 query_alloc_block_size 8192
query_prealloc_size 8192 query_prealloc_size 8192
range_alloc_block_size 4096 range_alloc_block_size 4096
transaction_alloc_block_size 8192 transaction_alloc_block_size 8192
transaction_prealloc_size 4096 transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
RANGE_ALLOC_BLOCK_SIZE 4096
TRANSACTION_ALLOC_BLOCK_SIZE 8192
TRANSACTION_PREALLOC_SIZE 4096
SELECT @@version LIKE 'non-existent'; SELECT @@version LIKE 'non-existent';
@@version LIKE 'non-existent' @@version LIKE 'non-existent'
0 0
......
...@@ -921,6 +921,32 @@ c4 ...@@ -921,6 +921,32 @@ c4
DROP DATABASE mysqltest1; DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
USE db1;
SELECT f1 FROM t1;
f1
SELECT f2 FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 't1'
SELECT * FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
SELECT f1 FROM v1;
f1
SELECT f2 FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'v1'
SELECT * FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'v1'
USE test;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
End of 5.0 tests. End of 5.0 tests.
DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
......
...@@ -18,6 +18,8 @@ insert into t1 values (3,5,"C"); ...@@ -18,6 +18,8 @@ insert into t1 values (3,5,"C");
insert into t1 values (3,6,"D"); insert into t1 values (3,6,"D");
# Test of MySQL field extension with and without matching records. # Test of MySQL field extension with and without matching records.
#### Note: The two following statements may fail if the execution plan
#### or optimizer is changed. The result for column c is undefined.
select a,c,sum(a) from t1 group by a; select a,c,sum(a) from t1 group by a;
select a,c,sum(a) from t1 where a > 10 group by a; select a,c,sum(a) from t1 where a > 10 group by a;
select sum(a) from t1 where a > 10; select sum(a) from t1 where a > 10;
......
...@@ -1139,4 +1139,22 @@ DROP TABLE t1; ...@@ -1139,4 +1139,22 @@ DROP TABLE t1;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
#
# Bug#42567 Invalid GROUP BY error
#
# Setup of the subtest
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(i INT);
INSERT INTO t1 VALUES (1), (10);
# The actual test
SELECT COUNT(i) FROM t1;
SELECT COUNT(i) FROM t1 WHERE i > 1;
# Cleanup of subtest
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;
...@@ -961,3 +961,25 @@ insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; ...@@ -961,3 +961,25 @@ insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a;
select * from t1; select * from t1;
explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
drop table t1; drop table t1;
#
# Bug #41610: key_infix_len can be overwritten causing some group by queries
# to return no rows
#
CREATE TABLE t1 (a int, b int, c int, d int,
KEY foo (c,d,a,b), KEY bar (c,a,b,d));
INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4);
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT a,b,c+1,d FROM t1;
#Should be non-empty
EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4;
SELECT DISTINCT c FROM t1 WHERE d=4;
DROP TABLE t1;
--echo End of 5.0 tests
...@@ -946,8 +946,13 @@ set global max_prepared_stmt_count=3; ...@@ -946,8 +946,13 @@ set global max_prepared_stmt_count=3;
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
prepare stmt from "select 1"; prepare stmt from "select 1";
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
# Switch to connection con1
connection con1; connection con1;
let $con1_id=`SELECT CONNECTION_ID()`;
prepare stmt from "select 2"; prepare stmt from "select 2";
prepare stmt1 from "select 3"; prepare stmt1 from "select 3";
--error ER_MAX_PREPARED_STMT_COUNT_REACHED --error ER_MAX_PREPARED_STMT_COUNT_REACHED
...@@ -957,18 +962,17 @@ connection default; ...@@ -957,18 +962,17 @@ connection default;
prepare stmt2 from "select 4"; prepare stmt2 from "select 4";
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
# Disconnect connection con1 and switch to default connection
disconnect con1; disconnect con1;
connection default; connection default;
# Wait for the connection to die: deal with a possible race
# Wait for the connection con1 to die
let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist WHERE id=$con1_id;
--source include/wait_condition.inc
deallocate prepare stmt; deallocate prepare stmt;
let $query= select variable_value from information_schema.global_status
where variable_name = 'prepared_stmt_count';
let $count= `$query`;
if ($count)
{
--sleep 1
let $count= `$query`;
}
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
# #
......
...@@ -173,21 +173,63 @@ select @@timestamp>0; ...@@ -173,21 +173,63 @@ select @@timestamp>0;
set @@rand_seed1=10000000,@@rand_seed2=1000000; set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5); select ROUND(RAND(),5);
show variables like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; --echo
set @@range_alloc_block_size=1024*16; --echo ==+ Testing %alloc% system variables +==
--echo ==+ NOTE: These values *must* be a multiple of 1024 +==
--echo ==+ Other values will be rounded down to nearest multiple +==
--echo
--echo ==+ Show initial values +==
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
--echo ==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
--echo Testing values that are multiples of 1024
set @@range_alloc_block_size=1024*15+1024;
set @@query_alloc_block_size=1024*15+1024*2;
set @@query_prealloc_size=1024*18-1024;
set @@transaction_alloc_block_size=1024*21-1024*1;
set @@transaction_prealloc_size=1024*21-2048;
--echo ==+ Check manipulated values ==+
select @@query_alloc_block_size;
SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
--echo ==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
--echo ==+ Manipulate variable values +==
--echo Testing values that are not 1024 multiples
set @@range_alloc_block_size=1024*16+1023;
set @@query_alloc_block_size=1024*17+2; set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18; set @@query_prealloc_size=1024*18-1023;
set @@transaction_alloc_block_size=1024*20-1; set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1; set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size; select @@query_alloc_block_size;
show variables like '%alloc%'; --echo ==+ Check manipulated values ==+
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
--echo ==+ information_schema data +==
SELECT * FROM information_schema.session_variables
WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size') ORDER BY 1;
--echo ==+ Set values back to the default values +==
set @@range_alloc_block_size=default; set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%'; --echo ==+ Check the values now that they are reset +==
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size',
'query_alloc_block_size', 'query_prealloc_size',
'transaction_alloc_block_size', 'transaction_prealloc_size');
# #
# Bug #10904 Illegal mix of collations between # Bug #10904 Illegal mix of collations between
......
...@@ -1191,6 +1191,46 @@ DROP DATABASE mysqltest1; ...@@ -1191,6 +1191,46 @@ DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
#
# Bug #41354: Access control is bypassed when all columns of a view are
# selected by * wildcard
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
connect (addconfoo, localhost, foo,,);
connection addconfoo;
USE db1;
SELECT f1 FROM t1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM t1;
SELECT f1 FROM v1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM v1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM v1;
connection default;
USE test;
disconnect addconfoo;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
......
...@@ -9239,32 +9239,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9239,32 +9239,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/ */
KEY *cur_index_info= table->key_info; KEY *cur_index_info= table->key_info;
KEY *cur_index_info_end= cur_index_info + table->s->keys; KEY *cur_index_info_end= cur_index_info + table->s->keys;
KEY_PART_INFO *cur_part= NULL;
KEY_PART_INFO *end_part; /* Last part for loops. */
/* Last index part. */
KEY_PART_INFO *last_part= NULL;
KEY_PART_INFO *first_non_group_part= NULL;
KEY_PART_INFO *first_non_infix_part= NULL;
uint key_infix_parts= 0;
uint cur_group_key_parts= 0;
uint cur_group_prefix_len= 0;
/* Cost-related variables for the best index so far. */ /* Cost-related variables for the best index so far. */
double best_read_cost= DBL_MAX; double best_read_cost= DBL_MAX;
ha_rows best_records= 0; ha_rows best_records= 0;
SEL_ARG *best_index_tree= NULL; SEL_ARG *best_index_tree= NULL;
ha_rows best_quick_prefix_records= 0; ha_rows best_quick_prefix_records= 0;
uint best_param_idx= 0; uint best_param_idx= 0;
double cur_read_cost= DBL_MAX;
ha_rows cur_records; const uint pk= param->table->s->primary_key;
SEL_ARG *cur_index_tree= NULL; SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0; ha_rows cur_quick_prefix_records= 0;
uint cur_param_idx=MAX_KEY; uint cur_param_idx=MAX_KEY;
key_map cur_used_key_parts;
uint pk= param->table->s->primary_key;
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ; for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
cur_index_info++, cur_index++) cur_index_info++, cur_index++)
{ {
KEY_PART_INFO *cur_part;
KEY_PART_INFO *end_part; /* Last part for loops. */
/* Last index part. */
KEY_PART_INFO *last_part;
KEY_PART_INFO *first_non_group_part;
KEY_PART_INFO *first_non_infix_part;
uint key_infix_parts;
uint cur_group_key_parts= 0;
uint cur_group_prefix_len= 0;
double cur_read_cost;
ha_rows cur_records;
key_map used_key_parts_map;
uint cur_key_infix_len= 0;
uchar cur_key_infix[MAX_KEY_LENGTH];
uint cur_used_key_parts;
/* Check (B1) - if current index is covering. */ /* Check (B1) - if current index is covering. */
if (!table->covering_keys.is_set(cur_index)) if (!table->covering_keys.is_set(cur_index))
goto next_index; goto next_index;
...@@ -9334,7 +9339,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9334,7 +9339,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else if (join->select_distinct) else if (join->select_distinct)
{ {
select_items_it.rewind(); select_items_it.rewind();
cur_used_key_parts.clear_all(); used_key_parts_map.clear_all();
uint max_key_part= 0; uint max_key_part= 0;
while ((item= select_items_it++)) while ((item= select_items_it++))
{ {
...@@ -9345,13 +9350,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9345,13 +9350,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
Check if this attribute was already present in the select list. Check if this attribute was already present in the select list.
If it was present, then its corresponding key part was alredy used. If it was present, then its corresponding key part was alredy used.
*/ */
if (cur_used_key_parts.is_set(key_part_nr)) if (used_key_parts_map.is_set(key_part_nr))
continue; continue;
if (key_part_nr < 1 || key_part_nr > join->fields_list.elements) if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
goto next_index; goto next_index;
cur_part= cur_index_info->key_part + key_part_nr - 1; cur_part= cur_index_info->key_part + key_part_nr - 1;
cur_group_prefix_len+= cur_part->store_length; cur_group_prefix_len+= cur_part->store_length;
cur_used_key_parts.set_bit(key_part_nr); used_key_parts_map.set_bit(key_part_nr);
++cur_group_key_parts; ++cur_group_key_parts;
max_key_part= max(max_key_part,key_part_nr); max_key_part= max(max_key_part,key_part_nr);
} }
...@@ -9363,7 +9368,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9363,7 +9368,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/ */
ulonglong all_parts, cur_parts; ulonglong all_parts, cur_parts;
all_parts= (1<<max_key_part) - 1; all_parts= (1<<max_key_part) - 1;
cur_parts= cur_used_key_parts.to_ulonglong() >> 1; cur_parts= used_key_parts_map.to_ulonglong() >> 1;
if (all_parts != cur_parts) if (all_parts != cur_parts)
goto next_index; goto next_index;
} }
...@@ -9413,7 +9418,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9413,7 +9418,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
&dummy); &dummy);
if (!get_constant_key_infix(cur_index_info, index_range_tree, if (!get_constant_key_infix(cur_index_info, index_range_tree,
first_non_group_part, min_max_arg_part, first_non_group_part, min_max_arg_part,
last_part, thd, key_infix, &key_infix_len, last_part, thd, cur_key_infix,
&cur_key_infix_len,
&first_non_infix_part)) &first_non_infix_part))
goto next_index; goto next_index;
} }
...@@ -9467,9 +9473,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9467,9 +9473,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
} }
/* If we got to this point, cur_index_info passes the test. */ /* If we got to this point, cur_index_info passes the test. */
key_infix_parts= key_infix_len ? key_infix_parts= cur_key_infix_len ?
(first_non_infix_part - first_non_group_part) : 0; (first_non_infix_part - first_non_group_part) : 0;
used_key_parts= cur_group_key_parts + key_infix_parts; cur_used_key_parts= cur_group_key_parts + key_infix_parts;
/* Compute the cost of using this index. */ /* Compute the cost of using this index. */
if (tree) if (tree)
...@@ -9481,7 +9487,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9481,7 +9487,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
cur_quick_prefix_records= check_quick_select(param, cur_param_idx, cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
cur_index_tree, TRUE); cur_index_tree, TRUE);
} }
cost_group_min_max(table, cur_index_info, used_key_parts, cost_group_min_max(table, cur_index_info, cur_used_key_parts,
cur_group_key_parts, tree, cur_index_tree, cur_group_key_parts, tree, cur_index_tree,
cur_quick_prefix_records, have_min, have_max, cur_quick_prefix_records, have_min, have_max,
&cur_read_cost, &cur_records); &cur_read_cost, &cur_records);
...@@ -9492,7 +9498,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9492,7 +9498,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/ */
if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost)) if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
{ {
DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
index_info= cur_index_info; index_info= cur_index_info;
index= cur_index; index= cur_index;
best_read_cost= cur_read_cost; best_read_cost= cur_read_cost;
...@@ -9502,11 +9507,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -9502,11 +9507,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
best_param_idx= cur_param_idx; best_param_idx= cur_param_idx;
group_key_parts= cur_group_key_parts; group_key_parts= cur_group_key_parts;
group_prefix_len= cur_group_prefix_len; group_prefix_len= cur_group_prefix_len;
key_infix_len= cur_key_infix_len;
if (key_infix_len)
memcpy (key_infix, cur_key_infix, sizeof (key_infix));
used_key_parts= cur_used_key_parts;
} }
next_index: next_index:;
cur_group_key_parts= 0;
cur_group_prefix_len= 0;
} }
if (!index_info) /* No usable index found. */ if (!index_info) /* No usable index found. */
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
......
...@@ -573,7 +573,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags) ...@@ -573,7 +573,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
else else
{ {
/* With conversion */ /* With conversion */
uint max_char_len; ulonglong max_length;
uint32 field_length;
int2store(pos, thd_charset->number); int2store(pos, thd_charset->number);
/* /*
For TEXT/BLOB columns, field_length describes the maximum data For TEXT/BLOB columns, field_length describes the maximum data
...@@ -584,12 +585,22 @@ bool Protocol::send_fields(List<Item> *list, uint flags) ...@@ -584,12 +585,22 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
char_count * mbmaxlen, where character count is taken from the char_count * mbmaxlen, where character count is taken from the
definition of the column. In other words, the maximum number definition of the column. In other words, the maximum number
of characters here is limited by the column definition. of characters here is limited by the column definition.
When one has a LONG TEXT column with a single-byte
character set, and the connection character set is multi-byte, the
client may get fields longer than UINT_MAX32, due to
<character set column> -> <character set connection> conversion.
In that case column max length does not fit into the 4 bytes
reserved for it in the protocol.
*/ */
max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB && max_length= (field.type >= MYSQL_TYPE_TINY_BLOB &&
field.type <= (int) MYSQL_TYPE_BLOB) ? field.type <= MYSQL_TYPE_BLOB) ?
field.length / item->collation.collation->mbminlen : field.length / item->collation.collation->mbminlen :
field.length / item->collation.collation->mbmaxlen; field.length / item->collation.collation->mbmaxlen;
int4store(pos+2, max_char_len * thd_charset->mbmaxlen); max_length*= thd_charset->mbmaxlen;
field_length= (max_length > UINT_MAX32) ?
UINT_MAX32 : (uint32) max_length;
int4store(pos + 2, field_length);
} }
pos[6]= field.type; pos[6]= field.type;
int2store(pos+7,field.flags); int2store(pos+7,field.flags);
......
...@@ -6154,3 +6154,18 @@ WARN_PLUGIN_BUSY ...@@ -6154,3 +6154,18 @@ WARN_PLUGIN_BUSY
ER_VARIABLE_IS_READONLY ER_VARIABLE_IS_READONLY
eng "%s variable '%s' is read-only. Use SET %s to assign the value" eng "%s variable '%s' is read-only. Use SET %s to assign the value"
ER_WARN_ENGINE_TRANSACTION_ROLLBACK
eng "Storage engine %s does not support rollback for this statement. Transaction rolled back and must be restarted"
ER_SLAVE_HEARTBEAT_FAILURE
eng "Unexpected master's heartbeat data: %s"
ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
eng "The requested value for the heartbeat period %s %s"
ER_NDB_REPLICATION_SCHEMA_ERROR
eng "Bad schema for mysql.ndb_replication table. Message: %-.64s"
ER_CONFLICT_FN_PARSE_ERROR
eng "Error in parsing conflict function. Message: %-.64s"
ER_EXCEPTIONS_WRITE_ERROR
eng "Write to exceptions table failed. Message: %-.128s""
...@@ -723,6 +723,7 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -723,6 +723,7 @@ static void do_verify_prepare_field(MYSQL_RES *result,
{ {
MYSQL_FIELD *field; MYSQL_FIELD *field;
CHARSET_INFO *cs; CHARSET_INFO *cs;
ulonglong expected_field_length;
if (!(field= mysql_fetch_field_direct(result, no))) if (!(field= mysql_fetch_field_direct(result, no)))
{ {
...@@ -731,6 +732,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -731,6 +732,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
} }
cs= get_charset(field->charsetnr, 0); cs= get_charset(field->charsetnr, 0);
DIE_UNLESS(cs); DIE_UNLESS(cs);
if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
expected_field_length= UINT_MAX32;
if (!opt_silent) if (!opt_silent)
{ {
fprintf(stdout, "\n field[%d]:", no); fprintf(stdout, "\n field[%d]:", no);
...@@ -745,8 +748,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -745,8 +748,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
field->org_table, org_table); field->org_table, org_table);
fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
fprintf(stdout, "\n length :`%lu`\t(expected: `%lu`)", fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)",
field->length, length * cs->mbmaxlen); field->length, expected_field_length);
fprintf(stdout, "\n maxlength:`%ld`", field->max_length); fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
...@@ -782,11 +785,11 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -782,11 +785,11 @@ static void do_verify_prepare_field(MYSQL_RES *result,
as utf8. Field length is calculated as number of characters * maximum as utf8. Field length is calculated as number of characters * maximum
number of bytes a character can occupy. number of bytes a character can occupy.
*/ */
if (length && field->length != length * cs->mbmaxlen) if (length && (field->length != expected_field_length))
{ {
fprintf(stderr, "Expected field length: %d, got length: %d\n", fprintf(stderr, "Expected field length: %llu, got length: %lu\n",
(int) (length * cs->mbmaxlen), (int) field->length); expected_field_length, field->length);
DIE_UNLESS(field->length == length * cs->mbmaxlen); DIE_UNLESS(field->length == expected_field_length);
} }
if (def) if (def)
DIE_UNLESS(strcmp(field->def, def) == 0); DIE_UNLESS(strcmp(field->def, def) == 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment