1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.6 into 10.7

This commit is contained in:
Marko Mäkelä
2022-06-09 14:11:43 +03:00
126 changed files with 1296 additions and 1145 deletions

View File

@@ -1997,11 +1997,10 @@ static void DBUGOpenFile(CODE_STATE *cs,
static void DBUGCloseFile(CODE_STATE *cs, sFILE *new_value)
{
sFILE *fp;
if (!cs || !cs->stack || !cs->stack->out_file)
if (!cs || !cs->stack || !(fp= cs->stack->out_file))
return;
fp= cs->stack->out_file;
if (--fp->used == 0)
if (fp != sstdout && fp != sstderr && --fp->used == 0)
{
if (fclose(fp->file) == EOF)
{

View File

@@ -18,7 +18,7 @@
.\" SQL scripts
.\" batch SQL files
.SH "NAME"
mysql \- the MariaDB command\-line tool
mariadb \- the MariaDB command\-line tool (mysql is now a symlink to mariadb)
.SH "SYNOPSIS"
.HP \w'\fBmysql\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIdb_name\fR\fR\ 'u
\fBmysql [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIdb_name\fR\fR

View File

@@ -14,9 +14,9 @@
.\" mysql_client_test
.\" mysql_client_test_embedded
.SH "NAME"
mysql_client_test \- test client API
mariadb-client-test \- test client API (mysql_client_test is now a symlink to mariadb-client-test)
.br
mysql_client_test_embedded \- test client API for embedded server
mariadb-client-test-embedded \- test client API for embedded server (mysql_client_test_embedded is now a symlink to mariadb-client-test-embedded)
.SH "SYNOPSIS"
.HP \w'\fBmysql_client_test\ [\fR\fB\fIoptions\fR\fR\fB]\ [\fR\fB\fItest_name\fR\fR\fB]\ \&.\&.\&.\fR\ 'u
\fBmysql_client_test [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fItest_name\fR\fR\fB] \&.\&.\&.\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_convert_table_format
.SH "NAME"
mysql_convert_table_format \- convert tables to use a given storage engine
mariadb-convert-table-format \- convert tables to use a given storage engine (mysql_convert_table_format is now a symlink to mariadb-convert-table-format)
.SH "SYNOPSIS"
.HP \w'\fBmysql_convert_table_format\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIdb_name\fR\fR\ 'u
\fBmysql_convert_table_format [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIdb_name\fR\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_find_rows
.SH "NAME"
mysql_find_rows \- extract SQL statements from files
mariadb-find-rows \- extract SQL statements from files (mysql_find_rows is now a symlink to mariadb-find-rows)
.SH "SYNOPSIS"
.HP \w'\fBmysql_find_rows\ [\fR\fB\fIoptions\fR\fR\fB]\ [\fR\fB\fIfile_name\fR\fR\fB\ \&.\&.\&.]\fR\ 'u
\fBmysql_find_rows [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIfile_name\fR\fR\fB \&.\&.\&.]\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_fix_extensions
.SH "NAME"
mysql_fix_extensions \- normalize table file name extensions
mariadb-fix-extensions \- normalize table file name extensions (mysql_fix_extensions is now a symlink to mariadb-fix-extensions)
.SH "SYNOPSIS"
.HP \w'\fBmysql_fix_extensions\ \fR\fB\fIdata_dir\fR\fR\ 'u
\fBmysql_fix_extensions \fR\fB\fIdata_dir\fR\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_install_db
.SH "NAME"
mysql_install_db \- initialize MariaDB data directory
mariadb-install-db \- initialize MariaDB data directory (mysql_install_db is now a symlink to mariadb-install-db)
.SH "SYNOPSIS"
.HP \w'\fBmysql_install_db\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysql_install_db [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -9,7 +9,7 @@
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
mysql_ldb \- RocksDB tool
mariadb-ldb \- RocksDB tool (mysql_ldb is now a symlink to mariadb-ldb)
.SH DESCRIPTION
Use \fBmysql_ldb \-\-help\fR for details on usage\.
.PP

View File

@@ -22,7 +22,7 @@
.\" -----------------------------------------------------------------
.\" mysql_plugin
.SH "NAME"
mysql_plugin \- configure MariaDB server plugins
mariadb-plugin \- configure MariaDB server plugins (mysql_plugin is now a symlink to mariadb-plugin)
.SH "SYNOPSIS"
.HP \w'\fBmysql_plugin\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIplugin\fR\fR\fB\ {ENABLE|DISABLE}\fR\ 'u
\fBmysql_plugin [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIplugin\fR\fR\fB {ENABLE|DISABLE}\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_secure_installation
.SH "NAME"
mysql_secure_installation \- improve MariaDB installation security
mariadb-secure-installation \- improve MariaDB installation security (mysql_secure_installation is now a symlink to mariadb-secure-installation)
.SH "SYNOPSIS"
.HP \w'\fBmysql_secure_installation\fR\ 'u
\fBmysql_secure_installation\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_setpermission
.SH "NAME"
mysql_setpermission \- interactively set permissions in grant tables
mariadb-setpermission \- interactively set permissions in grant tables (mysql_setpermission is now a symlink to mariadb-setpermission)
.SH "SYNOPSIS"
.HP \w'\fBmysql_setpermission\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysql_setpermission [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -14,7 +14,7 @@
.\" mysql_tzinfo_to_sql
.\" time zone tables
.SH "NAME"
mysql_tzinfo_to_sql \- load the time zone tables
mariadb-tzinfo-to-sql \- load the time zone tables (mysql_tzinfo_to_sql is now a symlink to mariadb-tzinfo-to-sql)
.SH "SYNOPSIS"
.HP \w'\fBmysql_tzinfo_to_sql\ \fR\fB\fIarguments\fR\fR\ 'u
\fBmysql_tzinfo_to_sql \fR\fB\fIarguments\fR\fR

View File

@@ -15,7 +15,7 @@
.\" upgrading MySQL
.\" MySQL: upgrading
.SH "NAME"
mysql_upgrade \- check tables for MariaDB upgrade
mariadb-upgrade \- check tables for MariaDB upgrade (mysql_upgrade is now a symlink to mariadb-upgrade)
.SH "SYNOPSIS"
.HP \w'\fBmysql_upgrade\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysql_upgrade [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysql_waitpid
.SH "NAME"
mysql_waitpid \- kill process and wait for its termination
mariadb-waitpid \- kill process and wait for its termination (mysql_waitpid is now a symlink to mariadb-waitpid)
.SH "SYNOPSIS"
.HP \w'\fBmysql_waitpid\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIpid\fR\fR\fB\ \fR\fB\fIwait_time\fR\fR\ 'u
\fBmysql_waitpid [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIpid\fR\fR\fB \fR\fB\fIwait_time\fR\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysqlaccess
.SH "NAME"
mysqlaccess \- client for checking access privileges
mariadb-access \- client for checking access privileges (mysqlaccess is now a symlink to mariadb-access)
.SH "SYNOPSIS"
.HP \w'\fBmysqlaccess\ [\fR\fB\fIhost_name\fR\fR\fB\ [\fR\fB\fIuser_name\fR\fR\fB\ [\fR\fB\fIdb_name\fR\fR\fB]]]\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysqlaccess [\fR\fB\fIhost_name\fR\fR\fB [\fR\fB\fIuser_name\fR\fR\fB [\fR\fB\fIdb_name\fR\fR\fB]]] [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -15,7 +15,7 @@
.\" administration: server
.\" server administration
.SH "NAME"
mysqladmin \- client for administering a MariaDB server
mariadb-admin \- client for administering a MariaDB server (mysqladmin is now a symlink to mariadb-admin)
.SH "SYNOPSIS"
.HP \w'\fBmysqladmin\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-arg\fR\fR\fB]\ [\fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-arg\fR\fR\fB]]\ \&.\&.\&.\fR\ 'u
\fBmysqladmin [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-arg\fR\fR\fB] [\fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-arg\fR\fR\fB]] \&.\&.\&.\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysqlbinlog
.SH "NAME"
mysqlbinlog \- utility for processing binary log files
mariadb-binlog \- utility for processing binary log files (mysqlbinlog is now a symlink to mariadb-binlog)
.SH "SYNOPSIS"
.HP \w'\fBmysqlbinlog\ [\fR\fBoptions\fR\fB]\ \fR\fB\fIlog_file\fR\fR\fB\ \&.\&.\&.\fR\ 'u
\fBmysqlbinlog [\fR\fBoptions\fR\fB] \fR\fB\fIlog_file\fR\fR\fB \&.\&.\&.\fR

View File

@@ -17,7 +17,7 @@
.\" tables: maintenance
.\" tables: repair
.SH "NAME"
mysqlcheck \- a table maintenance program
mariadb-check \- a table maintenance program (mysqlcheck is now a symlink to mariadb-check)
.SH "SYNOPSIS"
.HP \w'\fBmysqlcheck\ [\fR\fB\fIoptions\fR\fR\fB]\ [\fR\fB\fIdb_name\fR\fR\fB\ [\fR\fB\fItbl_name\fR\fR\fB\ \&.\&.\&.]]\fR\ 'u
\fBmysqlcheck [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIdb_name\fR\fR\fB [\fR\fB\fItbl_name\fR\fR\fB \&.\&.\&.]]\fR

View File

@@ -14,7 +14,7 @@
.\" mysqld: MariaDB server
.\" MariaDB server: mysqld
.SH "NAME"
mysqld \- the MariaDB server
mariadbd \- the MariaDB server (mysqld is now a symlink to mariadbd)
.SH "SYNOPSIS"
.HP \w'\fBmysqld\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysqld [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -1,6 +1,6 @@
'\" t
.\"
.TH "\FBMARIADB-MULTI\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.TH "\FBMARIADBD-MULTI\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -16,7 +16,7 @@
.\" scripts
.\" multi mysqld
.SH "NAME"
mysqld_multi \- manage multiple MariaDB servers
mariadbd-multi \- manage multiple MariaDB servers (mysqld_multi is now a symlink to mariadbd-multi)
.SH "SYNOPSIS"
.HP \w'\fBmysqld_multi\ [\fR\fB\fIoptions\fR\fR\fB]\ {start|stop|report}\ [\fR\fB\fIGNR\fR\fR\fB[,\fR\fB\fIGNR\fR\fR\fB]\ \&.\&.\&.]\fR\ 'u
\fBmysqld_multi [\fR\fB\fIoptions\fR\fR\fB] {start|stop|report} [\fR\fB\fIGNR\fR\fR\fB[,\fR\fB\fIGNR\fR\fR\fB] \&.\&.\&.]\fR

View File

@@ -1,6 +1,6 @@
'\" t
.\"
.TH "\FBMARIADB-SAFE\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.TH "\FBMARIADBD-SAFE\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -15,7 +15,7 @@
.\" tools: mysqld_safe
.\" scripts
.SH "NAME"
mysqld_safe \- MariaDB server startup script
mariadbd-safe \- MariaDB server startup script (mysqld_safe is now a symlink to mariadbd-safe)
.SH "SYNOPSIS"
.HP \w'\fBmysqld_safe\ \fR\fB\fIoptions\fR\fR\ 'u
\fBmysqld_safe \fR\fB\fIoptions\fR\fR

View File

@@ -1,6 +1,6 @@
'\" t
.\"
.TH "\FBMARIADB-SAFE-HELPER\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.TH "\FBMARIADBD-SAFE-HELPER\FR" "1" "15 May 2020" "MariaDB 10\&.7" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -9,7 +9,7 @@
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
mysqld_safe_helper \- helper script
mariadbd-safe-helper \- helper script (mysqld_safe_helper is now a symlink to mariadbd-safe-helper)
.SH DESCRIPTION
Use: Helper script\.
.PP

View File

@@ -17,7 +17,7 @@
.\" databases: dumping
.\" tables: dumping
.SH "NAME"
mysqldump \- a database backup program
mariadb-dump \- a database backup program (mysqldump is now a symlink to mariadb-dump)
.SH "SYNOPSIS"
.HP \w'\fBmysqldump\ [\fR\fB\fIoptions\fR\fR\fB]\ [\fR\fB\fIdb_name\fR\fR\fB\ [\fR\fB\fItbl_name\fR\fR\fB\ \&.\&.\&.]]\fR\ 'u
\fBmysqldump [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIdb_name\fR\fR\fB [\fR\fB\fItbl_name\fR\fR\fB \&.\&.\&.]]\fR

View File

@@ -13,7 +13,7 @@
.\" -----------------------------------------------------------------
.\" mysqldumpslow
.SH "NAME"
mysqldumpslow \- Summarize slow query log files
mariadb-dumpslow \- Summarize slow query log files (mysqldumpslow is now a symlink to mariadb-dumpslow)
.SH "SYNOPSIS"
.HP \w'\fBmysqldumpslow\ [\fR\fBoptions\fR\fB]\ [\fR\fB\fIlog_file\fR\fR\fB\ \&.\&.\&.]\fR\ 'u
\fBmysqldumpslow [\fR\fBoptions\fR\fB] [\fR\fB\fIlog_file\fR\fR\fB \&.\&.\&.]\fR

View File

@@ -17,7 +17,7 @@
.\" databases: dumping
.\" tables: dumping
.SH "NAME"
mysqlhotcopy \- a database backup program
mariadb-hotcopy \- a database backup program (mysqlhotcopy is now a symlink to mariadb-hotcopy)
.SH "SYNOPSIS"
.HP \w'\fBmysqlhotcopy\ \fR\fB\fIarguments\fR\fR\ 'u
\fBmysqlhotcopy \fR\fB\fIarguments\fR\fR

View File

@@ -17,7 +17,7 @@
.\" files: text
.\" text files: importing
.SH "NAME"
mysqlimport \- a data import program
mariadb-import \- a data import program (mysqlimport is now a symlink to mariadb-import)
.SH "SYNOPSIS"
.HP \w'\fBmysqlimport\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIdb_name\fR\fR\fB\ \fR\fB\fItextfile1\fR\fR\fB\ \&.\&.\&.\fR\ 'u
\fBmysqlimport [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIdb_name\fR\fR\fB \fR\fB\fItextfile1\fR\fR\fB \&.\&.\&.\fR

View File

@@ -18,7 +18,7 @@
.\" columns: displaying
.\" showing: database information
.SH "NAME"
mysqlshow \- display database, table, and column information
mariadb-show \- display database, table, and column information (mysqlshow is now a symlink to mariadb-show)
.SH "SYNOPSIS"
.HP \w'\fBmysqlshow\ [\fR\fB\fIoptions\fR\fR\fB]\ [\fR\fB\fIdb_name\fR\fR\fB\ [\fR\fB\fItbl_name\fR\fR\fB\ [\fR\fB\fIcol_name\fR\fR\fB]]]\fR\ 'u
\fBmysqlshow [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIdb_name\fR\fR\fB [\fR\fB\fItbl_name\fR\fR\fB [\fR\fB\fIcol_name\fR\fR\fB]]]\fR

View File

@@ -14,7 +14,7 @@
.\" mysqlslap
.\" load emulation
.SH "NAME"
mysqlslap \- load emulation client
mariadb-slap \- load emulation client (mysqlslap is now a symlink to mariadb-slap)
.SH "SYNOPSIS"
.HP \w'\fBmysqlslap\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
\fBmysqlslap [\fR\fB\fIoptions\fR\fR\fB]\fR

View File

@@ -14,7 +14,7 @@
.\" mysqltest
.\" mysqltest_embedded
.SH "NAME"
mysqltest \- program to run test cases
mariadb-test \- program to run test cases (mysqltest is now a symlink to mariadb-test)
.br
mysqltest_embedded \- program to run embedded test cases
.SH "SYNOPSIS"

View File

@@ -3454,10 +3454,10 @@ a b max_c avg_c a b max_c avg_c a b min_c a b c d
6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 80 800 314
6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 23 303 909
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909
8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 64 248 107
8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 80 800 314
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 7 11 708 7 13 312 406
8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 64 248 107
8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 20 315 279
@@ -3472,10 +3472,10 @@ a b max_c avg_c a b max_c avg_c a b min_c a b c d
6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 80 800 314
6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 23 303 909
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909
8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 64 248 107
8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 80 800 314
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279
6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 7 11 708 7 13 312 406
8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 64 248 107
8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 20 315 279
@@ -3487,8 +3487,8 @@ and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <derived4> ref key0 key0 5 test.t2.a 2 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort
@@ -3536,6 +3536,35 @@ EXPLAIN
}
}
},
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 20,
"filtered": 100,
"attached_condition": "v1.max_c < 500"
},
"buffer_type": "flat",
"buffer_size": "715",
"join_type": "BNL",
"materialized": {
"query_block": {
"select_id": 2,
"having_condition": "max_c < 707 and max_c < 500",
"filesort": {
"sort_key": "t1.a, t1.b",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 20,
"filtered": 100
}
}
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "<derived3>",
@@ -3544,9 +3573,10 @@ EXPLAIN
"filtered": 100,
"attached_condition": "v2.max_c > 300"
},
"buffer_type": "flat",
"buffer_size": "715",
"buffer_type": "incremental",
"buffer_size": "9Kb",
"join_type": "BNL",
"attached_condition": "v2.a = v1.a or v1.a = t2.a",
"materialized": {
"query_block": {
"select_id": 3,
@@ -3565,36 +3595,6 @@ EXPLAIN
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 20,
"filtered": 100,
"attached_condition": "v1.max_c < 500"
},
"buffer_type": "incremental",
"buffer_size": "9Kb",
"join_type": "BNL",
"attached_condition": "v1.a = v2.a or v1.a = t2.a",
"materialized": {
"query_block": {
"select_id": 2,
"having_condition": "max_c < 707 and max_c < 500",
"filesort": {
"sort_key": "t1.a, t1.b",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 20,
"filtered": 100
}
}
}
}
}
}
}
}
@@ -9684,11 +9684,22 @@ EXPLAIN
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "1 in (0,dt1.a)",
"attached_condition": "1 in (0,t1.a) and t1.a is not null"
},
"table": {
"table_name": "<derived2>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 2,
@@ -9706,18 +9717,6 @@ EXPLAIN
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL",
"attached_condition": "t1.a = dt1.a"
}
}
}
@@ -9743,11 +9742,22 @@ EXPLAIN
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "dt.a in (1,dt.a)",
"attached_condition": "t1.a in (1,t1.a) and t1.a is not null"
},
"table": {
"table_name": "<derived2>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 2,
@@ -9765,18 +9775,6 @@ EXPLAIN
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL",
"attached_condition": "t1.a = dt.a"
}
}
}
@@ -10376,11 +10374,22 @@ EXPLAIN
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived3>",
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t.f2 < 2",
"attached_condition": "t1.f2 < 2 and t1.f2 is not null"
},
"table": {
"table_name": "<derived3>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["f2"],
"ref": ["test.t1.f2"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
@@ -10393,13 +10402,6 @@ EXPLAIN
}
}
}
},
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t1.f2 = t.f2"
}
}
}
@@ -10417,11 +10419,22 @@ EXPLAIN
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived3>",
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t.f2 < 2",
"attached_condition": "t1.f2 < 2 and t1.f2 is not null"
},
"table": {
"table_name": "<derived3>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["f2"],
"ref": ["test.t1.f2"],
"rows": 1,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
@@ -10436,18 +10449,6 @@ EXPLAIN
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL",
"attached_condition": "t1.f2 = t.f2"
}
}
}
@@ -14388,8 +14389,8 @@ a b c a b c
3 21 500 3 21 231
explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.b 2 Using where
2 DERIVED t3 range i1 i1 5 NULL 2 Using index condition
3 UNION t3 range i1 i1 5 NULL 1 Using index condition
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -14399,9 +14400,21 @@ EXPLAIN
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"table_name": "t2",
"access_type": "ALL",
"rows": 3,
"rows": 9,
"filtered": 100,
"attached_condition": "t2.b is not null"
},
"table": {
"table_name": "<derived2>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["b"],
"ref": ["test.t2.b"],
"rows": 2,
"filtered": 100,
"attached_condition": "v1.a < 4",
"materialized": {
@@ -14447,18 +14460,6 @@ EXPLAIN
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 9,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "173",
"join_type": "BNL",
"attached_condition": "t2.b = v1.b"
}
}
}

