Commit 9962cda5 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.2 into 10.3

parents 7ea12742 ed0a224b
...@@ -184,16 +184,20 @@ IF(WIN32) ...@@ -184,16 +184,20 @@ IF(WIN32)
SET(SIGNTOOL_PARAMETERS SET(SIGNTOOL_PARAMETERS
/a /t http://timestamp.globalsign.com/?signature=sha2 /a /t http://timestamp.globalsign.com/?signature=sha2
CACHE STRING "parameters for signtool (list)") 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) IF(NOT SIGNTOOL_EXECUTABLE)
MESSAGE(FATAL_ERROR FILE(GLOB path_list
"signtool is not found. Signing executables not possible") "$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() ENDIF()
MARK_AS_ADVANCED(SIGNTOOL_EXECUTABLE SIGNTOOL_PARAMETERS)
ENDIF() ENDIF()
ENDIF() ENDIF()
......
...@@ -2086,6 +2086,56 @@ a b a b ...@@ -2086,6 +2086,56 @@ a b a b
1 3 1 3 1 3 1 3
drop procedure sp; drop procedure sp;
drop table t1; 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 # End of 10.2 tests
# #
# MDEV-21673: several references to CTE that uses # MDEV-21673: several references to CTE that uses
......
...@@ -1542,6 +1542,42 @@ call sp(); ...@@ -1542,6 +1542,42 @@ call sp();
drop procedure sp; drop procedure sp;
drop table t1; 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 # End of 10.2 tests
--echo # --echo #
......
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;
[crc32]
innodb-checksum-algorithm=crc32
[none]
innodb-checksum-algorithm=none
[innodb]
innodb-checksum-algorithm=innodb
--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
...@@ -1036,6 +1036,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, ...@@ -1036,6 +1036,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
lex_start(thd); lex_start(thd);
lex->clone_spec_offset= unparsed_spec_offset; lex->clone_spec_offset= unparsed_spec_offset;
lex->with_cte_resolution= true; 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. 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, ...@@ -1081,6 +1090,29 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
if (parse_status) if (parse_status)
goto err; 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 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 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, ...@@ -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->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= &lex->unit;
res->with_element= this; 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; last_clone_select= lex->all_selects_list;
while (last_clone_select->next_select_in_list()) while (last_clone_select->next_select_in_list())
last_clone_select= last_clone_select->next_select_in_list(); last_clone_select= last_clone_select->next_select_in_list();
......
...@@ -667,16 +667,14 @@ fil_space_encrypt( ...@@ -667,16 +667,14 @@ fil_space_encrypt(
@param[in] tmp_frame Temporary buffer @param[in] tmp_frame Temporary buffer
@param[in] page_size Page size @param[in] page_size Page size
@param[in,out] src_frame Page to decrypt @param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED @return DB_SUCCESS or error */
@return true if page decrypted, false if not.*/
UNIV_INTERN UNIV_INTERN
bool dberr_t
fil_space_decrypt( fil_space_decrypt(
fil_space_crypt_t* crypt_data, fil_space_crypt_t* crypt_data,
byte* tmp_frame, byte* tmp_frame,
const page_size_t& page_size, const page_size_t& page_size,
byte* src_frame, byte* src_frame)
dberr_t* err)
{ {
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); 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); uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
...@@ -685,12 +683,7 @@ fil_space_decrypt( ...@@ -685,12 +683,7 @@ fil_space_decrypt(
uint space = mach_read_from_4(src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); 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); ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
*err = DB_SUCCESS; ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
return false;
}
ut_a(crypt_data != NULL && crypt_data->is_encrypted()); ut_a(crypt_data != NULL && crypt_data->is_encrypted());
/* read space & lsn */ /* read space & lsn */
...@@ -721,8 +714,7 @@ fil_space_decrypt( ...@@ -721,8 +714,7 @@ fil_space_decrypt(
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
if (rc == -1) { if (rc == -1) {
*err = DB_DECRYPTION_FAILED; return DB_DECRYPTION_FAILED;
return false;
} }
ib::fatal() << "Unable to decrypt data-block " ib::fatal() << "Unable to decrypt data-block "
...@@ -747,7 +739,7 @@ fil_space_decrypt( ...@@ -747,7 +739,7 @@ fil_space_decrypt(
srv_stats.pages_decrypted.inc(); srv_stats.pages_decrypted.inc();
return true; /* page was decrypted */ return DB_SUCCESS; /* page was decrypted */
} }
/** /**
...@@ -764,27 +756,21 @@ fil_space_decrypt( ...@@ -764,27 +756,21 @@ fil_space_decrypt(
byte* tmp_frame, byte* tmp_frame,
byte* src_frame) byte* src_frame)
{ {
dberr_t err = DB_SUCCESS;
byte* res = NULL;
const page_size_t page_size(space->flags); const page_size_t page_size(space->flags);
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted()); ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
ut_ad(space->pending_io()); ut_ad(space->pending_io());
bool encrypted = fil_space_decrypt(space->crypt_data, tmp_frame, if (DB_SUCCESS != fil_space_decrypt(space->crypt_data, tmp_frame,
page_size, src_frame, &err); page_size, src_frame)) {
return NULL;
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;
} }
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;
} }
/****************************************************************** /******************************************************************
......
...@@ -357,16 +357,14 @@ Decrypt a page. ...@@ -357,16 +357,14 @@ Decrypt a page.
@param[in] tmp_frame Temporary buffer @param[in] tmp_frame Temporary buffer
@param[in] page_size Page size @param[in] page_size Page size
@param[in,out] src_frame Page to decrypt @param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or error @return DB_SUCCESS or error */
@return true if page decrypted, false if not.*/
UNIV_INTERN UNIV_INTERN
bool dberr_t
fil_space_decrypt( fil_space_decrypt(
fil_space_crypt_t* crypt_data, fil_space_crypt_t* crypt_data,
byte* tmp_frame, byte* tmp_frame,
const page_size_t& page_size, const page_size_t& page_size,
byte* src_frame, byte* src_frame);
dberr_t* err);
/****************************************************************** /******************************************************************
Decrypt a page Decrypt a page
......
...@@ -3499,9 +3499,12 @@ dberr_t FetchIndexRootPages::run(const fil_iterator_t& iter, ...@@ -3499,9 +3499,12 @@ dberr_t FetchIndexRootPages::run(const fil_iterator_t& iter,
if (!fil_space_verify_crypt_checksum(readptr, get_page_size())) if (!fil_space_verify_crypt_checksum(readptr, get_page_size()))
goto page_corrupted; goto page_corrupted;
if (!fil_space_decrypt(iter.crypt_data, readptr, if (ENCRYPTION_KEY_NOT_ENCRYPTED ==
get_page_size(), readptr, &err) || mach_read_from_4(readptr + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION))
err != DB_SUCCESS) goto page_corrupted;
if ((err = fil_space_decrypt(iter.crypt_data, readptr,
get_page_size(), readptr)))
goto func_exit; goto func_exit;
} }
...@@ -3644,7 +3647,6 @@ static dberr_t fil_iterate( ...@@ -3644,7 +3647,6 @@ static dberr_t fil_iterate(
} else if (!mach_read_from_4( } else if (!mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ src)) { + src)) {
not_encrypted:
if (block->page.id.page_no() == 0 if (block->page.id.page_no() == 0
&& block->page.zip.data) { && block->page.zip.data) {
block->page.zip.data = src; block->page.zip.data = src;
...@@ -3663,18 +3665,13 @@ static dberr_t fil_iterate( ...@@ -3663,18 +3665,13 @@ static dberr_t fil_iterate(
goto page_corrupted; goto page_corrupted;
} }
decrypted = fil_space_decrypt( if ((err = fil_space_decrypt(
iter.crypt_data, dst, iter.crypt_data, dst,
callback.get_page_size(), src, &err); callback.get_page_size(), src))) {
if (err != DB_SUCCESS) {
goto func_exit; goto func_exit;
} }
if (!decrypted) { decrypted = true;
goto not_encrypted;
}
updated = true; updated = true;
} }
......
...@@ -448,7 +448,7 @@ void CUpgradeDlg::UpgradeOneService(const string& servicename) ...@@ -448,7 +448,7 @@ void CUpgradeDlg::UpgradeOneService(const string& servicename)
output_line.push_back(pipeReadBuf[0]); output_line.push_back(pipeReadBuf[0]);
} }
} }
CloseHandle(hPipeWrite); CloseHandle(hPipeRead);
if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
ErrorExit("WaitForSingleObject failed"); ErrorExit("WaitForSingleObject failed");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment