Browse Source

Merging with mysql-5.5.

Mats Kindahl 15 years ago
parent
commit
c497fb7d84
  1. 2
      README
  2. 2
      client/mysql.cc
  3. 8
      client/readline.cc
  4. 2
      include/my_pthread.h
  5. 28
      mysql-test/collections/default.daily
  6. 5
      mysql-test/collections/default.experimental
  7. 14
      mysql-test/collections/default.weekly
  8. 2
      mysql-test/include/mysqlhotcopy.inc
  9. 10
      mysql-test/mysql-test-run.pl
  10. 74
      mysql-test/r/grant.result
  11. 14
      mysql-test/r/type_year.result
  12. 6
      mysql-test/r/user_var.result
  13. 2
      mysql-test/suite/binlog/r/binlog_unsafe.result
  14. 2
      mysql-test/suite/binlog/t/binlog_unsafe.test
  15. 30
      mysql-test/suite/innodb/r/innodb-autoinc-56228.result
  16. 1
      mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt
  17. 33
      mysql-test/suite/innodb/t/innodb-autoinc-56228.test
  18. 15
      mysql-test/suite/rpl/r/rpl_loaddatalocal.result
  19. 26
      mysql-test/suite/rpl/t/rpl_loaddatalocal.test
  20. 6
      mysql-test/suite/sys_vars/r/secure_file_priv2.result
  21. 1
      mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt
  22. 23
      mysql-test/suite/sys_vars/t/secure_file_priv2.test
  23. 101
      mysql-test/t/grant.test
  24. 10
      mysql-test/t/type_year.test
  25. 12
      mysql-test/t/user_var.test
  26. 42
      mysql-test/valgrind.supp
  27. 2
      mysys/my_fopen.c
  28. 2
      mysys/my_getsystime.c
  29. 2
      sql/handler.cc
  30. 13
      sql/item.h
  31. 9
      sql/item_cmpfunc.cc
  32. 2
      sql/item_func.cc
  33. 2
      sql/item_geofunc.h
  34. 2
      sql/log.cc
  35. 2
      sql/net_serv.cc
  36. 14
      sql/sql_base.cc
  37. 85
      sql/sql_load.cc
  38. 2
      sql/sql_select.cc
  39. 2
      sql/sql_show.cc
  40. 2
      sql/sql_view.cc
  41. 156
      storage/innobase/btr/btr0cur.c
  42. 30
      storage/innobase/buf/buf0buf.c
  43. 10
      storage/innobase/dict/dict0dict.c
  44. 2
      storage/innobase/dict/dict0load.c
  45. 8
      storage/innobase/fsp/fsp0fsp.c
  46. 11
      storage/innobase/handler/ha_innodb.cc
  47. 11
      storage/innobase/handler/i_s.cc
  48. 8
      storage/innobase/ibuf/ibuf0ibuf.c
  49. 42
      storage/innobase/include/btr0cur.h
  50. 8
      storage/innobase/include/buf0buf.h
  51. 26
      storage/innobase/include/row0upd.h
  52. 19
      storage/innobase/include/univ.i
  53. 19
      storage/innobase/include/ut0vec.h
  54. 29
      storage/innobase/include/ut0vec.ic
  55. 78
      storage/innobase/lock/lock0lock.c
  56. 2
      storage/innobase/row/row0ins.c
  57. 4
      storage/innobase/row/row0merge.c
  58. 14
      storage/innobase/row/row0mysql.c
  59. 68
      storage/innobase/row/row0purge.c
  60. 35
      storage/innobase/row/row0umod.c
  61. 43
      storage/innobase/row/row0upd.c
  62. 13
      storage/innobase/srv/srv0start.c
  63. 4
      storage/innobase/trx/trx0roll.c

2
README

@ -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.
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.

2
client/mysql.cc