View File

@@ -3,7 +3,7 @@ call mtr.add_suppression("mysql.user");
flush tables;
flush privileges;
Warnings:
Error 145 Table './mysql/user' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './mysql/user'
Warning 1034 12544 clients are using or haven't closed the table properly
Note 1034 Table is fixed
# switching back from mysql.user to mysql.global_priv

View File

@@ -274,12 +274,16 @@ delete from mysql.help_relation where help_keyword_id=@keyword1_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topic_id=@topic1_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
End of 4.1 tests.
DROP TABLE IF EXISTS t1;
flush tables;
#
# End of 4.1 tests.
#
CREATE TABLE t1 (i INT);
LOCK TABLES t1 WRITE;
HELP no_such_topic;
name is_it_category
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests.
#
# End of 5.1 tests.
#

View File

@@ -122,25 +122,22 @@ delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
--echo End of 4.1 tests.
flush tables;
--echo #
--echo # End of 4.1 tests.
--echo #
#
# Test that we can use HELP even under LOCK TABLES. See bug#9953:
# CONVERT_TZ requires mysql.time_zone_name to be locked.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (i INT);
LOCK TABLES t1 WRITE;
HELP no_such_topic;
UNLOCK TABLES;
DROP TABLE t1;
--echo End of 5.1 tests.
--echo #
--echo # End of 5.1 tests.
--echo #

View File

@@ -916,11 +916,11 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null)
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null)
INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
@@ -1476,9 +1476,9 @@ join t5 on t5.a=t3.b) on t3.a=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t5 ref a a 5 test.t3.b X
1 SIMPLE t4 ref a a 5 test.t5.a X Using where
1 SIMPLE t4 ref a a 5 test.t3.b X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
1 SIMPLE t5 ref a a 5 test.t3.b X
drop table t0, t1, t2, t3, t4, t5, t6, t7;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

View File

@@ -925,11 +925,11 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null)
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null)
INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
@@ -1027,8 +1027,8 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null)
@@ -1485,9 +1485,9 @@ join t5 on t5.a=t3.b) on t3.a=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t4 ref a a 5 test.t5.a X Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
drop table t0, t1, t2, t3, t4, t5, t6, t7;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

View File

@@ -5494,6 +5494,11 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"rows_for_plan": 729,
"cost_for_plan": 451.8615234,
"semijoin_strategy_choice": [
{
"strategy": "FirstMatch",
"records": 27,
"read_time": 665.225293
},
{
"strategy": "DuplicateWeedout",
"records": 27,
@@ -5644,44 +5649,6 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"cost_for_plan": 172.4410156,
"semijoin_strategy_choice": [],
"rest_of_plan": [
{
"plan_prefix": [
"t_outer_1",
"t_inner_1",
"t_outer_2",
"t_inner_3"
],
"table": "t_inner_4",
"best_access_path": {
"considered_access_paths": [
{
"access_type": "scan",
"resulting_rows": 3,
"cost": 2.005126953,
"chosen": true
}
],
"chosen_access_method": {
"type": "scan",
"records": 3,
"cost": 2.005126953,
"uses_join_buffering": true
}
},
"rows_for_plan": 2187,
"cost_for_plan": 611.8461426,
"semijoin_strategy_choice": [
{
"strategy": "FirstMatch",
"records": 81,
"read_time": 2232.809033
},
{
"chosen_strategy": "FirstMatch"
}
],
"pruned_by_cost": true
},
{
"plan_prefix": [
"t_outer_1",
@@ -5710,6 +5677,35 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"cost_for_plan": 1486.656396,
"semijoin_strategy_choice": [],
"pruned_by_cost": true
},
{
"plan_prefix": [
"t_outer_1",
"t_inner_1",
"t_outer_2",
"t_inner_3"
],
"table": "t_inner_4",
"best_access_path": {
"considered_access_paths": [
{
"access_type": "scan",
"resulting_rows": 3,
"cost": 2.005126953,
"chosen": true
}
],
"chosen_access_method": {
"type": "scan",
"records": 3,
"cost": 2.005126953,
"uses_join_buffering": true
}
},
"rows_for_plan": 2187,
"cost_for_plan": 611.8461426,
"semijoin_strategy_choice": [],
"pruned_by_cost": true
}
]
}
@@ -5740,7 +5736,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"rest_of_plan": [
{
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"],
"table": "t_outer_2",
"table": "t_inner_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -5766,9 +5762,9 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"t_outer_1",
"t_inner_1",
"t_inner_4",
"t_outer_2"
"t_inner_2"
],
"table": "t_inner_2",
"table": "t_outer_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -5795,7 +5791,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"t_outer_1",
"t_inner_1",
"t_inner_4",
"t_outer_2"
"t_inner_2"
],
"table": "t_inner_3",
"best_access_path": {
@@ -5823,7 +5819,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
},
{
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"],
"table": "t_inner_2",
"table": "t_outer_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -5896,7 +5892,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"rest_of_plan": [
{
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_3"],
"table": "t_outer_2",
"table": "t_inner_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -5922,7 +5918,36 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"t_outer_1",
"t_inner_1",
"t_inner_3",
"t_outer_2"
"t_inner_2"
],
"table": "t_outer_2",
"best_access_path": {
"considered_access_paths": [
{
"access_type": "scan",
"resulting_rows": 9,
"cost": 2.015380859,
"chosen": true
}
],
"chosen_access_method": {
"type": "scan",
"records": 9,
"cost": 2.015380859,
"uses_join_buffering": true
}
},
"rows_for_plan": 6561,
"cost_for_plan": 1486.656396,
"semijoin_strategy_choice": [],
"pruned_by_cost": true
},
{
"plan_prefix": [
"t_outer_1",
"t_inner_1",
"t_inner_3",
"t_inner_2"
],
"table": "t_inner_4",
"best_access_path": {
@@ -5945,15 +5970,12 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"cost_for_plan": 611.8461426,
"semijoin_strategy_choice": [],
"pruned_by_cost": true
}
]
},
{
"plan_prefix": [
"t_outer_1",
"t_inner_1",
"t_inner_3",
"t_outer_2"
],
"table": "t_inner_2",
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_3"],
"table": "t_outer_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -5970,12 +5992,10 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"uses_join_buffering": true
}
},
"rows_for_plan": 6561,
"cost_for_plan": 1486.656396,
"rows_for_plan": 729,
"cost_for_plan": 172.4410156,
"semijoin_strategy_choice": [],
"pruned_by_cost": true
}
]
"pruned_by_heuristic": true
},
{
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_3"],
@@ -6007,7 +6027,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"t_inner_3",
"t_inner_4"
],
"table": "t_outer_2",
"table": "t_inner_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -6036,7 +6056,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"t_inner_3",
"t_inner_4"
],
"table": "t_inner_2",
"table": "t_outer_2",
"best_access_path": {
"considered_access_paths": [
{
@@ -6059,30 +6079,6 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"pruned_by_cost": true
}
]
},
{
"plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_3"],
"table": "t_inner_2",
"best_access_path": {
"considered_access_paths": [
{
"access_type": "scan",
"resulting_rows": 9,
"cost": 2.015380859,
"chosen": true
}
],
"chosen_access_method": {
"type": "scan",
"records": 9,
"cost": 2.015380859,
"uses_join_buffering": true
}
},
"rows_for_plan": 729,
"cost_for_plan": 172.4410156,
"semijoin_strategy_choice": [],
"pruned_by_heuristic": true
}
]
}

View File

@@ -326,8 +326,8 @@ group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
order by o_totalprice desc, o_orderdate;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index
2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index
Warnings:
@@ -360,8 +360,8 @@ group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
order by o_totalprice desc, o_orderdate;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index
2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index
Warnings:

View File

@@ -331,8 +331,8 @@ group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
order by o_totalprice desc, o_orderdate;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index
2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00
Warnings:
@@ -365,8 +365,8 @@ group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
order by o_totalprice desc, o_orderdate;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00
1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index
2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00
Warnings:

View File

@@ -1160,8 +1160,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A ALL NULL NULL NULL NULL 10
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary; Using join buffer (flat, BNL join)
1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
count(*)

View File

@@ -1163,8 +1163,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A ALL NULL NULL NULL NULL 10
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary; Using join buffer (incremental, BNL join)
1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; Using join buffer (incremental, BNLH join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (incremental, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join)
flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
count(*)

View File

@@ -2178,10 +2178,10 @@ INSERT INTO t5 VALUES (7,0),(9,0);
explain
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
a
0
@@ -2500,8 +2500,8 @@ WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
1 PRIMARY t2 ref a a 5 const 1 Using index
1 PRIMARY t1 ref a a 5 func 1 Using index
1 PRIMARY t1 ref a a 5 const 1 Using index
1 PRIMARY t2 ref a a 5 func 1 Using index
2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0
SELECT * FROM t1, t2
WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);

View File

@@ -1129,8 +1129,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@@ -1150,8 +1150,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5

View File

@@ -1142,8 +1142,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@@ -1163,8 +1163,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5

View File

@@ -1131,8 +1131,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@@ -1152,8 +1152,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL # Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d # Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b # Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@@ -1933,19 +1933,19 @@ AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2
AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 18 Using index
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY <subquery6> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t3.id_product,const 1 Using where; Using index
1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery6> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t3.id_product,const 1 Using where; Using index
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY t1 index NULL PRIMARY 8 NULL 73 Using where; Using index; Using join buffer (flat, BNL join)
1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 4 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where
5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where
6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where
3 MATERIALIZED t2_2 ref id_t2,id_product id_t2 5 const 12
4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where
6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where
2 MATERIALIZED t2_1 ALL id_t2,id_product NULL NULL NULL 223 Using where
5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where
set optimizer_switch='rowid_filter=default';
drop table t1,t2,t3,t4,t5;
set global innodb_stats_persistent= @innodb_stats_persistent_save;

View File

@@ -2189,10 +2189,10 @@ INSERT INTO t5 VALUES (7,0),(9,0);
explain
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (incremental, BNL join)
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
a
0
@@ -2511,8 +2511,8 @@ WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
1 PRIMARY t2 ref a a 5 const 1 Using index
1 PRIMARY t1 ref a a 5 func 1 Using index
1 PRIMARY t1 ref a a 5 const 1 Using index
1 PRIMARY t2 ref a a 5 func 1 Using index
2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0
SELECT * FROM t1, t2
WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);

View File

@@ -8,6 +8,10 @@ connection default;
SET DEBUG_SYNC='now WAIT_FOR c';
# restart
disconnect wait;
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
InnoDB 0 transactions not purged
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
SELECT COUNT(*) FROM t1;
COUNT(*)
0

View File

@@ -0,0 +1 @@
--innodb-checksum-algorithm=crc32

View File

@@ -17,7 +17,13 @@ SET DEBUG_SYNC='now WAIT_FOR c';
--source include/restart_mysqld.inc
disconnect wait;
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
--source include/wait_all_purged.inc
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
--replace_result 2 0
SELECT COUNT(*) FROM t1;
TRUNCATE TABLE t1;
DROP TABLE t1;

View File

@@ -1,15 +1,17 @@
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression('Unknown key id 1');
call mtr.add_suppression('try to repair it');
call mtr.add_suppression('Index is corrupted');
set global aria_encrypt_tables= 1;
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
alter table t1 enable keys;
ERROR HY000: Unknown key id 1. Can't continue!
ERROR HY000: Unknown key id 1 for ./test/t1. Can't continue!
repair table t1 use_frm;
Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair Error Unknown key id 1 for ./test/t1. Can't continue!
test.t1 repair Error Unknown key id 1 for ./test/t1. Can't continue!
test.t1 repair status OK
drop table t1;
set global aria_encrypt_tables= default;

View File

@@ -1,14 +1,18 @@
#
# MDEV-18496 Crash when Aria encryption is enabled but plugin not available
#
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression('Unknown key id 1');
call mtr.add_suppression('try to repair it');
call mtr.add_suppression('Index is corrupted');
set global aria_encrypt_tables= 1;
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
error 192;
--replace_result \\ /
--error 192
alter table t1 enable keys;
--replace_result \\ /
repair table t1 use_frm;
drop table t1;
set global aria_encrypt_tables= default;

View File

@@ -26,9 +26,10 @@ a
ThursdayMorningsMarket
ThursdayMorningsMarketb
Warnings:
Error 145 t_corrupted2' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './mysqltest/t_corrupted2'
Warning 1034 1 client is using or hasn't closed the table properly
Error 1034 Wrong base information on indexpage at page: 1
Error 176 Got error '176 "Read page with wrong checksum"' for './mysqltest/t_corrupted2.MAI'
Error 1034 Can't read indexpage from page: 1, error: 176
select * from t_corrupted2;
a
ThursdayMorningsMarket

