merge from 5.1
This commit is contained in:
commit
7fe2980563
2
README
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.
|
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.
|
||||||
|
|
||||||
|
@ -25,9 +25,11 @@ typedef struct st_line_buffer
|
|||||||
uint eof;
|
uint eof;
|
||||||
ulong max_size;
|
ulong max_size;
|
||||||
ulong read_length; /* Length of last read string */
|
ulong read_length; /* Length of last read string */
|
||||||
|
int error;
|
||||||
|
bool truncated;
|
||||||
} LINE_BUFFER;
|
} LINE_BUFFER;
|
||||||
|
|
||||||
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
|
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
|
||||||
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
|
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
|
||||||
extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated);
|
extern char *batch_readline(LINE_BUFFER *buffer);
|
||||||
extern void batch_readline_end(LINE_BUFFER *buffer);
|
extern void batch_readline_end(LINE_BUFFER *buffer);
|
||||||
|
@ -1872,14 +1872,13 @@ static int read_and_execute(bool interactive)
|
|||||||
ulong line_number=0;
|
ulong line_number=0;
|
||||||
bool ml_comment= 0;
|
bool ml_comment= 0;
|
||||||
COMMANDS *com;
|
COMMANDS *com;
|
||||||
bool truncated= 0;
|
|
||||||
status.exit_status=1;
|
status.exit_status=1;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!interactive)
|
if (!interactive)
|
||||||
{
|
{
|
||||||
line=batch_readline(status.line_buff, &truncated);
|
line=batch_readline(status.line_buff);
|
||||||
/*
|
/*
|
||||||
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
|
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
|
||||||
Editors like "notepad" put this marker in
|
Editors like "notepad" put this marker in
|
||||||
@ -1953,9 +1952,13 @@ static int read_and_execute(bool interactive)
|
|||||||
if (opt_outfile && line)
|
if (opt_outfile && line)
|
||||||
fprintf(OUTFILE, "%s\n", line);
|
fprintf(OUTFILE, "%s\n", line);
|
||||||
}
|
}
|
||||||
if (!line) // End of file
|
// End of file or system error
|
||||||
|
if (!line)
|
||||||
{
|
{
|
||||||
status.exit_status=0;
|
if (status.line_buff && status.line_buff->error)
|
||||||
|
status.exit_status= 1;
|
||||||
|
else
|
||||||
|
status.exit_status= 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1976,7 +1979,8 @@ static int read_and_execute(bool interactive)
|
|||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated))
|
if (add_line(glob_buffer, line, &in_string, &ml_comment,
|
||||||
|
status.line_buff ? status.line_buff->truncated : 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if in batch mode, send last query even if it doesn't end with \g or go */
|
/* if in batch mode, send last query even if it doesn't end with \g or go */
|
||||||
|
@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
|
|||||||
ulong max_size);
|
ulong max_size);
|
||||||
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
|
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
|
||||||
static size_t fill_buffer(LINE_BUFFER *buffer);
|
static size_t fill_buffer(LINE_BUFFER *buffer);
|
||||||
static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated);
|
static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
|
||||||
|
|
||||||
|
|
||||||
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
|
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
|
||||||
@ -42,13 +42,12 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *batch_readline(LINE_BUFFER *line_buff, bool *truncated)
|
char *batch_readline(LINE_BUFFER *line_buff)
|
||||||
{
|
{
|
||||||
char *pos;
|
char *pos;
|
||||||
ulong out_length;
|
ulong out_length;
|
||||||
DBUG_ASSERT(truncated != NULL);
|
|
||||||
|
|
||||||
if (!(pos=intern_read_line(line_buff,&out_length, truncated)))
|
if (!(pos=intern_read_line(line_buff, &out_length)))
|
||||||
return 0;
|
return 0;
|
||||||
if (out_length && pos[out_length-1] == '\n')
|
if (out_length && pos[out_length-1] == '\n')
|
||||||
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
|
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
|
||||||
@ -162,7 +161,10 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
|
|||||||
if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
|
if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
|
||||||
buffer->bufread+1,
|
buffer->bufread+1,
|
||||||
MYF(MY_WME | MY_FAE))))
|
MYF(MY_WME | MY_FAE))))
|
||||||
return (uint) -1;
|
{
|
||||||
|
buffer->error= my_errno;
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
buffer->start_of_line=buffer->buffer+start_offset;
|
buffer->start_of_line=buffer->buffer+start_offset;
|
||||||
buffer->end=buffer->buffer+bufbytes;
|
buffer->end=buffer->buffer+bufbytes;
|
||||||
}
|
}
|
||||||
@ -177,7 +179,10 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
|
|||||||
/* Read in new stuff. */
|
/* Read in new stuff. */
|
||||||
if ((read_count= my_read(buffer->file, (uchar*) buffer->end, read_count,
|
if ((read_count= my_read(buffer->file, (uchar*) buffer->end, read_count,
|
||||||
MYF(MY_WME))) == MY_FILE_ERROR)
|
MYF(MY_WME))) == MY_FILE_ERROR)
|
||||||
|
{
|
||||||
|
buffer->error= my_errno;
|
||||||
return (size_t) -1;
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong) read_count));
|
DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong) read_count));
|
||||||
|
|
||||||
@ -198,8 +203,7 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length)
|
||||||
char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated)
|
|
||||||
{
|
{
|
||||||
char *pos;
|
char *pos;
|
||||||
size_t length;
|
size_t length;
|
||||||
@ -214,22 +218,25 @@ char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated)
|
|||||||
if (pos == buffer->end)
|
if (pos == buffer->end)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
fill_buffer() can return 0 either on EOF in which case we abort
|
fill_buffer() can return NULL on EOF (in which case we abort),
|
||||||
or when the internal buffer has hit the size limit. In the latter case
|
on error, or when the internal buffer has hit the size limit.
|
||||||
return what we have read so far and signal string truncation.
|
In the latter case return what we have read so far and signal
|
||||||
|
string truncation.
|
||||||
*/
|
*/
|
||||||
if (!(length=fill_buffer(buffer)) || length == (uint) -1)
|
if (!(length= fill_buffer(buffer)))
|
||||||
{
|
{
|
||||||
if (buffer->eof)
|
if (buffer->eof)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
else if (length == (size_t) -1)
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
pos--; /* break line here */
|
pos--; /* break line here */
|
||||||
*truncated= 1;
|
buffer->truncated= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*truncated= 0;
|
buffer->truncated= 0;
|
||||||
buffer->end_of_line=pos+1;
|
buffer->end_of_line=pos+1;
|
||||||
*out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
|
*out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
|
||||||
DBUG_RETURN(buffer->start_of_line);
|
DBUG_RETURN(buffer->start_of_line);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
|
|
||||||
perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big funcs_1.myisam_views-big
|
perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big 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-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-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
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental
|
|
@ -1,4 +0,0 @@
|
|||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb
|
|
||||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
|
|
@ -107,7 +107,7 @@ DROP DATABASE hotcopy_save;
|
|||||||
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
|
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
|
||||||
--list_files $MYSQLD_DATADIR/hotcopy_save
|
--list_files $MYSQLD_DATADIR/hotcopy_save
|
||||||
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
|
--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
|
--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
|
||||||
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
|
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
|
||||||
--exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
|
--exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
|
||||||
|
@ -88,7 +88,7 @@ while ($_rpl_i) {
|
|||||||
{
|
{
|
||||||
--echo Sync IO: $_rpl_slave_io_running; Sync SQL: $_rpl_slave_sql_running
|
--echo Sync IO: $_rpl_slave_io_running; Sync SQL: $_rpl_slave_sql_running
|
||||||
}
|
}
|
||||||
--let $_rpl_slave_io_running= `SELECT IF('$_rpl_slave_io_running' = 'Yes', 1, '')`
|
--let $_rpl_slave_io_running= `SELECT IF('$_rpl_slave_io_running' != 'No', 1, '')`
|
||||||
--let $_rpl_slave_sql_running= `SELECT IF('$_rpl_slave_sql_running' = 'Yes', 1, '')`
|
--let $_rpl_slave_sql_running= `SELECT IF('$_rpl_slave_sql_running' = 'Yes', 1, '')`
|
||||||
if ($_rpl_slave_io_running)
|
if ($_rpl_slave_io_running)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -1638,4 +1638,29 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 index NULL a 8 NULL 10 Using index; Using temporary; Using filesort
|
1 SIMPLE t1 index NULL a 8 NULL 10 Using index; Using temporary; Using filesort
|
||||||
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where
|
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
|
||||||
|
# and
|
||||||
|
# Bug #59308: Incorrect result for
|
||||||
|
SELECT DISTINCT <col>... ORDER BY <col> DESC
|
||||||
|
|
||||||
|
# Use Valgrind to detect #59110!
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT,KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||||
|
EXPLAIN SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index a a 5 NULL 10 Using where; Using index; Using filesort
|
||||||
|
SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
|
||||||
|
a 1
|
||||||
|
10 1
|
||||||
|
9 1
|
||||||
|
8 1
|
||||||
|
7 1
|
||||||
|
6 1
|
||||||
|
5 1
|
||||||
|
4 1
|
||||||
|
3 1
|
||||||
|
2 1
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t2;
|
DROP TABLE IF EXISTS t1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
CREATE TABLE t1(c1 CHAR(100) NOT NULL);
|
CREATE TABLE t1(c1 CHAR(100) NOT NULL);
|
||||||
PREPARE stmt1 FROM 'INSERT INTO t1 (c1) VALUES(?)';
|
PREPARE stmt1 FROM 'INSERT INTO t1 (c1) VALUES(?)';
|
||||||
|
30
mysql-test/suite/innodb_plugin/r/innodb-autoinc-56228.result
Normal file
30
mysql-test/suite/innodb_plugin/r/innodb-autoinc-56228.result
Normal 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'
|
@ -0,0 +1 @@
|
|||||||
|
--innodb_autoinc_lock_mode=0
|
42
mysql-test/suite/innodb_plugin/t/innodb-autoinc-56228.test
Normal file
42
mysql-test/suite/innodb_plugin/t/innodb-autoinc-56228.test
Normal 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;
|
@ -121,11 +121,11 @@ Master D 12 D
|
|||||||
* Remove wrong event from C and restore B->C->D *
|
* Remove wrong event from C and restore B->C->D *
|
||||||
include/stop_slave.inc
|
include/stop_slave.inc
|
||||||
DELETE FROM t1 WHERE a = 6;
|
DELETE FROM t1 WHERE a = 6;
|
||||||
START SLAVE;
|
include/start_slave.inc
|
||||||
RESET MASTER;
|
RESET MASTER;
|
||||||
RESET SLAVE;
|
RESET SLAVE;
|
||||||
include/rpl_change_topology.inc [new topology=1->2->3->4->1]
|
include/rpl_change_topology.inc [new topology=1->2->3->4->1]
|
||||||
START SLAVE;
|
include/start_slave.inc
|
||||||
include/rpl_sync.inc
|
include/rpl_sync.inc
|
||||||
|
|
||||||
* Check data inserted before restoring schema A->B->C->D->A *
|
* Check data inserted before restoring schema A->B->C->D->A *
|
||||||
|
@ -175,7 +175,7 @@ SELECT 'Master D',a,b FROM t1 WHERE c = 3 ORDER BY a,b;
|
|||||||
source include/stop_slave.inc;
|
source include/stop_slave.inc;
|
||||||
--connection server_3
|
--connection server_3
|
||||||
DELETE FROM t1 WHERE a = 6;
|
DELETE FROM t1 WHERE a = 6;
|
||||||
START SLAVE;
|
--source include/start_slave.inc
|
||||||
--connection server_2
|
--connection server_2
|
||||||
--sync_slave_with_master server_3
|
--sync_slave_with_master server_3
|
||||||
RESET MASTER;
|
RESET MASTER;
|
||||||
@ -189,7 +189,7 @@ RESET SLAVE;
|
|||||||
--source include/rpl_change_topology.inc
|
--source include/rpl_change_topology.inc
|
||||||
#--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 $file_d LOG_FILE $pos_d LOG_POS
|
#--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 $file_d LOG_FILE $pos_d LOG_POS
|
||||||
#--eval CHANGE MASTER TO master_host='127.0.0.1',master_port=$SERVER_MYPORT_3,master_user='root',master_log_file='$file_d',master_log_pos=$pos_d
|
#--eval CHANGE MASTER TO master_host='127.0.0.1',master_port=$SERVER_MYPORT_3,master_user='root',master_log_file='$file_d',master_log_pos=$pos_d
|
||||||
START SLAVE;
|
--source include/start_slave.inc
|
||||||
--connection server_3
|
--connection server_3
|
||||||
--sync_slave_with_master server_4
|
--sync_slave_with_master server_4
|
||||||
--source include/rpl_sync.inc
|
--source include/rpl_sync.inc
|
||||||
|
6
mysql-test/suite/sys_vars/r/secure_file_priv2.result
Normal file
6
mysql-test/suite/sys_vars/r/secure_file_priv2.result
Normal 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;
|
1
mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt
Normal file
1
mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--secure_file_priv=$SECURE_LOAD_PATH
|
23
mysql-test/suite/sys_vars/t/secure_file_priv2.test
Normal file
23
mysql-test/suite/sys_vars/t/secure_file_priv2.test
Normal 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;
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -412,6 +412,12 @@ drop table t1;
|
|||||||
--echo
|
--echo
|
||||||
--exec $MYSQL --skip-column-names --vertical test -e "select 1 as a"
|
--exec $MYSQL --skip-column-names --vertical test -e "select 1 as a"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#57450: mysql client enter in an infinite loop if the standard input is a directory
|
||||||
|
#
|
||||||
|
--error 1
|
||||||
|
--exec $MYSQL < .
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -1492,4 +1492,21 @@ LIMIT 2;
|
|||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
|
||||||
|
--echo # and
|
||||||
|
--echo # Bug #59308: Incorrect result for
|
||||||
|
--echo SELECT DISTINCT <col>... ORDER BY <col> DESC
|
||||||
|
--echo
|
||||||
|
--echo # Use Valgrind to detect #59110!
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT,KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||||
|
|
||||||
|
EXPLAIN SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
|
||||||
|
SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -744,3 +744,50 @@
|
|||||||
Memcheck:Addr1
|
Memcheck:Addr1
|
||||||
fun:buf_buddy_relocate
|
fun:buf_buddy_relocate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
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
|
||||||
|
fun:page_cur_insert_rec_zip_reorg
|
||||||
|
fun:page_cur_insert_rec_zip
|
||||||
|
fun:page_cur_tuple_insert
|
||||||
|
fun:btr_cur_optimistic_insert
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
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
|
||||||
|
fun:buf_LRU_invalidate_tablespace
|
||||||
|
fun:fil_delete_tablespace
|
||||||
|
fun:row_drop_table_for_mysql
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
13
sql/item.h
13
sql/item.h
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
@ -13364,12 +13364,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
{
|
{
|
||||||
int ref_key;
|
int ref_key;
|
||||||
uint ref_key_parts;
|
uint ref_key_parts;
|
||||||
int order_direction;
|
int order_direction= 0;
|
||||||
uint used_key_parts;
|
uint used_key_parts;
|
||||||
TABLE *table=tab->table;
|
TABLE *table=tab->table;
|
||||||
SQL_SELECT *select=tab->select;
|
SQL_SELECT *select=tab->select;
|
||||||
key_map usable_keys;
|
key_map usable_keys;
|
||||||
QUICK_SELECT_I *save_quick= 0;
|
QUICK_SELECT_I *save_quick= 0;
|
||||||
|
int best_key= -1;
|
||||||
|
|
||||||
DBUG_ENTER("test_if_skip_sort_order");
|
DBUG_ENTER("test_if_skip_sort_order");
|
||||||
LINT_INIT(ref_key_parts);
|
LINT_INIT(ref_key_parts);
|
||||||
|
|
||||||
@ -13473,13 +13475,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
new_ref_key_map.clear_all(); // Force the creation of quick select
|
new_ref_key_map.clear_all(); // Force the creation of quick select
|
||||||
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
|
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
|
||||||
|
|
||||||
|
select->quick= 0;
|
||||||
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
|
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
|
||||||
(tab->join->select_options &
|
(tab->join->select_options &
|
||||||
OPTION_FOUND_ROWS) ?
|
OPTION_FOUND_ROWS) ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
tab->join->unit->select_limit_cnt,0) <=
|
tab->join->unit->select_limit_cnt,0) <=
|
||||||
0)
|
0)
|
||||||
DBUG_RETURN(0);
|
goto use_filesort;
|
||||||
}
|
}
|
||||||
ref_key= new_ref_key;
|
ref_key= new_ref_key;
|
||||||
}
|
}
|
||||||
@ -13504,7 +13507,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
int best_key_direction= 0;
|
int best_key_direction= 0;
|
||||||
ha_rows best_records= 0;
|
ha_rows best_records= 0;
|
||||||
double read_time;
|
double read_time;
|
||||||
int best_key= -1;
|
|
||||||
bool is_best_covering= FALSE;
|
bool is_best_covering= FALSE;
|
||||||
double fanout= 1;
|
double fanout= 1;
|
||||||
JOIN *join= tab->join;
|
JOIN *join= tab->join;
|
||||||
@ -13681,72 +13683,21 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
tab->join->tables > tab->join->const_tables + 1) &&
|
tab->join->tables > tab->join->const_tables + 1) &&
|
||||||
((unsigned) best_key != table->s->primary_key ||
|
((unsigned) best_key != table->s->primary_key ||
|
||||||
!table->file->primary_key_is_clustered()))
|
!table->file->primary_key_is_clustered()))
|
||||||
DBUG_RETURN(0);
|
goto use_filesort;
|
||||||
|
|
||||||
if (best_key >= 0)
|
if (best_key >= 0)
|
||||||
{
|
{
|
||||||
bool quick_created= FALSE;
|
|
||||||
if (table->quick_keys.is_set(best_key) && best_key != ref_key)
|
if (table->quick_keys.is_set(best_key) && best_key != ref_key)
|
||||||
{
|
{
|
||||||
key_map map;
|
key_map map;
|
||||||
map.clear_all(); // Force the creation of quick select
|
map.clear_all(); // Force the creation of quick select
|
||||||
map.set_bit(best_key); // only best_key.
|
map.set_bit(best_key); // only best_key.
|
||||||
quick_created=
|
select->quick= 0;
|
||||||
select->test_quick_select(join->thd, map, 0,
|
select->test_quick_select(join->thd, map, 0,
|
||||||
join->select_options & OPTION_FOUND_ROWS ?
|
join->select_options & OPTION_FOUND_ROWS ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
join->unit->select_limit_cnt,
|
join->unit->select_limit_cnt,
|
||||||
0) > 0;
|
0);
|
||||||
}
|
|
||||||
if (!no_changes)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If ref_key used index tree reading only ('Using index' in EXPLAIN),
|
|
||||||
and best_key doesn't, then revert the decision.
|
|
||||||
*/
|
|
||||||
if (!table->covering_keys.is_set(best_key))
|
|
||||||
table->set_keyread(FALSE);
|
|
||||||
if (!quick_created)
|
|
||||||
{
|
|
||||||
tab->index= best_key;
|
|
||||||
tab->read_first_record= best_key_direction > 0 ?
|
|
||||||
join_read_first:join_read_last;
|
|
||||||
tab->type=JT_NEXT; // Read with index_first(), index_next()
|
|
||||||
if (select && select->quick)
|
|
||||||
{
|
|
||||||
delete select->quick;
|
|
||||||
select->quick= 0;
|
|
||||||
}
|
|
||||||
if (table->covering_keys.is_set(best_key))
|
|
||||||
table->set_keyread(TRUE);
|
|
||||||
table->file->ha_index_or_rnd_end();
|
|
||||||
if (join->select_options & SELECT_DESCRIBE)
|
|
||||||
{
|
|
||||||
tab->ref.key= -1;
|
|
||||||
tab->ref.key_parts= 0;
|
|
||||||
if (select_limit < table_records)
|
|
||||||
tab->limit= select_limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (tab->type != JT_ALL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We're about to use a quick access to the table.
|
|
||||||
We need to change the access method so as the quick access
|
|
||||||
method is actually used.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(tab->select->quick);
|
|
||||||
tab->type=JT_ALL;
|
|
||||||
tab->use_quick=1;
|
|
||||||
tab->ref.key= -1;
|
|
||||||
tab->ref.key_parts=0; // Don't use ref key.
|
|
||||||
tab->read_first_record= join_init_read_record;
|
|
||||||
if (tab->is_using_loose_index_scan())
|
|
||||||
join->tmp_table_param.precomputed_group_by= TRUE;
|
|
||||||
/*
|
|
||||||
TODO: update the number of records in join->best_positions[tablenr]
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
order_direction= best_key_direction;
|
order_direction= best_key_direction;
|
||||||
/*
|
/*
|
||||||
@ -13759,10 +13710,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
saved_best_key_parts : best_key_parts;
|
saved_best_key_parts : best_key_parts;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DBUG_RETURN(0);
|
goto use_filesort;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_reverse_order:
|
check_reverse_order:
|
||||||
|
DBUG_ASSERT(order_direction != 0);
|
||||||
|
|
||||||
if (order_direction == -1) // If ORDER BY ... DESC
|
if (order_direction == -1) // If ORDER BY ... DESC
|
||||||
{
|
{
|
||||||
if (select && select->quick)
|
if (select && select->quick)
|
||||||
@ -13771,9 +13724,10 @@ check_reverse_order:
|
|||||||
Don't reverse the sort order, if it's already done.
|
Don't reverse the sort order, if it's already done.
|
||||||
(In some cases test_if_order_by_key() can be called multiple times
|
(In some cases test_if_order_by_key() can be called multiple times
|
||||||
*/
|
*/
|
||||||
if (!select->quick->reverse_sorted())
|
if (select->quick->reverse_sorted())
|
||||||
|
goto skipped_filesort;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
QUICK_SELECT_DESC *tmp;
|
|
||||||
int quick_type= select->quick->get_type();
|
int quick_type= select->quick->get_type();
|
||||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
||||||
@ -13781,39 +13735,132 @@ check_reverse_order:
|
|||||||
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
|
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
|
||||||
{
|
{
|
||||||
tab->limit= 0;
|
tab->limit= 0;
|
||||||
select->quick= save_quick;
|
goto use_filesort; // Use filesort
|
||||||
DBUG_RETURN(0); // Use filesort
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ORDER BY range_key DESC */
|
|
||||||
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
|
|
||||||
used_key_parts);
|
|
||||||
if (!tmp || tmp->error)
|
|
||||||
{
|
|
||||||
delete tmp;
|
|
||||||
select->quick= save_quick;
|
|
||||||
tab->limit= 0;
|
|
||||||
DBUG_RETURN(0); // Reverse sort not supported
|
|
||||||
}
|
|
||||||
select->quick=tmp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
|
|
||||||
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
|
|
||||||
|
|
||||||
Use a traversal function that starts by reading the last row
|
|
||||||
with key part (A) and then traverse the index backwards.
|
|
||||||
*/
|
|
||||||
tab->read_first_record= join_read_last_key;
|
|
||||||
tab->read_record.read_record= join_read_prev_same;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (select && select->quick)
|
|
||||||
select->quick->sorted= 1;
|
/*
|
||||||
|
Update query plan with access pattern for doing
|
||||||
|
ordered access according to what we have decided
|
||||||
|
above.
|
||||||
|
*/
|
||||||
|
if (!no_changes) // We are allowed to update QEP
|
||||||
|
{
|
||||||
|
if (best_key >= 0)
|
||||||
|
{
|
||||||
|
bool quick_created=
|
||||||
|
(select && select->quick && select->quick!=save_quick);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If ref_key used index tree reading only ('Using index' in EXPLAIN),
|
||||||
|
and best_key doesn't, then revert the decision.
|
||||||
|
*/
|
||||||
|
if (!table->covering_keys.is_set(best_key))
|
||||||
|
table->set_keyread(FALSE);
|
||||||
|
if (!quick_created)
|
||||||
|
{
|
||||||
|
if (select) // Throw any existing quick select
|
||||||
|
select->quick= 0; // Cleanup either reset to save_quick,
|
||||||
|
// or 'delete save_quick'
|
||||||
|
tab->index= best_key;
|
||||||
|
tab->read_first_record= order_direction > 0 ?
|
||||||
|
join_read_first:join_read_last;
|
||||||
|
tab->type=JT_NEXT; // Read with index_first(), index_next()
|
||||||
|
|
||||||
|
if (table->covering_keys.is_set(best_key))
|
||||||
|
table->set_keyread(TRUE);
|
||||||
|
table->file->ha_index_or_rnd_end();
|
||||||
|
if (tab->join->select_options & SELECT_DESCRIBE)
|
||||||
|
{
|
||||||
|
tab->ref.key= -1;
|
||||||
|
tab->ref.key_parts= 0;
|
||||||
|
if (select_limit < table->file->stats.records)
|
||||||
|
tab->limit= select_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tab->type != JT_ALL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We're about to use a quick access to the table.
|
||||||
|
We need to change the access method so as the quick access
|
||||||
|
method is actually used.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(tab->select->quick);
|
||||||
|
tab->type=JT_ALL;
|
||||||
|
tab->use_quick=1;
|
||||||
|
tab->ref.key= -1;
|
||||||
|
tab->ref.key_parts=0; // Don't use ref key.
|
||||||
|
tab->read_first_record= join_init_read_record;
|
||||||
|
if (tab->is_using_loose_index_scan())
|
||||||
|
tab->join->tmp_table_param.precomputed_group_by= TRUE;
|
||||||
|
/*
|
||||||
|
TODO: update the number of records in join->best_positions[tablenr]
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} // best_key >= 0
|
||||||
|
|
||||||
|
if (order_direction == -1) // If ORDER BY ... DESC
|
||||||
|
{
|
||||||
|
if (select && select->quick)
|
||||||
|
{
|
||||||
|
QUICK_SELECT_DESC *tmp;
|
||||||
|
/* ORDER BY range_key DESC */
|
||||||
|
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
|
||||||
|
used_key_parts);
|
||||||
|
if (tmp && select->quick == save_quick)
|
||||||
|
save_quick= 0; // ::QUICK_SELECT_DESC consumed it
|
||||||
|
|
||||||
|
if (!tmp || tmp->error)
|
||||||
|
{
|
||||||
|
delete tmp;
|
||||||
|
tab->limit= 0;
|
||||||
|
goto use_filesort; // Reverse sort failed -> filesort
|
||||||
|
}
|
||||||
|
select->quick= tmp;
|
||||||
|
}
|
||||||
|
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
|
||||||
|
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
|
||||||
|
|
||||||
|
Use a traversal function that starts by reading the last row
|
||||||
|
with key part (A) and then traverse the index backwards.
|
||||||
|
*/
|
||||||
|
tab->read_first_record= join_read_last_key;
|
||||||
|
tab->read_record.read_record= join_read_prev_same;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (select && select->quick)
|
||||||
|
select->quick->sorted= 1;
|
||||||
|
|
||||||
|
} // QEP has been modified
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cleanup:
|
||||||
|
We may have both a 'select->quick' and 'save_quick' (original)
|
||||||
|
at this point. Delete the one that we wan't use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
skipped_filesort:
|
||||||
|
// Keep current (ordered) select->quick
|
||||||
|
if (select && save_quick != select->quick)
|
||||||
|
{
|
||||||
|
delete save_quick;
|
||||||
|
save_quick= NULL;
|
||||||
|
}
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
use_filesort:
|
||||||
|
// Restore original save_quick
|
||||||
|
if (select && select->quick != save_quick)
|
||||||
|
{
|
||||||
|
delete select->quick;
|
||||||
|
select->quick= save_quick;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2011-01-31 The InnoDB Team
|
||||||
|
|
||||||
|
* btr/btr0cur.c, include/row0upd.h,
|
||||||
|
row/row0purge.c, row/row0umod.c, row/row0upd.c:
|
||||||
|
Bug#59230 assert 0 row_upd_changes_ord_field_binary()
|
||||||
|
in post-crash rollback or purge
|
||||||
|
|
||||||
2011-01-27 The InnoDB Team
|
2011-01-27 The InnoDB Team
|
||||||
|
|
||||||
* btr/btr0cur.c:
|
* btr/btr0cur.c:
|
||||||
@ -49,6 +56,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
|
||||||
|
@ -186,7 +186,7 @@ static
|
|||||||
ulint
|
ulint
|
||||||
btr_rec_get_externally_stored_len(
|
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() */
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
@ -1768,8 +1768,8 @@ btr_cur_update_in_place(
|
|||||||
NOT call it if index is secondary */
|
NOT call it if index is secondary */
|
||||||
|
|
||||||
if (!dict_index_is_clust(index)
|
if (!dict_index_is_clust(index)
|
||||||
|| row_upd_changes_ord_field_binary(NULL, NULL,
|
|| row_upd_changes_ord_field_binary(index, update, thr,
|
||||||
index, update)) {
|
NULL, NULL)) {
|
||||||
|
|
||||||
/* Remove possible hash index pointer to this record */
|
/* Remove possible hash index pointer to this record */
|
||||||
btr_search_update_hash_on_delete(cursor);
|
btr_search_update_hash_on_delete(cursor);
|
||||||
@ -3483,6 +3483,35 @@ btr_estimate_number_of_different_key_vals(
|
|||||||
|
|
||||||
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
|
/*================== 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.
|
Gets the externally stored size of a record, in units of a database page.
|
||||||
@return externally stored part, in units of a database page */
|
@return externally stored part, in units of a database page */
|
||||||
@ -3490,28 +3519,27 @@ static
|
|||||||
ulint
|
ulint
|
||||||
btr_rec_get_externally_stored_len(
|
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() */
|
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
||||||
{
|
{
|
||||||
ulint n_fields;
|
ulint n_fields;
|
||||||
byte* data;
|
|
||||||
ulint local_len;
|
|
||||||
ulint extern_len;
|
|
||||||
ulint total_extern_len = 0;
|
ulint total_extern_len = 0;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
|
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);
|
n_fields = rec_offs_n_fields(offsets);
|
||||||
|
|
||||||
for (i = 0; i < n_fields; i++) {
|
for (i = 0; i < n_fields; i++) {
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
if (rec_offs_nth_extern(offsets, i)) {
|
||||||
|
|
||||||
data = rec_get_nth_field(rec, offsets, i, &local_len);
|
ulint extern_len = mach_read_from_4(
|
||||||
|
btr_rec_get_field_ref(rec, offsets, i)
|
||||||
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
|
+ BTR_EXTERN_LEN + 4);
|
||||||
|
|
||||||
extern_len = mach_read_from_4(data + local_len
|
|
||||||
+ BTR_EXTERN_LEN + 4);
|
|
||||||
|
|
||||||
total_extern_len += ut_calc_align(extern_len,
|
total_extern_len += ut_calc_align(extern_len,
|
||||||
UNIV_PAGE_SIZE);
|
UNIV_PAGE_SIZE);
|
||||||
@ -3541,7 +3569,7 @@ btr_cur_set_ownership_of_extern_field(
|
|||||||
ulint byte_val;
|
ulint byte_val;
|
||||||
|
|
||||||
data = rec_get_nth_field(rec, offsets, i, &local_len);
|
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);
|
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
|
||||||
|
|
||||||
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
|
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
|
||||||
@ -3551,6 +3579,9 @@ btr_cur_set_ownership_of_extern_field(
|
|||||||
if (val) {
|
if (val) {
|
||||||
byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG);
|
byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG);
|
||||||
} else {
|
} 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;
|
byte_val = byte_val | BTR_EXTERN_OWNER_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3788,8 +3819,8 @@ file segment of the index tree.
|
|||||||
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ulint
|
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
|
dict_index_t* index, /*!< in: index of rec; the index tree
|
||||||
MUST be X-latched */
|
MUST be X-latched */
|
||||||
buf_block_t* rec_block, /*!< in/out: block containing rec */
|
buf_block_t* rec_block, /*!< in/out: block containing rec */
|
||||||
@ -3798,11 +3829,17 @@ btr_store_big_rec_extern_fields(
|
|||||||
the "external storage" flags in offsets
|
the "external storage" flags in offsets
|
||||||
will not correspond to rec when
|
will not correspond to rec when
|
||||||
this function returns */
|
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 */
|
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;
|
ulint rec_page_no;
|
||||||
byte* field_ref;
|
byte* field_ref;
|
||||||
@ -3820,6 +3857,7 @@ btr_store_big_rec_extern_fields(
|
|||||||
z_stream c_stream;
|
z_stream c_stream;
|
||||||
|
|
||||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
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),
|
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
|
||||||
MTR_MEMO_X_LOCK));
|
MTR_MEMO_X_LOCK));
|
||||||
ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
|
ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
|
||||||
@ -3851,21 +3889,37 @@ btr_store_big_rec_extern_fields(
|
|||||||
ut_a(err == Z_OK);
|
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
|
/* We have to create a file segment to the tablespace
|
||||||
for each field and put the pointer to the field in rec */
|
for each field and put the pointer to the field in rec */
|
||||||
|
|
||||||
for (i = 0; i < big_rec_vec->n_fields; i++) {
|
for (i = 0; i < big_rec_vec->n_fields; i++) {
|
||||||
ut_ad(rec_offs_nth_extern(offsets,
|
field_ref = btr_rec_get_field_ref(
|
||||||
big_rec_vec->fields[i].field_no));
|
rec, offsets, big_rec_vec->fields[i].field_no);
|
||||||
{
|
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
|
||||||
ulint local_len;
|
/* A zero BLOB pointer should have been initially inserted. */
|
||||||
field_ref = rec_get_nth_field(
|
ut_a(!memcmp(field_ref, field_ref_zero,
|
||||||
rec, offsets, big_rec_vec->fields[i].field_no,
|
BTR_EXTERN_FIELD_REF_SIZE));
|
||||||
&local_len);
|
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
|
||||||
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
|
|
||||||
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
|
|
||||||
field_ref += local_len;
|
|
||||||
}
|
|
||||||
extern_len = big_rec_vec->fields[i].len;
|
extern_len = big_rec_vec->fields[i].len;
|
||||||
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
|
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
|
||||||
extern_len);
|
extern_len);
|
||||||
@ -4147,6 +4201,23 @@ next_zip_page:
|
|||||||
mem_heap_free(heap);
|
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);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4169,6 +4240,7 @@ btr_check_blob_fil_page_type(
|
|||||||
if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) {
|
if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) {
|
||||||
ulint flags = fil_space_get_flags(space_id);
|
ulint flags = fil_space_get_flags(space_id);
|
||||||
|
|
||||||
|
#ifndef UNIV_DEBUG /* Improve debug test coverage */
|
||||||
if (UNIV_LIKELY
|
if (UNIV_LIKELY
|
||||||
((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) {
|
((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) {
|
||||||
/* Old versions of InnoDB did not initialize
|
/* Old versions of InnoDB did not initialize
|
||||||
@ -4177,6 +4249,7 @@ btr_check_blob_fil_page_type(
|
|||||||
a BLOB page that is in Antelope format.*/
|
a BLOB page that is in Antelope format.*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif /* !UNIV_DEBUG */
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -4226,23 +4299,13 @@ btr_free_externally_stored_field(
|
|||||||
ulint page_no;
|
ulint page_no;
|
||||||
ulint next_page_no;
|
ulint next_page_no;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
|
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
|
||||||
MTR_MEMO_X_LOCK));
|
MTR_MEMO_X_LOCK));
|
||||||
ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
|
ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
|
||||||
MTR_MEMO_PAGE_X_FIX));
|
MTR_MEMO_PAGE_X_FIX));
|
||||||
ut_ad(!rec || rec_offs_validate(rec, index, offsets));
|
ut_ad(!rec || rec_offs_validate(rec, index, offsets));
|
||||||
|
ut_ad(!rec || field_ref == btr_rec_get_field_ref(rec, offsets, i));
|
||||||
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 */
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
|
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
|
||||||
BTR_EXTERN_FIELD_REF_SIZE))) {
|
BTR_EXTERN_FIELD_REF_SIZE))) {
|
||||||
@ -4407,13 +4470,8 @@ btr_rec_free_externally_stored_fields(
|
|||||||
|
|
||||||
for (i = 0; i < n_fields; i++) {
|
for (i = 0; i < n_fields; i++) {
|
||||||
if (rec_offs_nth_extern(offsets, 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(
|
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);
|
rec, offsets, page_zip, i, rb_ctx, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,9 +657,9 @@ buf_block_init(
|
|||||||
|
|
||||||
block->modify_clock = 0;
|
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;
|
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->check_index_page_at_flush = FALSE;
|
||||||
block->index = NULL;
|
block->index = NULL;
|
||||||
@ -1600,7 +1600,7 @@ buf_page_peek_if_search_hashed(
|
|||||||
return(is_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.
|
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
|
This function should be called when we free a file page and want the
|
||||||
@ -1621,6 +1621,8 @@ buf_page_set_file_page_was_freed(
|
|||||||
bpage = buf_page_hash_get(space, offset);
|
bpage = buf_page_hash_get(space, offset);
|
||||||
|
|
||||||
if (bpage) {
|
if (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;
|
bpage->file_page_was_freed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1656,7 +1658,7 @@ buf_page_reset_file_page_was_freed(
|
|||||||
|
|
||||||
return(bpage);
|
return(bpage);
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Get read access to a compressed page (usually of type
|
Get read access to a compressed page (usually of type
|
||||||
@ -1753,7 +1755,7 @@ got_block:
|
|||||||
|
|
||||||
buf_page_set_accessed_make_young(bpage, access_time);
|
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);
|
ut_a(!bpage->file_page_was_freed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2321,7 +2323,7 @@ wait_until_unfixed:
|
|||||||
|
|
||||||
buf_page_set_accessed_make_young(&block->page, access_time);
|
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);
|
ut_a(!block->page.file_page_was_freed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2479,7 +2481,7 @@ buf_page_optimistic_get(
|
|||||||
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
#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);
|
ut_a(block->page.file_page_was_freed == FALSE);
|
||||||
#endif
|
#endif
|
||||||
if (UNIV_UNLIKELY(!access_time)) {
|
if (UNIV_UNLIKELY(!access_time)) {
|
||||||
@ -2587,7 +2589,7 @@ buf_page_get_known_nowait(
|
|||||||
ut_a(block->page.buf_fix_count > 0);
|
ut_a(block->page.buf_fix_count > 0);
|
||||||
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
#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);
|
ut_a(block->page.file_page_was_freed == FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2670,9 +2672,9 @@ buf_page_try_get_func(
|
|||||||
ut_a(block->page.buf_fix_count > 0);
|
ut_a(block->page.buf_fix_count > 0);
|
||||||
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
#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);
|
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_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||||
|
|
||||||
buf_pool->stat.n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
@ -2701,9 +2703,9 @@ buf_page_init_low(
|
|||||||
bpage->newest_modification = 0;
|
bpage->newest_modification = 0;
|
||||||
bpage->oldest_modification = 0;
|
bpage->oldest_modification = 0;
|
||||||
HASH_INVALIDATE(bpage, hash);
|
HASH_INVALIDATE(bpage, hash);
|
||||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
|
||||||
bpage->file_page_was_freed = FALSE;
|
bpage->file_page_was_freed = FALSE;
|
||||||
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
@ -3009,9 +3011,9 @@ buf_page_create(
|
|||||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||||
ut_a(ibuf_count_get(space, offset) == 0);
|
ut_a(ibuf_count_get(space, offset) == 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
|
||||||
block->page.file_page_was_freed = FALSE;
|
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 */
|
/* Page can be found in buf_pool */
|
||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -3444,9 +3444,9 @@ fseg_free_page(
|
|||||||
|
|
||||||
fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
|
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);
|
buf_page_set_file_page_was_freed(space, page);
|
||||||
#endif
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
@ -3513,13 +3513,13 @@ fseg_free_extent(
|
|||||||
|
|
||||||
fsp_free_extent(space, zip_size, page, mtr);
|
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++) {
|
for (i = 0; i < FSP_EXTENT_SIZE; i++) {
|
||||||
|
|
||||||
buf_page_set_file_page_was_freed(space,
|
buf_page_set_file_page_was_freed(space,
|
||||||
first_page_in_extent + i);
|
first_page_in_extent + i);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
@ -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
|
||||||
|
@ -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];
|
||||||
|
@ -1878,9 +1878,9 @@ ibuf_remove_free_page(void)
|
|||||||
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
|
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
|
||||||
IBUF_SPACE_ID, page_no, &mtr);
|
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);
|
buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
|
||||||
#endif
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
|
|
||||||
ibuf_enter();
|
ibuf_enter();
|
||||||
|
|
||||||
@ -1922,9 +1922,9 @@ ibuf_remove_free_page(void)
|
|||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits(
|
||||||
bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
|
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);
|
buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
|
||||||
#endif
|
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
|
@ -512,8 +512,8 @@ file segment of the index tree.
|
|||||||
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ulint
|
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
|
dict_index_t* index, /*!< in: index of rec; the index tree
|
||||||
MUST be X-latched */
|
MUST be X-latched */
|
||||||
buf_block_t* rec_block, /*!< in/out: block containing rec */
|
buf_block_t* rec_block, /*!< in/out: block containing rec */
|
||||||
@ -522,10 +522,42 @@ btr_store_big_rec_extern_fields(
|
|||||||
the "external storage" flags in offsets
|
the "external storage" flags in offsets
|
||||||
will not correspond to rec when
|
will not correspond to rec when
|
||||||
this function returns */
|
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 */
|
to be stored externally */
|
||||||
mtr_t* local_mtr); /*!< in: mtr containing the latch to
|
__attribute__((nonnull));
|
||||||
rec and to the tree */
|
|
||||||
|
/** 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
|
Frees the space in an externally stored field to the file space
|
||||||
management if the field in data is owned the externally stored field,
|
management if the field in data is owned the externally stored field,
|
||||||
|
@ -368,7 +368,7 @@ buf_reset_check_index_page_at_flush(
|
|||||||
/*================================*/
|
/*================================*/
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
ulint offset);/*!< in: page number */
|
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.
|
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
|
This function should be called when we free a file page and want the
|
||||||
@ -393,7 +393,7 @@ buf_page_reset_file_page_was_freed(
|
|||||||
/*===============================*/
|
/*===============================*/
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
ulint offset); /*!< in: page number */
|
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.
|
Reads the freed_page_clock of a buffer block.
|
||||||
@return freed_page_clock */
|
@return freed_page_clock */
|
||||||
@ -1135,11 +1135,11 @@ struct buf_page_struct{
|
|||||||
0 if the block was never accessed
|
0 if the block was never accessed
|
||||||
in the buffer pool */
|
in the buffer pool */
|
||||||
/* @} */
|
/* @} */
|
||||||
# ifdef UNIV_DEBUG_FILE_ACCESSES
|
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
|
||||||
ibool file_page_was_freed;
|
ibool file_page_was_freed;
|
||||||
/*!< this is set to TRUE when fsp
|
/*!< this is set to TRUE when fsp
|
||||||
frees a page in buffer pool */
|
frees a page in buffer pool */
|
||||||
# endif /* UNIV_DEBUG_FILE_ACCESSES */
|
# endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 */
|
@return TRUE if update vector changes an ordering field in the index record */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ibool
|
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
|
const dtuple_t* row, /*!< in: old value of row, or NULL if the
|
||||||
row and the data values in update are not
|
row and the data values in update are not
|
||||||
known when this function is called, e.g., at
|
known when this function is called, e.g., at
|
||||||
compile time */
|
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 */
|
stored columns in the old row */
|
||||||
dict_index_t* index, /*!< in: index of the record */
|
__attribute__((nonnull(1,2), warn_unused_result));
|
||||||
const upd_t* update) /*!< in: update vector for the row; NOTE: the
|
#ifdef UNIV_DEBUG
|
||||||
field numbers in this MUST be clustered index
|
# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
|
||||||
positions! */
|
row_upd_changes_ord_field_binary_func(index,update,thr,row,ext)
|
||||||
__attribute__((nonnull(3,4), warn_unused_result));
|
#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.
|
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
|
This function is fast if the update vector is short or the number of ordering
|
||||||
|
@ -177,14 +177,15 @@ command. Not tested on Windows. */
|
|||||||
debugging without UNIV_DEBUG */
|
debugging without UNIV_DEBUG */
|
||||||
#define UNIV_BUF_DEBUG /* Enable buffer pool
|
#define UNIV_BUF_DEBUG /* Enable buffer pool
|
||||||
debugging without UNIV_DEBUG */
|
debugging without UNIV_DEBUG */
|
||||||
|
#define UNIV_BLOB_LIGHT_DEBUG /* Enable off-page column
|
||||||
|
debugging without UNIV_DEBUG */
|
||||||
#define UNIV_DEBUG /* Enable ut_ad() assertions
|
#define UNIV_DEBUG /* Enable ut_ad() assertions
|
||||||
and disable UNIV_INLINE */
|
and disable UNIV_INLINE */
|
||||||
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
|
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
|
||||||
ut_ad(lock_rec_validate_page())
|
ut_ad(lock_rec_validate_page())
|
||||||
assertions. */
|
assertions. */
|
||||||
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
|
#define UNIV_DEBUG_FILE_ACCESSES /* Enable freed block access
|
||||||
(field file_page_was_freed
|
debugging without UNIV_DEBUG */
|
||||||
in buf_page_t) */
|
|
||||||
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
|
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
|
||||||
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
|
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
|
||||||
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
||||||
@ -296,6 +297,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
|
||||||
==========================
|
==========================
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -2130,7 +2130,7 @@ function_exit:
|
|||||||
|
|
||||||
err = btr_store_big_rec_extern_fields(
|
err = btr_store_big_rec_extern_fields(
|
||||||
index, btr_cur_get_block(&cursor),
|
index, btr_cur_get_block(&cursor),
|
||||||
rec, offsets, big_rec, &mtr);
|
rec, offsets, &mtr, FALSE, big_rec);
|
||||||
|
|
||||||
if (modify) {
|
if (modify) {
|
||||||
dtuple_big_rec_free(big_rec);
|
dtuple_big_rec_free(big_rec);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +387,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. */
|
marked record if that record contained an externally stored field. */
|
||||||
static
|
static
|
||||||
void
|
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 */
|
purge_node_t* node) /*!< in: row purge node */
|
||||||
{
|
{
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
@ -413,8 +416,8 @@ row_purge_upd_exist_or_extern(
|
|||||||
while (node->index != NULL) {
|
while (node->index != NULL) {
|
||||||
index = node->index;
|
index = node->index;
|
||||||
|
|
||||||
if (row_upd_changes_ord_field_binary(NULL, NULL, node->index,
|
if (row_upd_changes_ord_field_binary(node->index, node->update,
|
||||||
node->update)) {
|
thr, NULL, NULL)) {
|
||||||
/* Build the older version of the index entry */
|
/* Build the older version of the index entry */
|
||||||
entry = row_build_index_entry(node->row, NULL,
|
entry = row_build_index_entry(node->row, NULL,
|
||||||
index, heap);
|
index, heap);
|
||||||
@ -496,6 +499,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.
|
Parses the row reference and other info in a modify undo log record.
|
||||||
@return TRUE if purge operation required: NOTE that then the CALLER
|
@return TRUE if purge operation required: NOTE that then the CALLER
|
||||||
@ -602,47 +613,32 @@ err_exit:
|
|||||||
/***********************************************************//**
|
/***********************************************************//**
|
||||||
Fetches an undo log record and does the purge for the recorded operation.
|
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
|
If none left, or the current purge completed, returns the control to the
|
||||||
parent node, which is always a query thread node.
|
parent node, which is always a query thread node. */
|
||||||
@return DB_SUCCESS if operation successfully completed, else error code */
|
static __attribute__((nonnull))
|
||||||
static
|
void
|
||||||
ulint
|
|
||||||
row_purge(
|
row_purge(
|
||||||
/*======*/
|
/*======*/
|
||||||
purge_node_t* node, /*!< in: row purge node */
|
purge_node_t* node, /*!< in: row purge node */
|
||||||
que_thr_t* thr) /*!< in: query thread */
|
que_thr_t* thr) /*!< in: query thread */
|
||||||
{
|
{
|
||||||
roll_ptr_t roll_ptr;
|
|
||||||
ibool purge_needed;
|
|
||||||
ibool updated_extern;
|
ibool updated_extern;
|
||||||
trx_t* trx;
|
|
||||||
|
|
||||||
ut_ad(node && thr);
|
ut_ad(node);
|
||||||
|
ut_ad(thr);
|
||||||
|
|
||||||
trx = thr_get_trx(thr);
|
node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr,
|
||||||
|
&node->reservation,
|
||||||
node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
|
|
||||||
&(node->reservation),
|
|
||||||
node->heap);
|
node->heap);
|
||||||
if (!node->undo_rec) {
|
if (!node->undo_rec) {
|
||||||
/* Purge completed for this query thread */
|
/* Purge completed for this query thread */
|
||||||
|
|
||||||
thr->run_node = que_node_get_parent(node);
|
thr->run_node = que_node_get_parent(node);
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->roll_ptr = roll_ptr;
|
if (node->undo_rec != &trx_purge_dummy_rec
|
||||||
|
&& row_purge_parse_undo_rec(node, &updated_extern, thr)) {
|
||||||
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! */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (purge_needed) {
|
|
||||||
node->found_clust = FALSE;
|
node->found_clust = FALSE;
|
||||||
|
|
||||||
node->index = dict_table_get_next_index(
|
node->index = dict_table_get_next_index(
|
||||||
@ -654,14 +650,14 @@ row_purge(
|
|||||||
} else if (updated_extern
|
} else if (updated_extern
|
||||||
|| node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
|
|| 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) {
|
if (node->found_clust) {
|
||||||
btr_pcur_close(&(node->pcur));
|
btr_pcur_close(&(node->pcur));
|
||||||
}
|
}
|
||||||
|
|
||||||
row_mysql_unfreeze_data_dictionary(trx);
|
row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do some cleanup */
|
/* Do some cleanup */
|
||||||
@ -669,8 +665,6 @@ row_purge(
|
|||||||
mem_heap_empty(node->heap);
|
mem_heap_empty(node->heap);
|
||||||
|
|
||||||
thr->run_node = node;
|
thr->run_node = node;
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************//**
|
/***********************************************************//**
|
||||||
@ -684,9 +678,6 @@ row_purge_step(
|
|||||||
que_thr_t* thr) /*!< in: query thread */
|
que_thr_t* thr) /*!< in: query thread */
|
||||||
{
|
{
|
||||||
purge_node_t* node;
|
purge_node_t* node;
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
ulint err;
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
|
|
||||||
ut_ad(thr);
|
ut_ad(thr);
|
||||||
|
|
||||||
@ -694,12 +685,7 @@ row_purge_step(
|
|||||||
|
|
||||||
ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
|
ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
err =
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
row_purge(node, thr);
|
row_purge(node, thr);
|
||||||
|
|
||||||
ut_ad(err == DB_SUCCESS);
|
|
||||||
|
|
||||||
return(thr);
|
return(thr);
|
||||||
}
|
}
|
||||||
|
@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low(
|
|||||||
mtr_t* mtr, /*!< in: mtr */
|
mtr_t* mtr, /*!< in: mtr */
|
||||||
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
|
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
|
||||||
{
|
{
|
||||||
btr_pcur_t* pcur;
|
|
||||||
btr_cur_t* btr_cur;
|
btr_cur_t* btr_cur;
|
||||||
ulint err;
|
ulint err;
|
||||||
ibool success;
|
|
||||||
|
|
||||||
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
|
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);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out if we can remove the whole clustered index record */
|
btr_cur = btr_pcur_get_btr_cur(&node->pcur);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == BTR_MODIFY_LEAF) {
|
if (mode == BTR_MODIFY_LEAF) {
|
||||||
success = btr_cur_optimistic_delete(btr_cur, mtr);
|
err = btr_cur_optimistic_delete(btr_cur, mtr)
|
||||||
|
? DB_SUCCESS
|
||||||
if (success) {
|
: DB_FAIL;
|
||||||
err = DB_SUCCESS;
|
|
||||||
} else {
|
|
||||||
err = DB_FAIL;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ut_ad(mode == BTR_MODIFY_TREE);
|
ut_ad(mode == BTR_MODIFY_TREE);
|
||||||
|
|
||||||
@ -668,8 +654,9 @@ row_undo_mod_upd_exist_sec(
|
|||||||
while (node->index != NULL) {
|
while (node->index != NULL) {
|
||||||
index = node->index;
|
index = node->index;
|
||||||
|
|
||||||
if (row_upd_changes_ord_field_binary(
|
if (row_upd_changes_ord_field_binary(node->index, node->update,
|
||||||
node->row, node->ext, node->index, node->update)) {
|
thr,
|
||||||
|
node->row, node->ext)) {
|
||||||
|
|
||||||
/* Build the newest version of the index entry */
|
/* Build the newest version of the index entry */
|
||||||
entry = row_build_index_entry(node->row, node->ext,
|
entry = row_build_index_entry(node->row, node->ext,
|
||||||
|
@ -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 */
|
@return TRUE if update vector changes an ordering field in the index record */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ibool
|
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
|
const dtuple_t* row, /*!< in: old value of row, or NULL if the
|
||||||
row and the data values in update are not
|
row and the data values in update are not
|
||||||
known when this function is called, e.g., at
|
known when this function is called, e.g., at
|
||||||
compile time */
|
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 */
|
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 n_unique;
|
||||||
ulint i;
|
ulint i;
|
||||||
const dict_index_t* clust_index;
|
const dict_index_t* clust_index;
|
||||||
|
|
||||||
ut_ad(update);
|
|
||||||
ut_ad(index);
|
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);
|
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_LIKELY_NULL(buf)) {
|
||||||
if (UNIV_UNLIKELY(buf == field_ref_zero)) {
|
if (UNIV_UNLIKELY(buf == field_ref_zero)) {
|
||||||
/* This should never happen, but
|
/* The externally stored field
|
||||||
we try to fail safe here. */
|
was not written yet. This
|
||||||
ut_ad(0);
|
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);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1612,8 +1623,8 @@ row_upd_sec_step(
|
|||||||
ut_ad(!dict_index_is_clust(node->index));
|
ut_ad(!dict_index_is_clust(node->index));
|
||||||
|
|
||||||
if (node->state == UPD_NODE_UPDATE_ALL_SEC
|
if (node->state == UPD_NODE_UPDATE_ALL_SEC
|
||||||
|| row_upd_changes_ord_field_binary(node->row, node->ext,
|
|| row_upd_changes_ord_field_binary(node->index, node->update,
|
||||||
node->index, node->update)) {
|
thr, node->row, node->ext)) {
|
||||||
return(row_upd_sec_index_entry(node, thr));
|
return(row_upd_sec_index_entry(node, thr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1941,7 +1952,7 @@ row_upd_clust_rec(
|
|||||||
index, btr_cur_get_block(btr_cur), rec,
|
index, btr_cur_get_block(btr_cur), rec,
|
||||||
rec_get_offsets(rec, index, offsets_,
|
rec_get_offsets(rec, index, offsets_,
|
||||||
ULINT_UNDEFINED, &heap),
|
ULINT_UNDEFINED, &heap),
|
||||||
big_rec, mtr);
|
mtr, TRUE, big_rec);
|
||||||
mtr_commit(mtr);
|
mtr_commit(mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2140,8 +2151,8 @@ exit_func:
|
|||||||
|
|
||||||
row_upd_store_row(node);
|
row_upd_store_row(node);
|
||||||
|
|
||||||
if (row_upd_changes_ord_field_binary(node->row, node->ext, index,
|
if (row_upd_changes_ord_field_binary(index, node->update, thr,
|
||||||
node->update)) {
|
node->row, node->ext)) {
|
||||||
|
|
||||||
/* Update causes an ordering field (ordering fields within
|
/* Update causes an ordering field (ordering fields within
|
||||||
the B-tree) of the clustered index record to change: perform
|
the B-tree) of the clustered index record to change: perform
|
||||||
|
@ -48,8 +48,8 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
rollback */
|
rollback */
|
||||||
#define TRX_ROLL_TRUNC_THRESHOLD 1
|
#define TRX_ROLL_TRUNC_THRESHOLD 1
|
||||||
|
|
||||||
/** In crash recovery, the current trx to be rolled back */
|
/** In crash recovery, the current trx to be rolled back; NULL otherwise */
|
||||||
static trx_t* trx_roll_crash_recv_trx = NULL;
|
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
|
/** 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. */
|
rolled back. Then we can print how many % the rollback has progressed. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user