@ -1127,6 +1127,8 @@ int main(int argc,char *argv[])
if (status.batch && !status.line_buff &&
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{
put_info("Can't initialize batch_readline - may be the input source is "
"a directory or a block device.", INFO_ERROR, 0);
free_defaults(defaults_argv);
my_end(0);
exit(1);

8
client/readline.cc

@ -18,6 +18,7 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <my_dir.h>
#include "my_readline.h"
static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
@ -30,6 +31,13 @@ static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
{
LINE_BUFFER *line_buff;
MY_STAT input_file_stat;
if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) ||
MY_S_ISDIR(input_file_stat.st_mode) ||
MY_S_ISBLK(input_file_stat.st_mode))
return 0;
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;

2
include/my_pthread.h

@ -1,4 +1,4 @@
/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 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
it under the terms of the GNU General Public License as published by

28
mysql-test/collections/default.daily

@ -1,15 +1,15 @@
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=row --vardir=var-row --mysqld=--binlog-format=row
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --mysqld=--binlog-format=row --ps-protocol
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --ps-protocol
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps_funcs1 --vardir=var-ps_funcs_1 --suite=funcs_1 --ps-protocol
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-ps_nist --suite=nist --ps-protocol
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=row --vardir=var-row --mysqld=--binlog-format=row
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --mysqld=--binlog-format=row --ps-protocol
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --ps-protocol
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_funcs1 --vardir=var-ps_funcs_1 --suite=funcs_1 --ps-protocol
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-ps_nist --suite=nist --ps-protocol

5
mysql-test/collections/default.experimental

@ -24,6 +24,11 @@ sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Severa
sys_vars.plugin_dir_basic # Bug#52223 2010-11-24 alik Test "plugin_dir_basic" does not support RPM build (test) directory structure
sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10
sys_vars.wait_timeout_func # Bug#41255 2010-04-26 alik wait_timeout_func fails
sys_vars.sys_vars # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
sys_vars.rpl_semi_sync_master_enabled_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
sys_vars.rpl_semi_sync_master_timeout_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
sys_vars.rpl_semi_sync_master_trace_level_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
sys_vars.rpl_semi_sync_master_wait_no_slave_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
# BUG #59055 : All ndb tests should be removed from the repository
# Leaving the sys_vars tests for now. sys_vars.all_vars.test fails on removing ndb tests

14
mysql-test/collections/default.weekly

@ -1,7 +1,7 @@
perl mysql-test-run.pl --timer --force --parallel=auto --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_2_innodb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb funcs_1.myisam_views-big
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=row
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=mixed
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=row
perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=mixed
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_2_innodb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb funcs_1.myisam_views-big
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-row-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=row
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-mixed-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=mixed
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-row-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=row
perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-mixed-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=mixed

2
mysql-test/include/mysqlhotcopy.inc

@ -107,7 +107,7 @@ DROP DATABASE hotcopy_save;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
--list_files $MYSQLD_DATADIR/hotcopy_save
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
--error 9,2304
--error 9,11,2304
--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
--exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save

10
mysql-test/mysql-test-run.pl

@ -2168,6 +2168,16 @@ sub environment_setup {
$ENV{'MYSQL_LIBDIR'}= "$basedir/lib";
$ENV{'MYSQL_SHAREDIR'}= $path_language;
$ENV{'MYSQL_CHARSETSDIR'}= $path_charsetsdir;
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

74
mysql-test/r/grant.result

@ -1378,6 +1378,80 @@ CURRENT_USER()
root@localhost
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
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
set names utf8;
grant select on test.* to юзер_юзер@localhost;

14
mysql-test/r/type_year.result

@ -341,4 +341,18 @@ ta_y s tb_y s
2001 2001 2001 2001
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

6
mysql-test/r/user_var.result

@ -448,6 +448,12 @@ DROP TABLE t1;
select @v:=@v:=sum(1) from dual;
@v:=@v:=sum(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
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));

2
mysql-test/suite/binlog/r/binlog_unsafe.result

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

2
mysql-test/suite/binlog/t/binlog_unsafe.test

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

30
mysql-test/suite/innodb/r/innodb-autoinc-56228.result

@ -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 test.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'

1
mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt

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

33
mysql-test/suite/innodb/t/innodb-autoinc-56228.test

@ -0,0 +1,33 @@
-- source include/have_innodb.inc
##
# 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;

15
mysql-test/suite/rpl/r/rpl_loaddatalocal.result

@ -74,6 +74,21 @@ LOAD/*!99999 special comments that do not expand */DATA/*!99999 code from the fu
SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER';
LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
[slave]
Bug #59267:
"LOAD DATA LOCAL INFILE not executed on slave with SBR"
[master]
SELECT * INTO OUTFILE 'MYSQLD_DATADIR/bug59267.sql' FROM t1;
TRUNCATE TABLE t1;
LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1;
SELECT 'Master', COUNT(*) FROM t1;
Master COUNT(*)
Master 44
[slave]
SELECT 'Slave', COUNT(*) FROM t1;
Slave COUNT(*)
Slave 44
[master]
DROP TABLE t1;
SET SESSION sql_mode=@old_mode;

26
mysql-test/suite/rpl/t/rpl_loaddatalocal.test

@ -151,12 +151,34 @@ eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
--echo [slave]
sync_slave_with_master;
# cleanup
--echo
--echo Bug #59267:
--echo "LOAD DATA LOCAL INFILE not executed on slave with SBR"
--echo
--remove_file $MYSQLD_DATADIR/bug43746.sql
--echo [master]
connection master;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval SELECT * INTO OUTFILE '$MYSQLD_DATADIR/bug59267.sql' FROM t1;
TRUNCATE TABLE t1;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1;
SELECT 'Master', COUNT(*) FROM t1;
--echo [slave]
--sync_slave_with_master
SELECT 'Slave', COUNT(*) FROM t1;
# cleanup
--echo [master]
connection master;
--remove_file $MYSQLD_DATADIR/bug43746.sql
--remove_file $MYSQLD_DATADIR/bug59267.sql
DROP TABLE t1;
SET SESSION sql_mode=@old_mode;

6
mysql-test/suite/sys_vars/r/secure_file_priv2.result

@ -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;

1
mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt

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

23
mysql-test/suite/sys_vars/t/secure_file_priv2.test

@ -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;

101
mysql-test/t/grant.test

@ -1295,6 +1295,107 @@ SELECT CURRENT_USER();
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
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
#

10
mysql-test/t/type_year.test

@ -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;
--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 End of 5.1 tests

12
mysql-test/t/user_var.test

@ -351,6 +351,18 @@ DROP TABLE t1;
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
#

42
mysql-test/valgrind.supp

@ -835,3 +835,45 @@
fun:lf_hash_search
}
{
Bug 59874 Valgrind warning in InnoDB compression code
Memcheck:Cond
fun:*
fun:*
fun:deflate
fun:btr_store_big_rec_extern_fields_func
fun:row_ins_index_entry_low
fun:row_ins_index_entry
fun:row_ins_index_entry_step
fun:row_ins
fun:row_ins_step
fun:row_insert_for_mysql
}
{
In page0zip.c we have already checked that the memory is initialized before calling deflate()
Memcheck:Cond
fun:*
fun:*
fun:deflate
fun:page_zip_compress
}
{
In page0zip.c we have already checked that the memory is initialized before calling deflate()
Memcheck:Cond
fun:*
fun:*
fun:deflate
fun:page_zip_compress_deflate
}
{
Bug 59875 Valgrind warning in buf0buddy.c
Memcheck:Addr1
fun:mach_read_from_4
fun:buf_buddy_relocate
fun:buf_buddy_free_low
fun:buf_buddy_free
fun:buf_LRU_block_remove_hashed_page
}

2
mysys/my_fopen.c

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB, 2008-2009 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
it under the terms of the GNU General Public License as published by

2
mysys/my_getsystime.c

@ -1,4 +1,4 @@
/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
/* Copyright (c) 2004, 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

2
sql/handler.cc

@ -1,4 +1,4 @@
/* Copyright 2000-2008 MySQL AB, 2008-2009 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
it under the terms of the GNU General Public License as published by

13
sql/item.h

@ -3203,11 +3203,10 @@ class Item_cache: public Item_basic_constant
protected:
Item *example;
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
by IN->EXISTS transformation.
For all other uses of Item_cache, cached_field doesn't matter.
*/
Field *cached_field;
enum enum_field_types cached_field_type;
@ -3275,6 +3274,14 @@ public:
{
return (value_cached || cache_value()) && !null_value;
}
/**
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 bool cache_value()= 0;
bool basic_const_item() const

9
sql/item_cmpfunc.cc

@ -1208,9 +1208,12 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
value of 2000.
*/
Item *real_item= item->real_item();
if (!(real_item->type() == Item::FIELD_ITEM &&
((Item_field *)real_item)->field->type() == MYSQL_TYPE_YEAR &&
((Item_field *)real_item)->field->field_length == 4))
Field *field= NULL;
if (real_item->type() == Item::FIELD_ITEM)
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)
value+= 100;

