Merge from mysql-5.1.55-release

This commit is contained in:
unknown 2011-02-08 12:52:33 +01:00 committed by Karen Langford
commit 17fe23e46c
41 changed files with 583 additions and 87 deletions

2
README
View File

@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software
is released under the version 2 of the GNU General Public License. is released under the version 2 of the GNU General Public License.
MySQL is brought to you by the MySQL team at Oracle. MySQL is brought to you by the MySQL team at Oracle.
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
License information can be found in the COPYING file. License information can be found in the COPYING file.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -2055,6 +2055,16 @@ sub environment_setup {
$ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'} || 3306; $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'} || 3306;
$ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir; $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir;
$ENV{'MYSQLTEST_VARDIR'}= $opt_vardir; $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir;
if (IS_WINDOWS)
{
$ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."\\std_data";
}
else
{
$ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."/std_data";
}
# ---------------------------------------------------- # ----------------------------------------------------
# Setup env for NDB # Setup env for NDB

View File

@ -1252,6 +1252,80 @@ CURRENT_USER()
root@localhost root@localhost
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
# Bug#57952
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
use mysqltest1;
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1, 1);
CREATE TABLE t2(a INT);
INSERT INTO t2 VALUES (2);
CREATE TABLE mysqltest2.t3(a INT);
INSERT INTO mysqltest2.t3 VALUES (4);
CREATE USER testuser@localhost;
GRANT CREATE ROUTINE, EXECUTE ON mysqltest1.* TO testuser@localhost;
GRANT SELECT(b) ON t1 TO testuser@localhost;
GRANT SELECT ON t2 TO testuser@localhost;
GRANT SELECT ON mysqltest2.* TO testuser@localhost;
# Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
PREPARE s1 FROM 'SELECT b FROM t1';
PREPARE s2 FROM 'SELECT a FROM t2';
PREPARE s3 FROM 'SHOW TABLES FROM mysqltest2';
CREATE PROCEDURE p1() SELECT b FROM t1;
CREATE PROCEDURE p2() SELECT a FROM t2;
CREATE PROCEDURE p3() SHOW TABLES FROM mysqltest2;
CALL p1;
b
1
CALL p2;
a
2
CALL p3;
Tables_in_mysqltest2
t3
# Connection: default
REVOKE SELECT ON t1 FROM testuser@localhost;
GRANT SELECT(a) ON t1 TO testuser@localhost;
REVOKE SELECT ON t2 FROM testuser@localhost;
REVOKE SELECT ON mysqltest2.* FROM testuser@localhost;
# Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
# - Check column-level privileges...
EXECUTE s1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
SELECT b FROM t1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
EXECUTE s1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
CALL p1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
# - Check table-level privileges...
SELECT a FROM t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
EXECUTE s2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
CALL p2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
# - Check database-level privileges...
SHOW TABLES FROM mysqltest2;
ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
EXECUTE s3;
ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
CALL p3;
ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
# Connection: default
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER testuser@localhost;
use test;
End of 5.0 tests End of 5.0 tests
set names utf8; set names utf8;
grant select on test.* to юзер_юзер@localhost; grant select on test.* to юзер_юзер@localhost;

View File

@ -341,4 +341,18 @@ ta_y s tb_y s
2001 2001 2001 2001 2001 2001 2001 2001
DROP TABLE t1; DROP TABLE t1;
# #
# Bug #59211: Select Returns Different Value for min(year) Function
#
CREATE TABLE t1(c1 YEAR(4));
INSERT INTO t1 VALUES (1901),(2155),(0000);
SELECT * FROM t1;
c1
1901
2155
0000
SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
total_rows min_value MAX(c1)
3 0 2155
DROP TABLE t1;
#
End of 5.1 tests End of 5.1 tests

View File

@ -450,4 +450,10 @@ DROP TABLE t1;
select @v:=@v:=sum(1) from dual; select @v:=@v:=sum(1) from dual;
@v:=@v:=sum(1) @v:=@v:=sum(1)
1 1
CREATE TABLE t1(a DECIMAL(31,21));
INSERT INTO t1 VALUES (0);
SELECT (@v:=a) <> (@v:=1) FROM t1;
(@v:=a) <> (@v:=1)
1
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests

View File

@ -271,7 +271,7 @@ INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
"Should NOT have any warning message issued in the following func7() and trig" "Should NOT have any warning message issued in the following func7() and trig"
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a CHAR(40)); CREATE TABLE t2 (a TEXT);
CREATE TABLE trigger_table (a CHAR(7)); CREATE TABLE trigger_table (a CHAR(7));
CREATE FUNCTION func7() CREATE FUNCTION func7()
RETURNS INT RETURNS INT

View File

@ -329,7 +329,7 @@ DROP TABLE t1,t2;
--echo "Should NOT have any warning message issued in the following func7() and trig" --echo "Should NOT have any warning message issued in the following func7() and trig"
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a CHAR(40)); CREATE TABLE t2 (a TEXT);
CREATE TABLE trigger_table (a CHAR(7)); CREATE TABLE trigger_table (a CHAR(7));
DELIMITER |; DELIMITER |;
CREATE FUNCTION func7() CREATE FUNCTION func7()

View File

@ -0,0 +1,30 @@
DROP TABLE IF EXISTS t1_56228;
Warnings:
Note 1051 Unknown table 't1_56228'
DROP TABLE IF EXISTS t2_56228;
Warnings:
Note 1051 Unknown table 't2_56228'
DROP FUNCTION IF EXISTS bug56228;
Warnings:
Note 1305 FUNCTION bug56228 does not exist
CREATE TEMPORARY TABLE t1_56228(
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
CREATE TEMPORARY TABLE t2_56228(
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
BEGIN
INSERT INTO t1_56228 VALUES(NULL);
INSERT INTO t2_56228 VALUES(NULL);
INSERT INTO t1_56228 VALUES(NULL);
INSERT INTO t2_56228 VALUES(NULL);
DROP TEMPORARY TABLE t1_56228;
RETURN 42;
END //
SELECT bug56228();
bug56228()
42
DROP FUNCTION bug56228;
DROP TEMPORARY TABLE t2_56228;
DROP TEMPORARY TABLE IF EXISTS t1_56228;
Warnings:
Note 1051 Unknown table 't1_56228'

View File

@ -0,0 +1 @@
--innodb_autoinc_lock_mode=0

View File

@ -0,0 +1,42 @@
-- source include/have_innodb_plugin.inc
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
##
# Bug #56228: dropping tables from within an active statement crashes server
#
DROP TABLE IF EXISTS t1_56228;
DROP TABLE IF EXISTS t2_56228;
DROP FUNCTION IF EXISTS bug56228;
CREATE TEMPORARY TABLE t1_56228(
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
CREATE TEMPORARY TABLE t2_56228(
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
DELIMITER //;
CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
BEGIN
INSERT INTO t1_56228 VALUES(NULL);
INSERT INTO t2_56228 VALUES(NULL);
INSERT INTO t1_56228 VALUES(NULL);
INSERT INTO t2_56228 VALUES(NULL);
DROP TEMPORARY TABLE t1_56228;
RETURN 42;
END //
DELIMITER ;//
SELECT bug56228();
DROP FUNCTION bug56228;
DROP TEMPORARY TABLE t2_56228;
DROP TEMPORARY TABLE IF EXISTS t1_56228;
#
# restore environment to the state it was before this test execution
#
-- disable_query_log
eval set global innodb_file_format_check=$innodb_file_format_check_orig;

View File

@ -0,0 +1,6 @@
CREATE TABLE t1 (c1 INT);
LOAD DATA INFILE "t1.MYI" into table t1;
ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
LOAD DATA INFILE "/test" into table t1;
ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
DROP TABLE t1;

View File

@ -0,0 +1 @@
--secure_file_priv=$SECURE_LOAD_PATH

View File

@ -0,0 +1,23 @@
#
# Bug58747 breaks secure_file_priv+not secure yet+still accesses other folders
#
CREATE TABLE t1 (c1 INT);
#
# Before the patch this statement failed with
# Linux:
# -> errno 13: 'Can't get stat of '
# Windows:
# -> Warning 1366 Incorrect integer value: '■■☺' for
# -> column 'c1' at row 1
# Now it should consistently fail with ER_OPTION_PREVENTS_STATEMENT
# on all platforms.
--error ER_OPTION_PREVENTS_STATEMENT
LOAD DATA INFILE "t1.MYI" into table t1;
#
# The following test makes the assuption that /test isn't a valid path in any
# operating system running the test suite.
--error ER_OPTION_PREVENTS_STATEMENT
LOAD DATA INFILE "/test" into table t1;
DROP TABLE t1;

View File

@ -1295,6 +1295,107 @@ SELECT CURRENT_USER();
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
#
# Bug#57952: privilege change is not taken into account by EXECUTE.
#
--echo
--echo # Bug#57952
--echo
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
use mysqltest1;
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1, 1);
CREATE TABLE t2(a INT);
INSERT INTO t2 VALUES (2);
CREATE TABLE mysqltest2.t3(a INT);
INSERT INTO mysqltest2.t3 VALUES (4);
CREATE USER testuser@localhost;
GRANT CREATE ROUTINE, EXECUTE ON mysqltest1.* TO testuser@localhost;
GRANT SELECT(b) ON t1 TO testuser@localhost;
GRANT SELECT ON t2 TO testuser@localhost;
GRANT SELECT ON mysqltest2.* TO testuser@localhost;
--echo
--echo # Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
--connect (bug57952_con1,localhost,testuser,,mysqltest1)
PREPARE s1 FROM 'SELECT b FROM t1';
PREPARE s2 FROM 'SELECT a FROM t2';
PREPARE s3 FROM 'SHOW TABLES FROM mysqltest2';
CREATE PROCEDURE p1() SELECT b FROM t1;
CREATE PROCEDURE p2() SELECT a FROM t2;
CREATE PROCEDURE p3() SHOW TABLES FROM mysqltest2;
CALL p1;
CALL p2;
CALL p3;
--echo
--echo # Connection: default
--connection default
REVOKE SELECT ON t1 FROM testuser@localhost;
GRANT SELECT(a) ON t1 TO testuser@localhost;
REVOKE SELECT ON t2 FROM testuser@localhost;
REVOKE SELECT ON mysqltest2.* FROM testuser@localhost;
--echo
--echo # Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
--connection bug57952_con1
--echo # - Check column-level privileges...
--error ER_COLUMNACCESS_DENIED_ERROR
EXECUTE s1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT b FROM t1;
--error ER_COLUMNACCESS_DENIED_ERROR
EXECUTE s1;
--error ER_COLUMNACCESS_DENIED_ERROR
CALL p1;
--echo # - Check table-level privileges...
--error ER_TABLEACCESS_DENIED_ERROR
SELECT a FROM t2;
--error ER_TABLEACCESS_DENIED_ERROR
EXECUTE s2;
--error ER_TABLEACCESS_DENIED_ERROR
CALL p2;
--echo # - Check database-level privileges...
--error ER_DBACCESS_DENIED_ERROR
SHOW TABLES FROM mysqltest2;
--error ER_DBACCESS_DENIED_ERROR
EXECUTE s3;
--error ER_DBACCESS_DENIED_ERROR
CALL p3;
--echo
--echo # Connection: default
--connection default
--disconnect bug57952_con1
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER testuser@localhost;
use test;
--echo
--echo End of 5.0 tests --echo End of 5.0 tests
# #

View File

@ -149,6 +149,16 @@ SELECT ta.y AS ta_y, ta.s, tb.y AS tb_y, tb.s FROM t1 ta, t1 tb HAVING ta_y = tb
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #59211: Select Returns Different Value for min(year) Function
--echo #
CREATE TABLE t1(c1 YEAR(4));
INSERT INTO t1 VALUES (1901),(2155),(0000);
SELECT * FROM t1;
SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
DROP TABLE t1;
--echo # --echo #
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -353,4 +353,16 @@ DROP TABLE t1;
select @v:=@v:=sum(1) from dual; select @v:=@v:=sum(1) from dual;
#
# Bug #57187: more user variable fun with multiple assignments and
# comparison in query
#
CREATE TABLE t1(a DECIMAL(31,21));
INSERT INTO t1 VALUES (0);
SELECT (@v:=a) <> (@v:=1) FROM t1;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2004 MySQL AB /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -2960,11 +2960,10 @@ class Item_cache: public Item_basic_constant
protected: protected:
Item *example; Item *example;
table_map used_table_map; table_map used_table_map;
/* /**
Field that this object will get value from. This is set/used by Field that this object will get value from. This is used by
index-based subquery engines to detect and remove the equality injected index-based subquery engines to detect and remove the equality injected
by IN->EXISTS transformation. by IN->EXISTS transformation.
For all other uses of Item_cache, cached_field doesn't matter.
*/ */
Field *cached_field; Field *cached_field;
enum enum_field_types cached_field_type; enum enum_field_types cached_field_type;
@ -3021,6 +3020,14 @@ public:
{ {
return this == item; return this == item;
} }
/**
If this item caches a field value, return pointer to underlying field.
@return Pointer to field, or NULL if this is not a cache for a field value.
*/
Field* field() { return cached_field; }
virtual void store(Item *item); virtual void store(Item *item);
virtual bool cache_value()= 0; virtual bool cache_value()= 0;
}; };

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -1196,9 +1196,12 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
value of 2000. value of 2000.
*/ */
Item *real_item= item->real_item(); Item *real_item= item->real_item();
if (!(real_item->type() == Item::FIELD_ITEM && Field *field= NULL;
((Item_field *)real_item)->field->type() == MYSQL_TYPE_YEAR && if (real_item->type() == Item::FIELD_ITEM)
((Item_field *)real_item)->field->field_length == 4)) field= ((Item_field *)real_item)->field;
else if (real_item->type() == Item::CACHE_ITEM)
field= ((Item_cache *)real_item)->field();
if (!(field && field->type() == MYSQL_TYPE_YEAR && field->field_length == 4))
{ {
if (value < 70) if (value < 70)
value+= 100; value+= 100;

View File

@ -4069,7 +4069,7 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val); int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val);
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
val= (my_decimal *)value; my_decimal2decimal((my_decimal *) value, val);
break; break;
case STRING_RESULT: case STRING_RESULT:
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val); str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -5941,6 +5941,8 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
/* /*
Find field by name in a base table or a view with temp table algorithm. Find field by name in a base table or a view with temp table algorithm.
The caller is expected to check column-level privileges.
SYNOPSIS SYNOPSIS
find_field_in_table() find_field_in_table()
thd thread handler thd thread handler
@ -6048,6 +6050,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
This procedure detects the type of the table reference 'table_list' This procedure detects the type of the table reference 'table_list'
and calls the corresponding search routine. and calls the corresponding search routine.
The routine checks column-level privieleges for the found field.
RETURN RETURN
0 field is not found 0 field is not found
view_ref_found found value in VIEW (real result is in *ref) view_ref_found found value in VIEW (real result is in *ref)
@ -6321,8 +6325,16 @@ find_field_in_tables(THD *thd, Item_ident *item,
when table_ref->field_translation != NULL. when table_ref->field_translation != NULL.
*/ */
if (table_ref->table && !table_ref->view) if (table_ref->table && !table_ref->view)
{
found= find_field_in_table(thd, table_ref->table, name, length, found= find_field_in_table(thd, table_ref->table, name, length,
TRUE, &(item->cached_field_index)); TRUE, &(item->cached_field_index));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check if there are sufficient access rights to the found field. */
if (found && check_privileges &&
check_column_grant_in_table_ref(thd, table_ref, name, length))
found= WRONG_GRANT;
#endif
}
else else
found= find_field_in_table_ref(thd, table_ref, name, length, item->name, found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
NULL, NULL, ref, check_privileges, NULL, NULL, ref, check_privileges,

View File

@ -314,56 +314,57 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(void) fn_format(name, ex->file_name, mysql_real_data_home, "", (void) fn_format(name, ex->file_name, mysql_real_data_home, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME | MY_RELATIVE_PATH | MY_UNPACK_FILENAME |
MY_RETURN_REAL_PATH); MY_RETURN_REAL_PATH);
#if !defined(__WIN__) && ! defined(__NETWARE__) }
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(TRUE);
// if we are not in slave thread, the file must be: if (thd->slave_thread)
if (!thd->slave_thread && {
!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
((stat_info.st_mode & S_IFREG) == S_IFREG ||
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
{
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
DBUG_RETURN(TRUE);
}
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
is_fifo = 1;
#endif
if (thd->slave_thread)
{
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
if (strncmp(active_mi->rli.slave_patternload_file, name, if (strncmp(active_mi->rli.slave_patternload_file, name,
active_mi->rli.slave_patternload_file_size)) active_mi->rli.slave_patternload_file_size))
{
/*
LOAD DATA INFILE in the slave SQL Thread can only read from
--slave-load-tmpdir". This should never happen. Please, report a bug.
*/
sql_print_error("LOAD DATA INFILE in the slave SQL Thread can only read from --slave-load-tmpdir. " \
"Please, report a bug.");
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--slave-load-tmpdir");
DBUG_RETURN(TRUE);
}
#else
/*
This is impossible and should never happen.
*/
DBUG_ASSERT(FALSE);
#endif
}
else if (!is_secure_file_path(name))
{ {
/* Read only allowed from within dir specified by secure_file_priv */ /*
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); LOAD DATA INFILE in the slave SQL Thread can only read from
--slave-load-tmpdir". This should never happen. Please, report a bug.
*/
sql_print_error("LOAD DATA INFILE in the slave SQL Thread can only read from --slave-load-tmpdir. " \
"Please, report a bug.");
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--slave-load-tmpdir");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
#else
/*
This is impossible and should never happen.
*/
DBUG_ASSERT(FALSE);
#endif
} }
else if (!is_secure_file_path(name))
{
/* Read only allowed from within dir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
DBUG_RETURN(TRUE);
}
#if !defined(__WIN__) && ! defined(__NETWARE__)
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(TRUE);
// if we are not in slave thread, the file must be:
if (!thd->slave_thread &&
!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
((stat_info.st_mode & S_IFREG) == S_IFREG ||
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
{
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
DBUG_RETURN(TRUE);
}
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
is_fifo = 1;
#endif
if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2004 MySQL AB /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -49,6 +49,16 @@
Fix Bug#30423 InnoDBs treatment of NULL in index stats causes Fix Bug#30423 InnoDBs treatment of NULL in index stats causes
bad "rows examined" estimates bad "rows examined" estimates
2011-01-06 The InnoDB Team
* row/row0merge.c:
Fix Bug#59312 Examine MAX_FULL_NAME_LEN in InnoDB to address
possible insufficient name buffer
2011-01-06 The InnoDB Team
* dict/dict0dict.c, handler/ha_innodb.cc, handler/i_s.cc,
include/univ.i:
Fix Bug#58643 InnoDB: too long table name
2011-01-06 The InnoDB Team 2011-01-06 The InnoDB Team
* handler/i_s.cc, include/trx0i_s.h, trx/trx0i_s.c: * handler/i_s.cc, include/trx0i_s.h, trx/trx0i_s.c:
Fix Bug#55397 cannot select from innodb_trx when trx_query contains Fix Bug#55397 cannot select from innodb_trx when trx_query contains

View File

@ -932,7 +932,7 @@ dict_table_rename_in_cache(
dict_foreign_t* foreign; dict_foreign_t* foreign;
dict_index_t* index; dict_index_t* index;
ulint fold; ulint fold;
char old_name[MAX_TABLE_NAME_LEN + 1]; char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(table); ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
@ -944,7 +944,7 @@ dict_table_rename_in_cache(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', " fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", table->name, "max length is %d\n", table->name,
MAX_TABLE_NAME_LEN); MAX_FULL_NAME_LEN);
ut_error; ut_error;
} }
@ -994,11 +994,11 @@ dict_table_rename_in_cache(
ut_fold_string(old_name), table); ut_fold_string(old_name), table);
if (strlen(new_name) > strlen(table->name)) { if (strlen(new_name) > strlen(table->name)) {
/* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid /* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid
memory fragmentation, we assume a repeated calls of memory fragmentation, we assume a repeated calls of
ut_realloc() with the same size do not cause fragmentation */ ut_realloc() with the same size do not cause fragmentation */
ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN); ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN);
table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1); table->name = ut_realloc(table->name, MAX_FULL_NAME_LEN + 1);
} }
memcpy(table->name, new_name, strlen(new_name) + 1); memcpy(table->name, new_name, strlen(new_name) + 1);

