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. @@ -1081,6 +1090,29 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, if (parse_status) 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 @@ -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");