2
sql/item_func.cc

@ -4478,7 +4478,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);
break;
case DECIMAL_RESULT:
val= (my_decimal *)value;
my_decimal2decimal((my_decimal *) value, val);
break;
case STRING_RESULT:
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);

2
sql/item_geofunc.h

@ -1,7 +1,7 @@
#ifndef ITEM_GEOFUNC_INCLUDED
#define ITEM_GEOFUNC_INCLUDED
/* Copyright (C) 2000-2003 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
it under the terms of the GNU General Public License as published by

2
sql/log.cc

@ -1,4 +1,4 @@
/* Copyright 2000-2008 MySQL AB, 2008-2009 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
it under the terms of the GNU General Public License as published by

2
sql/net_serv.cc

@ -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
it under the terms of the GNU General Public License as published by

14
sql/sql_base.cc

@ -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
it under the terms of the GNU General Public License as published by
@ -6155,6 +6155,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.
The caller is expected to check column-level privileges.
SYNOPSIS
find_field_in_table()
thd thread handler
@ -6262,6 +6264,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'
and calls the corresponding search routine.
The routine checks column-level privieleges for the found field.
RETURN
0 field is not found
view_ref_found found value in VIEW (real result is in *ref)
@ -6537,8 +6541,16 @@ find_field_in_tables(THD *thd, Item_ident *item,
when table_ref->field_translation != NULL.
*/
if (table_ref->table && !table_ref->view)
{
found= find_field_in_table(thd, table_ref->table, name, length,
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
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
NULL, NULL, ref, check_privileges,

85
sql/sql_load.cc

@ -363,58 +363,59 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(void) fn_format(name, ex->file_name, mysql_real_data_home, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME |
MY_RETURN_REAL_PATH);
#if !defined(__WIN__)
MY_STAT stat_info;
if (!mysql_file_stat(key_file_load, 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 (thd->slave_thread)
{
if (thd->slave_thread)
{
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
if (strncmp(active_mi->rli.slave_patternload_file, name,
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
if (strncmp(active_mi->rli.slave_patternload_file, name,
active_mi->rli.slave_patternload_file_size))
{
/*
This is impossible and should never happen.
LOAD DATA INFILE in the slave SQL Thread can only read from
--slave-load-tmpdir". This should never happen. Please, report a bug.
*/
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");
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");
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= mysql_file_open(key_file_load,
name, O_RDONLY, MYF(MY_WME))) < 0)
DBUG_RETURN(TRUE);
}

2
sql/sql_select.cc

@ -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
it under the terms of the GNU General Public License as published by

2
sql/sql_show.cc

@ -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
it under the terms of the GNU General Public License as published by

2
sql/sql_view.cc

@ -1,4 +1,4 @@
/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
/* Copyright (c) 2004, 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

156
storage/innobase/btr/btr0cur.c

@ -197,7 +197,7 @@ static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
rec_t* rec, /*!< in: record */
const rec_t* rec, /*!< in: record */
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
#endif /* !UNIV_HOTBACKUP */
@ -1886,8 +1886,8 @@ btr_cur_update_in_place(
NOT call it if index is secondary */
if (!dict_index_is_clust(index)
|| row_upd_changes_ord_field_binary(NULL, NULL,
index, update)) {
|| row_upd_changes_ord_field_binary(index, update, thr,
NULL, NULL)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
@ -3761,6 +3761,35 @@ btr_estimate_number_of_different_key_vals(
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
/***********************************************************//**
Gets the offset of the pointer to the externally stored part of a field.
@return offset of the pointer to the externally stored part */
static
ulint
btr_rec_get_field_ref_offs(
/*=======================*/
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: index of the external field */
{
ulint field_ref_offs;
ulint local_len;
ut_a(rec_offs_nth_extern(offsets, n));
field_ref_offs = rec_get_nth_field_offs(offsets, n, &local_len);
ut_a(local_len != UNIV_SQL_NULL);
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
return(field_ref_offs + local_len - BTR_EXTERN_FIELD_REF_SIZE);
}
/** Gets a pointer to the externally stored part of a field.
@param rec record
@param offsets rec_get_offsets(rec)
@param n index of the externally stored field
@return pointer to the externally stored part */
#define btr_rec_get_field_ref(rec, offsets, n) \
((rec) + btr_rec_get_field_ref_offs(offsets, n))
/***********************************************************//**
Gets the externally stored size of a record, in units of a database page.
@return externally stored part, in units of a database page */
@ -3768,28 +3797,27 @@ static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
rec_t* rec, /*!< in: record */
const rec_t* rec, /*!< in: record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
byte* data;
ulint local_len;
ulint extern_len;
ulint total_extern_len = 0;
ulint i;
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
if (!rec_offs_any_extern(offsets)) {
return(0);
}
n_fields = rec_offs_n_fields(offsets);
for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) {
data = rec_get_nth_field(rec, offsets, i, &local_len);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
extern_len = mach_read_from_4(data + local_len
+ BTR_EXTERN_LEN + 4);
ulint extern_len = mach_read_from_4(
btr_rec_get_field_ref(rec, offsets, i)
+ BTR_EXTERN_LEN + 4);
total_extern_len += ut_calc_align(extern_len,
UNIV_PAGE_SIZE);
@ -3819,7 +3847,7 @@ btr_cur_set_ownership_of_extern_field(
ulint byte_val;
data = rec_get_nth_field(rec, offsets, i, &local_len);
ut_ad(rec_offs_nth_extern(offsets, i));
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
@ -3829,6 +3857,9 @@ btr_cur_set_ownership_of_extern_field(
if (val) {
byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG);
} else {
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!(byte_val & BTR_EXTERN_OWNER_FLAG));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
byte_val = byte_val | BTR_EXTERN_OWNER_FLAG;
}
@ -4067,8 +4098,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
btr_store_big_rec_extern_fields_func(
/*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */
@ -4077,11 +4108,17 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
big_rec_t* big_rec_vec, /*!< in: vector containing fields
#ifdef UNIV_DEBUG
mtr_t* local_mtr, /*!< in: mtr containing the
latch to rec and to the tree */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ibool update_in_place,/*! in: TRUE if the record is updated
in place (not delete+insert) */
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */
mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to rec and to the
tree */
{
ulint rec_page_no;
byte* field_ref;
@ -4099,6 +4136,7 @@ btr_store_big_rec_extern_fields(
z_stream c_stream;
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_any_extern(offsets));
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
@ -4130,21 +4168,37 @@ btr_store_big_rec_extern_fields(
ut_a(err == Z_OK);
}
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/* All pointers to externally stored columns in the record
must either be zero or they must be pointers to inherited
columns, owned by this record or an earlier record version. */
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (!rec_offs_nth_extern(offsets, i)) {
continue;
}
field_ref = btr_rec_get_field_ref(rec, offsets, i);
ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
/* Either this must be an update in place,
or the BLOB must be inherited, or the BLOB pointer
must be zero (will be written in this function). */
ut_a(update_in_place
|| (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_INHERITED_FLAG)
|| !memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
}
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
/* We have to create a file segment to the tablespace
for each field and put the pointer to the field in rec */
for (i = 0; i < big_rec_vec->n_fields; i++) {
ut_ad(rec_offs_nth_extern(offsets,
big_rec_vec->fields[i].field_no));
{
ulint local_len;
field_ref = rec_get_nth_field(
rec, offsets, big_rec_vec->fields[i].field_no,
&local_len);
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
field_ref += local_len;
}
field_ref = btr_rec_get_field_ref(
rec, offsets, big_rec_vec->fields[i].field_no);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/* A zero BLOB pointer should have been initially inserted. */
ut_a(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
extern_len = big_rec_vec->fields[i].len;
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
extern_len);
@ -4426,6 +4480,23 @@ next_zip_page:
mem_heap_free(heap);
}
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/* All pointers to externally stored columns in the record
must be valid. */
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (!rec_offs_nth_extern(offsets, i)) {
continue;
}
field_ref = btr_rec_get_field_ref(rec, offsets, i);
/* The pointer must not be zero. */
ut_a(0 != memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
/* The column must not be disowned by this record. */
ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
}
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
return(DB_SUCCESS);
}
@ -4448,6 +4519,7 @@ btr_check_blob_fil_page_type(
if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) {
ulint flags = fil_space_get_flags(space_id);
#ifndef UNIV_DEBUG /* Improve debug test coverage */
if (UNIV_LIKELY
((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) {
/* Old versions of InnoDB did not initialize
@ -4456,6 +4528,7 @@ btr_check_blob_fil_page_type(
a BLOB page that is in Antelope format.*/
return;
}
#endif /* !UNIV_DEBUG */
ut_print_timestamp(stderr);
fprintf(stderr,
@ -4505,23 +4578,13 @@ btr_free_externally_stored_field(
ulint page_no;
ulint next_page_no;
mtr_t mtr;
#ifdef UNIV_DEBUG
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
MTR_MEMO_PAGE_X_FIX));
ut_ad(!rec || rec_offs_validate(rec, index, offsets));
if (rec) {
ulint local_len;
const byte* f = rec_get_nth_field(rec, offsets,
i, &local_len);
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
f += local_len;
ut_ad(f == field_ref);
}
#endif /* UNIV_DEBUG */
ut_ad(!rec || field_ref == btr_rec_get_field_ref(rec, offsets, i));
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE))) {
@ -4684,13 +4747,8 @@ btr_rec_free_externally_stored_fields(
for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) {
ulint len;
byte* data
= rec_get_nth_field(rec, offsets, i, &len);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
btr_free_externally_stored_field(
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
index, btr_rec_get_field_ref(rec, offsets, i),
rec, offsets, page_zip, i, rb_ctx, mtr);
}
}

30
storage/innobase/buf/buf0buf.c

@ -865,9 +865,9 @@ buf_block_init(
block->modify_clock = 0;
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
block->check_index_page_at_flush = FALSE;
block->index = NULL;
@ -2229,7 +2229,7 @@ buf_page_peek_if_search_hashed(
return(is_hashed);
}
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
@ -2252,6 +2252,8 @@ buf_page_set_file_page_was_freed(
if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
/* bpage->file_page_was_freed can already hold
when this code is invoked from dict_drop_index_tree() */
bpage->file_page_was_freed = TRUE;
}
@ -2289,7 +2291,7 @@ buf_page_reset_file_page_was_freed(
return(bpage);
}
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//**
Get read access to a compressed page (usually of type
@ -2390,7 +2392,7 @@ got_block:
buf_page_set_accessed_make_young(bpage, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed);
#endif
@ -3058,7 +3060,7 @@ wait_until_unfixed:
buf_page_set_accessed_make_young(&block->page, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!block->page.file_page_was_freed);
#endif
@ -3217,7 +3219,7 @@ buf_page_optimistic_get(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
if (UNIV_UNLIKELY(!access_time)) {
@ -3329,7 +3331,7 @@ buf_page_get_known_nowait(
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
@ -3415,9 +3417,9 @@ buf_page_try_get_func(
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
buf_pool->stat.n_page_gets++;
@ -3446,9 +3448,9 @@ buf_page_init_low(
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
bpage->file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/********************************************************************//**
@ -3807,9 +3809,9 @@ buf_page_create(
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(space, offset) == 0);
#endif
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */
buf_pool_mutex_exit(buf_pool);

10
storage/innobase/dict/dict0dict.c

@ -949,7 +949,7 @@ dict_table_rename_in_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint fold;
char old_name[MAX_TABLE_NAME_LEN + 1];
char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
@ -961,7 +961,7 @@ dict_table_rename_in_cache(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", table->name,
MAX_TABLE_NAME_LEN);
MAX_FULL_NAME_LEN);
ut_error;
}
@ -1011,11 +1011,11 @@ dict_table_rename_in_cache(
ut_fold_string(old_name), table);
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
ut_realloc() with the same size do not cause fragmentation */
ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN);
table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1);
ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN);
table->name = ut_realloc(table->name, MAX_FULL_NAME_LEN + 1);
}
memcpy(table->name, new_name, strlen(new_name) + 1);

2
storage/innobase/dict/dict0load.c

@ -1552,7 +1552,7 @@ err_len:
"InnoDB: in InnoDB data dictionary"
" has unknown type %lx.\n",
(ulong) flags);
return(NULL);
return("incorrect flags in SYS_TABLES");
}
} else {
flags = 0;

8
storage/innobase/fsp/fsp0fsp.c

@ -3435,9 +3435,9 @@ fseg_free_page(
fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(space, page);
#endif
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/**********************************************************************//**
@ -3503,13 +3503,13 @@ fseg_free_extent(
fsp_free_extent(space, zip_size, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
for (i = 0; i < FSP_EXTENT_SIZE; i++) {
buf_page_set_file_page_was_freed(space,
first_page_in_extent + i);
}
#endif
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/**********************************************************************//**

11
storage/innobase/handler/ha_innodb.cc

@ -6236,6 +6236,17 @@ create_table_def(
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;
/* We pass 0 as the space id, and determine at a lower level the space

11
storage/innobase/handler/i_s.cc

@ -767,16 +767,7 @@ fill_innodb_locks_from_cache(
for (i = 0; i < rows_num; i++) {
i_s_locks_row_t* row;
/* 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];
char buf[MAX_FULL_NAME_LEN + 1];
const char* bufend;
char lock_trx_id[TRX_ID_MAX_LEN + 1];

8
storage/innobase/ibuf/ibuf0ibuf.c

@ -2276,9 +2276,9 @@ ibuf_remove_free_page(void)
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_SPACE_ID, page_no, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
#endif
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
ibuf_enter();
@ -2322,9 +2322,9 @@ ibuf_remove_free_page(void)
ibuf_bitmap_page_set_bits(
bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
#endif
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
mtr_commit(&mtr);
ibuf_exit();

42
storage/innobase/include/btr0cur.h

@ -500,8 +500,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
btr_store_big_rec_extern_fields_func(
/*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */
@ -510,10 +510,42 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
big_rec_t* big_rec_vec, /*!< in: vector containing fields
#ifdef UNIV_DEBUG
mtr_t* local_mtr, /*!< in: mtr containing the
latch to rec and to the tree */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ibool update_in_place,/*! in: TRUE if the record is updated
in place (not delete+insert) */
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */
mtr_t* local_mtr); /*!< in: mtr containing the latch to
rec and to the tree */
__attribute__((nonnull));
/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
file segment of the index tree.
@param index in: clustered index; MUST be X-latched by mtr
@param b in/out: block containing rec; MUST be X-latched by mtr
@param rec in/out: clustered index record
@param offsets in: rec_get_offsets(rec, index);
the "external storage" flags in offsets will not be adjusted
@param mtr in: mini-transaction that holds x-latch on index and b
@param upd in: TRUE if the record is updated in place (not delete+insert)
@param big in: vector containing fields to be stored externally
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
#ifdef UNIV_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
#elif defined UNIV_BLOB_LIGHT_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
#else
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
#endif
/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned the externally stored field,

8
storage/innobase/include/buf0buf.h

@ -480,7 +480,7 @@ buf_reset_check_index_page_at_flush(
/*================================*/
ulint space, /*!< in: space id */
ulint offset);/*!< in: page number */
#ifdef UNIV_DEBUG_FILE_ACCESSES
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
@ -505,7 +505,7 @@ buf_page_reset_file_page_was_freed(
/*===============================*/
ulint space, /*!< in: space id */
ulint offset); /*!< in: page number */
#endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//**
Reads the freed_page_clock of a buffer block.
@return freed_page_clock */
@ -1403,11 +1403,11 @@ struct buf_page_struct{
0 if the block was never accessed
in the buffer pool */
/* @} */
# ifdef UNIV_DEBUG_FILE_ACCESSES
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
/*!< this is set to TRUE when fsp
frees a page in buffer pool */
# endif /* UNIV_DEBUG_FILE_ACCESSES */
# endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
};

26
storage/innobase/include/row0upd.h

@ -280,19 +280,29 @@ NOTE: we compare the fields as binary strings!
@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
row_upd_changes_ord_field_binary_func(
/*==================================*/
dict_index_t* index, /*!< in: index of the record */
const upd_t* update, /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
#ifdef UNIV_DEBUG
const que_thr_t*thr, /*!< in: query thread */
#endif /* UNIV_DEBUG */
const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
const row_ext_t*ext, /*!< NULL, or prefixes of the externally
const row_ext_t*ext) /*!< NULL, or prefixes of the externally
stored columns in the old row */
dict_index_t* index, /*!< in: index of the record */
const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
__attribute__((nonnull(3,4), warn_unused_result));
__attribute__((nonnull(1,2), warn_unused_result));
#ifdef UNIV_DEBUG
# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
row_upd_changes_ord_field_binary_func(index,update,thr,row,ext)
#else /* UNIV_DEBUG */
# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
row_upd_changes_ord_field_binary_func(index,update,row,ext)
#endif /* UNIV_DEBUG */
/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering

19
storage/innobase/include/univ.i

@ -184,14 +184,15 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_BUF_DEBUG /* Enable buffer pool
debugging without UNIV_DEBUG */
#define UNIV_BLOB_LIGHT_DEBUG /* Enable off-page column
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
ut_ad(lock_rec_validate_page())
assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
(field file_page_was_freed
in buf_page_t) */
#define UNIV_DEBUG_FILE_ACCESSES /* Enable freed block access
debugging without UNIV_DEBUG */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
@ -308,6 +309,18 @@ number does not include a terminating '\0'. InnoDB probably can handle
longer names internally */
#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
==========================

19
storage/innobase/include/ut0vec.h

@ -93,6 +93,25 @@ ib_vector_get(
ib_vector_t* vec, /*!< in: vector */
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. */
UNIV_INLINE

29
storage/innobase/include/ut0vec.ic

@ -50,6 +50,35 @@ ib_vector_get(
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.
@return last vector element */

78
storage/innobase/lock/lock0lock.c

@ -3621,6 +3621,80 @@ lock_table_create(
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;
this is a low-level function which does NOT check if waiting requests
@ -3660,10 +3734,8 @@ lock_table_remove_low(
if (!lock_get_wait(lock)
&& !ib_vector_is_empty(trx->autoinc_locks)) {
lock_t* autoinc_lock;
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
ut_a(autoinc_lock == lock);
lock_table_remove_autoinc_lock(lock, trx);
}
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);

2
storage/innobase/row/row0ins.c

@ -2122,7 +2122,7 @@ function_exit:
err = btr_store_big_rec_extern_fields(
index, btr_cur_get_block(&cursor),
rec, offsets, big_rec, &mtr);
rec, offsets, &mtr, FALSE, big_rec);
if (modify) {
dtuple_big_rec_free(big_rec);

4
storage/innobase/row/row0merge.c

@ -2388,7 +2388,7 @@ row_merge_rename_tables(
{
ulint err = DB_ERROR;
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(old_table != new_table);
@ -2403,7 +2403,7 @@ row_merge_rename_tables(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", old_table->name,
MAX_TABLE_NAME_LEN);
MAX_FULL_NAME_LEN);
ut_error;
}

14
storage/innobase/row/row0mysql.c

@ -1939,15 +1939,13 @@ err_exit:
err = trx->error_state;
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
switch (err) {
case DB_SUCCESS:
break;
case DB_OUT_OF_FILE_SPACE:
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
/* TO DO: free table? The code below will dereference
table->name, though. */
}
switch (err) {
case DB_OUT_OF_FILE_SPACE:
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: cannot create table ",
stderr);
@ -1962,9 +1960,13 @@ err_exit:
break;
case DB_DUPLICATE_KEY:
default:
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
dict_mem_table_free(table);
break;
}

68
storage/innobase/row/row0purge.c

@ -489,8 +489,11 @@ Purges an update of an existing record. Also purges an update of a delete
marked record if that record contained an externally stored field. */
static
void
row_purge_upd_exist_or_extern(
/*==========================*/
row_purge_upd_exist_or_extern_func(
/*===============================*/
#ifdef UNIV_DEBUG
const que_thr_t*thr, /*!< in: query thread */
#endif /* UNIV_DEBUG */
purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
@ -515,8 +518,8 @@ row_purge_upd_exist_or_extern(
while (node->index != NULL) {
index = node->index;
if (row_upd_changes_ord_field_binary(NULL, NULL, node->index,
node->update)) {
if (row_upd_changes_ord_field_binary(node->index, node->update,
thr, NULL, NULL)) {
/* Build the older version of the index entry */
entry = row_build_index_entry(node->row, NULL,
index, heap);
@ -598,6 +601,14 @@ skip_secondaries:
}
}
#ifdef UNIV_DEBUG
# define row_purge_upd_exist_or_extern(thr,node) \
row_purge_upd_exist_or_extern_func(thr,node)
#else /* UNIV_DEBUG */
# define row_purge_upd_exist_or_extern(thr,node) \
row_purge_upd_exist_or_extern_func(node)
#endif /* UNIV_DEBUG */
/***********************************************************//**
Parses the row reference and other info in a modify undo log record.
@return TRUE if purge operation required: NOTE that then the CALLER
@ -704,47 +715,32 @@ err_exit:
/***********************************************************//**
Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the
parent node, which is always a query thread node.
@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
parent node, which is always a query thread node. */
static __attribute__((nonnull))
void
row_purge(
/*======*/
purge_node_t* node, /*!< in: row purge node */
que_thr_t* thr) /*!< in: query thread */
{
roll_ptr_t roll_ptr;
ibool purge_needed;
ibool updated_extern;
trx_t* trx;
ut_ad(node && thr);
trx = thr_get_trx(thr);
ut_ad(node);
ut_ad(thr);
node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
&(node->reservation),
node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr,
&node->reservation,
node->heap);
if (!node->undo_rec) {
/* Purge completed for this query thread */
thr->run_node = que_node_get_parent(node);
return(DB_SUCCESS);
}
node->roll_ptr = roll_ptr;
if (node->undo_rec == &trx_purge_dummy_rec) {
purge_needed = FALSE;
} else {
purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
thr);
/* If purge_needed == TRUE, we must also remember to unfreeze
data dictionary! */
return;
}
if (purge_needed) {
if (node->undo_rec != &trx_purge_dummy_rec
&& row_purge_parse_undo_rec(node, &updated_extern, thr)) {
node->found_clust = FALSE;
node->index = dict_table_get_next_index(
@ -756,14 +752,14 @@ row_purge(
} else if (updated_extern
|| node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
row_purge_upd_exist_or_extern(node);
row_purge_upd_exist_or_extern(thr, node);
}
if (node->found_clust) {
btr_pcur_close(&(node->pcur));
}
row_mysql_unfreeze_data_dictionary(trx);
row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
}
/* Do some cleanup */
@ -771,8 +767,6 @@ row_purge(
mem_heap_empty(node->heap);
thr->run_node = node;
return(DB_SUCCESS);
}
/***********************************************************//**
@ -786,9 +780,6 @@ row_purge_step(
que_thr_t* thr) /*!< in: query thread */
{
purge_node_t* node;
#ifdef UNIV_DEBUG
ulint err;
#endif /* UNIV_DEBUG */
ut_ad(thr);
@ -796,12 +787,7 @@ row_purge_step(
ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
#ifdef UNIV_DEBUG
err =
#endif /* UNIV_DEBUG */
row_purge(node, thr);
ut_ad(err == DB_SUCCESS);
return(thr);
}

35
storage/innobase/row/row0umod.c

@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low(
mtr_t* mtr, /*!< in: mtr */
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
ulint err;
ibool success;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);
success = btr_pcur_restore_position(mode, pcur, mtr);
/* Find out if the record has been purged already
or if we can remove it. */
if (!success) {
if (!btr_pcur_restore_position(mode, &node->pcur, mtr)
|| row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
return(DB_SUCCESS);
}
/* Find out if we can remove the whole clustered index record */
if (node->rec_type == TRX_UNDO_UPD_DEL_REC
&& !row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
/* Ok, we can remove */
} else {
return(DB_SUCCESS);
}
btr_cur = btr_pcur_get_btr_cur(&node->pcur);
if (mode == BTR_MODIFY_LEAF) {
success = btr_cur_optimistic_delete(btr_cur, mtr);
if (success) {
err = DB_SUCCESS;
} else {
err = DB_FAIL;
}
err = btr_cur_optimistic_delete(btr_cur, mtr)
? DB_SUCCESS
: DB_FAIL;
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@ -693,8 +679,9 @@ row_undo_mod_upd_exist_sec(
while (node->index != NULL) {
index = node->index;
if (row_upd_changes_ord_field_binary(
node->row, node->ext, node->index, node->update)) {
if (row_upd_changes_ord_field_binary(node->index, node->update,
thr,
node->row, node->ext)) {
/* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, node->ext,

43
storage/innobase/row/row0upd.c

@ -1192,25 +1192,31 @@ NOTE: we compare the fields as binary strings!
@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
row_upd_changes_ord_field_binary_func(
/*==================================*/
dict_index_t* index, /*!< in: index of the record */
const upd_t* update, /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
#ifdef UNIV_DEBUG
const que_thr_t*thr, /*!< in: query thread */
#endif /* UNIV_DEBUG */
const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
const row_ext_t*ext, /*!< NULL, or prefixes of the externally
const row_ext_t*ext) /*!< NULL, or prefixes of the externally
stored columns in the old row */
dict_index_t* index, /*!< in: index of the record */
const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
{
ulint n_unique;
ulint i;
const dict_index_t* clust_index;
ut_ad(update);
ut_ad(index);
ut_ad(update);
ut_ad(thr);
ut_ad(thr->graph);
ut_ad(thr->graph->trx);
n_unique = dict_index_get_n_unique(index);
@ -1263,9 +1269,14 @@ row_upd_changes_ord_field_binary(
if (UNIV_LIKELY_NULL(buf)) {
if (UNIV_UNLIKELY(buf == field_ref_zero)) {
/* This should never happen, but
we try to fail safe here. */
ut_ad(0);
/* The externally stored field
was not written yet. This
record should only be seen by
recv_recovery_rollback_active(),
when the server had crashed before
storing the field. */
ut_ad(thr->graph->trx->is_recovered);
ut_ad(trx_is_recv(thr->graph->trx));
return(TRUE);
}
@ -1640,8 +1651,8 @@ row_upd_sec_step(
ut_ad(!dict_index_is_clust(node->index));
if (node->state == UPD_NODE_UPDATE_ALL_SEC
|| row_upd_changes_ord_field_binary(node->row, node->ext,
node->index, node->update)) {
|| row_upd_changes_ord_field_binary(node->index, node->update,
thr, node->row, node->ext)) {
return(row_upd_sec_index_entry(node, thr));
}
@ -1971,7 +1982,7 @@ row_upd_clust_rec(
index, btr_cur_get_block(btr_cur), rec,
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
big_rec, mtr);
mtr, TRUE, big_rec);
mtr_commit(mtr);
}
@ -2169,8 +2180,8 @@ exit_func:
row_upd_store_row(node);
if (row_upd_changes_ord_field_binary(node->row, node->ext, index,
node->update)) {
if (row_upd_changes_ord_field_binary(index, node->update, thr,
node->row, node->ext)) {
/* Update causes an ordering field (ordering fields within
the B-tree) of the clustered index record to change: perform

13
storage/innobase/srv/srv0start.c

@ -1327,13 +1327,16 @@ innobase_start_or_create_for_mysql(void)
ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
/* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
still applies to windows. */
if (!srv_use_native_aio) {
io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
} else {
io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
/* On Windows when using native aio the number of aio requests
that a thread can handle at a given time is limited to 32
i.e.: SRV_N_PENDING_IOS_PER_THREAD */
# ifdef __WIN__
if (srv_use_native_aio) {
io_limit = SRV_N_PENDING_IOS_PER_THREAD;
}
# endif /* __WIN__ */
os_aio_init(io_limit,
srv_n_read_io_threads,

4
storage/innobase/trx/trx0roll.c

@ -47,8 +47,8 @@ Created 3/26/1996 Heikki Tuuri
rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
/** In crash recovery, the current trx to be rolled back */
static trx_t* trx_roll_crash_recv_trx = NULL;
/** In crash recovery, the current trx to be rolled back; NULL otherwise */
static const trx_t* trx_roll_crash_recv_trx = NULL;
/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */

Loading…
Cancel
Save