View File

@ -6028,6 +6028,16 @@ create_table_def(
DBUG_RETURN(HA_ERR_GENERIC); DBUG_RETURN(HA_ERR_GENERIC);
} }
/* MySQL does the name length check. But we do additional check
on the name length here */
if (strlen(table_name) > MAX_FULL_NAME_LEN) {
push_warning_printf(
(THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TABLE_NAME,
"InnoDB: Table Name or Database Name is too long");
DBUG_RETURN(ER_TABLE_NAME);
}
n_cols = form->s->fields; n_cols = form->s->fields;
/* We pass 0 as the space id, and determine at a lower level the space /* We pass 0 as the space id, and determine at a lower level the space

View File

@ -587,16 +587,7 @@ fill_innodb_locks_from_cache(
for (i = 0; i < rows_num; i++) { for (i = 0; i < rows_num; i++) {
i_s_locks_row_t* row; i_s_locks_row_t* row;
char buf[MAX_FULL_NAME_LEN + 1];
/* note that the decoded database or table name is
never expected to be longer than NAME_LEN;
NAME_LEN for database name
2 for surrounding quotes around database name
NAME_LEN for table name
2 for surrounding quotes around table name
1 for the separating dot (.)
9 for the #mysql50# prefix */
char buf[2 * NAME_LEN + 14];
const char* bufend; const char* bufend;
char lock_trx_id[TRX_ID_MAX_LEN + 1]; char lock_trx_id[TRX_ID_MAX_LEN + 1];

View File

@ -296,6 +296,18 @@ number does not include a terminating '\0'. InnoDB probably can handle
longer names internally */ longer names internally */
#define MAX_TABLE_NAME_LEN 192 #define MAX_TABLE_NAME_LEN 192
/* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is
the MySQL's NAME_LEN, see check_and_convert_db_name(). */
#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN
/* MAX_FULL_NAME_LEN defines the full name path including the
database name and table name. In addition, 14 bytes is added for:
2 for surrounding quotes around table name
1 for the separating dot (.)
9 for the #mysql50# prefix */
#define MAX_FULL_NAME_LEN \
(MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14)
/* /*
UNIVERSAL TYPE DEFINITIONS UNIVERSAL TYPE DEFINITIONS
========================== ==========================

View File

@ -93,6 +93,25 @@ ib_vector_get(
ib_vector_t* vec, /*!< in: vector */ ib_vector_t* vec, /*!< in: vector */
ulint n); /*!< in: element index to get */ ulint n); /*!< in: element index to get */
/****************************************************************//**
Get last element. The vector must not be empty.
@return last element */
UNIV_INLINE
void*
ib_vector_get_last(
/*===============*/
ib_vector_t* vec); /*!< in: vector */
/****************************************************************//**
Set the n'th element. */
UNIV_INLINE
void
ib_vector_set(
/*==========*/
ib_vector_t* vec, /*!< in/out: vector */
ulint n, /*!< in: element index to set */
void* elem); /*!< in: data element */
/****************************************************************//** /****************************************************************//**
Remove the last element from the vector. */ Remove the last element from the vector. */
UNIV_INLINE UNIV_INLINE