View File

@@ -20,8 +20,8 @@ select count(*) from mysql.proc;
# account for Unix and Windows variation.
call mtr.add_suppression("Checking table: '\\..mysqltest.t_corrupted2'");
call mtr.add_suppression("Recovering table: '\\..mysqltest.t_corrupted2'");
call mtr.add_suppression("Table '\\..mysqltest.t_corrupted2' is marked as crashed and should be repaired");
call mtr.add_suppression("Table 't_corrupted2' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed and should be repaired");
call mtr.add_suppression("Read page with wrong checksum");
let $def_checkinterval=`select @@global.aria_checkpoint_interval`;
@@ -78,7 +78,7 @@ perl;
syswrite (FILE, $whatever) or die;
close FILE;
EOF
replace_regex /Table.*t_corrupted2/t_corrupted2/ ;
--replace_result \\ /
--enable_prepare_warnings
select * from t_corrupted2; # should show corruption and repair messages
--disable_prepare_warnings

View File

@@ -1,4 +1,4 @@
call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");
create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1;
create table t2 (a int primary key auto_increment, b int) engine=aria transactional= 0;
@@ -54,7 +54,7 @@ a b
10 11
11 12
Warnings:
Error 145 Table './test/t2' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './test/t2'
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
insert into t1 (b) values (100),(200);
@@ -92,7 +92,7 @@ NEXT VALUE for s1 seq
11 3
12 4
Warnings:
Error 145 Table './test/s1' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './test/s1'
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
drop table t1,t2;
@@ -100,7 +100,7 @@ drop sequence s1;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Table \'.*\' is marked as crashed and should be repaired' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Table was marked as crashed' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Checking table: .*' COLLATE 'latin1_swedish_ci'))

View File

@@ -3,7 +3,7 @@
# no-protocol doesn't print warnings about repaired tables
--source include/no_protocol.inc
call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");
#

View File

@@ -3,7 +3,7 @@
#
# restart
FOUND 1 /InnoDB: New log file created, LSN=175964\d{8}/ in mysqld.1.err
CREATE TABLE t(i INT) ENGINE INNODB;
CREATE TABLE t(i INT) ENGINE=INNODB ENCRYPTED=YES;
INSERT INTO t VALUES(1);
# xtrabackup backup
SET GLOBAL innodb_flush_log_at_trx_commit=1;
@@ -16,6 +16,14 @@ INSERT INTO t VALUES(2);
SELECT * FROM t;
i
1
FLUSH TABLE t FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
ALTER TABLE t IMPORT TABLESPACE;
FLUSH TABLE t FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
ALTER TABLE t IMPORT TABLESPACE;
DROP TABLE t;
# shutdown server
# remove datadir

View File

@@ -42,7 +42,7 @@ let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= InnoDB: New log file created, LSN=175964\d{8}
--source include/search_pattern_in_file.inc
CREATE TABLE t(i INT) ENGINE INNODB;
CREATE TABLE t(i INT) ENGINE=INNODB ENCRYPTED=YES;
INSERT INTO t VALUES(1);
echo # xtrabackup backup;
@@ -58,6 +58,22 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir;
--source include/restart_and_restore.inc
--enable_result_log
SELECT * FROM t;
FLUSH TABLE t FOR EXPORT;
copy_file $_datadir/test/t.ibd $_datadir/test/t_copy.ibd;
copy_file $_datadir/test/t.cfg $_datadir/test/t_copy.cfg;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
move_file $_datadir/test/t_copy.ibd $_datadir/test/t.ibd;
move_file $_datadir/test/t_copy.cfg $_datadir/test/t.cfg;
ALTER TABLE t IMPORT TABLESPACE;
FLUSH TABLE t FOR EXPORT;
copy_file $_datadir/test/t.ibd $_datadir/test/t_copy.ibd;
copy_file $_datadir/test/t.cfg $_datadir/test/t_copy.cfg;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
move_file $_datadir/test/t_copy.ibd $_datadir/test/t.ibd;
move_file $_datadir/test/t_copy.cfg $_datadir/test/t.cfg;
ALTER TABLE t IMPORT TABLESPACE;
DROP TABLE t;
rmdir $targetdir;
let $targetdir= $targetdir_old;

View File

@@ -23,7 +23,7 @@
#ifndef MAIN
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
#if defined(_AIX) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
{
uint i, res= 1;
@@ -74,7 +74,7 @@ err:
return res;
}
#elif defined(__linux__) || defined(__sun)
#elif defined(_AIX) || defined(__linux__) || defined(__sun)
#include <net/if.h>
#include <sys/ioctl.h>
#include <net/if_arp.h>
@@ -87,11 +87,15 @@ err:
my_bool my_gethwaddr(uchar *to)
{
int fd, res= 1;
#ifdef _AIX
struct ifhwaddr_req ifr[32];
#else
struct ifreq ifr[32];
#endif
struct ifconf ifc;
DBUG_ENTER("my_gethwaddr");
ifc.ifc_req= ifr;
ifc.ifc_req= (struct ifreq *) ifr;
ifc.ifc_len= sizeof(ifr);
fd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -106,9 +110,14 @@ my_bool my_gethwaddr(uchar *to)
uint i;
for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++)
{
#ifdef __linux__
#if !defined(_AIX) || !defined(__linux__)
#if defined(__linux___)
#define HWADDR_DATA ifr[i].ifr_hwaddr.sa_data
#else
#define HWADDR_DATA ifr[i].ifr_hwaddr
#endif
if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0)
res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data,
res= memcpy_and_test(to, (uchar *)&HWADDR_DATA,
ETHER_ADDR_LEN);
#else
/*

View File

@@ -842,7 +842,7 @@ EOF
fi
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then
if grep -m1 -qE "^$BYPASS_TAG([[space]]+.*)?\$" -- "$MAGIC_FILE"; then
if grep -m1 -qE "^$BYPASS_TAG([[:space:]]+.*)?\$" -- "$MAGIC_FILE"; then
readonly WSREP_SST_OPT_BYPASS=1
readonly WSREP_TRANSFER_TYPE='IST'
fi

View File

@@ -179,6 +179,8 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
{
/* Can't scan one range => can't do MRR scan at all */
total_rows= HA_POS_ERROR;
if (thd->is_error())
DBUG_RETURN(HA_POS_ERROR);
break;
}
if (pages.first_page == UNUSED_PAGE_NO)

View File

@@ -180,7 +180,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- optimize_semijoin_nests() does pre-optimization
- during join optimization, the join has one JOIN_TAB (or is it POSITION?)
array, and suffix-based detection is used, see advance_sj_state()
array, and suffix-based detection is used, see optimize_semi_joins()
- after join optimization is done, get_best_combination() switches
the data-structure to prefix-based, multiple JOIN_TAB ranges format.
@@ -2761,7 +2761,7 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
Do semi-join optimization step after we've added a new tab to join prefix
SYNOPSIS
advance_sj_state()
optimize_semi_joins()
join The join we're optimizing
remaining_tables Tables not in the join prefix
new_join_tab Join tab we've just added to the join prefix
@@ -2821,9 +2821,9 @@ bool is_multiple_semi_joins(JOIN *join, POSITION *prefix, uint idx, table_map in
}
void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count, double *current_read_time,
POSITION *loose_scan_pos)
void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count,
double *current_read_time, POSITION *loose_scan_pos)
{
POSITION *pos= join->positions + idx;
const JOIN_TAB *new_join_tab= pos->table;
@@ -3014,19 +3014,36 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
}
}
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
update_sj_state(join, new_join_tab, idx, remaining_tables);
pos->prefix_cost.convert_from_cost(*current_read_time);
pos->prefix_record_count= *current_record_count;
pos->dups_producing_tables= dups_producing_tables;
}
/*
Update JOIN's semi-join optimization state after the join tab new_tab
has been added into the join prefix.
@seealso restore_prev_sj_state() does the reverse actoion
*/
void update_sj_state(JOIN *join, const JOIN_TAB *new_tab,
uint idx, table_map remaining_tables)
{
if (TABLE_LIST *emb_sj_nest= new_tab->emb_sj_nest)
{
join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;
/* Remove the sj_nest if all of its SJ-inner tables are in cur_table_map */
if (!(remaining_tables &
emb_sj_nest->sj_inner_tables & ~new_join_tab->table->map))
emb_sj_nest->sj_inner_tables & ~new_tab->table->map))
join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
}
pos->prefix_cost.convert_from_cost(*current_read_time);
pos->prefix_record_count= *current_record_count;
pos->dups_producing_tables= dups_producing_tables;
#ifndef DBUG_OFF
join->dbug_verify_sj_inner_tables(idx + 1);
#endif
}
@@ -3579,10 +3596,45 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join,
return FALSE;
}
#ifndef DBUG_OFF
/*
Verify the value of JOIN::cur_sj_inner_tables by recomputing it
*/
void JOIN::dbug_verify_sj_inner_tables(uint prefix_size) const
{
table_map cur_map= const_table_map;
table_map nests_entered= 0;
if (emb_sjm_nest)
{
DBUG_ASSERT(cur_sj_inner_tables == 0);
return;
}
for (uint i= const_tables; i < prefix_size; i++)
{
JOIN_TAB *tab= positions[i].table;
cur_map |= tab->table->map;
if (TABLE_LIST *sj_nest= tab->emb_sj_nest)
{
nests_entered |= sj_nest->sj_inner_tables;
if (!(sj_nest->sj_inner_tables & ~cur_map))
{
// all nest tables are in the prefix already
nests_entered &= ~sj_nest->sj_inner_tables;
}
}
}
DBUG_ASSERT(nests_entered == cur_sj_inner_tables);
}
#endif
/*
Remove the last join tab from from join->cur_sj_inner_tables bitmap
we assume remaining_tables doesnt contain @tab.
@note
remaining_tables contains @tab.
@seealso update_sj_state() does the reverse
*/
void restore_prev_sj_state(const table_map remaining_tables,
@@ -3596,15 +3648,30 @@ void restore_prev_sj_state(const table_map remaining_tables,
tab->join->sjm_lookup_tables &= ~subq_tables;
}
if ((emb_sj_nest= tab->emb_sj_nest))
if (!tab->join->emb_sjm_nest && (emb_sj_nest= tab->emb_sj_nest))
{
table_map subq_tables= emb_sj_nest->sj_inner_tables &
~tab->join->const_table_map;
/* If we're removing the last SJ-inner table, remove the sj-nest */
if ((remaining_tables & emb_sj_nest->sj_inner_tables) ==
(emb_sj_nest->sj_inner_tables & ~tab->table->map))
if ((remaining_tables & subq_tables) == subq_tables)
{
// All non-const tables of the SJ nest are in the remaining_tables.
// we are not in the nest anymore.
tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
}
else
{
// Semi-join nest has:
// - a table being removed (not in the prefix)
// - some tables in the prefix.
tab->join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;
}
}
#ifndef DBUG_OFF
/* positions[idx] has been removed. Verify the state for [0...idx-1] */
tab->join->dbug_verify_sj_inner_tables(idx);
#endif
}
@@ -3831,8 +3898,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
join->best_positions[first].n_sj_tables= sjm->tables;
/*
Do what advance_sj_state did: re-run best_access_path for every table
in the [last_inner_table + 1; pos..) range
Do what optimize_semi_joins did: re-run best_access_path for every
table in the [last_inner_table + 1; pos..) range
*/
double prefix_rec_count;
/* Get the prefix record count */
@@ -5086,7 +5153,7 @@ int setup_semijoin_loosescan(JOIN *join)
The choice between the strategies is made by the join optimizer (see
advance_sj_state() and fix_semijoin_strategies_for_picked_join_order()).
optimize_semi_joins() and fix_semijoin_strategies_for_picked_join_order()).
This function sets up all fields/structures/etc needed for execution except
for setup/initialization of semi-join materialization which is done in
setup_sj_materialization() (todo: can't we move that to here also?)

View File

@@ -314,9 +314,11 @@ public:
};
void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count, double *current_read_time,
POSITION *loose_scan_pos);
void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count,
double *current_read_time, POSITION *loose_scan_pos);
void update_sj_state(JOIN *join, const JOIN_TAB *new_tab,
uint idx, table_map remaining_tables);
void restore_prev_sj_state(const table_map remaining_tables,
const JOIN_TAB *tab, uint idx);

View File

@@ -890,7 +890,7 @@ void partition_info::vers_check_limit(THD *thd)
#ifndef DBUG_OFF
const uint32 sub_factor= num_subparts ? num_subparts : 1;
uint32 part_id= vers_info->hist_part->id * sub_factor;
const uint32 part_id_end= part_id + sub_factor;
const uint32 part_id_end __attribute__((unused)) = part_id + sub_factor;
DBUG_ASSERT(part_id_end <= num_parts * sub_factor);
#endif

View File

