Commit 70e788b1 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.3 into 10.4

parents 878f7e38 9962cda5
......@@ -183,16 +183,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()
......
......@@ -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
......
......@@ -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 #
......
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: Index for table 'dst' is corrupt; try to repair it
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_NOT_KEYFILE
ALTER TABLE dst IMPORT TABLESPACE;
DROP TABLE dst;
--remove_file $MYSQLD_DATADIR/test/tmp.ibd
--remove_file $MYSQLD_DATADIR/test/tmp.cfg
......@@ -1047,6 +1047,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.
......@@ -1091,6 +1100,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
......@@ -1115,32 +1147,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();
......
......@@ -767,24 +767,19 @@ fil_space_encrypt(
@param[in] crypt_data crypt_data
@param[in] tmp_frame Temporary buffer
@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.*/
static bool fil_space_decrypt_full_crc32(
@return DB_SUCCESS or error */
static dberr_t fil_space_decrypt_full_crc32(
ulint space,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
byte* src_frame,
dberr_t* err)
byte* src_frame)
{
uint key_version = mach_read_from_4(
src_frame + FIL_PAGE_FCRC32_KEY_VERSION);
lsn_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
uint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET);
*err = DB_SUCCESS;
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
return false;
}
ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
ut_ad(crypt_data);
ut_ad(crypt_data->is_encrypted());
......@@ -798,9 +793,7 @@ static bool fil_space_decrypt_full_crc32(
bool corrupted = false;
uint size = buf_page_full_crc32_size(src_frame, NULL, &corrupted);
if (UNIV_UNLIKELY(corrupted)) {
fail:
*err = DB_DECRYPTION_FAILED;
return false;
return DB_DECRYPTION_FAILED;
}
uint srclen = size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
......@@ -812,7 +805,7 @@ static bool fil_space_decrypt_full_crc32(
if (rc != MY_AES_OK || dstlen != srclen) {
if (rc == -1) {
goto fail;
return DB_DECRYPTION_FAILED;
}
ib::fatal() << "Unable to decrypt data-block "
......@@ -829,7 +822,7 @@ static bool fil_space_decrypt_full_crc32(
srv_stats.pages_decrypted.inc();
return true; /* page was decrypted */
return DB_SUCCESS; /* page was decrypted */
}
/** Decrypt a page for non full checksum format.
......@@ -837,14 +830,12 @@ static bool fil_space_decrypt_full_crc32(
@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 true if page decrypted, false if not.*/
static bool fil_space_decrypt_for_non_full_checksum(
@return DB_SUCCESS or error */
static dberr_t fil_space_decrypt_for_non_full_checksum(
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_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(
......@@ -856,12 +847,7 @@ static bool 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);
*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 */
......@@ -891,8 +877,7 @@ static bool fil_space_decrypt_for_non_full_checksum(
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 "
......@@ -917,7 +902,7 @@ static bool fil_space_decrypt_for_non_full_checksum(
srv_stats.pages_decrypted.inc();
return true; /* page was decrypted */
return DB_SUCCESS; /* page was decrypted */
}
/** Decrypt a page.
......@@ -928,26 +913,25 @@ static bool fil_space_decrypt_for_non_full_checksum(
@param[in] fsp_flags Tablespace flags
@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(
ulint space_id,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_size,
ulint fsp_flags,
byte* src_frame,
dberr_t* err)
byte* src_frame)
{
if (fil_space_t::full_crc32(fsp_flags)) {
return fil_space_decrypt_full_crc32(
space_id, crypt_data, tmp_frame, src_frame, err);
space_id, crypt_data, tmp_frame, src_frame);
}
return fil_space_decrypt_for_non_full_checksum(crypt_data, tmp_frame,
physical_size, src_frame,
err);
physical_size,
src_frame);
}
/**
......@@ -964,29 +948,22 @@ fil_space_decrypt(
byte* tmp_frame,
byte* src_frame)
{
dberr_t err = DB_SUCCESS;
byte* res = NULL;
const ulint physical_size = space->physical_size();
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
ut_ad(space->pending_io());
bool encrypted = fil_space_decrypt(space->id, space->crypt_data,
tmp_frame, physical_size,
space->flags,
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, physical_size);
}
res = src_frame;
if (DB_SUCCESS != fil_space_decrypt(space->id, space->crypt_data,
tmp_frame, physical_size,
space->flags, src_frame)) {
return nullptr;
}
return res;
/* Copy the decrypted page back to page buffer, not
really any other options. */
memcpy(src_frame, tmp_frame, physical_size);
return src_frame;
}
/**
......@@ -2901,7 +2878,10 @@ encrypted, or corrupted.
@return true if page is encrypted AND OK, false otherwise */
bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
{
ut_ad(mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION));
if (ENCRYPTION_KEY_NOT_ENCRYPTED == mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)) {
return false;
}
/* Compressed and encrypted pages do not have checksum. Assume not
corrupted. Page verification happens after decompression in
......
......@@ -358,18 +358,16 @@ fil_space_encrypt(
@param[in] physical_size page size
@param[in] fsp_flags Tablespace flags
@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(
ulint space_id,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_size,
ulint fsp_flags,
byte* src_frame,
dberr_t* err);
byte* src_frame);
/******************************************************************
Decrypt a page
......
......@@ -3122,10 +3122,9 @@ static dberr_t decrypt_decompress(fil_space_crypt_t *space_crypt,
if (!buf_page_verify_crypt_checksum(data, space_flags))
return DB_CORRUPTION;
dberr_t err;
if (!fil_space_decrypt(space_id, space_crypt, data, page.size(),
space_flags, data, &err))
return err ? err : DB_CORRUPTION;
if (dberr_t err= fil_space_decrypt(space_id, space_crypt, data,
page.size(), space_flags, data))
return err;
}
else if (fil_page_is_compressed_encrypted(data))
return DB_CORRUPTION;
......@@ -3835,9 +3834,12 @@ dberr_t FetchIndexRootPages::run(const fil_iterator_t& iter,
if (!buf_page_verify_crypt_checksum(readptr, m_space_flags))
goto page_corrupted;
if (!fil_space_decrypt(get_space_id(), iter.crypt_data, readptr,
size, m_space_flags, readptr, &err) ||
err != DB_SUCCESS)
if (ENCRYPTION_KEY_NOT_ENCRYPTED ==
buf_page_get_key_version(readptr, m_space_flags))
goto page_corrupted;
if ((err= fil_space_decrypt(get_space_id(), iter.crypt_data, readptr, size,
m_space_flags, readptr)))
goto func_exit;
}
......@@ -3989,7 +3991,6 @@ static dberr_t fil_iterate(
if (!encrypted) {
} else if (!key_version) {
not_encrypted:
if (block->page.id.page_no() == 0
&& block->page.zip.data) {
block->page.zip.data = src;
......@@ -4008,21 +4009,16 @@ static dberr_t fil_iterate(
goto page_corrupted;
}
decrypted = fil_space_decrypt(
if ((err = fil_space_decrypt(
actual_space_id,
iter.crypt_data, dst,
callback.physical_size(),
callback.get_space_flags(),
src, &err);
if (err != DB_SUCCESS) {
src))) {
goto func_exit;
}
if (!decrypted) {
goto not_encrypted;
}
decrypted = true;
updated = true;
}
......
......@@ -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");
......
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