View File

@ -50,6 +50,35 @@ ib_vector_get(
return(vec->data[n]); return(vec->data[n]);
} }
/****************************************************************//**
Get last element. The vector must not be empty.
@return last element */
UNIV_INLINE
void*
ib_vector_get_last(
/*===============*/
ib_vector_t* vec) /*!< in: vector */
{
ut_a(vec->used > 0);
return(vec->data[vec->used - 1]);
}
/****************************************************************//**
Set the n'th element. */
UNIV_INLINE
void
ib_vector_set(
/*==========*/
ib_vector_t* vec, /*!< in/out: vector */
ulint n, /*!< in: element index to set */
void* elem) /*!< in: data element */
{
ut_a(n < vec->used);
vec->data[n] = elem;
}
/****************************************************************//** /****************************************************************//**
Remove the last element from the vector. Remove the last element from the vector.
@return last vector element */ @return last vector element */

View File

@ -3624,6 +3624,80 @@ lock_table_create(
return(lock); return(lock);
} }
/*************************************************************//**
Pops autoinc lock requests from the transaction's autoinc_locks. We
handle the case where there are gaps in the array and they need to
be popped off the stack. */
UNIV_INLINE
void
lock_table_pop_autoinc_locks(
/*=========================*/
trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
/* Skip any gaps, gaps are NULL lock entries in the
trx->autoinc_locks vector. */
do {
ib_vector_pop(trx->autoinc_locks);
if (ib_vector_is_empty(trx->autoinc_locks)) {
return;
}
} while (ib_vector_get_last(trx->autoinc_locks) == NULL);
}
/*************************************************************//**
Removes an autoinc lock request from the transaction's autoinc_locks. */
UNIV_INLINE
void
lock_table_remove_autoinc_lock(
/*===========================*/
lock_t* lock, /*!< in: table lock */
trx_t* trx) /*!< in/out: transaction that owns the lock */
{
lock_t* autoinc_lock;
lint i = ib_vector_size(trx->autoinc_locks) - 1;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC);
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
/* With stored functions and procedures the user may drop
a table within the same "statement". This special case has
to be handled by deleting only those AUTOINC locks that were
held by the table being dropped. */
autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
/* This is the default fast case. */
if (autoinc_lock == lock) {
lock_table_pop_autoinc_locks(trx);
} else {
/* The last element should never be NULL */
ut_a(autoinc_lock != NULL);
/* Handle freeing the locks from within the stack. */
while (--i >= 0) {
autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
if (UNIV_LIKELY(autoinc_lock == lock)) {
ib_vector_set(trx->autoinc_locks, i, NULL);
return;
}
}
/* Must find the autoinc lock. */
ut_error;
}
}
/*************************************************************//** /*************************************************************//**
Removes a table lock request from the queue and the trx list of locks; Removes a table lock request from the queue and the trx list of locks;
this is a low-level function which does NOT check if waiting requests this is a low-level function which does NOT check if waiting requests
@ -3663,10 +3737,8 @@ lock_table_remove_low(
if (!lock_get_wait(lock) if (!lock_get_wait(lock)
&& !ib_vector_is_empty(trx->autoinc_locks)) { && !ib_vector_is_empty(trx->autoinc_locks)) {
lock_t* autoinc_lock;
autoinc_lock = ib_vector_pop(trx->autoinc_locks); lock_table_remove_autoinc_lock(lock, trx);
ut_a(autoinc_lock == lock);
} }
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0); ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);

View File

@ -2341,7 +2341,7 @@ row_merge_rename_tables(
{ {
ulint err = DB_ERROR; ulint err = DB_ERROR;
pars_info_t* info; pars_info_t* info;
char old_name[MAX_TABLE_NAME_LEN + 1]; char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_ad(old_table != new_table); ut_ad(old_table != new_table);
@ -2356,7 +2356,7 @@ row_merge_rename_tables(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', " fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", old_table->name, "max length is %d\n", old_table->name,
MAX_TABLE_NAME_LEN); MAX_FULL_NAME_LEN);
ut_error; ut_error;
} }