@@ -9444,7 +9444,7 @@ ER_JSON_ESCAPING
spa "Incorrecta escapatoria en texto JSON en argumento %d a función '%s' en la posicón %d"
ER_JSON_DEPTH
chi "超过JSON嵌套深度的%d限制 参数%d 函数'%s' 位置%d的"
eng "Limit of %d on JSON nested strucures depth is reached in argument %d to function '%s' at position %d"
eng "Limit of %d on JSON nested structures depth is reached in argument %d to function '%s' at position %d"
spa "El límite de %d en profundidad de estructuras JSON anidadas se ha alcanzado en argumento %d a función '%s' en la posición %d"
ER_JSON_PATH_EOS
chi "JSON文本路径错误 参数%d 函数'%s'"

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
Copyright (c) 2009, 2021, MariaDB Corporation.
Copyright (c) 2009, 2022, MariaDB Corporation
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
@@ -6718,8 +6718,8 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
can be satisfied only with the strict mode that ensures
against "genuine" gtid duplicates.
*/
rpl_gtid *gtid_in_slave_state=
mi->gtid_current_pos.find(mi->last_queued_gtid.domain_id);
IF_DBUG(rpl_gtid *gtid_in_slave_state=
mi->gtid_current_pos.find(mi->last_queued_gtid.domain_id),);
// Slave gtid state must not have updated yet to the last received gtid.
DBUG_ASSERT((mi->using_gtid == Master_info::USE_GTID_NO ||

View File

@@ -392,6 +392,7 @@ POSITION::POSITION()
ref_depend_map= dups_producing_tables= 0;
inner_tables_handled_with_other_sjs= 0;
type= JT_UNKNOWN;
key_dependent= 0;
dups_weedout_picker.set_empty();
firstmatch_picker.set_empty();
loosescan_picker.set_empty();
@@ -6290,7 +6291,11 @@ add_key_field(JOIN *join,
Field IN ...
*/
if (field->flags & PART_KEY_FLAG)
stat[0].key_dependent|=used_tables;
{
stat[0].key_dependent|= used_tables;
if (field->key_start.bits_set())
stat[0].key_start_dependent= 1;
}
bool is_const=1;
for (uint i=0; i<num_values; i++)
@@ -7241,6 +7246,7 @@ bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
use= save_pos= dynamic_element(keyuse,0,KEYUSE*);
prev= &key_end;
found_eq_constant= 0;
/* Loop over all elements except the last 'key_end' */
for (i=0 ; i < keyuse->elements-1 ; i++,use++)
{
if (!use->is_for_hash_join())
@@ -7634,7 +7640,7 @@ double cost_for_index_read(const THD *thd, const TABLE *table, uint key,
Adjust cost from table->quick_costs calculated by
multi_range_read_info_const() to be comparable with cost_for_index_read()
This functions is needed because best_access_patch doesn't add
This functions is needed because best_access_path() doesn't add
TIME_FOR_COMPARE to it's costs until very late.
Preferably we should fix so that all costs are comparably.
(All compared costs should include TIME_FOR_COMPARE for all found
@@ -7698,6 +7704,13 @@ best_access_path(JOIN *join,
double best_time= DBL_MAX;
double records= DBL_MAX;
table_map best_ref_depends_map= 0;
/*
key_dependent is 0 if all key parts could be used or if there was an
EQ_REF table found (which uses all key parts). In other words, we cannot
find a better key for the table even if remaining_tables is reduced.
Otherwise it's a bitmap of tables that could improve key usage.
*/
table_map key_dependent= 0;
Range_rowid_filter_cost_info *best_filter= 0;
double tmp;
ha_rows rec;
@@ -7749,6 +7762,8 @@ best_access_path(JOIN *join,
key_part_map const_part= 0;
/* The or-null keypart in ref-or-null access: */
key_part_map ref_or_null_part= 0;
key_part_map all_parts= 0;
if (is_hash_join_key_no(key))
{
/*
@@ -7780,7 +7795,7 @@ best_access_path(JOIN *join,
do /* For each keypart */
{
uint keypart= keyuse->keypart;
table_map best_part_found_ref= 0;
table_map best_part_found_ref= 0, key_parts_dependent= 0;
double best_prev_record_reads= DBL_MAX;
do /* For each way to access the keypart */
@@ -7789,6 +7804,7 @@ best_access_path(JOIN *join,
if 1. expression doesn't refer to forward tables
2. we won't get two ref-or-null's
*/
all_parts|= keyuse->keypart_map;
if (!(remaining_tables & keyuse->used_tables) &&
(!keyuse->validity_ref || *keyuse->validity_ref) &&
s->access_from_tables_is_allowed(keyuse->used_tables,
@@ -7797,6 +7813,7 @@ best_access_path(JOIN *join,
KEY_OPTIMIZE_REF_OR_NULL)))
{
found_part|= keyuse->keypart_map;
key_parts_dependent= 0;
if (!(keyuse->used_tables & ~join->const_table_map))
const_part|= keyuse->keypart_map;
@@ -7819,10 +7836,16 @@ best_access_path(JOIN *join,
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
ref_or_null_part |= keyuse->keypart_map;
}
else if (!(found_part & keyuse->keypart_map))
key_parts_dependent|= keyuse->used_tables;
loose_scan_opt.add_keyuse(remaining_tables, keyuse);
keyuse++;
} while (keyuse->table == table && keyuse->key == key &&
keyuse->keypart == keypart);
/* If we found a usable key, remember the dependent tables */
if (all_parts & 1)
key_dependent|= key_parts_dependent;
found_ref|= best_part_found_ref;
} while (keyuse->table == table && keyuse->key == key);
@@ -8209,6 +8232,27 @@ best_access_path(JOIN *join,
} /* for each key */
records= best_records;
}
else
{
/*
No usable keys found. However, there may still be an option to use
"Range checked for each record" when all depending tables has
been read. s->key_dependent tells us which tables these could be and
s->key_start_dependent tells us if a first key part was used.
s->key_dependent may include more tables than could be used,
but this is ok as not having any usable keys is a rare thing and
the performance penalty for extra table bits is that
best_extension_by_limited_search() would not be able to prune tables
earlier.
Example query:
SELECT * FROM t1,t2 where t1.key1=t2.key1 OR t2.key2<1
*/
if (s->key_start_dependent)
key_dependent= s->key_dependent;
}
/* Check that s->key_dependent contains all used_tables found in s->keyuse */
key_dependent&= ~PSEUDO_TABLE_BITS;
DBUG_ASSERT((key_dependent & s->key_dependent) == key_dependent);
/*
If there is no key to access the table, but there is an equi-join
@@ -8460,6 +8504,8 @@ best_access_path(JOIN *join,
pos->use_join_buffer= best_uses_jbuf;
pos->spl_plan= spl_plan;
pos->range_rowid_filter_info= best_filter;
pos->key_dependent= (best_type == JT_EQ_REF ? (table_map) 0 :
key_dependent & remaining_tables);
loose_scan_opt.save_to_position(s, loose_scan_pos);
@@ -8662,6 +8708,10 @@ choose_plan(JOIN *join, table_map join_tables)
{
choose_initial_table_order(join);
}
/*
Note: constant tables are already in the join prefix. We don't
put them into the cur_sj_inner_tables, though.
*/
join->cur_sj_inner_tables= 0;
if (straight_join)
@@ -8941,7 +8991,7 @@ determine_search_depth(JOIN *join)
*/
static void
optimize_straight_join(JOIN *join, table_map join_tables)
optimize_straight_join(JOIN *join, table_map remaining_tables)
{
JOIN_TAB *s;
uint idx= join->const_tables;
@@ -8959,30 +9009,32 @@ optimize_straight_join(JOIN *join, table_map join_tables)
Json_writer_object trace_one_table(thd);
if (unlikely(thd->trace_started()))
{
trace_plan_prefix(join, idx, join_tables);
trace_plan_prefix(join, idx, remaining_tables);
trace_one_table.add_table_name(s);
}
/* Find the best access method from 's' to the current partial plan */
best_access_path(join, s, join_tables, join->positions, idx,
best_access_path(join, s, remaining_tables, join->positions, idx,
disable_jbuf, record_count,
position, &loose_scan_pos);
/* compute the cost of the new plan extended with 's' */
/* Compute the cost of the new plan extended with 's' */
record_count= COST_MULT(record_count, position->records_read);
const double filter_cmp_gain= position->range_rowid_filter_info
? position->range_rowid_filter_info->get_cmp_gain(record_count)
: 0;
read_time+= COST_ADD(read_time - filter_cmp_gain,
COST_ADD(position->read_time,
record_count / TIME_FOR_COMPARE));
advance_sj_state(join, join_tables, idx, &record_count, &read_time,
read_time= COST_ADD(read_time,
COST_ADD(position->read_time -
filter_cmp_gain,
record_count /
TIME_FOR_COMPARE));
optimize_semi_joins(join, remaining_tables, idx, &record_count, &read_time,
&loose_scan_pos);
join_tables&= ~(s->table->map);
remaining_tables&= ~(s->table->map);
double pushdown_cond_selectivity= 1.0;
if (use_cond_selectivity > 1)
pushdown_cond_selectivity= table_cond_selectivity(join, idx, s,
join_tables);
remaining_tables);
position->cond_selectivity= pushdown_cond_selectivity;
++idx;
}
@@ -9156,6 +9208,12 @@ greedy_search(JOIN *join,
/* This has been already checked by best_extension_by_limited_search */
DBUG_ASSERT(!is_interleave_error);
/*
Also, update the semi-join optimization state. Information about the
picked semi-join operation is in best_pos->...picker, but we need to
update the global state in the JOIN object, too.
*/
update_sj_state(join, best_table, idx, remaining_tables);
/* find the position of 'best_table' in 'join->best_ref' */
best_idx= idx;
@@ -9163,8 +9221,13 @@ greedy_search(JOIN *join,
while (pos && best_table != pos)
pos= join->best_ref[++best_idx];
DBUG_ASSERT((pos != NULL)); // should always find 'best_table'
/* move 'best_table' at the first free position in the array of joins */
swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]);
/*
move 'best_table' at the first free position in the array of joins,
keeping the sorted table order intact
*/
memmove(join->best_ref + idx + 1, join->best_ref + idx,
sizeof(JOIN_TAB*) * (best_idx - idx));
join->best_ref[idx]= best_table;
/* compute the cost of the new plan extended with 'best_table' */
record_count= COST_MULT(record_count, join->positions[idx].records_read);
@@ -9383,10 +9446,7 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
double sel= 1.0;
COND_EQUAL *cond_equal= join->cond_equal;
if (!cond_equal || !cond_equal->current_level.elements)
return sel;
if (!s->keyuse)
if (!cond_equal || !cond_equal->current_level.elements || !s->keyuse)
return sel;
Item_equal *item_equal;
@@ -9911,7 +9971,7 @@ best_extension_by_limited_search(JOIN *join,
'join' is a partial plan with lower cost than the best plan so far,
so continue expanding it further with the tables in 'remaining_tables'.
*/
JOIN_TAB *s;
JOIN_TAB *s, **pos;
double best_record_count= DBL_MAX;
double best_read_time= DBL_MAX;
bool disable_jbuf= join->thd->variables.join_cache_level == 0;
@@ -9939,11 +9999,13 @@ best_extension_by_limited_search(JOIN *join,
if (join->emb_sjm_nest)
allowed_tables= join->emb_sjm_nest->sj_inner_tables & ~join->const_table_map;
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
for (pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
table_map real_table_bit= s->table->map;
DBUG_ASSERT(remaining_tables & real_table_bit);
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
if ((allowed_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
!check_interleaving_with_nj(s))
@@ -9964,12 +10026,12 @@ best_extension_by_limited_search(JOIN *join,
best_access_path(join, s, remaining_tables, join->positions, idx,
disable_jbuf, record_count, position, &loose_scan_pos);
/* Compute the cost of extending the plan with 's' */
/* Compute the cost of the new plan extended with 's' */
current_record_count= COST_MULT(record_count, position->records_read);
const double filter_cmp_gain= position->range_rowid_filter_info
? position->range_rowid_filter_info->get_cmp_gain(current_record_count)
: 0;
current_read_time=COST_ADD(read_time,
current_read_time= COST_ADD(read_time,
COST_ADD(position->read_time -
filter_cmp_gain,
current_record_count /
@@ -9980,7 +10042,7 @@ best_extension_by_limited_search(JOIN *join,
trace_one_table.add("rows_for_plan", current_record_count);
trace_one_table.add("cost_for_plan", current_read_time);
}
advance_sj_state(join, remaining_tables, idx, &current_record_count,
optimize_semi_joins(join, remaining_tables, idx, &current_record_count,
&current_read_time, &loose_scan_pos);
/* Expand only partial plans with lower cost than the best QEP so far */
@@ -10008,11 +10070,18 @@ best_extension_by_limited_search(JOIN *join,
(idx == join->const_tables && // 's' is the first table in the QEP
s->table == join->sort_by_table))
{
/*
Store the current record count and cost as the best
possible cost at this level if the following holds:
- It's the lowest record number and cost so far
- There is no remaing table that could improve index usage
or we found an EQ_REF or REF key with less than 2
matching records (good enough).
*/
if (best_record_count >= current_record_count &&
best_read_time >= current_read_time &&
/* TODO: What is the reasoning behind this condition? */
(!(s->key_dependent & allowed_tables & remaining_tables) ||
join->positions[idx].records_read < 2.0))
(!(position->key_dependent & allowed_tables) ||
position->records_read < 2.0))
{
best_record_count= current_record_count;
best_read_time= current_read_time;
@@ -10056,7 +10125,6 @@ best_extension_by_limited_search(JOIN *join,
allowed_tables)
{
/* Recursively expand the current partial plan */
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
Json_writer_array trace_rest(thd, "rest_of_plan");
best_res=
best_extension_by_limited_search(join,
@@ -10069,8 +10137,7 @@ best_extension_by_limited_search(JOIN *join,
prune_level,
use_cond_selectivity);
if ((int) best_res < (int) SEARCH_OK)
DBUG_RETURN(best_res); // Abort
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
goto end; // Return best_res
if (best_res == SEARCH_FOUND_EDGE &&
check_if_edge_table(join->positions+ idx,
pushdown_cond_selectivity) !=
@@ -10115,11 +10182,27 @@ best_extension_by_limited_search(JOIN *join,
if (best_res == SEARCH_FOUND_EDGE)
{
trace_one_table.add("pruned_by_hanging_leaf", true);
goto end;
}
}
}
best_res= SEARCH_OK;
end:
/* Restore original table order */
if (!*pos)
pos--; // Revert last pos++ in for loop
if (pos != join->best_ref + idx)
{
JOIN_TAB *tmp= join->best_ref[idx];
uint elements= (uint) (pos - (join->best_ref + idx));
memmove((void*) (join->best_ref + idx),
(void*) (join->best_ref + idx + 1),
elements * sizeof(JOIN_TAB*));
*pos= tmp;
}
DBUG_RETURN(best_res);
}
}
}
DBUG_RETURN(SEARCH_OK);
}
@@ -12519,6 +12602,7 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
(uchar *) &first_keyuse))
{
JOIN_TAB *tab;
first_keyuse= save_first_keyuse;
if (table->add_tmp_key(table->s->keys, parts,
get_next_field_for_derived_key,
@@ -12526,6 +12610,9 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
FALSE))
return TRUE;
table->reginfo.join_tab->keys.set_bit(table->s->keys);
tab= table->reginfo.join_tab;
for (uint i=0; i < parts; i++)
tab->key_dependent|= save_first_keyuse[i].used_tables;
}
else
{

View File

@@ -376,6 +376,8 @@ typedef struct st_join_table {
uint used_null_fields;
uint used_uneven_bit_fields;
enum join_type type;
/* If first key part is used for any key in 'key_dependent' */
bool key_start_dependent;
bool cached_eq_ref_table,eq_ref_table;
bool shortcut_for_distinct;
bool sorted;
@@ -958,6 +960,8 @@ public:
/* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map;
/* tables that may help best_access_path() to find a better key */
table_map key_dependent;
/*
Bitmap of semi-join inner tables that are in the join prefix and for
which there's no provision for how to eliminate semi-join duplicates
@@ -1307,9 +1311,15 @@ public:
Bitmap of inner tables of semi-join nests that have a proper subset of
their tables in the current join prefix. That is, of those semi-join
nests that have their tables both in and outside of the join prefix.
(Note: tables that are constants but have not been pulled out of semi-join
nests are not considered part of semi-join nests)
*/
table_map cur_sj_inner_tables;
#ifndef DBUG_OFF
void dbug_verify_sj_inner_tables(uint n_positions) const;
#endif
/* We also maintain a stack of join optimization states in * join->positions[] */
/******* Join optimization state members end *******/

View File

@@ -2488,15 +2488,6 @@ MEM_ROOT tz_storage;
char fullname[FN_REFLEN + 1];
char *root_name_end;
/*
known file types that exist in the zoneinfo directory that are safe to
silently skip
*/
const char *known_extensions[]= {
".tab",
NullS
};
/*
Recursively scan zoneinfo directory and print all found time zone
@@ -2593,20 +2584,19 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose)
else
{
/*
Some systems (like debian, opensuse etc) have description
files (.tab). We skip these silently if verbose is > 0
Some systems (like Debian, openSUSE, etc) have non-timezone files:
* iso3166.tab
* leap-seconds.list
* leapseconds
* tzdata.zi
* zone.tab
* zone1970.tab
We skip these silently unless verbose > 0.
*/
const char *current_ext= fn_ext(fullname);
my_bool known_ext= 0;
my_bool known_ext= strlen(current_ext) ||
!strcmp(my_basename(fullname), "leapseconds");
for (const char **ext= known_extensions ; *ext ; ext++)
{
if (!strcmp(*ext, current_ext))
{
known_ext= 1;
break;
}
}
if (verbose > 0 || !known_ext)
{
fflush(stdout);

View File

@@ -128,7 +128,6 @@ SET(INNOBASE_SOURCES
include/fil0crypt.h
include/fil0crypt.inl
include/fil0fil.h
include/fil0fil.inl
include/fil0pagecompress.h
include/fsp0file.h
include/fsp0fsp.h

View File

@@ -234,7 +234,9 @@ buf_block_t *btr_block_get(const dict_index_t &index,
{
if (!!page_is_comp(block->page.frame) != index.table->not_redundant() ||
btr_page_get_index_id(block->page.frame) != index.id ||
!fil_page_index_page_check(block->page.frame))
!fil_page_index_page_check(block->page.frame) ||
index.is_spatial() !=
(fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE))
{
*err= DB_PAGE_CORRUPTED;
block= nullptr;
@@ -1305,10 +1307,12 @@ static dberr_t btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
page_get_max_insert_size_after_reorganize(block->page.frame, 1);
if (UNIV_UNLIKELY(data_size1 != data_size2 || max1 != max2))
ib::fatal() << "Page old data size " << data_size1
<< " new data size " << data_size2
<< ", page old max ins size " << max1
<< " new max ins size " << max2;
{
sql_print_error("InnoDB: Page old data size %u new data size %u"
", page old max ins size %zu new max ins size %zu",
data_size1, data_size2, max1, max2);
return DB_CORRUPTION;
}
/* Restore the cursor position. */
if (pos)
@@ -2714,11 +2718,9 @@ page_move_rec_list_end(
ut_ad(new_data_size >= old_data_size);
page_delete_rec_list_end(split_rec, block, index,
return page_delete_rec_list_end(split_rec, block, index,
new_n_recs - old_n_recs,
new_data_size - old_data_size, mtr);
return DB_SUCCESS;
}
/*************************************************************//**
@@ -2978,10 +2980,15 @@ insert_empty:
page_zip_copy_recs(new_block,
page_zip, page, cursor->index, mtr);
page_delete_rec_list_end(move_limit - page + new_page,
new_block, cursor->index,
*err = page_delete_rec_list_end(move_limit
- page + new_page,
new_block,
cursor->index,
ULINT_UNDEFINED,
ULINT_UNDEFINED, mtr);
if (*err != DB_SUCCESS) {
return nullptr;
}
/* Update the lock table and possible hash index. */
if (cursor->index->has_locking()) {
@@ -3043,10 +3050,13 @@ insert_empty:
/* Delete the records from the source page. */
page_delete_rec_list_end(move_limit, block,
*err = page_delete_rec_list_end(move_limit, block,
cursor->index,
ULINT_UNDEFINED,
ULINT_UNDEFINED, mtr);
if (*err != DB_SUCCESS) {
return nullptr;
}
}
left_block = block;
@@ -4697,13 +4707,16 @@ btr_validate_level(
default:
err = e;
}
ut_a(index->table->space_id == block->page.id().space());
ut_a(block->page.id().space() == page_get_space_id(page));
ut_ad(index->table->space_id == block->page.id().space());
ut_ad(block->page.id().space() == page_get_space_id(page));
#ifdef UNIV_ZIP_DEBUG
page_zip = buf_block_get_page_zip(block);
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
ut_a(!page_is_leaf(page));
if (page_is_leaf(page)) {
err = DB_CORRUPTION;
goto invalid_page;
}
page_cur_set_before_first(block, &cursor);
page_cur_move_to_next(&cursor);
@@ -4831,7 +4844,11 @@ func_exit:
err = DB_CORRUPTION;
}
rec = page_rec_get_prev(page_get_supremum_rec(page));
if (!(rec = page_rec_get_prev(page_get_supremum_rec(page)))) {
btr_validate_report1(index, level, block);
fputs("InnoDB: broken record links\n", stderr);
goto invalid_page;
}
right_rec = page_rec_get_next(page_get_infimum_rec(
right_page));
offsets = rec_get_offsets(rec, index, offsets,
@@ -4855,10 +4872,12 @@ func_exit:
fputs("InnoDB: records in wrong order"
" on adjacent pages\n", stderr);
fputs("InnoDB: record ", stderr);
rec = page_rec_get_prev(page_get_supremum_rec(page));
if (rec) {
fputs("InnoDB: record ", stderr);
rec_print(stderr, rec, index);
putc('\n', stderr);
}
fputs("InnoDB: record ", stderr);
rec = page_rec_get_next(
page_get_infimum_rec(right_page));
@@ -4903,15 +4922,17 @@ func_exit:
rightmost_child = page_rec_is_supremum(
page_rec_get_next(node_ptr));
btr_cur_position(
index,
page_rec_get_prev(page_get_supremum_rec(page)),
block, &node_cur);
rec = page_rec_get_prev(page_get_supremum_rec(page));
if (rec) {
btr_cur_position(index, rec, block, &node_cur);
offsets = btr_page_get_father_node_ptr_for_validate(
offsets, heap, &node_cur, &mtr);
} else {
offsets = nullptr;
}
if (node_ptr != btr_cur_get_rec(&node_cur)
if (!offsets || node_ptr != btr_cur_get_rec(&node_cur)
|| btr_node_ptr_get_child_page_no(node_ptr, offsets)
!= block->page.id().page_no()) {
@@ -4923,14 +4944,17 @@ func_exit:
fputs("InnoDB: node ptr ", stderr);
rec_print(stderr, node_ptr, index);
if (offsets) {
rec = btr_cur_get_rec(&node_cur);
fprintf(stderr, "\n"
"InnoDB: node ptr child page n:o %u\n",
btr_node_ptr_get_child_page_no(rec, offsets));
btr_node_ptr_get_child_page_no(
rec, offsets));
fputs("InnoDB: record on page ", stderr);
rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
}
err = DB_CORRUPTION;
goto node_ptr_fails;
}
@@ -4961,15 +4985,21 @@ func_exit:
}
if (left_page_no == FIL_NULL) {
ut_a(node_ptr == page_rec_get_next(
page_get_infimum_rec(father_page)));
ut_a(!page_has_prev(father_page));
if (page_has_prev(father_page)
|| node_ptr != page_rec_get_next(
page_get_infimum_rec(father_page))) {
err = DB_CORRUPTION;
goto node_ptr_fails;
}
}
if (right_page_no == FIL_NULL) {
ut_a(node_ptr == page_rec_get_prev(
page_get_supremum_rec(father_page)));
ut_a(!page_has_next(father_page));
if (page_has_next(father_page)
|| node_ptr != page_rec_get_prev(
page_get_supremum_rec(father_page))) {
err = DB_CORRUPTION;
goto node_ptr_fails;
}
} else {
const rec_t* right_node_ptr;

View File

@@ -637,7 +637,7 @@ PageBulk::getSplitRec()
< total_used_size / 2);
/* Keep at least one record on left page */
if (page_rec_is_infimum(page_rec_get_prev(rec))) {
if (page_rec_is_second(rec, m_page)) {
rec = page_rec_get_next(rec);
ut_ad(page_rec_is_user_rec(rec));
}
@@ -679,34 +679,39 @@ void
PageBulk::copyOut(
rec_t* split_rec)
{
rec_t* rec;
rec_t* last_rec;
ulint n;
/* Suppose before copyOut, we have 5 records on the page:
infimum->r1->r2->r3->r4->r5->supremum, and r3 is the split rec.
after copyOut, we have 2 records on the page:
infimum->r1->r2->supremum. slot ajustment is not done. */
rec = page_rec_get_next(page_get_infimum_rec(m_page));
last_rec = page_rec_get_prev(page_get_supremum_rec(m_page));
n = 0;
rec_t *rec = page_get_infimum_rec(m_page);
ulint n;
while (rec != split_rec) {
rec = page_rec_get_next(rec);
n++;
for (n = 0;; n++) {
rec_t *next = page_rec_get_next(rec);
if (next == split_rec) {
break;
}
rec = next;
}
ut_ad(n > 0);
const rec_t *last_rec = split_rec;
for (;;) {
const rec_t *next = page_rec_get_next_const(last_rec);
if (page_rec_is_supremum(next)) {
break;
}
last_rec = next;
}
/* Set last record's next in page */
rec_offs* offsets = NULL;
rec = page_rec_get_prev(split_rec);
const ulint n_core = page_rec_is_leaf(split_rec)
? m_index->n_core_fields : 0;
offsets = rec_get_offsets(rec, m_index, offsets, n_core,
rec_offs* offsets = rec_get_offsets(rec, m_index, nullptr, n_core,
ULINT_UNDEFINED, &m_heap);
mach_write_to_2(rec - REC_NEXT, m_is_comp
? static_cast<uint16_t>

View File

@@ -71,6 +71,7 @@ Created 10/16/1994 Heikki Tuuri
#ifdef WITH_WSREP
#include "mysql/service_wsrep.h"
#endif /* WITH_WSREP */
#include "log.h"
/** Buffered B-tree operation types, introduced as part of delete buffering. */
enum btr_op_t {
@@ -2131,12 +2132,10 @@ need_opposite_intention:
if (matched_fields
>= rec_offs_n_fields(offsets) - 1) {
detected_same_key_root = true;
} else {
const rec_t* last_rec;
last_rec = page_rec_get_prev_const(
page_get_supremum_rec(page));
} else if (const rec_t* last_rec
= page_rec_get_prev_const(
page_get_supremum_rec(
page))) {
matched_fields = 0;
offsets2 = rec_get_offsets(
@@ -2150,6 +2149,9 @@ need_opposite_intention:
>= rec_offs_n_fields(offsets) - 1) {
detected_same_key_root = true;
}
} else {
err = DB_CORRUPTION;
goto func_exit;
}
}
}
@@ -2709,7 +2711,10 @@ btr_cur_open_at_index_side(
if (from_left) {
page_cur_move_to_next(page_cursor);
} else {
page_cur_move_to_prev(page_cursor);
if (!page_cur_move_to_prev(page_cursor)) {
err = DB_CORRUPTION;
goto exit_loop;
}
}
if (estimate) {
@@ -2799,7 +2804,7 @@ btr_cur_open_at_index_side(
}
exit_loop:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -3844,6 +3849,7 @@ static void btr_cur_write_sys(
trx_write_roll_ptr(static_cast<byte*>(r->data), roll_ptr);
}
MY_ATTRIBUTE((warn_unused_result))
/** Update DB_TRX_ID, DB_ROLL_PTR in a clustered index record.
@param[in,out] block clustered index leaf page
@param[in,out] rec clustered index record
@@ -3851,8 +3857,9 @@ static void btr_cur_write_sys(
@param[in] offsets rec_get_offsets(rec, index)
@param[in] trx transaction
@param[in] roll_ptr DB_ROLL_PTR value
@param[in,out] mtr mini-transaction */
static void btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
@param[in,out] mtr mini-transaction
@return error code */
static dberr_t btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
dict_index_t *index, const rec_offs *offsets,
const trx_t *trx, roll_ptr_t roll_ptr,
mtr_t *mtr)
@@ -3864,7 +3871,7 @@ static void btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
{
page_zip_write_trx_id_and_roll_ptr(block, rec, offsets, index->db_trx_id(),
trx->id, roll_ptr, mtr);
return;
return DB_SUCCESS;
}
ulint offset= index->trx_id_offset;
@@ -3894,8 +3901,8 @@ static void btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
if (UNIV_LIKELY(index->trx_id_offset))
{
const rec_t *prev= page_rec_get_prev_const(rec);
if (UNIV_UNLIKELY(prev == rec))
ut_ad(0);
if (UNIV_UNLIKELY(!prev || prev == rec))
return DB_CORRUPTION;
else if (page_rec_is_infimum(prev));
else
for (src= prev + offset; d < DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN; d++)
@@ -3933,6 +3940,8 @@ static void btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
if (UNIV_LIKELY(len)) /* extra safety, to avoid corrupting the log */
mtr->memcpy<mtr_t::MAYBE_NOP>(*block, dest, sys + d, len);
return DB_SUCCESS;
}
/*************************************************************//**
@@ -4238,8 +4247,11 @@ btr_cur_update_in_place(
}
if (!(flags & BTR_KEEP_SYS_FLAG)) {
btr_cur_upd_rec_sys(block, rec, index, offsets,
err = btr_cur_upd_rec_sys(block, rec, index, offsets,
thr_get_trx(thr), roll_ptr, mtr);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
goto func_exit;
}
}
was_delete_marked = rec_get_deleted_flag(
@@ -4693,7 +4705,9 @@ any_extern:
page_cur_delete_rec(page_cursor, index, *offsets, mtr);
page_cur_move_to_prev(page_cursor);
if (!page_cur_move_to_prev(page_cursor)) {
return DB_CORRUPTION;
}
if (!(flags & BTR_KEEP_SYS_FLAG)) {
btr_cur_write_sys(new_entry, index, trx_id, roll_ptr);
@@ -5055,7 +5069,10 @@ btr_cur_pessimistic_update(
page_cur_delete_rec(page_cursor, index, *offsets, mtr);
page_cur_move_to_prev(page_cursor);
if (!page_cur_move_to_prev(page_cursor)) {
err = DB_CORRUPTION;
goto return_after_reservations;
}
rec = btr_cur_insert_if_possible(cursor, new_entry,
offsets, offsets_heap, n_ext, mtr);
@@ -5353,8 +5370,8 @@ btr_cur_del_mark_set_clust_rec(
<< ib::hex(trx->id) << ": "
<< rec_printer(rec, offsets).str());
btr_cur_upd_rec_sys(block, rec, index, offsets, trx, roll_ptr, mtr);
return(err);
return btr_cur_upd_rec_sys(block, rec, index, offsets, trx, roll_ptr,
mtr);
}
/*==================== B-TREE RECORD REMOVE =========================*/
@@ -7195,29 +7212,29 @@ func_exit:
}
/** Check the FIL_PAGE_TYPE on an uncompressed BLOB page.
@param[in] block uncompressed BLOB page
@param[in] read true=read, false=purge */
static void btr_check_blob_fil_page_type(const buf_block_t& block, bool read)
@param block uncompressed BLOB page
@param op operation
@return whether the type is invalid */
static bool btr_check_blob_fil_page_type(const buf_block_t& block,
const char *op)
{
uint16_t type= fil_page_get_type(block.page.frame);
if (UNIV_LIKELY(type == FIL_PAGE_TYPE_BLOB))
return;
/* FIXME: take the tablespace as a parameter */
if (fil_space_t *space= fil_space_t::get(block.page.id().space()))
if (UNIV_LIKELY(type == FIL_PAGE_TYPE_BLOB));
else if (fil_space_t *space= fil_space_t::get(block.page.id().space()))
{
/* Old versions of InnoDB did not initialize FIL_PAGE_TYPE on BLOB
pages. Do not print anything about the type mismatch when reading
a BLOB page that may be from old versions. */
if (space->full_crc32() || DICT_TF_HAS_ATOMIC_BLOBS(space->flags))
{
ib::fatal() << "FIL_PAGE_TYPE=" << type
<< (read ? " on BLOB read file " : " on BLOB purge file ")
<< space->chain.start->name
<< " page " << block.page.id().page_no();
}
bool fail= space->full_crc32() || DICT_TF_HAS_ATOMIC_BLOBS(space->flags);
if (fail)
sql_print_error("InnoDB: FIL_PAGE_TYPE=%u on BLOB %s file %s page %u",
type, op, space->chain.start->name,
block.page.id().page_no());
space->release();
return fail;
}
return false;
}
/*******************************************************************//**
@@ -7364,7 +7381,7 @@ skip_free:
}
} else {
ut_ad(!block->page.zip.data);
btr_check_blob_fil_page_type(*ext_block, false);
btr_check_blob_fil_page_type(*ext_block, "purge");
const uint32_t next_page_no = mach_read_from_4(
page + FIL_PAGE_DATA
@@ -7498,14 +7515,12 @@ btr_copy_blob_prefix(
mtr_start(&mtr);
block = buf_page_get(id, 0, RW_S_LATCH, &mtr);
if (!block) {
if (!block || btr_check_blob_fil_page_type(*block, "read")) {
mtr.commit();
return copied_len;
}
page = buf_block_get_frame(block);
btr_check_blob_fil_page_type(*block, true);
blob_header = page + offset;
part_len = btr_blob_get_part_len(blob_header);
copy_len = ut_min(part_len, len - copied_len);

View File

@@ -707,9 +707,11 @@ processed:
page_t* last_page = buf_block_get_frame(last_block);
rec_t* rec = page_rec_get_prev(
page_get_supremum_rec(last_page));
ut_a(page_rec_is_user_rec(rec));
if (rec && page_rec_is_user_rec(rec)) {
page_cur_position(rec, last_block,
btr_pcur_get_page_cur(item->pcur));
btr_pcur_get_page_cur(
item->pcur));
}
btr_pcur_store_position(item->pcur, &mtr);
mtr_commit(&mtr);
/* Update the last_processed time of this index. */

View File

@@ -148,6 +148,11 @@ before_first:
if (page_rec_is_supremum_low(offs)) {
rec = page_rec_get_prev(rec);
if (UNIV_UNLIKELY(!rec || page_rec_is_infimum(rec))) {
ut_ad("corrupted index" == 0);
cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
return;
}
ut_ad(!page_rec_is_infimum(rec));
if (UNIV_UNLIKELY(rec_is_metadata(rec, *index))) {
@@ -486,7 +491,17 @@ btr_pcur_move_to_next_page(
const page_t* page = btr_pcur_get_page(cursor);
const uint32_t next_page_no = btr_page_get_next(page);
ut_ad(next_page_no != FIL_NULL);
switch (next_page_no) {
case 0:
case 1:
case FIL_NULL:
return DB_CORRUPTION;
}
if (UNIV_UNLIKELY(next_page_no == btr_pcur_get_block(cursor)
->page.id().page_no())) {
return DB_CORRUPTION;
}
ulint mode = cursor->latch_mode;
switch (mode) {
@@ -599,13 +614,9 @@ btr_pcur_move_to_prev(
cursor->old_stored = false;
if (btr_pcur_is_before_first_on_page(cursor)) {
if (btr_pcur_is_before_first_in_tree(cursor)
|| btr_pcur_move_backward_from_page(cursor, mtr)) {
return false;
}
} else {
btr_pcur_move_to_prev_on_page(cursor);
return (!btr_pcur_is_before_first_in_tree(cursor)
&& !btr_pcur_move_backward_from_page(cursor, mtr));
}
return true;
return btr_pcur_move_to_prev_on_page(cursor) != nullptr;
}

View File

@@ -781,7 +781,7 @@ btr_search_check_guess(
mem_heap_t* heap = NULL;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_;
ibool success = FALSE;
bool success = false;
rec_offs_init(offsets_);
n_unique = dict_index_get_n_unique_in_tree(cursor->index);
@@ -806,7 +806,7 @@ btr_search_check_guess(
cursor->up_match = match;
if (match >= n_unique) {
success = TRUE;
success = true;
goto exit_func;
}
} else if (mode == PAGE_CUR_LE) {
@@ -835,10 +835,13 @@ btr_search_check_guess(
match = 0;
if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)) {
ut_ad(!page_rec_is_infimum(rec));
const rec_t* prev_rec = page_rec_get_prev(rec);
if (UNIV_UNLIKELY(!prev_rec)) {
ut_ad("corrupted index" == 0);
goto exit_func;
}
if (page_rec_is_infimum(prev_rec)) {
success = !page_has_prev(page_align(prev_rec));
goto exit_func;

View File

@@ -403,28 +403,22 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage,
return (true);
}
if (node.space->purpose == FIL_TYPE_TEMPORARY
buf_tmp_buffer_t* slot;
if (id.space() == SRV_TMP_SPACE_ID
&& innodb_encrypt_temporary_tables) {
buf_tmp_buffer_t* slot = buf_pool.io_buf_reserve();
slot = buf_pool.io_buf_reserve();
ut_a(slot);
slot->allocate();
if (!buf_tmp_page_decrypt(slot->crypt_buf, dst_frame)) {
bool ok = buf_tmp_page_decrypt(slot->crypt_buf, dst_frame);
slot->release();
ib::error() << "Encrypted page " << id
<< " in file " << node.name;
return false;
}
slot->release();
return true;
return ok;
}
/* Page is encrypted if encryption information is found from
tablespace and page contains used key_version. This is true
also for pages first compressed and then encrypted. */
buf_tmp_buffer_t* slot;
uint key_version = buf_page_get_key_version(dst_frame, flags);
if (page_compressed && !key_version) {
@@ -441,13 +435,9 @@ decompress:
slot->allocate();
decompress_with_slot:
ut_d(fil_page_type_validate(node.space, dst_frame));
ulint write_size = fil_page_decompress(
slot->crypt_buf, dst_frame, flags);
slot->release();
ut_ad(!write_size
|| fil_page_type_validate(node.space, dst_frame));
ut_ad(node.space->referenced());
return write_size != 0;
}
@@ -467,7 +457,6 @@ decrypt_failed:
slot = buf_pool.io_buf_reserve();
ut_a(slot);
slot->allocate();
ut_d(fil_page_type_validate(node.space, dst_frame));
/* decrypt using crypt_buf to dst_frame */
if (!fil_space_decrypt(node.space, slot->crypt_buf, dst_frame)) {
@@ -475,8 +464,6 @@ decrypt_failed:
goto decrypt_failed;
}
ut_d(fil_page_type_validate(node.space, dst_frame));
if ((fil_space_t::full_crc32(flags) && page_compressed)
|| fil_page_get_type(dst_frame)
== FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
@@ -2597,7 +2584,8 @@ loop:
checksum cannot be decypted. */
if (dberr_t local_err = buf_read_page(page_id, zip_size)) {
if (mode != BUF_GET_POSSIBLY_FREED
if (local_err != DB_CORRUPTION
&& mode != BUF_GET_POSSIBLY_FREED
&& retries++ < BUF_PAGE_READ_MAX_RETRIES) {
DBUG_EXECUTE_IF("intermittent_read_failure",
retries = BUF_PAGE_READ_MAX_RETRIES;);

View File

@@ -621,7 +621,6 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s,
ut_ad(space->id == bpage->id().space());
ut_ad(!*slot);
ut_d(fil_page_type_validate(space, s));
const uint32_t page_no= bpage->id().page_no();
switch (page_no) {
@@ -718,7 +717,6 @@ not_compressed:
/* Workaround for MDEV-15527. */
memset(tmp + len, 0 , srv_page_size - len);
ut_d(fil_page_type_validate(space, tmp));
if (encrypted)
tmp= fil_space_encrypt(space, page_no, tmp, d);
@@ -733,7 +731,6 @@ not_compressed:
d= tmp;
}
ut_d(fil_page_type_validate(space, d));
(*slot)->out_buf= d;
return d;
}

View File

@@ -822,7 +822,8 @@ err_exit:
high bit set in n_cols, and flags would be zero.
MySQL 4.1 was the first version to support innodb_file_per_table,
that is, *space_id != 0. */
if (not_redundant || *space_id != 0 || *n_cols & DICT_N_COLS_COMPACT) {
if (not_redundant || *space_id != 0 || *n_cols & DICT_N_COLS_COMPACT
|| fil_system.sys_space->full_crc32()) {
/* Get flags2 from SYS_TABLES.MIX_LEN */
field = rec_get_nth_field_old(
@@ -2651,7 +2652,6 @@ static dberr_t dict_load_foreign_cols(dict_foreign_t *foreign, trx_id_t trx_id)
goto func_exit;
}
for (ulint i = 0; i < foreign->n_fields; i++) {
retry:
ut_a(btr_pcur_is_on_user_rec(&pcur));
const rec_t* rec = btr_pcur_get_rec(&pcur);
@@ -2684,9 +2684,7 @@ retry:
if (rec_get_deleted_flag(rec, 0)) {
ut_ad(id);
next:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
goto retry;
goto next;
}
field = rec_get_nth_field_old(
@@ -2712,7 +2710,7 @@ next:
rec, DICT_FLD__SYS_FOREIGN_COLS__REF_COL_NAME,
&ref_col_name_len);
ib::fatal sout;
ib::error sout;
sout << "Unable to load column names for foreign"
" key '" << foreign->id
@@ -2727,6 +2725,9 @@ next:
sout << "', REF_COL_NAME='";
sout.write(ref_col_name, ref_col_name_len);
sout << "')";
err = DB_CORRUPTION;
break;
}
field = rec_get_nth_field_old(
@@ -2744,6 +2745,7 @@ next:
foreign->referenced_col_names[i] = mem_heap_strdupl(
foreign->heap, (char*) field, len);
next:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
func_exit:

View File

@@ -640,10 +640,7 @@ static dberr_t fil_space_decrypt_full_crc32(
lsn_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
uint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET);
ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
ut_ad(crypt_data);
ut_ad(crypt_data->is_encrypted());
ut_ad(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
memcpy(tmp_frame, src_frame, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
@@ -665,17 +662,9 @@ static dberr_t fil_space_decrypt_full_crc32(
(uint) space, offset, lsn);
if (rc != MY_AES_OK || dstlen != srclen) {
if (rc == -1) {
return DB_DECRYPTION_FAILED;
}
ib::fatal() << "Unable to decrypt data-block "
<< " src: " << src << "srclen: "
<< srclen << " buf: " << dst << "buflen: "
<< dstlen << " return-code: " << rc
<< " Can't continue!";
}
/* Copy only checksum part in the trailer */
memcpy(tmp_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
src_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
@@ -707,8 +696,7 @@ static dberr_t fil_space_decrypt_for_non_full_checksum(
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
ut_a(crypt_data != NULL && crypt_data->is_encrypted());
ut_ad(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
/* read space & lsn */
uint header_len = FIL_PAGE_DATA;
@@ -735,20 +723,9 @@ static dberr_t fil_space_decrypt_for_non_full_checksum(
space, offset, lsn);
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
if (rc == -1) {
return DB_DECRYPTION_FAILED;
}
ib::fatal() << "Unable to decrypt data-block "
<< " src: " << static_cast<const void*>(src)
<< "srclen: "
<< srclen << " buf: "
<< static_cast<const void*>(dst) << "buflen: "
<< dstlen << " return-code: " << rc
<< " Can't continue!";
}
/* For compressed tables we do not store the FIL header because
the whole page is not stored to the disk. In compressed tables only
the FIL header + compressed (and now encrypted) payload alligned
@@ -772,8 +749,8 @@ static dberr_t fil_space_decrypt_for_non_full_checksum(
@param[in] tmp_frame Temporary buffer
@param[in] physical_size page size
@param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
@return DB_SUCCESS or error */
@retval DB_SUCCESS on success
@retval DB_DECRYPTION_FAILED on error */
dberr_t
fil_space_decrypt(
uint32_t space_id,
@@ -783,6 +760,10 @@ fil_space_decrypt(
ulint physical_size,
byte* src_frame)
{
if (!crypt_data || !crypt_data->is_encrypted()) {
return DB_DECRYPTION_FAILED;
}
if (fil_space_t::full_crc32(fsp_flags)) {
return fil_space_decrypt_full_crc32(
space_id, crypt_data, tmp_frame, src_frame);
@@ -799,7 +780,8 @@ Decrypt a page.
@param[in] tmp_frame Temporary buffer used for decrypting
@param[in,out] src_frame Page to decrypt
@return decrypted page, or original not encrypted page if decryption is
not needed.*/
not needed.
@retval nullptr on failure */
byte*
fil_space_decrypt(
const fil_space_t* space,
@@ -808,7 +790,6 @@ fil_space_decrypt(
{
const ulint physical_size = space->physical_size();
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
ut_ad(space->referenced());
if (DB_SUCCESS != fil_space_decrypt(space->id, space->flags,
@@ -820,9 +801,7 @@ fil_space_decrypt(
/* Copy the decrypted page back to page buffer, not
really any other options. */
memcpy(src_frame, tmp_frame, physical_size);
return src_frame;
return static_cast<byte*>(memcpy(src_frame, tmp_frame, physical_size));
}
/***********************************************************************/

View File

@@ -2831,7 +2831,7 @@ fail:
io_error:
#endif
set_corrupted();
err = DB_IO_ERROR;
err = DB_CORRUPTION;
node = nullptr;
goto release;
}

View File

@@ -718,7 +718,6 @@ rtr_split_page_move_rec_list(
page_zip_des_t* new_page_zip
= buf_block_get_page_zip(new_block);
rec_t* rec;
rec_t* ret;
ulint moved = 0;
ulint max_to_move = 0;
rtr_rec_move_t* rec_move = NULL;
@@ -733,7 +732,6 @@ rtr_split_page_move_rec_list(
page = buf_block_get_frame(block);
new_page = buf_block_get_frame(new_block);
ret = page_rec_get_prev(page_get_supremum_rec(new_page));
end_split_node = node_array + page_get_n_recs(page);
@@ -804,32 +802,15 @@ rtr_split_page_move_rec_list(
if (!page_zip_compress(new_block, index,
page_zip_level, mtr)) {
/* Before trying to reorganize the page,
store the number of preceding records on the page. */
ulint ret_pos = page_rec_get_n_recs_before(ret);
/* Before copying, "ret" was the predecessor
of the predefined supremum record. If it was
the predefined infimum record, then it would
still be the infimum, and we would have
ret_pos == 0. */
switch (dberr_t err =
if (dberr_t err =
page_zip_reorganize(new_block, index,
page_zip_level, mtr)) {
case DB_FAIL:
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
new_page, FALSE))) {
ut_error;
if (err == DB_FAIL) {
ut_a(page_zip_decompress(new_page_zip,
new_page,
FALSE));
}
#ifdef UNIV_GIS_DEBUG
ut_ad(page_validate(new_page, index));
#endif
/* fall through */
default:
return err;
case DB_SUCCESS:
ret = page_rec_get_nth(new_page, ret_pos);
}
}
}
@@ -1284,14 +1265,9 @@ rtr_ins_enlarge_mbr(
/*************************************************************//**
Copy recs from a page to new_block of rtree.
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page or compress the page.
IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
if new_block is a compressed leaf page in a secondary index.
This has to be done either within the same mini-transaction,
or by invoking ibuf_reset_free_bits() before mtr_commit(). */
void
@return error code */
dberr_t
rtr_page_copy_rec_list_end_no_locks(
/*================================*/
buf_block_t* new_block, /*!< in: index page to copy to */
@@ -1355,8 +1331,7 @@ rtr_page_copy_rec_list_end_no_locks(
offsets1, offsets2, index, false,
&cur_matched_fields);
if (cmp < 0) {
page_cur_move_to_prev(&page_cur);
break;
goto move_to_prev;
} else if (cmp > 0) {
/* Skip small recs. */
page_cur_move_to_next(&page_cur);
@@ -1379,26 +1354,23 @@ rtr_page_copy_rec_list_end_no_locks(
/* If position is on suprenum rec, need to move to
previous rec. */
if (page_rec_is_supremum(cur_rec)) {
page_cur_move_to_prev(&page_cur);
move_to_prev:
cur_rec = page_cur_move_to_prev(&page_cur);
} else {
cur_rec = page_cur_get_rec(&page_cur);
}
cur_rec = page_cur_get_rec(&page_cur);
if (UNIV_UNLIKELY(!cur_rec)) {
return DB_CORRUPTION;
}
offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(&page_cur, index,
cur1_rec, offsets1, mtr);
if (UNIV_UNLIKELY(!ins_rec)) {
fprintf(stderr, "page number %u and %u\n",
new_block->page.id().page_no(),
block->page.id().page_no());
ib::fatal() << "rec offset " << page_offset(rec)
<< ", cur1 offset "
<< page_offset(page_cur_get_rec(&cur1))
<< ", cur_rec offset "
<< page_offset(cur_rec);
if (UNIV_UNLIKELY(!ins_rec || moved >= max_move)) {
return DB_CORRUPTION;
}
rec_move[moved].new_rec = ins_rec;
@@ -1406,20 +1378,18 @@ rtr_page_copy_rec_list_end_no_locks(
rec_move[moved].moved = false;
moved++;
next:
if (moved > max_move) {
ut_ad(0);
break;
}
page_cur_move_to_next(&cur1);
}
*num_moved = moved;
return DB_SUCCESS;
}
/*************************************************************//**
Copy recs till a specified rec from a page to new_block of rtree. */
void
Copy recs till a specified rec from a page to new_block of rtree.
@return error code */
dberr_t
rtr_page_copy_rec_list_start_no_locks(
/*==================================*/
buf_block_t* new_block, /*!< in: index page to copy to */
@@ -1474,9 +1444,7 @@ rtr_page_copy_rec_list_start_no_locks(
offsets1, offsets2, index, false,
&cur_matched_fields);
if (cmp < 0) {
page_cur_move_to_prev(&page_cur);
cur_rec = page_cur_get_rec(&page_cur);
break;
goto move_to_prev;
} else if (cmp > 0) {
/* Skip small recs. */
page_cur_move_to_next(&page_cur);
@@ -1500,23 +1468,22 @@ rtr_page_copy_rec_list_start_no_locks(
/* If position is on suprenum rec, need to move to
previous rec. */
if (page_rec_is_supremum(cur_rec)) {
page_cur_move_to_prev(&page_cur);
move_to_prev:
cur_rec = page_cur_move_to_prev(&page_cur);
if (UNIV_UNLIKELY(!cur_rec)) {
return DB_CORRUPTION;
}
} else {
cur_rec = page_cur_get_rec(&page_cur);
}
offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(&page_cur, index,
cur1_rec, offsets1, mtr);
if (UNIV_UNLIKELY(!ins_rec)) {
ib::fatal() << new_block->page.id()
<< "rec offset " << page_offset(rec)
<< ", cur1 offset "
<< page_offset(page_cur_get_rec(&cur1))
<< ", cur_rec offset "
<< page_offset(cur_rec);
if (UNIV_UNLIKELY(!ins_rec || moved >= max_move)) {
return DB_CORRUPTION;
}
rec_move[moved].new_rec = ins_rec;
@@ -1524,15 +1491,11 @@ rtr_page_copy_rec_list_start_no_locks(
rec_move[moved].moved = false;
moved++;
next:
if (moved > max_move) {
ut_ad(0);
break;
}
page_cur_move_to_next(&cur1);
}
*num_moved = moved;
return DB_SUCCESS;
}
/****************************************************************//**

View File

@@ -7450,9 +7450,12 @@ ha_innobase::build_template(
ulint num_v = 0;
if ((active_index != MAX_KEY
&& active_index == pushed_idx_cond_keyno)
|| (pushed_rowid_filter && rowid_filter_is_active)) {
if (active_index != MAX_KEY
&& active_index == pushed_idx_cond_keyno) {
m_prebuilt->idx_cond = this;
goto icp;
} else if (pushed_rowid_filter && rowid_filter_is_active) {
icp:
/* Push down an index condition or an end_range check. */
for (ulint i = 0; i < n_fields; i++) {
const Field* field = table->field[i];
@@ -7633,9 +7636,6 @@ ha_innobase::build_template(
}
}
}
if (active_index == pushed_idx_cond_keyno) {
m_prebuilt->idx_cond = this;
}
} else {
no_icp:
/* No index condition pushdown */

View File

@@ -1993,7 +1993,7 @@ static bool innobase_table_is_empty(const dict_table_t *table,
btr_pcur_t pcur;
buf_block_t *block;
page_cur_t *cur;
const rec_t *rec;
rec_t *rec;
bool next_page= false;
mtr.start();
@@ -2004,9 +2004,9 @@ non_empty:
mtr.commit();
return false;
}
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
if (!rec_is_metadata(btr_pcur_get_rec(&pcur), *clust_index))
btr_pcur_move_to_prev_on_page(&pcur);
rec= page_rec_get_next(btr_pcur_get_rec(&pcur));
if (rec_is_metadata(rec, *clust_index))
btr_pcur_get_page_cur(&pcur)->rec= rec;
scan_leaf:
cur= btr_pcur_get_page_cur(&pcur);
page_cur_move_to_next(cur);

View File

@@ -2035,23 +2035,25 @@ ibuf_get_merge_page_nos_func(
*n_stored = 0;
limit = ut_min(IBUF_MAX_N_PAGES_MERGED,
buf_pool_get_curr_size() / 4);
if (page_rec_is_supremum(rec)) {
rec = page_rec_get_prev_const(rec);
if (UNIV_UNLIKELY(!rec)) {
corruption:
ut_ad("corrupted page" == 0);
return 0;
}
}
if (page_rec_is_infimum(rec)) {
rec = page_rec_get_next_const(rec);
}
if (page_rec_is_supremum(rec)) {
return(0);
return 0;
}
}
limit = ut_min(IBUF_MAX_N_PAGES_MERGED,
buf_pool_get_curr_size() / 4);
first_page_no = ibuf_rec_get_page_no(mtr, rec);
first_space_id = ibuf_rec_get_space(mtr, rec);
@@ -2083,7 +2085,9 @@ ibuf_get_merge_page_nos_func(
prev_page_no = rec_page_no;
prev_space_id = rec_space_id;
rec = page_rec_get_prev_const(rec);
if (UNIV_UNLIKELY(!(rec = page_rec_get_prev_const(rec)))) {
goto corruption;
}
}
rec = page_rec_get_next_const(rec);
@@ -2809,14 +2813,16 @@ ibuf_get_volume_buffered(
page = page_align(rec);
ut_ad(page_validate(page, ibuf.index));
if (page_rec_is_supremum(rec)) {
rec = page_rec_get_prev_const(rec);
if (page_rec_is_supremum(rec)
&& UNIV_UNLIKELY(!(rec = page_rec_get_prev_const(rec)))) {
corruption:
ut_ad("corrupted page" == 0);
return srv_page_size;
}
uint32_t prev_page_no;
for (; !page_rec_is_infimum(rec);
rec = page_rec_get_prev_const(rec)) {
for (; !page_rec_is_infimum(rec); ) {
ut_ad(page_align(rec) == page);
if (page_no != ibuf_rec_get_page_no(mtr, rec)
@@ -2828,6 +2834,10 @@ ibuf_get_volume_buffered(
volume += ibuf_get_volume_buffered_count(
mtr, rec,
hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
if (UNIV_UNLIKELY(!(rec = page_rec_get_prev_const(rec)))) {
goto corruption;
}
}
/* Look at the previous page */
@@ -2853,13 +2863,16 @@ ibuf_get_volume_buffered(
if (UNIV_UNLIKELY(memcmp_aligned<4>(prev_page + FIL_PAGE_NEXT,
page + FIL_PAGE_OFFSET, 4))) {
return 0;
return srv_page_size;
}
rec = page_get_supremum_rec(prev_page);
rec = page_rec_get_prev_const(rec);
rec = page_rec_get_prev_const(page_get_supremum_rec(prev_page));
for (;; rec = page_rec_get_prev_const(rec)) {
if (UNIV_UNLIKELY(!rec)) {
goto corruption;
}
for (;;) {
ut_ad(page_align(rec) == prev_page);
if (page_rec_is_infimum(rec)) {
@@ -2880,6 +2893,10 @@ ibuf_get_volume_buffered(
volume += ibuf_get_volume_buffered_count(
mtr, rec,
hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
if (UNIV_UNLIKELY(!(rec = page_rec_get_prev_const(rec)))) {
goto corruption;
}
}
count_later:
@@ -3801,7 +3818,10 @@ ibuf_insert_to_index_page(
buffered one. */
page_cur_delete_rec(&page_cur, index, offsets, mtr);
page_cur_move_to_prev(&page_cur);
if (!(page_cur_move_to_prev(&page_cur))) {
err = DB_CORRUPTION;
goto updated_in_place;
}
} else {
offsets = NULL;
}

View File

@@ -331,10 +331,11 @@ void
btr_pcur_move_to_next_on_page(
/*==========================*/
btr_pcur_t* cursor);/*!< in/out: persistent cursor */
MY_ATTRIBUTE((nonnull, warn_unused_result))
/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
rec_t*
btr_pcur_move_to_prev_on_page(
/*==========================*/
btr_pcur_t* cursor);/*!< in/out: persistent cursor */

View File

@@ -171,17 +171,16 @@ btr_pcur_move_to_next_on_page(
/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
rec_t*
btr_pcur_move_to_prev_on_page(
/*==========================*/
btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
cursor->old_stored = false;
return page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
}
/*********************************************************//**

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2021, MariaDB Corporation.
Copyright (c) 2015, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -141,9 +141,6 @@ enum dberr_t {
DB_IO_PARTIAL_FAILED, /*!< Partial IO request failed */
DB_FORCED_ABORT, /*!< Transaction was forced to rollback
by a higher priority transaction */
DB_TABLE_CORRUPT, /*!< Table/clustered index is
corrupted */

View File

@@ -296,7 +296,8 @@ byte* fil_space_encrypt(
@param[in] tmp_frame Temporary buffer
@param[in] physical_size page size
@param[in,out] src_frame Page to decrypt
@return DB_SUCCESS or error */
@retval DB_SUCCESS on success
@retval DB_DECRYPTION_FAILED on error */
dberr_t
fil_space_decrypt(
uint32_t space_id,
@@ -312,7 +313,8 @@ Decrypt a page
@param[in] tmp_frame Temporary buffer used for decrypting
@param[in,out] src_frame Page to decrypt
@return decrypted page, or original not encrypted page if decryption is
not needed.*/
not needed.
@retval nullptr on failure */
byte*
fil_space_decrypt(
const fil_space_t* space,

View File

@@ -24,8 +24,7 @@ The low-level file system
Created 10/25/1995 Heikki Tuuri
*******************************************************/
#ifndef fil0fil_h
#define fil0fil_h
#pragma once
#include "fsp0types.h"
#include "mach0data.h"
@@ -1836,7 +1835,4 @@ void test_make_filepath();
@return block size */
ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset);
#include "fil0fil.inl"
#endif /* UNIV_INNOCHECKSUM */
#endif /* fil0fil_h */

View File

@@ -1,145 +0,0 @@
/*****************************************************************************
Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/fil0fil.ic
The low-level file system support functions
Created 31/03/2015 Jan Lindström
*******************************************************/
#ifndef fil0fil_ic
#define fil0fil_ic
/*******************************************************************//**
Return page type name */
UNIV_INLINE
const char*
fil_get_page_type_name(
/*===================*/
ulint page_type) /*!< in: FIL_PAGE_TYPE */
{
switch(page_type) {
case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
return "PAGE_COMPRESSED_ENRYPTED";
case FIL_PAGE_PAGE_COMPRESSED:
return "PAGE_COMPRESSED";
case FIL_PAGE_TYPE_INSTANT:
case FIL_PAGE_INDEX:
return "INDEX";
case FIL_PAGE_RTREE:
return "RTREE";
case FIL_PAGE_UNDO_LOG:
return "UNDO LOG";
case FIL_PAGE_INODE:
return "INODE";
case FIL_PAGE_IBUF_FREE_LIST:
return "IBUF_FREE_LIST";
case FIL_PAGE_TYPE_ALLOCATED:
return "ALLOCATED";
case FIL_PAGE_IBUF_BITMAP:
return "IBUF_BITMAP";
case FIL_PAGE_TYPE_SYS:
return "SYS";
case FIL_PAGE_TYPE_TRX_SYS:
return "TRX_SYS";
case FIL_PAGE_TYPE_FSP_HDR:
return "FSP_HDR";
case FIL_PAGE_TYPE_XDES:
return "XDES";
case FIL_PAGE_TYPE_BLOB:
return "BLOB";
case FIL_PAGE_TYPE_ZBLOB:
return "ZBLOB";
case FIL_PAGE_TYPE_ZBLOB2:
return "ZBLOB2";
case FIL_PAGE_TYPE_UNKNOWN:
return "OLD UNKNOWN PAGE TYPE";
default:
return "PAGE TYPE CORRUPTED";
}
}
#ifdef UNIV_DEBUG
/** Validate page type.
@param[in] space Tablespace object
@param[in] page page to validate
@return true if valid, false if not */
UNIV_INLINE
bool
fil_page_type_validate(
fil_space_t* space,
const byte* page)
{
const uint16_t page_type = fil_page_get_type(page);
if ((page_type & 1U << FIL_PAGE_COMPRESS_FCRC32_MARKER)
&& space->full_crc32()
&& space->is_compressed()) {
return true;
}
/* Validate page type */
if (!((page_type == FIL_PAGE_PAGE_COMPRESSED ||
page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED ||
page_type == FIL_PAGE_INDEX ||
page_type == FIL_PAGE_TYPE_INSTANT ||
page_type == FIL_PAGE_RTREE ||
page_type == FIL_PAGE_UNDO_LOG ||
page_type == FIL_PAGE_INODE ||
page_type == FIL_PAGE_IBUF_FREE_LIST ||
page_type == FIL_PAGE_TYPE_ALLOCATED ||
page_type == FIL_PAGE_IBUF_BITMAP ||
page_type == FIL_PAGE_TYPE_SYS ||
page_type == FIL_PAGE_TYPE_TRX_SYS ||
page_type == FIL_PAGE_TYPE_FSP_HDR ||
page_type == FIL_PAGE_TYPE_XDES ||
page_type == FIL_PAGE_TYPE_BLOB ||
page_type == FIL_PAGE_TYPE_ZBLOB ||
page_type == FIL_PAGE_TYPE_ZBLOB2 ||
page_type == FIL_PAGE_TYPE_UNKNOWN))) {
ulint space_id = mach_read_from_4(
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
ulint key_version = mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
if (space && space->full_crc32()) {
key_version = mach_read_from_4(
page + FIL_PAGE_FCRC32_KEY_VERSION);
}
/* Dump out the page info */
ib::fatal() << "Page " << space_id << ":" << offset
<< " name " << (space && space->chain.start
? space->chain.start->name : "???")
<< " page_type " << page_type
<< " key_version " << key_version
<< " lsn " << mach_read_from_8(page + FIL_PAGE_LSN)
<< " compressed_len " << mach_read_from_2(page + FIL_PAGE_DATA);
return false;
}
return true;
}
#endif /* UNIV_DEBUG */
#endif /* fil0fil_ic */

View File

@@ -337,9 +337,12 @@ rtr_get_parent_cursor(
ulint level, /*!< in: index level of buffer page */
ulint is_insert); /*!< in: whether insert operation */
MY_ATTRIBUTE((warn_unused_result))
/*************************************************************//**
Copy recs from a page to new_block of rtree. */
void
Copy recs from a page to new_block of rtree.
@return error code */
dberr_t
rtr_page_copy_rec_list_end_no_locks(
/*================================*/
buf_block_t* new_block, /*!< in: index page to copy to */
@@ -352,9 +355,12 @@ rtr_page_copy_rec_list_end_no_locks(
ulint* num_moved, /*!< out: num of rec to move */
mtr_t* mtr); /*!< in: mtr */
MY_ATTRIBUTE((warn_unused_result))
/*************************************************************//**
Copy recs till a specified rec from a page to new_block of rtree. */
void
Copy recs till a specified rec from a page to new_block of rtree.
@return error code */
dberr_t
rtr_page_copy_rec_list_start_no_locks(
/*==================================*/
buf_block_t* new_block, /*!< in: index page to copy to */

View File

@@ -120,10 +120,11 @@ void
page_cur_move_to_next(
/*==================*/
page_cur_t* cur); /*!< in/out: cursor; must not be after last */
MY_ATTRIBUTE((nonnull, warn_unused_result))
/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
rec_t*
page_cur_move_to_prev(
/*==================*/
page_cur_t* cur); /*!< in/out: cursor; not before first */

View File

@@ -168,14 +168,14 @@ page_cur_move_to_next(
/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
rec_t*
page_cur_move_to_prev(
/*==================*/
page_cur_t* cur) /*!< in/out: page cursor, not before first */
{
ut_ad(!page_cur_is_before_first(cur));
cur->rec = page_rec_get_prev(cur->rec);
return cur->rec = page_rec_get_prev(cur->rec);
}
/** Search the right position for a page cursor.

View File

@@ -669,7 +669,8 @@ page_dir_calc_reserved_space(
ulint n_recs); /*!< in: number of records */
/***************************************************************//**
Looks for the directory slot which owns the given record.
@return the directory slot number */
@return the directory slot number
@retval ULINT_UNDEFINED on corruption */
ulint
page_dir_find_owner_slot(
/*=====================*/
@@ -763,7 +764,8 @@ page_rec_get_next_non_del_marked(
const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the previous record.
@return pointer to previous record */
@return pointer to previous record
@retval nullptr on error */
UNIV_INLINE
const rec_t*
page_rec_get_prev_const(
@@ -772,13 +774,13 @@ page_rec_get_prev_const(
infimum */
/************************************************************//**
Gets the pointer to the previous record.
@return pointer to previous record */
UNIV_INLINE
rec_t*
page_rec_get_prev(
/*==============*/
rec_t* rec); /*!< in: pointer to record,
must not be page infimum */
@param rec record (not page infimum)
@return pointer to previous record
@retval nullptr on error */
inline rec_t *page_rec_get_prev(rec_t *rec)
{
return const_cast<rec_t*>(page_rec_get_prev_const(rec));
}
/************************************************************//**
true if the record is the first user record on a page.
@@ -997,7 +999,7 @@ page_copy_rec_list_start(
/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
void
dberr_t
page_delete_rec_list_end(
/*=====================*/
rec_t* rec, /*!< in: pointer to record on page */
@@ -1009,7 +1011,7 @@ page_delete_rec_list_end(
records in the end of the chain to
delete, or ULINT_UNDEFINED if not known */
mtr_t* mtr) /*!< in: mtr */
MY_ATTRIBUTE((nonnull));
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*************************************************************//**
Deletes records from page, up to the given record, NOT including
that record. Infimum and supremum records are not deleted. */

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2021, MariaDB Corporation.
Copyright (c) 2016, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -24,9 +24,6 @@ Index page routines
Created 2/2/1994 Heikki Tuuri
*******************************************************/
#ifndef page0page_ic
#define page0page_ic
#ifndef UNIV_INNOCHECKSUM
#include "rem0cmp.h"
#include "mtr0log.h"
@@ -506,7 +503,8 @@ page_rec_get_next_non_del_marked(
/************************************************************//**
Gets the pointer to the previous record.
@return pointer to previous record */
@return pointer to previous record
@retval nullptr on error */
UNIV_INLINE
const rec_t*
page_rec_get_prev_const(
@@ -528,42 +526,28 @@ page_rec_get_prev_const(
slot_no = page_dir_find_owner_slot(rec);
ut_a(slot_no != 0);
if (UNIV_UNLIKELY(!slot_no || slot_no == ULINT_UNDEFINED)) {
return nullptr;
}
slot = page_dir_get_nth_slot(page, slot_no - 1);
rec2 = page_dir_slot_get_rec(slot);
if (page_is_comp(page)) {
while (rec != rec2) {
while (rec2 && rec != rec2) {
prev_rec = rec2;
rec2 = page_rec_get_next_low(rec2, TRUE);
}
} else {
while (rec != rec2) {
while (rec2 && rec != rec2) {
prev_rec = rec2;
rec2 = page_rec_get_next_low(rec2, FALSE);
}
}
ut_a(prev_rec);
return(prev_rec);
}
/************************************************************//**
Gets the pointer to the previous record.
@return pointer to previous record */
UNIV_INLINE
rec_t*
page_rec_get_prev(
/*==============*/
rec_t* rec) /*!< in: pointer to record, must not be page
infimum */
{
return((rec_t*) page_rec_get_prev_const(rec));
}
#endif /* UNIV_INNOCHECKSUM */
/************************************************************//**
@@ -720,5 +704,3 @@ page_get_instant(const page_t* page)
return static_cast<uint16_t>(i >> 3); /* i / 8 */
}
#endif /* !UNIV_INNOCHECKSUM */
#endif

View File

@@ -1621,7 +1621,9 @@ copied:
if (UNIV_UNLIKELY(n_owned == PAGE_DIR_SLOT_MAX_N_OWNED))
{
const auto owner= page_dir_find_owner_slot(next_rec);
const ulint owner= page_dir_find_owner_slot(next_rec);
if (UNIV_UNLIKELY(owner == ULINT_UNDEFINED))
return nullptr;
page_dir_split_slot(*block,
page_dir_get_nth_slot(block->page.frame, owner));
}
@@ -2047,8 +2049,12 @@ inc_dir:
record. If the number exceeds PAGE_DIR_SLOT_MAX_N_OWNED,
we have to split the corresponding directory slot in two. */
if (UNIV_UNLIKELY(n_owned == PAGE_DIR_SLOT_MAX_N_OWNED))
page_zip_dir_split_slot(cursor->block,
page_dir_find_owner_slot(next_rec), mtr);
{
const ulint owner= page_dir_find_owner_slot(next_rec);
if (UNIV_UNLIKELY(owner == ULINT_UNDEFINED))
return nullptr;
page_zip_dir_split_slot(cursor->block, owner, mtr);
}
page_zip_write_rec(cursor->block, insert_rec, index, offsets, 1, mtr);
return insert_rec;
@@ -2144,7 +2150,6 @@ page_cur_delete_rec(
rec_t* current_rec;
rec_t* prev_rec = NULL;
rec_t* next_rec;
ulint cur_slot_no;
ulint cur_n_owned;
rec_t* rec;
@@ -2188,8 +2193,13 @@ page_cur_delete_rec(
}
/* Save to local variables some data associated with current_rec */
cur_slot_no = page_dir_find_owner_slot(current_rec);
ut_ad(cur_slot_no > 0);
ulint cur_slot_no = page_dir_find_owner_slot(current_rec);
if (UNIV_UNLIKELY(!cur_slot_no || cur_slot_no == ULINT_UNDEFINED)) {
/* Avoid crashing due to a corrupted page. */
return;
}
cur_dir_slot = page_dir_get_nth_slot(block->page.frame, cur_slot_no);
cur_n_owned = page_dir_slot_get_n_owned(cur_dir_slot);

View File

@@ -82,7 +82,8 @@ is 50 x 4 bytes = 200 bytes. */
/***************************************************************//**
Looks for the directory slot which owns the given record.
@return the directory slot number */
@return the directory slot number
@retval ULINT_UNDEFINED on corruption */
ulint
page_dir_find_owner_slot(
/*=====================*/
@@ -135,7 +136,7 @@ page_dir_find_owner_slot(
+ mach_decode_2(rec_offs_bytes));
}
ut_error;
return ULINT_UNDEFINED;
}
slot += PAGE_DIR_SLOT_SIZE;
@@ -589,7 +590,7 @@ page_copy_rec_list_end(
/* For spatial index, we need to insert recs one by one
to keep recs ordered. */
rtr_page_copy_rec_list_end_no_locks(new_block,
*err = rtr_page_copy_rec_list_end_no_locks(new_block,
block, rec, index,
heap, rec_move,
max_to_move,
@@ -719,6 +720,11 @@ page_copy_rec_list_start(
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
if (UNIV_UNLIKELY(!ret)) {
*err = DB_CORRUPTION;
return ret;
}
/* Here, "ret" may be pointing to a user record or the
predefined infimum record. */
@@ -753,10 +759,14 @@ page_copy_rec_list_start(
/* For spatial index, we need to insert recs one by one
to keep recs ordered. */
rtr_page_copy_rec_list_start_no_locks(new_block,
block, rec, index, heap,
rec_move, max_to_move,
*err = rtr_page_copy_rec_list_start_no_locks(new_block,
block, rec, index,
heap, rec_move,
max_to_move,
&num_moved, mtr);
if (*err != DB_SUCCESS) {
return nullptr;
}
} else {
while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(cur1.rec, index, offsets,
@@ -857,7 +867,7 @@ zip_reorganize:
/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
void
dberr_t
page_delete_rec_list_end(
/*=====================*/
rec_t* rec, /*!< in: pointer to record on page */
@@ -884,7 +894,7 @@ page_delete_rec_list_end(
{
ut_ad(n_recs == 0 || n_recs == ULINT_UNDEFINED);
/* Nothing to do, there are no records bigger than the page supremum. */
return;
return DB_SUCCESS;
}
if (page_rec_is_infimum(rec) ||
@@ -895,7 +905,7 @@ page_delete_rec_list_end(
{
/* We are deleting all records. */
page_create_empty(block, index, mtr);
return;
return DB_SUCCESS;
}
#if 0 // FIXME: consider deleting the last record as a special case
@@ -903,7 +913,7 @@ page_delete_rec_list_end(
{
page_cur_t cursor= { index, rec, offsets, block };
page_cur_delete_rec(&cursor, index, offsets, mtr);
return;
return DB_SUCCESS;
}
#endif
@@ -936,12 +946,16 @@ page_delete_rec_list_end(
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
return;
return DB_SUCCESS;
}
#endif
byte *prev_rec= page_rec_get_prev(rec);
if (UNIV_UNLIKELY(!prev_rec))
return DB_CORRUPTION;
byte *last_rec= page_rec_get_prev(page_get_supremum_rec(page));
if (UNIV_UNLIKELY(!last_rec))
return DB_CORRUPTION;
// FIXME: consider a special case of shrinking PAGE_HEAP_TOP
@@ -998,9 +1012,11 @@ page_delete_rec_list_end(
ut_ad(n_owned > count);
n_owned-= count;
slot_index= page_dir_find_owner_slot(owner_rec);
ut_ad(slot_index > 0);
}
if (UNIV_UNLIKELY(!slot_index || slot_index == ULINT_UNDEFINED))
return DB_CORRUPTION;
mtr->write<2,mtr_t::MAYBE_NOP>(*block, my_assume_aligned<2>
(PAGE_N_DIR_SLOTS + PAGE_HEADER + page),
slot_index + 1);
@@ -1046,7 +1062,7 @@ page_delete_rec_list_end(
mach_write_to_2(last_rec - REC_NEXT, free
? static_cast<uint16_t>(free - page_offset(last_rec))
: 0U);
return;
return DB_SUCCESS;
}
#endif
mtr->write<1,mtr_t::MAYBE_NOP>(*block, owned, new_owned);
@@ -1066,6 +1082,8 @@ page_delete_rec_list_end(
mtr->write<2>(*block, prev_rec - REC_NEXT, PAGE_OLD_SUPREMUM);
mtr->write<2>(*block, last_rec - REC_NEXT, free);
}
return DB_SUCCESS;
}
/*************************************************************//**

View File

@@ -1519,15 +1519,10 @@ inline bool IndexPurge::open() noexcept
&m_pcur, true, 0, &m_mtr) != DB_SUCCESS)
return false;
btr_pcur_move_to_next_user_rec(&m_pcur, &m_mtr);
if (rec_is_metadata(btr_pcur_get_rec(&m_pcur), *m_index))
{
if (!btr_pcur_is_on_user_rec(&m_pcur))
return false;
rec_t *rec= page_rec_get_next(btr_pcur_get_rec(&m_pcur));
if (rec_is_metadata(rec, *m_index))
/* Skip the metadata pseudo-record. */
}
else
btr_pcur_move_to_prev_on_page(&m_pcur);
btr_pcur_get_page_cur(&m_pcur)->rec= rec;
return true;
}
@@ -1570,55 +1565,10 @@ dberr_t IndexPurge::next() noexcept
return DB_END_OF_INDEX;
}
buf_block_t* block = btr_pcur_get_block(&m_pcur);
uint32_t next_page = btr_page_get_next(
block->page.frame);
/* MDEV-13542 FIXME: Make these checks part of
btr_pcur_move_to_next_page(), and introduce a
return status that will be checked in all callers! */
switch (next_page) {
default:
if (next_page != block->page.id().page_no()) {
break;
if (dberr_t err = btr_pcur_move_to_next_page(&m_pcur,
&m_mtr)) {
return err;
}
/* MDEV-20931 FIXME: Check that
next_page is within the tablespace
bounds! Also check that it is not a
change buffer bitmap page. */
/* fall through */
case 0:
case 1:
case FIL_NULL:
return DB_CORRUPTION;
}
dict_index_t* index = m_pcur.btr_cur.index;
buf_block_t* next_block = btr_block_get(
*index, next_page, BTR_MODIFY_LEAF, false,
&m_mtr);
if (UNIV_UNLIKELY(!next_block
|| !fil_page_index_page_check(
next_block->page.frame)
|| !!dict_index_is_spatial(index)
!= (fil_page_get_type(
next_block->page.frame)
== FIL_PAGE_RTREE)
|| page_is_comp(next_block->page.frame)
!= page_is_comp(block->page.frame)
|| btr_page_get_prev(
next_block->page.frame)
!= block->page.id().page_no())) {
return DB_CORRUPTION;
}
btr_leaf_page_release(block, BTR_MODIFY_LEAF, &m_mtr);
page_cur_set_before_first(next_block,
&m_pcur.btr_cur.page_cur);
ut_d(page_check_dir(next_block->page.frame));
} else {
btr_pcur_move_to_next_on_page(&m_pcur);
}
@@ -2335,11 +2285,11 @@ row_import_set_sys_max_row_id(
if (btr_pcur_open_at_index_side(false, index, BTR_SEARCH_LEAF,
&pcur, true, 0, &mtr) == DB_SUCCESS) {
btr_pcur_move_to_prev_on_page(&pcur);
rec = btr_pcur_get_rec(&pcur);
rec = btr_pcur_move_to_prev_on_page(&pcur);
/* Check for empty table. */
if (page_rec_is_infimum(rec)) {
if (!rec) {
/* The table is corrupted. */
} else if (page_rec_is_infimum(rec)) {
/* The table is empty. */
} else if (rec_is_metadata(rec, *index)) {
/* The clustered index contains the metadata

View File

@@ -139,7 +139,10 @@ public:
if (log_sys.check_flush_or_checkpoint()) {
if (mtr_started) {
btr_pcur_move_to_prev_on_page(pcur);
if (!btr_pcur_move_to_prev_on_page(pcur)) {
error = DB_CORRUPTION;
break;
}
btr_pcur_store_position(pcur, scan_mtr);
scan_mtr->commit();
mtr_started = false;
@@ -2010,14 +2013,27 @@ row_merge_read_clustered_index(
err_exit:
trx->error_key_num = 0;
goto func_exit;
}
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
if (rec_is_metadata(btr_pcur_get_rec(&pcur), *clust_index)) {
ut_ad(btr_pcur_is_on_user_rec(&pcur));
/* Skip the metadata pseudo-record. */
} else {
ut_ad(!clust_index->is_instant());
btr_pcur_move_to_prev_on_page(&pcur);
rec_t* rec = page_rec_get_next(btr_pcur_get_rec(&pcur));
if (!rec) {
corrupted_metadata:
err = DB_CORRUPTION;
goto err_exit;
}
if (rec_get_info_bits(rec, page_rec_is_comp(rec))
& REC_INFO_MIN_REC_FLAG) {
if (!clust_index->is_instant()) {
goto corrupted_metadata;
}
if (page_rec_is_comp(rec)
&& rec_get_status(rec) != REC_STATUS_INSTANT) {
goto corrupted_metadata;
}
/* Skip the metadata pseudo-record. */
btr_pcur_get_page_cur(&pcur)->rec = rec;
} else if (clust_index->is_instant()) {
goto corrupted_metadata;
}
}
/* Check if the table is supposed to be empty for our read view.
@@ -2157,13 +2173,16 @@ err_exit:
/* Store the cursor position on the last user
record on the page. */
btr_pcur_move_to_prev_on_page(&pcur);
if (!btr_pcur_move_to_prev_on_page(&pcur)) {
goto corrupted_index;
}
/* Leaf pages must never be empty, unless
this is the only page in the index tree. */
ut_ad(btr_pcur_is_on_user_rec(&pcur)
|| btr_pcur_get_block(
&pcur)->page.id().page_no()
== clust_index->page);
if (!btr_pcur_is_on_user_rec(&pcur)
&& btr_pcur_get_block(&pcur)->page.id()
.page_no() != clust_index->page) {
goto corrupted_index;
}
btr_pcur_store_position(&pcur, &mtr);
mtr.commit();
@@ -2666,8 +2685,10 @@ write_buffers:
we must reread it on the next
loop iteration. */
if (mtr_started) {
btr_pcur_move_to_prev_on_page(
&pcur);
if (!btr_pcur_move_to_prev_on_page(&pcur)) {
err = DB_CORRUPTION;
goto func_exit;
}
btr_pcur_store_position(
&pcur, &mtr);

View File

@@ -4715,6 +4715,15 @@ wait_table_again:
pcur, moves_up, &mtr);
if (UNIV_UNLIKELY(need_to_process)) {
if (UNIV_UNLIKELY(!btr_pcur_get_rec(pcur))) {
mtr.commit();
trx->op_info = "";
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return DB_CORRUPTION;
}
if (UNIV_UNLIKELY(prebuilt->row_read_type
== ROW_READ_DID_SEMI_CONSISTENT)) {
/* We did a semi-consistent read,
@@ -4732,7 +4741,7 @@ wait_table_again:
pessimistic locking read, the record
cannot be skipped. */
goto next_rec;
goto next_rec_after_check;
}
} else if (dtuple_get_n_fields(search_tuple) > 0) {
@@ -5727,6 +5736,7 @@ next_rec:
== ROW_READ_DID_SEMI_CONSISTENT)) {
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
}
next_rec_after_check:
did_semi_consistent_read = false;
prebuilt->new_rec_locks = 0;
vrow = NULL;
@@ -5752,7 +5762,6 @@ next_rec:
/* No need to do store restore for R-tree */
mtr.commit();
mtr.start();
mtr_extra_clust_savepoint = 0;
} else if (mtr_extra_clust_savepoint) {
/* We must release any clustered index latches
if we are moving to the next non-clustered
@@ -5760,9 +5769,10 @@ next_rec:
order if we would access a different clustered
index page right away without releasing the previous. */
mtr.rollback_to_savepoint(mtr_extra_clust_savepoint);
mtr_extra_clust_savepoint = 0;
}
mtr_extra_clust_savepoint = 0;
if (moves_up) {
if (UNIV_UNLIKELY(spatial_search)) {
if (rtr_pcur_move_to_next(
@@ -5792,6 +5802,10 @@ next_rec:
if (btr_pcur_move_to_prev(pcur, &mtr)) {
goto rec_loop;
}
if (UNIV_UNLIKELY(!btr_pcur_get_rec(pcur))) {
err = DB_CORRUPTION;
goto normal_return;
}
}
not_moved:

View File

@@ -449,9 +449,6 @@ ut_strerr(
return("Table is compressed or encrypted but uncompress or decrypt failed.");
case DB_IO_PARTIAL_FAILED:
return("Partial IO failed");
case DB_FORCED_ABORT:
return("Transaction aborted by another higher priority "
"transaction");
case DB_COMPUTE_VALUE_FAILED:
return("Compute generated column failed");
case DB_NO_FK_ON_S_BASE_COL:

Some files were not shown because too many files have changed in this diff Show More