summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-11-17 13:55:54 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-11-17 13:55:54 +0200
commit9962cda52722b77c2a7e0314bbaa2e4f963f55c1 (patch)
tree576d56bc2ddf7f644ce56c4a1ef27ca59cc42290
parent7ea12742d30be7b56120f1bf66d91f777b1da450 (diff)
parented0a224b3d42423699d977c338e3da05fccafaf2 (diff)
downloadmariadb-git-9962cda52722b77c2a7e0314bbaa2e4f963f55c1.tar.gz
Merge 10.2 into 10.3
-rw-r--r--cmake/install_macros.cmake20
-rw-r--r--mysql-test/main/cte_nonrecursive.result50
-rw-r--r--mysql-test/main/cte_nonrecursive.test36
-rw-r--r--mysql-test/suite/encryption/r/encryption_key_corruption.result13
-rw-r--r--mysql-test/suite/encryption/t/encryption_key_corruption.combinations6
-rw-r--r--mysql-test/suite/encryption/t/encryption_key_corruption.opt1
-rw-r--r--mysql-test/suite/encryption/t/encryption_key_corruption.test44
-rw-r--r--sql/sql_cte.cc57
-rw-r--r--storage/innobase/fil/fil0crypt.cc42
-rw-r--r--storage/innobase/include/fil0crypt.h8
-rw-r--r--storage/innobase/row/row0import.cc21
-rw-r--r--win/upgrade_wizard/upgradeDlg.cpp2
12 files changed, 223 insertions, 77 deletions
diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake
index 6b0e945abe4..ee1a39066b1 100644
--- a/cmake/install_macros.cmake
+++ b/cmake/install_macros.cmake
@@ -184,16 +184,20 @@ IF(WIN32)
SET(SIGNTOOL_PARAMETERS
/a /t http://timestamp.globalsign.com/?signature=sha2
CACHE STRING "parameters for signtool (list)")
- FIND_PROGRAM(SIGNTOOL_EXECUTABLE signtool
- PATHS "$ENV{ProgramFiles}/Microsoft SDKs/Windows/v7.0A/bin"
- "$ENV{ProgramFiles}/Windows Kits/8.0/bin/x86"
- "$ENV{ProgramFiles}/Windows Kits/8.1/bin/x86"
- )
IF(NOT SIGNTOOL_EXECUTABLE)
- MESSAGE(FATAL_ERROR
- "signtool is not found. Signing executables not possible")
+ FILE(GLOB path_list
+ "$ENV{ProgramFiles} (x86)/Windows Kits/*/bin/*/x64"
+ "$ENV{ProgramFiles} (x86)/Windows Kits/*/App Certification Kit"
+ )
+ FIND_PROGRAM(SIGNTOOL_EXECUTABLE signtool
+ PATHS ${path_list}
+ )
+ IF(NOT SIGNTOOL_EXECUTABLE)
+ MESSAGE(FATAL_ERROR
+ "signtool is not found. Signing executables not possible")
+ ENDIF()
+ MARK_AS_ADVANCED(SIGNTOOL_EXECUTABLE SIGNTOOL_PARAMETERS)
ENDIF()
- MARK_AS_ADVANCED(SIGNTOOL_EXECUTABLE SIGNTOOL_PARAMETERS)
ENDIF()
ENDIF()
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 2c3555755cd..eacc742b544 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -2086,6 +2086,56 @@ a b a b
1 3 1 3
drop procedure sp;
drop table t1;
+#
+# MDEV-26825: query with two usage of CTE that refers to another CTE
+# with stored function using a base table.
+#
+create table t1 (id int primary key);
+insert into t1 values
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+create function f(in_id int) returns integer
+return (select id from t1 where t1.id = in_id);
+with c1 as (select id from t1 where f(id)=id group by id),
+c2 as (select id from c1 as pt group by id)
+select id from c2 as s1 union select id from c2 as s2;
+id
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+with c1 as (select id from t1 as r where f(id)=id group by id),
+c2 as (select id from c1 as pt group by id)
+select id from c2 as s1 union select id from c2 as s2;
+id
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+create function g() returns int return (select count(*) from t1);
+create procedure sp1()
+with c1 as (select id from t1 a where g() > 10),
+c2 as (select id from c1)
+select id from c2 as s1 union select id from c2 as s2;
+call sp1();
+id
+call sp1();
+id
+drop procedure sp1;
+drop function g;
+drop function f;
+drop table t1;
# End of 10.2 tests
#
# MDEV-21673: several references to CTE that uses
diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test
index dfb14e65f2c..c748d3e70e0 100644
--- a/mysql-test/main/cte_nonrecursive.test
+++ b/mysql-test/main/cte_nonrecursive.test
@@ -1542,6 +1542,42 @@ call sp();
drop procedure sp;
drop table t1;
+--echo #
+--echo # MDEV-26825: query with two usage of CTE that refers to another CTE
+--echo # with stored function using a base table.
+--echo #
+
+create table t1 (id int primary key);
+insert into t1 values
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+
+create function f(in_id int) returns integer
+return (select id from t1 where t1.id = in_id);
+
+with c1 as (select id from t1 where f(id)=id group by id),
+ c2 as (select id from c1 as pt group by id)
+select id from c2 as s1 union select id from c2 as s2;
+
+with c1 as (select id from t1 as r where f(id)=id group by id),
+ c2 as (select id from c1 as pt group by id)
+select id from c2 as s1 union select id from c2 as s2;
+
+create function g() returns int return (select count(*) from t1);
+create procedure sp1()
+
+with c1 as (select id from t1 a where g() > 10),
+ c2 as (select id from c1)
+select id from c2 as s1 union select id from c2 as s2;
+
+call sp1();
+call sp1();
+
+drop procedure sp1;
+drop function g;
+
+drop function f;
+drop table t1;
+
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/suite/encryption/r/encryption_key_corruption.result b/mysql-test/suite/encryption/r/encryption_key_corruption.result
new file mode 100644
index 00000000000..f467207d0f7
--- /dev/null
+++ b/mysql-test/suite/encryption/r/encryption_key_corruption.result
@@ -0,0 +1,13 @@
+call mtr.add_suppression("InnoDB: .*: Page 0 at offset 0 looks corrupted");
+call mtr.add_suppression("Index for table 'dst' is corrupt; try to repair it");
+call mtr.add_suppression("Page for tablespace .* is index page with id .* but that index is not found from configuration file");
+CREATE TABLE src (pk INT PRIMARY KEY, value INT) ENGINE=INNODB;
+INSERT INTO src VALUES (1, 1), (2, 2), (3, 3);
+FLUSH TABLES src FOR EXPORT;
+UNLOCK TABLES;
+DROP TABLE src;
+CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB;
+ALTER TABLE dst DISCARD TABLESPACE;
+ALTER TABLE dst IMPORT TABLESPACE;
+ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`dst` : Data structure corruption
+DROP TABLE dst;
diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.combinations b/mysql-test/suite/encryption/t/encryption_key_corruption.combinations
new file mode 100644
index 00000000000..ec77ac17760
--- /dev/null
+++ b/mysql-test/suite/encryption/t/encryption_key_corruption.combinations
@@ -0,0 +1,6 @@
+[crc32]
+innodb-checksum-algorithm=crc32
+[none]
+innodb-checksum-algorithm=none
+[innodb]
+innodb-checksum-algorithm=innodb
diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.opt b/mysql-test/suite/encryption/t/encryption_key_corruption.opt
new file mode 100644
index 00000000000..682d06d5732
--- /dev/null
+++ b/mysql-test/suite/encryption/t/encryption_key_corruption.opt
@@ -0,0 +1 @@
+--innodb-encrypt-tables=1
diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.test b/mysql-test/suite/encryption/t/encryption_key_corruption.test
new file mode 100644
index 00000000000..defb2af741e
--- /dev/null
+++ b/mysql-test/suite/encryption/t/encryption_key_corruption.test
@@ -0,0 +1,44 @@
+--source include/have_innodb.inc
+--source include/have_example_key_management_plugin.inc
+
+call mtr.add_suppression("InnoDB: .*: Page 0 at offset 0 looks corrupted");
+call mtr.add_suppression("Index for table 'dst' is corrupt; try to repair it");
+call mtr.add_suppression("Page for tablespace .* is index page with id .* but that index is not found from configuration file");
+
+let MYSQLD_DATADIR = `SELECT @@datadir`;
+
+
+CREATE TABLE src (pk INT PRIMARY KEY, value INT) ENGINE=INNODB;
+INSERT INTO src VALUES (1, 1), (2, 2), (3, 3);
+
+FLUSH TABLES src FOR EXPORT;
+
+--copy_file $MYSQLD_DATADIR/test/src.ibd $MYSQLD_DATADIR/test/tmp.ibd
+--copy_file $MYSQLD_DATADIR/test/src.cfg $MYSQLD_DATADIR/test/tmp.cfg
+
+perl;
+use strict;
+die unless open(FILE, "+<$ENV{MYSQLD_DATADIR}/test/tmp.ibd");
+binmode FILE;
+die unless seek(FILE, 3 * 16384 + 26, 0);
+print FILE pack("N", 0x00000000);
+close(FILE);
+EOF
+
+UNLOCK TABLES;
+
+DROP TABLE src;
+
+CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB;
+ALTER TABLE dst DISCARD TABLESPACE;
+
+--copy_file $MYSQLD_DATADIR/test/tmp.ibd $MYSQLD_DATADIR/test/dst.ibd
+--copy_file $MYSQLD_DATADIR/test/tmp.cfg $MYSQLD_DATADIR/test/dst.cfg
+
+--error ER_INTERNAL_ERROR
+ALTER TABLE dst IMPORT TABLESPACE;
+
+DROP TABLE dst;
+
+--remove_file $MYSQLD_DATADIR/test/tmp.ibd
+--remove_file $MYSQLD_DATADIR/test/tmp.cfg
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index fa7011b7554..9acdf2278ac 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -1036,6 +1036,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
lex_start(thd);
lex->clone_spec_offset= unparsed_spec_offset;
lex->with_cte_resolution= true;
+ /*
+ There's no need to add SPs/SFs referenced in the clone to the global
+ list of the SPs/SFs used in the query as they were added when the first
+ reference to the cloned CTE was parsed. Yet the recursive call of the
+ parser must to know that they were already included into the list.
+ */
+ lex->sroutines= old_lex->sroutines;
+ lex->sroutines_list_own_last= old_lex->sroutines_list_own_last;
+ lex->sroutines_list_own_elements= old_lex->sroutines_list_own_elements;
/*
The specification of a CTE is to be parsed as a regular query.
@@ -1082,6 +1091,29 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
goto err;
/*
+ The unit of the specification that just has been parsed is included
+ as a slave of the select that contained in its from list the table
+ reference for which the unit has been created.
+ */
+ lex->unit.include_down(with_table->select_lex);
+ lex->unit.set_slave(with_select);
+ lex->unit.cloned_from= spec;
+
+ /*
+ Now all references to the CTE defined outside of the cloned specification
+ has to be resolved. Additionally if old_lex->only_cte_resolution == false
+ for the table references that has not been resolved requests for mdl_locks
+ has to be set.
+ */
+ lex->only_cte_resolution= old_lex->only_cte_resolution;
+ if (lex->resolve_references_to_cte(lex->query_tables,
+ lex->query_tables_last))
+ {
+ res= NULL;
+ goto err;
+ }
+
+ /*
The global chain of TABLE_LIST objects created for the specification that
just has been parsed is added to such chain that contains the reference
to the CTE whose specification is parsed right after the TABLE_LIST object
@@ -1105,32 +1137,11 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
old_lex->query_tables_last= lex->query_tables_last;
}
}
+ old_lex->sroutines_list_own_last= lex->sroutines_list_own_last;
+ old_lex->sroutines_list_own_elements= lex->sroutines_list_own_elements;
res= &lex->unit;
res->with_element= this;
- /*
- The unit of the specification that just has been parsed is included
- as a slave of the select that contained in its from list the table
- reference for which the unit has been created.
- */
- lex->unit.include_down(with_table->select_lex);
- lex->unit.set_slave(with_select);
- lex->unit.cloned_from= spec;
-
- /*
- Now all references to the CTE defined outside of the cloned specification
- has to be resolved. Additionally if old_lex->only_cte_resolution == false
- for the table references that has not been resolved requests for mdl_locks
- has to be set.
- */
- lex->only_cte_resolution= old_lex->only_cte_resolution;
- if (lex->resolve_references_to_cte(lex->query_tables,
- lex->query_tables_last))
- {
- res= NULL;
- goto err;
- }
-
last_clone_select= lex->all_selects_list;
while (last_clone_select->next_select_in_list())
last_clone_select= last_clone_select->next_select_in_list();
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index f63b75a0e44..83bd816457c 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -667,16 +667,14 @@ fil_space_encrypt(
@param[in] tmp_frame Temporary buffer
@param[in] page_size Page size
@param[in,out] src_frame Page to decrypt
-@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
-@return true if page decrypted, false if not.*/
+@return DB_SUCCESS or error */
UNIV_INTERN
-bool
+dberr_t
fil_space_decrypt(
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
const page_size_t& page_size,
- byte* src_frame,
- dberr_t* err)
+ byte* src_frame)
{
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
@@ -685,12 +683,7 @@ fil_space_decrypt(
uint space = mach_read_from_4(src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
- *err = DB_SUCCESS;
-
- if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
- return false;
- }
-
+ ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
ut_a(crypt_data != NULL && crypt_data->is_encrypted());
/* read space & lsn */
@@ -721,8 +714,7 @@ fil_space_decrypt(
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
if (rc == -1) {
- *err = DB_DECRYPTION_FAILED;
- return false;
+ return DB_DECRYPTION_FAILED;
}
ib::fatal() << "Unable to decrypt data-block "
@@ -747,7 +739,7 @@ fil_space_decrypt(
srv_stats.pages_decrypted.inc();
- return true; /* page was decrypted */
+ return DB_SUCCESS; /* page was decrypted */
}
/**
@@ -764,27 +756,21 @@ fil_space_decrypt(
byte* tmp_frame,
byte* src_frame)
{
- dberr_t err = DB_SUCCESS;
- byte* res = NULL;
const page_size_t page_size(space->flags);
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
ut_ad(space->pending_io());
- bool encrypted = fil_space_decrypt(space->crypt_data, tmp_frame,
- page_size, src_frame, &err);
-
- if (err == DB_SUCCESS) {
- if (encrypted) {
- /* Copy the decrypted page back to page buffer, not
- really any other options. */
- memcpy(src_frame, tmp_frame, page_size.physical());
- }
-
- res = src_frame;
+ if (DB_SUCCESS != fil_space_decrypt(space->crypt_data, tmp_frame,
+ page_size, src_frame)) {
+ return NULL;
}
- return res;
+ /* Copy the decrypted page back to page buffer, not
+ really any other options. */
+ memcpy(src_frame, tmp_frame, page_size.physical());
+
+ return src_frame;
}
/******************************************************************
diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h
index c7f74b743aa..620c4941972 100644
--- a/storage/innobase/include/fil0crypt.h
+++ b/storage/innobase/include/fil0crypt.h
@@ -357,16 +357,14 @@ Decrypt a page.
@param[in] tmp_frame Temporary buffer
@param[in] page_size Page size
@param[in,out] src_frame Page to decrypt
-@param[out] err DB_SUCCESS or error
-@return true if page decrypted, false if not.*/
+@return DB_SUCCESS or error */
UNIV_INTERN
-bool
+dberr_t
fil_space_decrypt(
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
const page_size_t& page_size,
- byte* src_frame,
- dberr_t* err);
+ byte* src_frame);
/******************************************************************
Decrypt a page
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 7751ac12dd8..cc570256ad0 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3499,9 +3499,12 @@ page_corrupted:
if (!fil_space_verify_crypt_checksum(readptr, get_page_size()))
goto page_corrupted;
- if (!fil_space_decrypt(iter.crypt_data, readptr,
- get_page_size(), readptr, &err) ||
- err != DB_SUCCESS)
+ if (ENCRYPTION_KEY_NOT_ENCRYPTED ==
+ mach_read_from_4(readptr + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION))
+ goto page_corrupted;
+
+ if ((err = fil_space_decrypt(iter.crypt_data, readptr,
+ get_page_size(), readptr)))
goto func_exit;
}
@@ -3644,7 +3647,6 @@ page_corrupted:
} else if (!mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ src)) {
-not_encrypted:
if (block->page.id.page_no() == 0
&& block->page.zip.data) {
block->page.zip.data = src;
@@ -3663,18 +3665,13 @@ not_encrypted:
goto page_corrupted;
}
- decrypted = fil_space_decrypt(
+ if ((err = fil_space_decrypt(
iter.crypt_data, dst,
- callback.get_page_size(), src, &err);
-
- if (err != DB_SUCCESS) {
+ callback.get_page_size(), src))) {
goto func_exit;
}
- if (!decrypted) {
- goto not_encrypted;
- }
-
+ decrypted = true;
updated = true;
}
diff --git a/win/upgrade_wizard/upgradeDlg.cpp b/win/upgrade_wizard/upgradeDlg.cpp
index a1b6c279fa6..80f7c18f757 100644
--- a/win/upgrade_wizard/upgradeDlg.cpp
+++ b/win/upgrade_wizard/upgradeDlg.cpp
@@ -448,7 +448,7 @@ void CUpgradeDlg::UpgradeOneService(const string& servicename)
output_line.push_back(pipeReadBuf[0]);
}
}
- CloseHandle(hPipeWrite);
+ CloseHandle(hPipeRead);
if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
ErrorExit("WaitForSingleObject failed");