Merge 10.3 into 10.4
This commit is contained in:
commit
ae6e214fd8
@ -211,7 +211,7 @@ fi
|
|||||||
|
|
||||||
max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
|
max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
|
||||||
max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
|
max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
|
||||||
max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --without-plugin=plugin_file_key_management --with-plugin-rocksdb=dynamic --without-plugin-tokudb --with-plugin-test_sql_discovery=DYNAMIC --with-plugin-file_key_management=DYNAMIC"
|
max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --with-plugin-rocksdb=dynamic --without-plugin-tokudb --with-plugin-test_sql_discovery=DYNAMIC --with-plugin-file_key_management=DYNAMIC"
|
||||||
all_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-innodb_plugin --with-libevent"
|
all_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-innodb_plugin --with-libevent"
|
||||||
|
|
||||||
#
|
#
|
||||||
|
2
CREDITS
2
CREDITS
@ -4,9 +4,11 @@ organization registered in the USA.
|
|||||||
The current main sponsors of the MariaDB Foundation are:
|
The current main sponsors of the MariaDB Foundation are:
|
||||||
|
|
||||||
Alibaba Cloud https://www.alibabacloud.com/ (2017)
|
Alibaba Cloud https://www.alibabacloud.com/ (2017)
|
||||||
|
Intel https://www.intel.com (2022)
|
||||||
MariaDB Corporation https://www.mariadb.com (2013)
|
MariaDB Corporation https://www.mariadb.com (2013)
|
||||||
Microsoft https://microsoft.com/ (2017)
|
Microsoft https://microsoft.com/ (2017)
|
||||||
ServiceNow https://servicenow.com (2019)
|
ServiceNow https://servicenow.com (2019)
|
||||||
|
SIT https://sit.org (2022)
|
||||||
Tencent Cloud https://cloud.tencent.com (2017)
|
Tencent Cloud https://cloud.tencent.com (2017)
|
||||||
Development Bank of Singapore https://dbs.com (2016)
|
Development Bank of Singapore https://dbs.com (2016)
|
||||||
IBM https://www.ibm.com (2017)
|
IBM https://www.ibm.com (2017)
|
||||||
|
@ -2558,6 +2558,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info,
|
|||||||
error("Could not write into log file '%s'", out_file_name);
|
error("Could not write into log file '%s'", out_file_name);
|
||||||
DBUG_RETURN(ERROR_STOP);
|
DBUG_RETURN(ERROR_STOP);
|
||||||
}
|
}
|
||||||
|
fflush(result_file);
|
||||||
|
|
||||||
DBUG_RETURN(OK_CONTINUE);
|
DBUG_RETURN(OK_CONTINUE);
|
||||||
}
|
}
|
||||||
|
@ -17,20 +17,29 @@ IF(GIT_EXECUTABLE AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
|||||||
${GIT_EXECUTABLE} config cmake.update-submodules yes")
|
${GIT_EXECUTABLE} config cmake.update-submodules yes")
|
||||||
ELSEIF(git_config_get_result EQUAL 128)
|
ELSEIF(git_config_get_result EQUAL 128)
|
||||||
SET(update_result 0)
|
SET(update_result 0)
|
||||||
ELSEIF (cmake_update_submodules MATCHES force)
|
|
||||||
MESSAGE(STATUS "Updating submodules (forced)")
|
|
||||||
EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --force --recursive --depth=1
|
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE update_result)
|
|
||||||
ELSEIF (cmake_update_submodules MATCHES yes)
|
|
||||||
EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --recursive --depth=1
|
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE update_result)
|
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(STATUS "Updating submodules")
|
SET(UPDATE_SUBMODULES_COMMAND
|
||||||
EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --recursive --depth=1
|
"${GIT_EXECUTABLE}" submodule update --init --recursive)
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
# Old Git may not work with "--depth 1".
|
||||||
RESULT_VARIABLE update_result)
|
# See also: https://github.com/git/git/commit/fb43e31f2b43076e7a30c9cd00d0241cb8cf97eb
|
||||||
|
IF(NOT GIT_VERSION_STRING VERSION_LESS "2.8.0")
|
||||||
|
SET(UPDATE_SUBMODULES_COMMAND ${UPDATE_SUBMODULES_COMMAND} --depth 1)
|
||||||
|
ENDIF()
|
||||||
|
IF(cmake_update_submodules MATCHES force)
|
||||||
|
MESSAGE(STATUS "Updating submodules (forced)")
|
||||||
|
EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND} --force
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE update_result)
|
||||||
|
ELSEIF(cmake_update_submodules MATCHES yes)
|
||||||
|
EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND}
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE update_result)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "Updating submodules")
|
||||||
|
EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND}
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE update_result)
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundati
|
|||||||
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
|
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
|
||||||
MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation
|
MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation
|
||||||
ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation
|
ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation
|
||||||
|
Intel https://www.intel.com Platinum Sponsor of the MariaDB Foundation
|
||||||
|
SIT https://sit.org Platinum Sponsor of the MariaDB Foundation
|
||||||
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
|
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
|
||||||
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
|
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
|
||||||
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
|
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
|
||||||
|
@ -2913,5 +2913,30 @@ t1 CREATE TABLE `t1` (
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
#
|
#
|
||||||
|
# MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
|
||||||
|
c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
|
||||||
|
);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` enum('a','b') CHARACTER SET utf32 DEFAULT 'a',
|
||||||
|
`c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
|
||||||
|
c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
|
||||||
|
);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` enum('00000061','00000062') CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '00000061',
|
||||||
|
`c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
|
@ -1067,6 +1067,25 @@ DROP TABLE t1;
|
|||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
|
||||||
|
c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
|
||||||
|
);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
|
||||||
|
c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
|
||||||
|
);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -207,4 +207,19 @@ ERROR 23000: Duplicate entry '0000-00-00 00:00:00' for key 'f2k'
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t3,t4;
|
DROP TABLE t3,t4;
|
||||||
SET @@sql_mode=@save_sql_mode;
|
SET @@sql_mode=@save_sql_mode;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-28095 crash in multi-update and implicit grouping
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (b int);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
UPDATE t1 NATURAL JOIN t2 SET a = 1 ORDER BY AVG (a) ;
|
||||||
|
ERROR HY000: Invalid use of group function
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
@ -243,4 +243,23 @@ DROP VIEW v1;
|
|||||||
DROP TABLE t3,t4;
|
DROP TABLE t3,t4;
|
||||||
SET @@sql_mode=@save_sql_mode;
|
SET @@sql_mode=@save_sql_mode;
|
||||||
|
|
||||||
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28095 crash in multi-update and implicit grouping
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a int) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (b int);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
--error ER_INVALID_GROUP_FUNC_USE
|
||||||
|
UPDATE t1 NATURAL JOIN t2 SET a = 1 ORDER BY AVG (a) ;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
@ -732,3 +732,30 @@ a b
|
|||||||
4 4
|
4 4
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SET @@in_predicate_conversion_threshold= default;
|
SET @@in_predicate_conversion_threshold= default;
|
||||||
|
#
|
||||||
|
# MDEV-27937: Prepared statement with ? in the list if IN predicate
|
||||||
|
#
|
||||||
|
set in_predicate_conversion_threshold=2;
|
||||||
|
create table t1 (id int, a int, b int);
|
||||||
|
insert into t1 values (1,3,30), (2,7,70), (3,1,10);
|
||||||
|
prepare stmt from "
|
||||||
|
select * from t1 where a in (7, ?, 5, 1);
|
||||||
|
";
|
||||||
|
execute stmt using 3;
|
||||||
|
id a b
|
||||||
|
1 3 30
|
||||||
|
2 7 70
|
||||||
|
3 1 10
|
||||||
|
deallocate prepare stmt;
|
||||||
|
prepare stmt from "
|
||||||
|
select * from t1 where (a,b) in ((7,70), (3,?), (5,50), (1,10));
|
||||||
|
";
|
||||||
|
execute stmt using 30;
|
||||||
|
id a b
|
||||||
|
1 3 30
|
||||||
|
2 7 70
|
||||||
|
3 1 10
|
||||||
|
deallocate prepare stmt;
|
||||||
|
drop table t1;
|
||||||
|
set in_predicate_conversion_threshold=default;
|
||||||
|
# End of 10.3 tests
|
||||||
|
@ -428,3 +428,29 @@ eval $query;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
SET @@in_predicate_conversion_threshold= default;
|
SET @@in_predicate_conversion_threshold= default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27937: Prepared statement with ? in the list if IN predicate
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set in_predicate_conversion_threshold=2;
|
||||||
|
|
||||||
|
create table t1 (id int, a int, b int);
|
||||||
|
insert into t1 values (1,3,30), (2,7,70), (3,1,10);
|
||||||
|
|
||||||
|
prepare stmt from "
|
||||||
|
select * from t1 where a in (7, ?, 5, 1);
|
||||||
|
";
|
||||||
|
execute stmt using 3;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
prepare stmt from "
|
||||||
|
select * from t1 where (a,b) in ((7,70), (3,?), (5,50), (1,10));
|
||||||
|
";
|
||||||
|
execute stmt using 30;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
set in_predicate_conversion_threshold=default;
|
||||||
|
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
@ -40,3 +40,23 @@ utf8mb4_string xxx😎yyy
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-28131 Unexpected warning while selecting from information_schema.processlist
|
||||||
|
#
|
||||||
|
connect conn1, localhost, root,,;
|
||||||
|
connection conn1;
|
||||||
|
SELECT SLEEP(1000);
|
||||||
|
connection default;
|
||||||
|
SELECT progress FROM information_schema.processlist WHERE info='SELECT SLEEP(1000)';
|
||||||
|
progress
|
||||||
|
0.000
|
||||||
|
connection conn1;
|
||||||
|
Got one of the listed errors
|
||||||
|
connection default;
|
||||||
|
disconnect conn1;
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
@ -70,3 +70,38 @@ SELECT INFO, INFO_BINARY, 'xxx😎yyy' AS utf8mb4_string FROM INFORMATION_SCHEMA
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28131 Unexpected warning while selecting from information_schema.processlist
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
connect (conn1, localhost, root,,);
|
||||||
|
connection conn1;
|
||||||
|
let $ID= `select connection_id()`;
|
||||||
|
send SELECT SLEEP(1000);
|
||||||
|
connection default;
|
||||||
|
let $wait_timeout= 10;
|
||||||
|
let $wait_condition=select count(*)=1 from information_schema.processlist
|
||||||
|
where state='User sleep' and info='SELECT SLEEP(1000)';
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
SELECT progress FROM information_schema.processlist WHERE info='SELECT SLEEP(1000)';
|
||||||
|
disable_query_log;
|
||||||
|
eval kill $ID;
|
||||||
|
enable_query_log;
|
||||||
|
let $wait_timeout= 10;
|
||||||
|
let $wait_condition=select count(*)=0 from information_schema.processlist
|
||||||
|
where state='User sleep' and info='SELECT SLEEP(1000)';
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
connection conn1;
|
||||||
|
--error 2013,ER_CONNECTION_KILLED
|
||||||
|
reap;
|
||||||
|
connection default;
|
||||||
|
disconnect conn1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
@ -737,3 +737,66 @@ rec.en1
|
|||||||
c
|
c
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-26009: Server crash when calling twice procedure using FOR-loop
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( id int, name varchar(24));
|
||||||
|
INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
|
||||||
|
create function get_name(_id int) returns varchar(24)
|
||||||
|
return (select name from t1 where id = _id);
|
||||||
|
select get_name(id) from t1;
|
||||||
|
get_name(id)
|
||||||
|
x
|
||||||
|
y
|
||||||
|
z
|
||||||
|
create procedure test_proc()
|
||||||
|
begin
|
||||||
|
declare _cur cursor for select get_name(id) from t1;
|
||||||
|
for row in _cur do select 1; end for;
|
||||||
|
end;
|
||||||
|
^^
|
||||||
|
call test_proc();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
call test_proc();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop procedure test_proc;
|
||||||
|
drop function get_name;
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (id int, name varchar(24));
|
||||||
|
INSERT INTO t1 (id, name) VALUES (1, 'x'),(2, 'y'),(3, 'z');
|
||||||
|
create function get_name(_id int) returns varchar(24)
|
||||||
|
return (select name from t1 where id = _id);
|
||||||
|
create view v1 as select get_name(id) from t1;
|
||||||
|
create procedure test_proc()
|
||||||
|
begin
|
||||||
|
declare _cur cursor for select 1 from v1;
|
||||||
|
for row in _cur do select 1; end for;
|
||||||
|
end$$
|
||||||
|
call test_proc();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
call test_proc();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop procedure test_proc;
|
||||||
|
drop view v1;
|
||||||
|
drop function get_name;
|
||||||
|
drop table t1;
|
||||||
|
@ -744,3 +744,59 @@ DELIMITER ;$$
|
|||||||
CALL p1();
|
CALL p1();
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-26009: Server crash when calling twice procedure using FOR-loop
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 ( id int, name varchar(24));
|
||||||
|
INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
|
||||||
|
|
||||||
|
create function get_name(_id int) returns varchar(24)
|
||||||
|
return (select name from t1 where id = _id);
|
||||||
|
|
||||||
|
select get_name(id) from t1;
|
||||||
|
|
||||||
|
delimiter ^^;
|
||||||
|
|
||||||
|
create procedure test_proc()
|
||||||
|
begin
|
||||||
|
declare _cur cursor for select get_name(id) from t1;
|
||||||
|
for row in _cur do select 1; end for;
|
||||||
|
end;
|
||||||
|
^^
|
||||||
|
delimiter ;^^
|
||||||
|
|
||||||
|
call test_proc();
|
||||||
|
call test_proc();
|
||||||
|
|
||||||
|
drop procedure test_proc;
|
||||||
|
drop function get_name;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id int, name varchar(24));
|
||||||
|
INSERT INTO t1 (id, name) VALUES (1, 'x'),(2, 'y'),(3, 'z');
|
||||||
|
|
||||||
|
create function get_name(_id int) returns varchar(24)
|
||||||
|
return (select name from t1 where id = _id);
|
||||||
|
|
||||||
|
create view v1 as select get_name(id) from t1;
|
||||||
|
|
||||||
|
delimiter $$;
|
||||||
|
create procedure test_proc()
|
||||||
|
begin
|
||||||
|
declare _cur cursor for select 1 from v1;
|
||||||
|
for row in _cur do select 1; end for;
|
||||||
|
end$$
|
||||||
|
delimiter ;$$
|
||||||
|
|
||||||
|
call test_proc();
|
||||||
|
call test_proc();
|
||||||
|
|
||||||
|
drop procedure test_proc;
|
||||||
|
drop view v1;
|
||||||
|
drop function get_name;
|
||||||
|
drop table t1;
|
||||||
|
@ -6851,6 +6851,34 @@ id bar
|
|||||||
Drop View v1;
|
Drop View v1;
|
||||||
Drop table t1;
|
Drop table t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-24281: Execution of PREPARE from CREATE VIEW statement
|
||||||
|
#
|
||||||
|
create table t1 (s1 int);
|
||||||
|
insert into t1 values (3), (7), (1);
|
||||||
|
prepare stmt from "
|
||||||
|
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||||
|
";
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
show create view v1;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 's1' AS `My_exp_1_s1`,`t1`.`s1` AS `s1`,1 AS `My_exp_s1` from `t1` latin1 latin1_swedish_ci
|
||||||
|
select * from v1;
|
||||||
|
My_exp_1_s1 s1 My_exp_s1
|
||||||
|
s1 3 1
|
||||||
|
s1 7 1
|
||||||
|
s1 1 1
|
||||||
|
drop view v1;
|
||||||
|
prepare stmt from "
|
||||||
|
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||||
|
";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
ERROR 42S01: Table 'v1' already exists
|
||||||
|
deallocate prepare stmt;
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -6577,6 +6577,32 @@ SELECT v.id, v.foo AS bar FROM v1 v
|
|||||||
Drop View v1;
|
Drop View v1;
|
||||||
Drop table t1;
|
Drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24281: Execution of PREPARE from CREATE VIEW statement
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1 (s1 int);
|
||||||
|
insert into t1 values (3), (7), (1);
|
||||||
|
|
||||||
|
prepare stmt from "
|
||||||
|
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||||
|
";
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
show create view v1;
|
||||||
|
select * from v1;
|
||||||
|
drop view v1;
|
||||||
|
|
||||||
|
prepare stmt from "
|
||||||
|
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||||
|
";
|
||||||
|
execute stmt;
|
||||||
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
|
||||||
|
# Restart the server so mysqld reads the gtid_slave_pos using innodb
|
||||||
|
# Set gtid_slave_pos should not hang
|
||||||
|
SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
|
||||||
|
COMMIT;
|
||||||
|
RESET MASTER;
|
@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
FLUSH LOGS;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
# timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
|
||||||
|
# MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
|
||||||
|
FOUND 1 /GTID 0-1-2/ in local-bin.000002.out
|
||||||
|
DROP TABLE t1;
|
@ -0,0 +1 @@
|
|||||||
|
--autocommit=0
|
45
mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
Normal file
45
mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#
|
||||||
|
# Purpose:
|
||||||
|
# When the mysql.gtid_slave_pos table uses the InnoDB engine, and mysqld
|
||||||
|
# starts, it reads the table and begins a transaction. After mysqld reads the
|
||||||
|
# value, it should end the transaction and release all associated locks.
|
||||||
|
# The bug reported in DBAAS-7828 shows that when autocommit is off, the locks
|
||||||
|
# are not released, resulting in indefinite hangs on future attempts to change
|
||||||
|
# gtid_slave_pos. This test ensures its fix such that the locks are properly
|
||||||
|
# released.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# DBAAS-7828: Primary/replica: configuration change of "autocommit=0" can
|
||||||
|
# not be applied
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_log_bin.inc
|
||||||
|
|
||||||
|
# Reading gtid_slave_pos table is format independent so just use one for
|
||||||
|
# reduced test time
|
||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
|
||||||
|
--let old_slave_pos_engine= query_get_value(SHOW TABLE STATUS FROM mysql LIKE 'gtid_slave_pos', Engine, 1)
|
||||||
|
|
||||||
|
# Use a transactional engine
|
||||||
|
ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
|
||||||
|
|
||||||
|
--echo # Restart the server so mysqld reads the gtid_slave_pos using innodb
|
||||||
|
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
--shutdown_server
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
--enable_reconnect
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
--echo # Set gtid_slave_pos should not hang
|
||||||
|
SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
# Revert table type
|
||||||
|
--disable_query_log
|
||||||
|
--eval ALTER TABLE mysql.gtid_slave_pos ENGINE=$old_slave_pos_engine
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
RESET MASTER;
|
45
mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
Normal file
45
mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#
|
||||||
|
# Purpose:
|
||||||
|
# When using mariadb-binlog with options for --raw and --stop-never, events
|
||||||
|
# from the master's currently active log file should be written to their
|
||||||
|
# respective log file specified by --result-file, and shown on-disk. This test
|
||||||
|
# ensures that the log files on disk, created by mariadb-binlog, have the most
|
||||||
|
# up-to-date events from the master.
|
||||||
|
#
|
||||||
|
# Methodology:
|
||||||
|
# On the master, rotate to a newly active binlog file and write an event to
|
||||||
|
# it. Read the master's binlog using mariadb-binlog with --raw and --stop-never
|
||||||
|
# and write the data to an intermediary binlog file (a timeout is used on this
|
||||||
|
# command to ensure it exits). Read the local intermediary binlog file to ensure
|
||||||
|
# that the master's most recent event exists in the local file.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# MDEV-14608: mysqlbinlog lastest backupfile size is 0
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/linux.inc
|
||||||
|
--source include/have_log_bin.inc
|
||||||
|
|
||||||
|
# Create newly active log
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
FLUSH LOGS;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
# Read binlog data from master to intermediary result file
|
||||||
|
--let TIMEOUT=1
|
||||||
|
--echo # timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
|
||||||
|
--error 124 # Error 124 means timeout was reached
|
||||||
|
--exec timeout $TIMEOUT $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --stop-never --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001
|
||||||
|
|
||||||
|
# Ensure the binlog output has the most recent events from the master
|
||||||
|
--echo # MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
|
||||||
|
--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/tmp/master-bin.000002 > $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
|
||||||
|
--let SEARCH_PATTERN= GTID 0-1-2
|
||||||
|
--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP TABLE t1;
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000001
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000002
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
|
@ -2962,3 +2962,311 @@ END $$
|
|||||||
CALL xyz.xyz123(17,18,@R);
|
CALL xyz.xyz123(17,18,@R);
|
||||||
DROP PACKAGE xyz;
|
DROP PACKAGE xyz;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func()
|
||||||
|
#
|
||||||
|
SELECT `db `.pkg.func();
|
||||||
|
ERROR 42000: Incorrect database name 'db '
|
||||||
|
SELECT db.`pkg `.func();
|
||||||
|
ERROR 42000: Incorrect routine name 'pkg '
|
||||||
|
SELECT db.pkg.`func `();
|
||||||
|
ERROR 42000: Incorrect routine name 'func '
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
USE db1;
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_db1_pkg1_f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_pkg1_f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_f1 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1
|
||||||
|
AS
|
||||||
|
FUNCTION f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db1.pkg1.f1';
|
||||||
|
END;
|
||||||
|
FUNCTION f2_db1_pkg1_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN db1.pkg1.f1();
|
||||||
|
END;
|
||||||
|
FUNCTION f2_pkg1_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN pkg1.f1();
|
||||||
|
END;
|
||||||
|
FUNCTION f2_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN f1();
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
USE db1;
|
||||||
|
SELECT pkg1.f2_db1_pkg1_f1();
|
||||||
|
pkg1.f2_db1_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT pkg1.f2_pkg1_f1();
|
||||||
|
pkg1.f2_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT pkg1.f2_f1();
|
||||||
|
pkg1.f2_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT db1.pkg1.f2_db1_pkg1_f1();
|
||||||
|
db1.pkg1.f2_db1_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT db1.pkg1.f2_pkg1_f1();
|
||||||
|
db1.pkg1.f2_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT db1.pkg1.f2_f1();
|
||||||
|
db1.pkg1.f2_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
USE test;
|
||||||
|
SELECT db1.pkg1.f2_db1_pkg1_f1();
|
||||||
|
db1.pkg1.f2_db1_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT db1.pkg1.f2_pkg1_f1();
|
||||||
|
db1.pkg1.f2_pkg1_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
SELECT db1.pkg1.f2_f1();
|
||||||
|
db1.pkg1.f2_f1()
|
||||||
|
This is db1.pkg1.f1
|
||||||
|
DROP DATABASE db1;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
CREATE PACKAGE db1.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db1.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db1.pkg1.f1';
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE db2.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
FUNCTION var1 RETURN TEXT;
|
||||||
|
FUNCTION var2 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db2.pkg1 AS
|
||||||
|
m_var1 TEXT;
|
||||||
|
m_var2 TEXT;
|
||||||
|
FUNCTION f1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db2.pkg1.f1';
|
||||||
|
END;
|
||||||
|
FUNCTION var1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var1;
|
||||||
|
END;
|
||||||
|
FUNCTION var2 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var2;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
m_var1:= db1.pkg1.f1();
|
||||||
|
m_var2:= db2.pkg1.f1();
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
SELECT db2.pkg1.var1(), db2.pkg1.var2();
|
||||||
|
db2.pkg1.var1() db2.pkg1.var2()
|
||||||
|
This is db1.pkg1.f1 This is db2.pkg1.f1
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
FUNCTION f1(a TEXT) RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
FUNCTION f1(a TEXT) RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN a;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
SELECT test.pkg1.f1('xxx');
|
||||||
|
test.pkg1.f1('xxx')
|
||||||
|
xxx
|
||||||
|
SELECT test.pkg1.f1('xxx' AS a);
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS a)' at line 1
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
#
|
||||||
|
# MDEV-19328 sql_mode=ORACLE: Package function in VIEW
|
||||||
|
#
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE PACKAGE test1 AS
|
||||||
|
FUNCTION f_test RETURN number;
|
||||||
|
END test1;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY test1
|
||||||
|
AS
|
||||||
|
FUNCTION f_test RETURN NUMBER IS
|
||||||
|
BEGIN
|
||||||
|
RETURN 1;
|
||||||
|
END;
|
||||||
|
END test1;
|
||||||
|
$$
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
DROP VIEW v_test;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
|
||||||
|
ERROR 42000: FUNCTION test1.f_test does not exist
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
DROP VIEW v_test;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
View v_test
|
||||||
|
Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
|
||||||
|
character_set_client latin1
|
||||||
|
collation_connection latin1_swedish_ci
|
||||||
|
DROP VIEW v_test;
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
DROP PACKAGE test1;
|
||||||
|
#
|
||||||
|
# MDEV-19804 sql_mode=ORACLE: call procedure in packages
|
||||||
|
#
|
||||||
|
CALL `db1 `.pkg.p;
|
||||||
|
ERROR 42000: Incorrect database name 'db1 '
|
||||||
|
CALL db1.`pkg `.p;
|
||||||
|
ERROR 42000: Incorrect routine name 'pkg '
|
||||||
|
CALL db1.pkg.`p `;
|
||||||
|
ERROR 42000: Incorrect routine name 'p '
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE PACKAGE pkg1 as
|
||||||
|
PROCEDURE p1();
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1 as
|
||||||
|
PROCEDURE p1() as
|
||||||
|
BEGIN
|
||||||
|
SELECT 'test-function' AS c1;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CALL pkg1.p1;
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
BEGIN
|
||||||
|
CALL pkg1.p1;
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
BEGIN
|
||||||
|
pkg1.p1;
|
||||||
|
test.pkg1.p1;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
c1
|
||||||
|
test-function
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE PACKAGE db1.pkg1 AS
|
||||||
|
PROCEDURE p1(a OUT TEXT);
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db1.pkg1 AS
|
||||||
|
PROCEDURE p1(a OUT TEXT) AS
|
||||||
|
BEGIN
|
||||||
|
a:= 'This is db1.pkg1.p1';
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
CREATE PACKAGE db2.pkg1 AS
|
||||||
|
FUNCTION var1 RETURN TEXT;
|
||||||
|
PROCEDURE p1(a OUT TEXT);
|
||||||
|
PROCEDURE p2_db1_pkg1_p1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db2.pkg1 AS
|
||||||
|
m_var1 TEXT;
|
||||||
|
FUNCTION var1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var1;
|
||||||
|
END;
|
||||||
|
PROCEDURE p1(a OUT TEXT) AS
|
||||||
|
BEGIN
|
||||||
|
a:= 'This is db2.pkg1.p1';
|
||||||
|
END;
|
||||||
|
PROCEDURE p2_db1_pkg1_p1 AS
|
||||||
|
a TEXT;
|
||||||
|
BEGIN
|
||||||
|
db1.pkg1.p1(a);
|
||||||
|
SELECT a;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
db1.pkg1.p1(m_var1);
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
SELECT db2.pkg1.var1();
|
||||||
|
db2.pkg1.var1()
|
||||||
|
This is db1.pkg1.p1
|
||||||
|
CALL db2.pkg1.p2_db1_pkg1_p1;
|
||||||
|
a
|
||||||
|
This is db1.pkg1.p1
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
@ -2689,3 +2689,330 @@ DELIMITER ;$$
|
|||||||
CALL xyz.xyz123(17,18,@R);
|
CALL xyz.xyz123(17,18,@R);
|
||||||
DROP PACKAGE xyz;
|
DROP PACKAGE xyz;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func()
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--error ER_WRONG_DB_NAME
|
||||||
|
SELECT `db `.pkg.func();
|
||||||
|
--error ER_SP_WRONG_NAME
|
||||||
|
SELECT db.`pkg `.func();
|
||||||
|
--error ER_SP_WRONG_NAME
|
||||||
|
SELECT db.pkg.`func `();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
USE db1;
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_db1_pkg1_f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_pkg1_f1 RETURN TEXT;
|
||||||
|
FUNCTION f2_f1 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1
|
||||||
|
AS
|
||||||
|
FUNCTION f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db1.pkg1.f1';
|
||||||
|
END;
|
||||||
|
FUNCTION f2_db1_pkg1_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN db1.pkg1.f1();
|
||||||
|
END;
|
||||||
|
FUNCTION f2_pkg1_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN pkg1.f1();
|
||||||
|
END;
|
||||||
|
FUNCTION f2_f1 RETURN TEXT IS
|
||||||
|
BEGIN
|
||||||
|
RETURN f1();
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
USE db1;
|
||||||
|
SELECT pkg1.f2_db1_pkg1_f1();
|
||||||
|
SELECT pkg1.f2_pkg1_f1();
|
||||||
|
SELECT pkg1.f2_f1();
|
||||||
|
|
||||||
|
SELECT db1.pkg1.f2_db1_pkg1_f1();
|
||||||
|
SELECT db1.pkg1.f2_pkg1_f1();
|
||||||
|
SELECT db1.pkg1.f2_f1();
|
||||||
|
|
||||||
|
USE test;
|
||||||
|
SELECT db1.pkg1.f2_db1_pkg1_f1();
|
||||||
|
SELECT db1.pkg1.f2_pkg1_f1();
|
||||||
|
SELECT db1.pkg1.f2_f1();
|
||||||
|
|
||||||
|
DROP DATABASE db1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing db.pkg.func() in the package initialization section
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE db1.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db1.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db1.pkg1.f1';
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE db2.pkg1 AS
|
||||||
|
FUNCTION f1 RETURN TEXT;
|
||||||
|
FUNCTION var1 RETURN TEXT;
|
||||||
|
FUNCTION var2 RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db2.pkg1 AS
|
||||||
|
m_var1 TEXT;
|
||||||
|
m_var2 TEXT;
|
||||||
|
FUNCTION f1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 'This is db2.pkg1.f1';
|
||||||
|
END;
|
||||||
|
FUNCTION var1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var1;
|
||||||
|
END;
|
||||||
|
FUNCTION var2 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var2;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
m_var1:= db1.pkg1.f1();
|
||||||
|
m_var2:= db2.pkg1.f1();
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
SELECT db2.pkg1.var1(), db2.pkg1.var2();
|
||||||
|
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure fully qualified package function call does not support AS syntax:
|
||||||
|
# SELECT db.pkg.func(10 AS a);
|
||||||
|
#
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
FUNCTION f1(a TEXT) RETURN TEXT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
FUNCTION f1(a TEXT) RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN a;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
SELECT test.pkg1.f1('xxx');
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
SELECT test.pkg1.f1('xxx' AS a);
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-19328 sql_mode=ORACLE: Package function in VIEW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE test1 AS
|
||||||
|
FUNCTION f_test RETURN number;
|
||||||
|
END test1;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY test1
|
||||||
|
AS
|
||||||
|
FUNCTION f_test RETURN NUMBER IS
|
||||||
|
BEGIN
|
||||||
|
RETURN 1;
|
||||||
|
END;
|
||||||
|
END test1;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
DROP VIEW v_test;
|
||||||
|
|
||||||
|
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
--error ER_SP_DOES_NOT_EXIST
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
|
||||||
|
|
||||||
|
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
DROP VIEW v_test;
|
||||||
|
|
||||||
|
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
SELECT * FROM v_test;
|
||||||
|
--vertical_results
|
||||||
|
SHOW CREATE VIEW v_test;
|
||||||
|
--horizontal_results
|
||||||
|
DROP VIEW v_test;
|
||||||
|
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
DROP PACKAGE test1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-19804 sql_mode=ORACLE: call procedure in packages
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--error ER_WRONG_DB_NAME
|
||||||
|
CALL `db1 `.pkg.p;
|
||||||
|
--error ER_SP_WRONG_NAME
|
||||||
|
CALL db1.`pkg `.p;
|
||||||
|
--error ER_SP_WRONG_NAME
|
||||||
|
CALL db1.pkg.`p `;
|
||||||
|
|
||||||
|
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE pkg1 as
|
||||||
|
PROCEDURE p1();
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1 as
|
||||||
|
PROCEDURE p1() as
|
||||||
|
BEGIN
|
||||||
|
SELECT 'test-function' AS c1;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
CALL pkg1.p1;
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
|
||||||
|
# In sql_mode=DEFAULT we support fully qualified package function names
|
||||||
|
# (this is needed for VIEWs). Let's make sure we also support fully
|
||||||
|
# qualified package procedure names, for symmetry
|
||||||
|
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
SET sql_mode=ORACLE;
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
BEGIN
|
||||||
|
CALL pkg1.p1;
|
||||||
|
CALL test.pkg1.p1;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
BEGIN
|
||||||
|
pkg1.p1;
|
||||||
|
test.pkg1.p1;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing packages in different databases calling each other
|
||||||
|
# in routines and in the initialization section.
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE db1.pkg1 AS
|
||||||
|
PROCEDURE p1(a OUT TEXT);
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db1.pkg1 AS
|
||||||
|
PROCEDURE p1(a OUT TEXT) AS
|
||||||
|
BEGIN
|
||||||
|
a:= 'This is db1.pkg1.p1';
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE db2.pkg1 AS
|
||||||
|
FUNCTION var1 RETURN TEXT;
|
||||||
|
PROCEDURE p1(a OUT TEXT);
|
||||||
|
PROCEDURE p2_db1_pkg1_p1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY db2.pkg1 AS
|
||||||
|
m_var1 TEXT;
|
||||||
|
FUNCTION var1 RETURN TEXT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN m_var1;
|
||||||
|
END;
|
||||||
|
PROCEDURE p1(a OUT TEXT) AS
|
||||||
|
BEGIN
|
||||||
|
a:= 'This is db2.pkg1.p1';
|
||||||
|
END;
|
||||||
|
PROCEDURE p2_db1_pkg1_p1 AS
|
||||||
|
a TEXT;
|
||||||
|
BEGIN
|
||||||
|
db1.pkg1.p1(a);
|
||||||
|
SELECT a;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
db1.pkg1.p1(m_var1);
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
SELECT db2.pkg1.var1();
|
||||||
|
CALL db2.pkg1.p2_db1_pkg1_p1;
|
||||||
|
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
--echo Killing server ...
|
--echo Killing server ...
|
||||||
|
|
||||||
|
if (!$kill_signal)
|
||||||
|
{
|
||||||
|
--let $kill_signal = KILL
|
||||||
|
}
|
||||||
|
|
||||||
# Write file to make mysql-test-run.pl expect the crash, but don't start it
|
# Write file to make mysql-test-run.pl expect the crash, but don't start it
|
||||||
--let $_server_id= `SELECT @@server_id`
|
--let $_server_id= `SELECT @@server_id`
|
||||||
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
|
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
|
||||||
@ -7,13 +12,15 @@
|
|||||||
|
|
||||||
# Kill the connected server
|
# Kill the connected server
|
||||||
--disable_reconnect
|
--disable_reconnect
|
||||||
|
--let KILL_SIGNAL_VALUE = $kill_signal
|
||||||
--let KILL_NODE_PIDFILE = `SELECT @@pid_file`
|
--let KILL_NODE_PIDFILE = `SELECT @@pid_file`
|
||||||
|
|
||||||
--perl
|
--perl
|
||||||
|
my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'};
|
||||||
my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
|
my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
|
||||||
my $mysqld_pid = `cat $pid_filename`;
|
my $mysqld_pid = `cat $pid_filename`;
|
||||||
chomp($mysqld_pid);
|
chomp($mysqld_pid);
|
||||||
system("kill -9 $mysqld_pid");
|
system("kill -s $kill_sig $mysqld_pid");
|
||||||
exit(0);
|
exit(0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ SET SESSION wsrep_on=ON;
|
|||||||
connection node_1;
|
connection node_1;
|
||||||
UPDATE t1 SET f2 = 'd' WHERE f1 > 3;
|
UPDATE t1 SET f2 = 'd' WHERE f1 > 3;
|
||||||
connection node_2;
|
connection node_2;
|
||||||
|
Killing server ...
|
||||||
connection node_1;
|
connection node_1;
|
||||||
UPDATE t1 SET f2 = 'e' WHERE f1 > 4;
|
UPDATE t1 SET f2 = 'e' WHERE f1 > 4;
|
||||||
connection node_2;
|
connection node_2;
|
||||||
|
@ -61,19 +61,7 @@ UPDATE t1 SET f2 = 'd' WHERE f1 > 3;
|
|||||||
|
|
||||||
# Kill node #2 while IST is in progress
|
# Kill node #2 while IST is in progress
|
||||||
--connection node_2
|
--connection node_2
|
||||||
|
--source include/kill_galera.inc
|
||||||
# Kill the connected server
|
|
||||||
--disable_reconnect
|
|
||||||
|
|
||||||
--perl
|
|
||||||
my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
|
|
||||||
my $mysqld_pid = `cat $pid_filename`;
|
|
||||||
chomp($mysqld_pid);
|
|
||||||
system("kill -9 $mysqld_pid");
|
|
||||||
exit(0);
|
|
||||||
EOF
|
|
||||||
|
|
||||||
--source include/wait_until_disconnected.inc
|
|
||||||
|
|
||||||
--connection node_1
|
--connection node_1
|
||||||
--source include/wait_until_connected_again.inc
|
--source include/wait_until_connected_again.inc
|
||||||
|
41
mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result
Normal file
41
mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
connection node_1;
|
||||||
|
connection node_1;
|
||||||
|
connection node_2;
|
||||||
|
connection node_3;
|
||||||
|
connection node_1;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
|
||||||
|
connection node_1;
|
||||||
|
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||||
|
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||||
|
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||||
|
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||||
|
connection node_2;
|
||||||
|
Killing node #3 to free ports for garbd ...
|
||||||
|
connection node_3;
|
||||||
|
connection node_1;
|
||||||
|
SET GLOBAL debug_dbug = "+d,sync.wsrep_donor_state";
|
||||||
|
Starting garbd ...
|
||||||
|
SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct=0;
|
||||||
|
SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
|
||||||
|
SET GLOBAL debug_dbug = "";
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
connection node_2;
|
||||||
|
Killing garbd ...
|
||||||
|
connection node_1;
|
||||||
|
connection node_2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE ten;
|
||||||
|
Restarting node #3 to satisfy MTR's end-of-test checks
|
||||||
|
connection node_3;
|
||||||
|
connection node_1;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct = 75.000000;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct_lwm = 0.000000;
|
||||||
|
connection node_1;
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
||||||
|
connection node_2;
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
||||||
|
connection node_3;
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
13
mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf
Normal file
13
mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
!include ../galera_3nodes.cnf
|
||||||
|
|
||||||
|
[mysqld]
|
||||||
|
wsrep_sst_method=rsync
|
||||||
|
|
||||||
|
[mysqld.1]
|
||||||
|
wsrep_node_name=node1
|
||||||
|
|
||||||
|
[mysqld.2]
|
||||||
|
wsrep_node_name=node2
|
||||||
|
|
||||||
|
[mysqld.3]
|
||||||
|
wsrep_node_name=node3
|
134
mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test
Normal file
134
mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#
|
||||||
|
# A very basic test for the galera arbitrator. We shut down node #3 and use its port allocation to start garbd.
|
||||||
|
# As MTR does not allow multiple servers to be down at the same time, we are limited as to what we can test.
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_garbd.inc
|
||||||
|
--source include/big_test.inc
|
||||||
|
--source include/have_debug.inc
|
||||||
|
--source include/have_debug_sync.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
# Save original auto_increment_offset values.
|
||||||
|
--let $node_1=node_1
|
||||||
|
--let $node_2=node_2
|
||||||
|
--let $node_3=node_3
|
||||||
|
|
||||||
|
--let $galera_connection_name = node_3
|
||||||
|
--let $galera_server_number = 3
|
||||||
|
--source include/galera_connect.inc
|
||||||
|
--source suite/galera/include/galera_base_port.inc
|
||||||
|
--let $NODE_GALERAPORT_3 = $_NODE_GALERAPORT
|
||||||
|
|
||||||
|
--source ../galera/include/auto_increment_offset_save.inc
|
||||||
|
|
||||||
|
# Save galera ports
|
||||||
|
--connection node_1
|
||||||
|
--source suite/galera/include/galera_base_port.inc
|
||||||
|
--let $NODE_GALERAPORT_1 = $_NODE_GALERAPORT
|
||||||
|
--let $datadir= `SELECT @@datadir`
|
||||||
|
|
||||||
|
--let $innodb_max_dirty_pages_pct = `SELECT @@innodb_max_dirty_pages_pct`
|
||||||
|
--let $innodb_max_dirty_pages_pct_lwm = `SELECT @@innodb_max_dirty_pages_pct_lwm`
|
||||||
|
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||||
|
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||||
|
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||||
|
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
--source suite/galera/include/galera_base_port.inc
|
||||||
|
--let $NODE_GALERAPORT_2 = $_NODE_GALERAPORT
|
||||||
|
|
||||||
|
--echo Killing node #3 to free ports for garbd ...
|
||||||
|
--connection node_3
|
||||||
|
--source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
# stop SST donor thread when node is in donor state
|
||||||
|
SET GLOBAL debug_dbug = "+d,sync.wsrep_donor_state";
|
||||||
|
|
||||||
|
--echo Starting garbd ...
|
||||||
|
--exec $MTR_GARBD_EXE --address "gcomm://127.0.0.1:$NODE_GALERAPORT_1" --group my_wsrep_cluster --donor node1 --sst backup --options 'base_port=$NODE_GALERAPORT_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 &
|
||||||
|
|
||||||
|
SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
|
||||||
|
|
||||||
|
#
|
||||||
|
# get hash of data directory contents before BP dirty page flushing
|
||||||
|
#
|
||||||
|
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
|
||||||
|
|
||||||
|
# this should force buffer pool flushing, if not already done by donor state change transfer
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
|
||||||
|
SET GLOBAL innodb_max_dirty_pages_pct=0;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
select f1 from t1;
|
||||||
|
select * from ten;
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# record the hash of data directory contents after BP dirty page flushing
|
||||||
|
#
|
||||||
|
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
|
||||||
|
|
||||||
|
# there should be no disk writes
|
||||||
|
--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
|
||||||
|
|
||||||
|
SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
|
||||||
|
SET GLOBAL debug_dbug = "";
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
|
||||||
|
#
|
||||||
|
# garbd will die automatically, because of the backup SST script
|
||||||
|
# but just to be sure, sending explicit kill here, as well
|
||||||
|
#
|
||||||
|
--echo Killing garbd ...
|
||||||
|
# FreeBSD's /bin/pkill only supports short versions of the options:
|
||||||
|
# -o Select only the oldest (least recently started)
|
||||||
|
# -f Match against full argument lists
|
||||||
|
--error 0,1
|
||||||
|
--exec pkill -o -f garbd.*$NODE_GALERAPORT_3
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE ten;
|
||||||
|
|
||||||
|
--echo Restarting node #3 to satisfy MTR's end-of-test checks
|
||||||
|
--connection node_3
|
||||||
|
let $restart_noprint=2;
|
||||||
|
--source include/start_mysqld.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--eval SET GLOBAL innodb_max_dirty_pages_pct = $innodb_max_dirty_pages_pct
|
||||||
|
--eval SET GLOBAL innodb_max_dirty_pages_pct_lwm = $innodb_max_dirty_pages_pct_lwm
|
||||||
|
|
||||||
|
--source ../galera/include/auto_increment_offset_restore.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
||||||
|
|
||||||
|
--connection node_3
|
||||||
|
CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
|
30
mysql-test/suite/rpl/r/mdev_24667.result
Normal file
30
mysql-test/suite/rpl/r/mdev_24667.result
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
include/rpl_init.inc [topology=1->2->3]
|
||||||
|
call mtr.add_suppression('Unsafe statement written to the binary log using ');
|
||||||
|
connection server_1;
|
||||||
|
set binlog_format=statement;
|
||||||
|
#first bug
|
||||||
|
create table t1 (a int);
|
||||||
|
create temporary table tmp like t1;
|
||||||
|
load data local infile 'MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
|
||||||
|
insert into t1 select * from tmp;
|
||||||
|
#second bug
|
||||||
|
create table t2 (a int);
|
||||||
|
create temporary table tmp2 like t2;
|
||||||
|
insert into tmp2 values(10);
|
||||||
|
update tmp2 set a = 20 limit 1;
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
|
||||||
|
insert into t2 select * from tmp2;
|
||||||
|
connection server_2;
|
||||||
|
connection server_3;
|
||||||
|
#t1 should have 2 rows
|
||||||
|
select count(*) = 2 from t1;
|
||||||
|
count(*) = 2
|
||||||
|
1
|
||||||
|
#t2 should have 1 rows with a = 20
|
||||||
|
select * from t2;
|
||||||
|
a
|
||||||
|
20
|
||||||
|
connection server_1;
|
||||||
|
drop table t1, t2, tmp, tmp2;
|
||||||
|
include/rpl_end.inc
|
8
mysql-test/suite/rpl/t/mdev_24667.cnf
Normal file
8
mysql-test/suite/rpl/t/mdev_24667.cnf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
!include ../my.cnf
|
||||||
|
|
||||||
|
[mysqld.3]
|
||||||
|
log-slave-updates
|
||||||
|
|
||||||
|
[ENV]
|
||||||
|
SERVER_MYPORT_3= @mysqld.3.port
|
||||||
|
SERVER_MYSOCK_3= @mysqld.3.socket
|
56
mysql-test/suite/rpl/t/mdev_24667.test
Normal file
56
mysql-test/suite/rpl/t/mdev_24667.test
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#
|
||||||
|
# MDEV-24667 LOAD DATA INFILE/inserted rows not written to binlog
|
||||||
|
#
|
||||||
|
# In this test we will have a replication configuration like 1->2->3
|
||||||
|
# 1 will have statement format
|
||||||
|
# 2 and 3 will have mixed format
|
||||||
|
# We will make some updates on temporary table which are unsafe , So 2 must
|
||||||
|
# Log these queries in row format, Since it is on tmp table , It wont be logged
|
||||||
|
# So the next query which copies the data from tmp table to normal must be logged
|
||||||
|
# into the row format. Instead of checking for the binlog We will compare the
|
||||||
|
# results on the 3, If no binlog is lost(ie it is logged into row format), There
|
||||||
|
# should not be any data loss.
|
||||||
|
--let $rpl_topology=1->2->3
|
||||||
|
--source include/rpl_init.inc
|
||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
call mtr.add_suppression('Unsafe statement written to the binary log using ');
|
||||||
|
--connection server_1
|
||||||
|
|
||||||
|
set binlog_format=statement;
|
||||||
|
--echo #first bug
|
||||||
|
create table t1 (a int);
|
||||||
|
create temporary table tmp like t1;
|
||||||
|
--write_file $MYSQLTEST_VARDIR/load_data
|
||||||
|
1
|
||||||
|
2
|
||||||
|
EOF
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval load data local infile '$MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
|
||||||
|
insert into t1 select * from tmp;
|
||||||
|
|
||||||
|
--echo #second bug
|
||||||
|
create table t2 (a int);
|
||||||
|
#insert into t2 values(10);
|
||||||
|
create temporary table tmp2 like t2;
|
||||||
|
insert into tmp2 values(10);
|
||||||
|
update tmp2 set a = 20 limit 1;
|
||||||
|
insert into t2 select * from tmp2;
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection server_2
|
||||||
|
--sync_with_master
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection server_3
|
||||||
|
--sync_with_master
|
||||||
|
--echo #t1 should have 2 rows
|
||||||
|
select count(*) = 2 from t1;
|
||||||
|
--echo #t2 should have 1 rows with a = 20
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
--connection server_1
|
||||||
|
drop table t1, t2, tmp, tmp2;
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/load_data
|
||||||
|
--source include/rpl_end.inc
|
@ -46,12 +46,15 @@ static BOOL win_rename_with_retries(const char *from, const char *to)
|
|||||||
|
|
||||||
for (int retry= RENAME_MAX_RETRIES; retry--;)
|
for (int retry= RENAME_MAX_RETRIES; retry--;)
|
||||||
{
|
{
|
||||||
DWORD ret = MoveFileEx(from, to,
|
BOOL ret= MoveFileEx(from, to,
|
||||||
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
|
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
|
||||||
|
|
||||||
DBUG_ASSERT(fp == NULL || (ret == FALSE && GetLastError() == ERROR_SHARING_VIOLATION));
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!ret && (GetLastError() == ERROR_SHARING_VIOLATION))
|
DWORD last_error= GetLastError();
|
||||||
|
if (last_error == ERROR_SHARING_VIOLATION ||
|
||||||
|
last_error == ERROR_ACCESS_DENIED)
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
/*
|
/*
|
||||||
|
@ -2352,6 +2352,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
|
|||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
db_off= 608;
|
db_off= 608;
|
||||||
db_len_off= 616;
|
db_len_off= 616;
|
||||||
|
#elif __aarch64__
|
||||||
|
db_off= 632;
|
||||||
|
db_len_off= 640;
|
||||||
#else
|
#else
|
||||||
db_off= 0;
|
db_off= 0;
|
||||||
db_len_off= 0;
|
db_len_off= 0;
|
||||||
@ -2362,6 +2365,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
|
|||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
db_off= 536;
|
db_off= 536;
|
||||||
db_len_off= 544;
|
db_len_off= 544;
|
||||||
|
#elif __aarch64__
|
||||||
|
db_off= 552;
|
||||||
|
db_len_off= 560;
|
||||||
#else
|
#else
|
||||||
db_off= 0;
|
db_off= 0;
|
||||||
db_len_off= 0;
|
db_len_off= 0;
|
||||||
|
@ -275,6 +275,7 @@ ELSE()
|
|||||||
wsrep_sst_mysqldump
|
wsrep_sst_mysqldump
|
||||||
wsrep_sst_rsync
|
wsrep_sst_rsync
|
||||||
wsrep_sst_mariabackup
|
wsrep_sst_mariabackup
|
||||||
|
wsrep_sst_backup
|
||||||
)
|
)
|
||||||
# The following script is sourced from other SST scripts, so it should
|
# The following script is sourced from other SST scripts, so it should
|
||||||
# not be made executable.
|
# not be made executable.
|
||||||
|
@ -541,7 +541,7 @@ mysqld_install_cmd_line()
|
|||||||
{
|
{
|
||||||
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
|
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
|
||||||
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
|
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
|
||||||
"--plugin-dir=${plugindir}" --loose-disable-plugin-file-key-management \
|
"--plugin-dir=${plugindir}" \
|
||||||
$args --max_allowed_packet=8M \
|
$args --max_allowed_packet=8M \
|
||||||
--net_buffer_length=16K
|
--net_buffer_length=16K
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- Copyright (C) 2003, 2013 Oracle and/or its affiliates.
|
-- Copyright (C) 2003, 2013 Oracle and/or its affiliates.
|
||||||
-- Copyright (C) 2010, 2018 MariaDB Corporation
|
-- Copyright (C) 2010, 2022, MariaDB Corporation
|
||||||
--
|
--
|
||||||
-- This program is free software; you can redistribute it and/or modify
|
-- 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
|
-- it under the terms of the GNU General Public License as published by
|
||||||
@ -744,6 +744,13 @@ ALTER TABLE help_topic MODIFY url TEXT NOT NULL;
|
|||||||
# MDEV-7383 - varbinary on mix/max of column_stats
|
# MDEV-7383 - varbinary on mix/max of column_stats
|
||||||
alter table column_stats modify min_value varbinary(255) DEFAULT NULL, modify max_value varbinary(255) DEFAULT NULL;
|
alter table column_stats modify min_value varbinary(255) DEFAULT NULL, modify max_value varbinary(255) DEFAULT NULL;
|
||||||
|
|
||||||
|
# MDEV-21873: 10.2 to 10.3 upgrade doesn't remove semi-sync reference from
|
||||||
|
# mysql.plugin table.
|
||||||
|
# As per suggested fix, check INFORMATION_SCHEMA.PLUGINS
|
||||||
|
# and if semisync plugins aren't there, delete them from mysql.plugin.
|
||||||
|
DELETE FROM mysql.plugin WHERE name="rpl_semi_sync_master" AND NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME="rpl_semi_sync_master");
|
||||||
|
DELETE FROM mysql.plugin WHERE name="rpl_semi_sync_slave" AND NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME="rpl_semi_sync_slave");
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Ensure that all tables are of type Aria and transactional
|
-- Ensure that all tables are of type Aria and transactional
|
||||||
--
|
--
|
||||||
|
112
scripts/wsrep_sst_backup.sh
Normal file
112
scripts/wsrep_sst_backup.sh
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -ue
|
||||||
|
|
||||||
|
# Copyright (C) 2017-2021 MariaDB
|
||||||
|
# Copyright (C) 2010-2014 Codership Oy
|
||||||
|
#
|
||||||
|
# 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; see the file COPYING. If not, write to the
|
||||||
|
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
||||||
|
# MA 02110-1335 USA.
|
||||||
|
|
||||||
|
# This is a reference script for rsync-based state snapshot transfer
|
||||||
|
|
||||||
|
RSYNC_REAL_PID=0 # rsync process id
|
||||||
|
STUNNEL_REAL_PID=0 # stunnel process id
|
||||||
|
|
||||||
|
OS="$(uname)"
|
||||||
|
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
# Setting the path for lsof on CentOS
|
||||||
|
export PATH="/usr/sbin:/sbin:$PATH"
|
||||||
|
|
||||||
|
. $(dirname "$0")/wsrep_sst_common
|
||||||
|
|
||||||
|
MAGIC_FILE="$WSREP_SST_OPT_DATA/backup_sst_complete"
|
||||||
|
rm -rf "$MAGIC_FILE"
|
||||||
|
|
||||||
|
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
|
||||||
|
# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
|
||||||
|
if [ -z "$WSREP_LOG_DIR" ]; then
|
||||||
|
WSREP_LOG_DIR=$(parse_cnf mysqld innodb-log-group-home-dir '')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$WSREP_LOG_DIR" ]; then
|
||||||
|
# handle both relative and absolute paths
|
||||||
|
WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$WSREP_LOG_DIR"; cd $WSREP_LOG_DIR; pwd -P)
|
||||||
|
else
|
||||||
|
# default to datadir
|
||||||
|
WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
|
||||||
|
then
|
||||||
|
|
||||||
|
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||||
|
|
||||||
|
RC=0
|
||||||
|
|
||||||
|
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then
|
||||||
|
|
||||||
|
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
|
||||||
|
ERROR="$WSREP_SST_OPT_DATA/sst_error"
|
||||||
|
|
||||||
|
[ -f "$FLUSHED" ] && rm -f "$FLUSHED"
|
||||||
|
[ -f "$ERROR" ] && rm -f "$ERROR"
|
||||||
|
|
||||||
|
echo "flush tables"
|
||||||
|
|
||||||
|
# Wait for :
|
||||||
|
# (a) Tables to be flushed, AND
|
||||||
|
# (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR
|
||||||
|
# (c) ERROR file, in case flush tables operation failed.
|
||||||
|
|
||||||
|
while [ ! -r "$FLUSHED" ] && \
|
||||||
|
! grep -q -F ':' '--' "$FLUSHED" >/dev/null 2>&1
|
||||||
|
do
|
||||||
|
# Check whether ERROR file exists.
|
||||||
|
if [ -f "$ERROR" ]; then
|
||||||
|
# Flush tables operation failed.
|
||||||
|
rm -f "$ERROR"
|
||||||
|
exit 255
|
||||||
|
fi
|
||||||
|
sleep 0.2
|
||||||
|
done
|
||||||
|
|
||||||
|
STATE=$(cat "$FLUSHED")
|
||||||
|
rm -f "$FLUSHED"
|
||||||
|
|
||||||
|
|
||||||
|
else # BYPASS
|
||||||
|
|
||||||
|
wsrep_log_info "Bypassing state dump."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'continue' # now server can resume updating data
|
||||||
|
|
||||||
|
echo "$STATE" > "$MAGIC_FILE"
|
||||||
|
|
||||||
|
echo "done $STATE"
|
||||||
|
|
||||||
|
elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
|
||||||
|
then
|
||||||
|
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
|
||||||
|
exit 22 # EINVAL
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
|
||||||
|
exit 22 # EINVAL
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
@ -42,6 +42,8 @@ struct show_table_contributors_st show_table_contributors[]= {
|
|||||||
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
|
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
|
||||||
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
|
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
|
||||||
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"},
|
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"},
|
||||||
|
{"Intel", "https://www.intel.com", "Platinum Sponsor of the MariaDB Foundation"},
|
||||||
|
{"SIT", "https://sit.org", "Platinum Sponsor of the MariaDB Foundation"},
|
||||||
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
|
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||||
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
|
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||||
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
|
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define HANDLER_INCLUDED
|
#define HANDLER_INCLUDED
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2021, MariaDB
|
Copyright (c) 2009, 2022, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
@ -5001,7 +5001,7 @@ static inline const char *ha_resolve_storage_engine_name(const handlerton *db_ty
|
|||||||
|
|
||||||
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
|
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
|
||||||
{
|
{
|
||||||
return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
|
return db_type && (db_type->flags & flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
|
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
|
||||||
|
20
sql/item.cc
20
sql/item.cc
@ -2676,9 +2676,11 @@ Item_sp::func_name(THD *thd) const
|
|||||||
/* Calculate length to avoid reallocation of string for sure */
|
/* Calculate length to avoid reallocation of string for sure */
|
||||||
size_t len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
|
size_t len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
|
||||||
m_name->m_name.length)*2 + //characters*quoting
|
m_name->m_name.length)*2 + //characters*quoting
|
||||||
2 + // ` and `
|
2 + // quotes for the function name
|
||||||
|
2 + // quotes for the package name
|
||||||
(m_name->m_explicit_name ?
|
(m_name->m_explicit_name ?
|
||||||
3 : 0) + // '`', '`' and '.' for the db
|
3 : 0) + // '`', '`' and '.' for the db
|
||||||
|
1 + // '.' between package and function
|
||||||
1 + // end of string
|
1 + // end of string
|
||||||
ALIGN_SIZE(1)); // to avoid String reallocation
|
ALIGN_SIZE(1)); // to avoid String reallocation
|
||||||
String qname((char *)alloc_root(thd->mem_root, len), len,
|
String qname((char *)alloc_root(thd->mem_root, len), len,
|
||||||
@ -2690,7 +2692,21 @@ Item_sp::func_name(THD *thd) const
|
|||||||
append_identifier(thd, &qname, &m_name->m_db);
|
append_identifier(thd, &qname, &m_name->m_db);
|
||||||
qname.append('.');
|
qname.append('.');
|
||||||
}
|
}
|
||||||
append_identifier(thd, &qname, &m_name->m_name);
|
if (m_sp && m_sp->m_handler == &sp_handler_package_function)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
In case of a package function split `pkg.func` and print
|
||||||
|
quoted `pkg` and `func` separately, so the entire result looks like:
|
||||||
|
`db`.`pkg`.`func`
|
||||||
|
*/
|
||||||
|
Database_qualified_name tmp= Database_qualified_name::split(m_name->m_name);
|
||||||
|
DBUG_ASSERT(tmp.m_db.length);
|
||||||
|
append_identifier(thd, &qname, &tmp.m_db);
|
||||||
|
qname.append('.');
|
||||||
|
append_identifier(thd, &qname, &tmp.m_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
append_identifier(thd, &qname, &m_name->m_name);
|
||||||
return qname.c_ptr_safe();
|
return qname.c_ptr_safe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4695,10 +4695,11 @@ void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
|
|||||||
Query_arena *arena, backup;
|
Query_arena *arena, backup;
|
||||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||||
|
|
||||||
if (to_be_transformed_into_in_subq(thd))
|
if (!transform_into_subq_checked)
|
||||||
{
|
{
|
||||||
transform_into_subq= true;
|
if ((transform_into_subq= to_be_transformed_into_in_subq(thd)))
|
||||||
thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
|
thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
|
||||||
|
transform_into_subq_checked= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arena)
|
if (arena)
|
||||||
|
@ -2345,6 +2345,7 @@ protected:
|
|||||||
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
|
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
|
||||||
Field *field, Item *value);
|
Field *field, Item *value);
|
||||||
bool transform_into_subq;
|
bool transform_into_subq;
|
||||||
|
bool transform_into_subq_checked;
|
||||||
public:
|
public:
|
||||||
/// An array of values, created when the bisection lookup method is used
|
/// An array of values, created when the bisection lookup method is used
|
||||||
in_vector *array;
|
in_vector *array;
|
||||||
@ -2367,6 +2368,7 @@ public:
|
|||||||
Item_func_opt_neg(thd, list),
|
Item_func_opt_neg(thd, list),
|
||||||
Predicant_to_list_comparator(thd, arg_count - 1),
|
Predicant_to_list_comparator(thd, arg_count - 1),
|
||||||
transform_into_subq(false),
|
transform_into_subq(false),
|
||||||
|
transform_into_subq_checked(false),
|
||||||
array(0), have_null(0),
|
array(0), have_null(0),
|
||||||
arg_types_compatible(FALSE), emb_on_expr_nest(0)
|
arg_types_compatible(FALSE), emb_on_expr_nest(0)
|
||||||
{ }
|
{ }
|
||||||
|
@ -1669,7 +1669,7 @@ end:
|
|||||||
{
|
{
|
||||||
table->file->ha_index_or_rnd_end();
|
table->file->ha_index_or_rnd_end();
|
||||||
ha_commit_trans(thd, FALSE);
|
ha_commit_trans(thd, FALSE);
|
||||||
ha_commit_trans(thd, TRUE);
|
trans_commit(thd);
|
||||||
}
|
}
|
||||||
if (table_opened)
|
if (table_opened)
|
||||||
{
|
{
|
||||||
|
@ -1229,6 +1229,7 @@ int Repl_semi_sync_master::flush_net(THD *thd,
|
|||||||
|
|
||||||
net_clear(net, 0);
|
net_clear(net, 0);
|
||||||
net->pkt_nr++;
|
net->pkt_nr++;
|
||||||
|
net->compress_pkt_nr++;
|
||||||
result = 0;
|
result = 0;
|
||||||
rpl_semi_sync_master_net_wait_num++;
|
rpl_semi_sync_master_net_wait_num++;
|
||||||
|
|
||||||
|
@ -3471,6 +3471,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
lex_query_tables_own_last= m_lex->query_tables_own_last;
|
lex_query_tables_own_last= m_lex->query_tables_own_last;
|
||||||
prelocking_tables= *lex_query_tables_own_last;
|
prelocking_tables= *lex_query_tables_own_last;
|
||||||
*lex_query_tables_own_last= NULL;
|
*lex_query_tables_own_last= NULL;
|
||||||
|
m_lex->query_tables_last= m_lex->query_tables_own_last;
|
||||||
m_lex->mark_as_requiring_prelocking(NULL);
|
m_lex->mark_as_requiring_prelocking(NULL);
|
||||||
}
|
}
|
||||||
thd->rollback_item_tree_changes();
|
thd->rollback_item_tree_changes();
|
||||||
|
@ -4195,13 +4195,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
DBUG_PRINT("debug",
|
DBUG_PRINT("debug",
|
||||||
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
|
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
|
||||||
YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
|
YESNO(has_temporary_tables()), YESNO(in_sub_stmt),
|
||||||
show_system_thread(system_thread)));
|
show_system_thread(system_thread)));
|
||||||
if (in_sub_stmt == 0)
|
if (in_sub_stmt == 0)
|
||||||
{
|
{
|
||||||
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
||||||
set_current_stmt_binlog_format_row();
|
set_current_stmt_binlog_format_row();
|
||||||
else if (!has_thd_temporary_tables())
|
else if (!has_temporary_tables())
|
||||||
set_current_stmt_binlog_format_stmt();
|
set_current_stmt_binlog_format_stmt();
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -6852,6 +6852,19 @@ public:
|
|||||||
}
|
}
|
||||||
void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db,
|
void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db,
|
||||||
const LEX_CSTRING &name);
|
const LEX_CSTRING &name);
|
||||||
|
|
||||||
|
static Database_qualified_name split(const LEX_CSTRING &txt)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input
|
||||||
|
const char *dot= strchr(txt.str, '.');
|
||||||
|
if (!dot)
|
||||||
|
return Database_qualified_name(NULL, 0, txt.str, txt.length);
|
||||||
|
size_t dblen= dot - txt.str;
|
||||||
|
Lex_cstring db(txt.str, dblen);
|
||||||
|
Lex_cstring name(txt.str + dblen + 1, txt.length - dblen - 1);
|
||||||
|
return Database_qualified_name(db, name);
|
||||||
|
}
|
||||||
|
|
||||||
// Export db and name as a qualified name string: 'db.name'
|
// Export db and name as a qualified name string: 'db.name'
|
||||||
size_t make_qname(char *dst, size_t dstlen) const
|
size_t make_qname(char *dst, size_t dstlen) const
|
||||||
{
|
{
|
||||||
|
@ -8493,6 +8493,40 @@ bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::call_statement_start(THD *thd, const LEX_CSTRING &db,
|
||||||
|
const LEX_CSTRING &pkg,
|
||||||
|
const LEX_CSTRING &proc)
|
||||||
|
{
|
||||||
|
Database_qualified_name q_db_pkg(db, pkg);
|
||||||
|
Database_qualified_name q_pkg_proc(pkg, proc);
|
||||||
|
sp_name *spname;
|
||||||
|
|
||||||
|
sql_command= SQLCOM_CALL;
|
||||||
|
|
||||||
|
if (check_db_name((LEX_STRING*) const_cast<LEX_CSTRING*>(&db)))
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (check_routine_name(&pkg) ||
|
||||||
|
check_routine_name(&proc))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Concat `pkg` and `name` to `pkg.name`
|
||||||
|
LEX_CSTRING pkg_dot_proc;
|
||||||
|
if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) ||
|
||||||
|
check_ident_length(&pkg_dot_proc) ||
|
||||||
|
!(spname= new (thd->mem_root) sp_name(&db, &pkg_dot_proc, true)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sp_handler_package_function.add_used_routine(thd->lex, thd, spname);
|
||||||
|
sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
|
||||||
|
|
||||||
|
return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(spname,
|
||||||
|
&sp_handler_package_procedure));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sp_package *LEX::get_sp_package() const
|
sp_package *LEX::get_sp_package() const
|
||||||
{
|
{
|
||||||
return sphead ? sphead->get_package() : NULL;
|
return sphead ? sphead->get_package() : NULL;
|
||||||
@ -8750,6 +8784,56 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a 3-step qualified function call.
|
||||||
|
Currently it's possible for package routines only, e.g.:
|
||||||
|
SELECT db.pkg.func();
|
||||||
|
*/
|
||||||
|
Item *LEX::make_item_func_call_generic(THD *thd,
|
||||||
|
Lex_ident_cli_st *cdb,
|
||||||
|
Lex_ident_cli_st *cpkg,
|
||||||
|
Lex_ident_cli_st *cfunc,
|
||||||
|
List<Item> *args)
|
||||||
|
{
|
||||||
|
static Lex_cstring dot(".", 1);
|
||||||
|
Lex_ident_sys db(thd, cdb), pkg(thd, cpkg), func(thd, cfunc);
|
||||||
|
Database_qualified_name q_db_pkg(db, pkg);
|
||||||
|
Database_qualified_name q_pkg_func(pkg, func);
|
||||||
|
sp_name *qname;
|
||||||
|
|
||||||
|
if (db.is_null() || pkg.is_null() || func.is_null())
|
||||||
|
return NULL; // EOM
|
||||||
|
|
||||||
|
if (check_db_name((LEX_STRING*) static_cast<LEX_CSTRING*>(&db)))
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (check_routine_name(&pkg) ||
|
||||||
|
check_routine_name(&func))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Concat `pkg` and `name` to `pkg.name`
|
||||||
|
LEX_CSTRING pkg_dot_func;
|
||||||
|
if (q_pkg_func.make_qname(thd->mem_root, &pkg_dot_func) ||
|
||||||
|
check_ident_length(&pkg_dot_func) ||
|
||||||
|
!(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sp_handler_package_function.add_used_routine(thd->lex, thd, qname);
|
||||||
|
sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
|
||||||
|
|
||||||
|
thd->lex->safe_to_cache_query= 0;
|
||||||
|
|
||||||
|
if (args && args->elements > 0)
|
||||||
|
return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
|
||||||
|
qname, &sp_handler_package_function,
|
||||||
|
*args);
|
||||||
|
return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
|
||||||
|
qname, &sp_handler_package_function);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *LEX::create_item_qualified_asterisk(THD *thd,
|
Item *LEX::create_item_qualified_asterisk(THD *thd,
|
||||||
const Lex_ident_sys_st *name)
|
const Lex_ident_sys_st *name)
|
||||||
{
|
{
|
||||||
|
@ -3798,6 +3798,9 @@ public:
|
|||||||
bool call_statement_start(THD *thd, const LEX_CSTRING *name);
|
bool call_statement_start(THD *thd, const LEX_CSTRING *name);
|
||||||
bool call_statement_start(THD *thd, const LEX_CSTRING *name1,
|
bool call_statement_start(THD *thd, const LEX_CSTRING *name1,
|
||||||
const LEX_CSTRING *name2);
|
const LEX_CSTRING *name2);
|
||||||
|
bool call_statement_start(THD *thd, const LEX_CSTRING &name1,
|
||||||
|
const LEX_CSTRING &name2,
|
||||||
|
const LEX_CSTRING &name3);
|
||||||
sp_variable *find_variable(const LEX_CSTRING *name,
|
sp_variable *find_variable(const LEX_CSTRING *name,
|
||||||
sp_pcontext **ctx,
|
sp_pcontext **ctx,
|
||||||
const Sp_rcontext_handler **rh) const;
|
const Sp_rcontext_handler **rh) const;
|
||||||
@ -4024,6 +4027,11 @@ public:
|
|||||||
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
|
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
|
||||||
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
|
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
|
||||||
Lex_ident_cli_st *name, List<Item> *args);
|
Lex_ident_cli_st *name, List<Item> *args);
|
||||||
|
Item *make_item_func_call_generic(THD *thd,
|
||||||
|
Lex_ident_cli_st *db,
|
||||||
|
Lex_ident_cli_st *pkg,
|
||||||
|
Lex_ident_cli_st *name,
|
||||||
|
List<Item> *args);
|
||||||
my_var *create_outvar(THD *thd, const LEX_CSTRING *name);
|
my_var *create_outvar(THD *thd, const LEX_CSTRING *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB
|
Copyright (c) 2009, 2022, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -3375,6 +3375,16 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg)
|
|||||||
arg->table->field[11]->store((double) tmp->progress.counter /
|
arg->table->field[11]->store((double) tmp->progress.counter /
|
||||||
(double) max_counter*100.0);
|
(double) max_counter*100.0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is a DECIMAL column without DEFAULT.
|
||||||
|
restore_record() fills its Field::ptr to zero bytes,
|
||||||
|
according to pack_length(). But an array of zero bytes
|
||||||
|
is not a valid decimal. Set it explicitly to 0.
|
||||||
|
*/
|
||||||
|
arg->table->field[11]->store((longlong) 0, true);
|
||||||
|
}
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9807,22 +9807,24 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
|||||||
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
|
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handlerton * const old_db_type= table->s->db_type();
|
||||||
|
handlerton *new_db_type= create_info->db_type;
|
||||||
|
|
||||||
DBUG_PRINT("info", ("old type: %s new type: %s",
|
DBUG_PRINT("info", ("old type: %s new type: %s",
|
||||||
ha_resolve_storage_engine_name(table->s->db_type()),
|
ha_resolve_storage_engine_name(old_db_type),
|
||||||
ha_resolve_storage_engine_name(create_info->db_type)));
|
ha_resolve_storage_engine_name(new_db_type)));
|
||||||
if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED))
|
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("doesn't support alter"));
|
DBUG_PRINT("info", ("doesn't support alter"));
|
||||||
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(table->s->db_type())->str,
|
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str,
|
||||||
alter_ctx.db.str, alter_ctx.table_name.str);
|
alter_ctx.db.str, alter_ctx.table_name.str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ha_check_storage_engine_flag(create_info->db_type,
|
if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||||
HTON_ALTER_NOT_SUPPORTED))
|
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("doesn't support alter"));
|
DBUG_PRINT("info", ("doesn't support alter"));
|
||||||
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(create_info->db_type)->str,
|
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str,
|
||||||
alter_ctx.new_db.str, alter_ctx.new_name.str);
|
alter_ctx.new_db.str, alter_ctx.new_name.str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
@ -9980,6 +9982,17 @@ do_continue:;
|
|||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
If the old table had partitions and we are doing ALTER TABLE ...
|
||||||
|
engine= <new_engine>, the new table must preserve the original
|
||||||
|
partitioning. This means that the new engine is still the
|
||||||
|
partitioning engine, not the engine specified in the parser.
|
||||||
|
This is discovered in prep_alter_part_table, which in such case
|
||||||
|
updates create_info->db_type.
|
||||||
|
It's therefore important that the assignment below is done
|
||||||
|
after prep_alter_part_table.
|
||||||
|
*/
|
||||||
|
new_db_type= create_info->db_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
|
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
|
||||||
@ -10060,7 +10073,7 @@ do_continue:;
|
|||||||
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
||||||
|| is_inplace_alter_impossible(table, create_info, alter_info)
|
|| is_inplace_alter_impossible(table, create_info, alter_info)
|
||||||
|| IF_PARTITIONING((partition_changed &&
|
|| IF_PARTITIONING((partition_changed &&
|
||||||
!(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
|
!(old_db_type->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
|
||||||
{
|
{
|
||||||
if (alter_info->algorithm(thd) ==
|
if (alter_info->algorithm(thd) ==
|
||||||
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
||||||
@ -10078,22 +10091,10 @@ do_continue:;
|
|||||||
request table rebuild. Set ALTER_RECREATE flag to force table
|
request table rebuild. Set ALTER_RECREATE flag to force table
|
||||||
rebuild.
|
rebuild.
|
||||||
*/
|
*/
|
||||||
if (create_info->db_type == table->s->db_type() &&
|
if (new_db_type == old_db_type &&
|
||||||
create_info->used_fields & HA_CREATE_USED_ENGINE)
|
create_info->used_fields & HA_CREATE_USED_ENGINE)
|
||||||
alter_info->flags|= ALTER_RECREATE;
|
alter_info->flags|= ALTER_RECREATE;
|
||||||
|
|
||||||
/*
|
|
||||||
If the old table had partitions and we are doing ALTER TABLE ...
|
|
||||||
engine= <new_engine>, the new table must preserve the original
|
|
||||||
partitioning. This means that the new engine is still the
|
|
||||||
partitioning engine, not the engine specified in the parser.
|
|
||||||
This is discovered in prep_alter_part_table, which in such case
|
|
||||||
updates create_info->db_type.
|
|
||||||
It's therefore important that the assignment below is done
|
|
||||||
after prep_alter_part_table.
|
|
||||||
*/
|
|
||||||
handlerton *new_db_type= create_info->db_type;
|
|
||||||
handlerton *old_db_type= table->s->db_type();
|
|
||||||
TABLE *new_table= NULL;
|
TABLE *new_table= NULL;
|
||||||
ha_rows copied=0,deleted=0;
|
ha_rows copied=0,deleted=0;
|
||||||
|
|
||||||
|
@ -899,8 +899,6 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
|
|||||||
if (!transform_into_subq)
|
if (!transform_into_subq)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
transform_into_subq= false;
|
|
||||||
|
|
||||||
List<List_item> values;
|
List<List_item> values;
|
||||||
|
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
@ -1057,15 +1055,38 @@ uint32 Item_func_in::max_length_of_left_expr()
|
|||||||
|
|
||||||
bool Item_func_in::to_be_transformed_into_in_subq(THD *thd)
|
bool Item_func_in::to_be_transformed_into_in_subq(THD *thd)
|
||||||
{
|
{
|
||||||
|
bool is_row_list= args[1]->type() == Item::ROW_ITEM;
|
||||||
uint values_count= arg_count-1;
|
uint values_count= arg_count-1;
|
||||||
|
|
||||||
if (args[1]->type() == Item::ROW_ITEM)
|
if (is_row_list)
|
||||||
values_count*= ((Item_row *)(args[1]))->cols();
|
values_count*= ((Item_row *)(args[1]))->cols();
|
||||||
|
|
||||||
if (thd->variables.in_subquery_conversion_threshold == 0 ||
|
if (thd->variables.in_subquery_conversion_threshold == 0 ||
|
||||||
thd->variables.in_subquery_conversion_threshold > values_count)
|
thd->variables.in_subquery_conversion_threshold > values_count)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Occurence of '?' in IN list is checked only for PREPARE <stmt> commands */
|
||||||
|
for (uint i=1; i < arg_count; i++)
|
||||||
|
{
|
||||||
|
if (!is_row_list)
|
||||||
|
{
|
||||||
|
if (args[i]->type() == Item::PARAM_ITEM)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Item_row *row_list= (Item_row *)(args[i]);
|
||||||
|
for (uint j=0; j < row_list->cols(); j++)
|
||||||
|
{
|
||||||
|
if (row_list->element_index(j)->type() == Item::PARAM_ITEM)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2288,6 +2288,11 @@ multi_update::initialize_tables(JOIN *join)
|
|||||||
if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
|
if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
|
||||||
error_if_full_join(join)))
|
error_if_full_join(join)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
if (join->implicit_grouping)
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
main_table=join->join_tab->table;
|
main_table=join->join_tab->table;
|
||||||
table_to_update= 0;
|
table_to_update= 0;
|
||||||
|
|
||||||
|
@ -97,7 +97,8 @@ static void make_unique_view_field_name(THD *thd, Item *target,
|
|||||||
itc.rewind();
|
itc.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
target->orig_name= target->name.str;
|
if (!target->orig_name)
|
||||||
|
target->orig_name= target->name.str;
|
||||||
target->set_name(thd, buff, name_len, system_charset_info);
|
target->set_name(thd, buff, name_len, system_charset_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3336,9 +3336,29 @@ sp_suid:
|
|||||||
;
|
;
|
||||||
|
|
||||||
call:
|
call:
|
||||||
CALL_SYM sp_name
|
CALL_SYM ident
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->call_statement_start(thd, $2)))
|
if (unlikely(Lex->call_statement_start(thd, &$2)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| CALL_SYM ident '.' ident
|
||||||
|
{
|
||||||
|
if (unlikely(Lex->call_statement_start(thd, &$2, &$4)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| CALL_SYM ident '.' ident '.' ident
|
||||||
|
{
|
||||||
|
if (unlikely(Lex->call_statement_start(thd, $2, $4, $6)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list
|
opt_sp_cparam_list
|
||||||
@ -11451,6 +11471,11 @@ function_call_generic:
|
|||||||
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
|
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
| ident_cli '.' ident_cli '.' ident_cli '(' opt_expr_list ')'
|
||||||
|
{
|
||||||
|
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7))))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
fulltext_options:
|
fulltext_options:
|
||||||
|
@ -3138,9 +3138,29 @@ sp_suid:
|
|||||||
;
|
;
|
||||||
|
|
||||||
call:
|
call:
|
||||||
CALL_SYM sp_name
|
CALL_SYM ident
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->call_statement_start(thd, $2)))
|
if (unlikely(Lex->call_statement_start(thd, &$2)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| CALL_SYM ident '.' ident
|
||||||
|
{
|
||||||
|
if (unlikely(Lex->call_statement_start(thd, &$2, &$4)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| CALL_SYM ident '.' ident '.' ident
|
||||||
|
{
|
||||||
|
if (unlikely(Lex->call_statement_start(thd, $2, $4, $6)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list
|
opt_sp_cparam_list
|
||||||
@ -4054,12 +4074,30 @@ sp_statement:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| ident_directly_assignable '.' ident
|
| ident_directly_assignable '.' ident
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->call_statement_start(thd, &$1, &$3)))
|
if (unlikely(Lex->call_statement_start(thd, &$1, &$3)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| ident_directly_assignable '.' ident '.' ident
|
||||||
|
{
|
||||||
|
if (unlikely(Lex->call_statement_start(thd, $1, $3, $5)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_proc_stmt_statement:
|
sp_proc_stmt_statement:
|
||||||
@ -11549,6 +11587,11 @@ function_call_generic:
|
|||||||
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
|
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
| ident_cli '.' ident_cli '.' ident_cli '(' opt_expr_list ')'
|
||||||
|
{
|
||||||
|
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7))))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
fulltext_options:
|
fulltext_options:
|
||||||
|
22
sql/table.cc
22
sql/table.cc
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2008, 2021, MariaDB
|
Copyright (c) 2008, 2022, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -1627,6 +1627,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
|
|
||||||
MEM_ROOT *old_root= thd->mem_root;
|
MEM_ROOT *old_root= thd->mem_root;
|
||||||
Virtual_column_info **table_check_constraints;
|
Virtual_column_info **table_check_constraints;
|
||||||
|
bool *interval_unescaped= NULL;
|
||||||
extra2_fields extra2;
|
extra2_fields extra2;
|
||||||
|
|
||||||
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
|
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
|
||||||
@ -2047,6 +2048,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
|
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (interval_count)
|
||||||
|
{
|
||||||
|
if (!(interval_unescaped= (bool*) my_alloca(interval_count * sizeof(bool))))
|
||||||
|
goto err;
|
||||||
|
bzero(interval_unescaped, interval_count * sizeof(bool));
|
||||||
|
}
|
||||||
|
|
||||||
field_ptr= share->field;
|
field_ptr= share->field;
|
||||||
table_check_constraints= share->check_constraints;
|
table_check_constraints= share->check_constraints;
|
||||||
read_length=(uint) (share->fields * field_pack_length +
|
read_length=(uint) (share->fields * field_pack_length +
|
||||||
@ -2323,11 +2331,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
if (share->mysql_version < 100200)
|
if (share->mysql_version < 100200)
|
||||||
attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
|
attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
|
||||||
|
|
||||||
if (interval_nr && attr.charset->mbminlen > 1)
|
if (interval_nr && attr.charset->mbminlen > 1 &&
|
||||||
|
!interval_unescaped[interval_nr - 1])
|
||||||
{
|
{
|
||||||
/* Unescape UCS2 intervals from HEX notation */
|
/*
|
||||||
|
Unescape UCS2/UTF16/UTF32 intervals from HEX notation.
|
||||||
|
Note, ENUM/SET columns with equal value list share a single
|
||||||
|
copy of TYPELIB. Unescape every TYPELIB only once.
|
||||||
|
*/
|
||||||
TYPELIB *interval= share->intervals + interval_nr - 1;
|
TYPELIB *interval= share->intervals + interval_nr - 1;
|
||||||
unhex_type2(interval);
|
unhex_type2(interval);
|
||||||
|
interval_unescaped[interval_nr - 1]= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TO_BE_DELETED_ON_PRODUCTION
|
#ifndef TO_BE_DELETED_ON_PRODUCTION
|
||||||
@ -3060,6 +3074,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
share->error= OPEN_FRM_OK;
|
share->error= OPEN_FRM_OK;
|
||||||
thd->status_var.opened_shares++;
|
thd->status_var.opened_shares++;
|
||||||
thd->mem_root= old_root;
|
thd->mem_root= old_root;
|
||||||
|
my_afree(interval_unescaped);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -3074,6 +3089,7 @@ err:
|
|||||||
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
|
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
|
||||||
|
|
||||||
thd->mem_root= old_root;
|
thd->mem_root= old_root;
|
||||||
|
my_afree(interval_unescaped);
|
||||||
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
|
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,7 +873,7 @@ void THD::restore_tmp_table_share(TMP_TABLE_SHARE *share)
|
|||||||
@return false Temporary tables exist
|
@return false Temporary tables exist
|
||||||
true No temporary table exist
|
true No temporary table exist
|
||||||
*/
|
*/
|
||||||
inline bool THD::has_temporary_tables()
|
bool THD::has_temporary_tables()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("THD::has_temporary_tables");
|
DBUG_ENTER("THD::has_temporary_tables");
|
||||||
bool result=
|
bool result=
|
||||||
|
@ -830,7 +830,16 @@ static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
|
|||||||
|
|
||||||
while ((field=it++) != last_field)
|
while ((field=it++) != last_field)
|
||||||
{
|
{
|
||||||
if (field->interval_id && field->interval->count == interval->count)
|
/*
|
||||||
|
ENUM/SET columns with equal value lists share a single
|
||||||
|
copy of the underlying TYPELIB.
|
||||||
|
Fields with different mbminlen can't reuse TYPELIBs, because:
|
||||||
|
- mbminlen==1 are written to FRM as is
|
||||||
|
- mbminlen>1 are written to FRM in hex-encoded format
|
||||||
|
*/
|
||||||
|
if (field->interval_id &&
|
||||||
|
field->interval->count == interval->count &&
|
||||||
|
field->charset->mbminlen == last_field->charset->mbminlen)
|
||||||
{
|
{
|
||||||
const char **a,**b;
|
const char **a,**b;
|
||||||
for (a=field->interval->type_names, b=interval->type_names ;
|
for (a=field->interval->type_names, b=interval->type_names ;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2008-2020 Codership Oy <http://www.codership.com>
|
/* Copyright 2008-2022 Codership Oy <http://www.codership.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include "debug_sync.h"
|
||||||
|
|
||||||
#include <my_service_manager.h>
|
#include <my_service_manager.h>
|
||||||
|
|
||||||
@ -1504,6 +1505,33 @@ static int run_sql_command(THD *thd, const char *query)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sst_disallow_writes (THD* thd, bool yes)
|
||||||
|
{
|
||||||
|
char query_str[64]= { 0, };
|
||||||
|
ssize_t const query_max= sizeof(query_str) - 1;
|
||||||
|
CHARSET_INFO *current_charset;
|
||||||
|
|
||||||
|
current_charset= thd->variables.character_set_client;
|
||||||
|
|
||||||
|
if (!is_supported_parser_charset(current_charset))
|
||||||
|
{
|
||||||
|
/* Do not use non-supported parser character sets */
|
||||||
|
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
|
||||||
|
thd->variables.character_set_client= &my_charset_latin1;
|
||||||
|
WSREP_WARN("For SST temporally setting character set to : %s",
|
||||||
|
my_charset_latin1.csname);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
|
||||||
|
yes ? 1 : 0);
|
||||||
|
|
||||||
|
if (run_sql_command(thd, query_str))
|
||||||
|
{
|
||||||
|
WSREP_ERROR("Failed to disallow InnoDB writes");
|
||||||
|
}
|
||||||
|
thd->variables.character_set_client= current_charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int sst_flush_tables(THD* thd)
|
static int sst_flush_tables(THD* thd)
|
||||||
{
|
{
|
||||||
@ -1565,6 +1593,11 @@ static int sst_flush_tables(THD* thd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WSREP_INFO("Tables flushed.");
|
WSREP_INFO("Tables flushed.");
|
||||||
|
|
||||||
|
/* disable further disk IO */
|
||||||
|
sst_disallow_writes(thd, true);
|
||||||
|
WSREP_INFO("Disabled further disk IO.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tables have been flushed. Create a file with cluster state ID and
|
Tables have been flushed. Create a file with cluster state ID and
|
||||||
wsrep_gtid_domain_id.
|
wsrep_gtid_domain_id.
|
||||||
@ -1574,6 +1607,9 @@ static int sst_flush_tables(THD* thd)
|
|||||||
(long long)wsrep_locked_seqno, wsrep_gtid_domain_id);
|
(long long)wsrep_locked_seqno, wsrep_gtid_domain_id);
|
||||||
err= sst_create_file(flush_success, content);
|
err= sst_create_file(flush_success, content);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
WSREP_INFO("Creating file for flush_success failed %d",err);
|
||||||
|
|
||||||
const char base_name[]= "tables_flushed";
|
const char base_name[]= "tables_flushed";
|
||||||
ssize_t const full_len= strlen(mysql_real_data_home) + strlen(base_name)+2;
|
ssize_t const full_len= strlen(mysql_real_data_home) + strlen(base_name)+2;
|
||||||
char *real_name= (char*) malloc(full_len);
|
char *real_name= (char*) malloc(full_len);
|
||||||
@ -1613,34 +1649,6 @@ static int sst_flush_tables(THD* thd)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sst_disallow_writes (THD* thd, bool yes)
|
|
||||||
{
|
|
||||||
char query_str[64]= { 0, };
|
|
||||||
ssize_t const query_max= sizeof(query_str) - 1;
|
|
||||||
CHARSET_INFO *current_charset;
|
|
||||||
|
|
||||||
current_charset= thd->variables.character_set_client;
|
|
||||||
|
|
||||||
if (!is_supported_parser_charset(current_charset))
|
|
||||||
{
|
|
||||||
/* Do not use non-supported parser character sets */
|
|
||||||
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
|
|
||||||
thd->variables.character_set_client= &my_charset_latin1;
|
|
||||||
WSREP_WARN("For SST temporally setting character set to : %s",
|
|
||||||
my_charset_latin1.csname);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
|
|
||||||
yes ? 1 : 0);
|
|
||||||
|
|
||||||
if (run_sql_command(thd, query_str))
|
|
||||||
{
|
|
||||||
WSREP_ERROR("Failed to disallow InnoDB writes");
|
|
||||||
}
|
|
||||||
thd->variables.character_set_client= current_charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* sst_donor_thread (void* a)
|
static void* sst_donor_thread (void* a)
|
||||||
{
|
{
|
||||||
sst_thread_arg* arg= (sst_thread_arg*)a;
|
sst_thread_arg* arg= (sst_thread_arg*)a;
|
||||||
@ -1688,8 +1696,7 @@ wait_signal:
|
|||||||
err= sst_flush_tables (thd.ptr);
|
err= sst_flush_tables (thd.ptr);
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
sst_disallow_writes (thd.ptr, true);
|
/*
|
||||||
/*
|
|
||||||
Lets also keep statements that modify binary logs (like RESET LOGS,
|
Lets also keep statements that modify binary logs (like RESET LOGS,
|
||||||
RESET MASTER) from proceeding until the files have been transferred
|
RESET MASTER) from proceeding until the files have been transferred
|
||||||
to the joiner node.
|
to the joiner node.
|
||||||
@ -1700,6 +1707,18 @@ wait_signal:
|
|||||||
}
|
}
|
||||||
|
|
||||||
locked= true;
|
locked= true;
|
||||||
|
|
||||||
|
WSREP_INFO("Donor state reached");
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("sync.wsrep_donor_state",
|
||||||
|
{
|
||||||
|
const char act[]=
|
||||||
|
"now "
|
||||||
|
"SIGNAL sync.wsrep_donor_state_reached "
|
||||||
|
"WAIT_FOR signal.wsrep_donor_state";
|
||||||
|
assert(!debug_sync_set_action(thd.ptr,
|
||||||
|
STRING_WITH_LEN(act)));
|
||||||
|
};);
|
||||||
goto wait_signal;
|
goto wait_signal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Copyright (c) 1995, 2021, Oracle and/or its affiliates.
|
Copyright (c) 1995, 2021, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2008, Google Inc.
|
Copyright (c) 2008, Google Inc.
|
||||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
Copyright (c) 2013, 2022, MariaDB Corporation.
|
||||||
|
|
||||||
Portions of this file contain modifications contributed and copyrighted by
|
Portions of this file contain modifications contributed and copyrighted by
|
||||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||||
@ -1021,9 +1021,6 @@ buf_page_is_corrupted(
|
|||||||
|
|
||||||
size_t checksum_field1 = 0;
|
size_t checksum_field1 = 0;
|
||||||
size_t checksum_field2 = 0;
|
size_t checksum_field2 = 0;
|
||||||
uint32_t crc32 = 0;
|
|
||||||
bool crc32_inited = false;
|
|
||||||
bool crc32_chksum = false;
|
|
||||||
const ulint zip_size = fil_space_t::zip_size(fsp_flags);
|
const ulint zip_size = fil_space_t::zip_size(fsp_flags);
|
||||||
ulint page_type = mach_read_from_2(read_buf + FIL_PAGE_TYPE);
|
ulint page_type = mach_read_from_2(read_buf + FIL_PAGE_TYPE);
|
||||||
|
|
||||||
@ -1119,9 +1116,14 @@ buf_page_is_corrupted(
|
|||||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||||
return !buf_page_is_checksum_valid_none(
|
return !buf_page_is_checksum_valid_none(
|
||||||
read_buf, checksum_field1, checksum_field2);
|
read_buf, checksum_field1, checksum_field2);
|
||||||
|
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||||
|
/* should have returned false earlier */
|
||||||
|
break;
|
||||||
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
|
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
|
||||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||||
|
const uint32_t crc32 = buf_calc_page_crc32(read_buf);
|
||||||
|
|
||||||
if (buf_page_is_checksum_valid_none(read_buf,
|
if (buf_page_is_checksum_valid_none(read_buf,
|
||||||
checksum_field1, checksum_field2)) {
|
checksum_field1, checksum_field2)) {
|
||||||
#ifdef UNIV_INNOCHECKSUM
|
#ifdef UNIV_INNOCHECKSUM
|
||||||
@ -1137,16 +1139,13 @@ buf_page_is_corrupted(
|
|||||||
" crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
|
" crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
|
||||||
cur_page_num,
|
cur_page_num,
|
||||||
buf_calc_page_new_checksum(read_buf),
|
buf_calc_page_new_checksum(read_buf),
|
||||||
buf_calc_page_crc32(read_buf),
|
crc32,
|
||||||
checksum_field1);
|
checksum_field1);
|
||||||
}
|
}
|
||||||
#endif /* UNIV_INNOCHECKSUM */
|
#endif /* UNIV_INNOCHECKSUM */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
crc32_chksum = curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32
|
|
||||||
|| curr_algo == SRV_CHECKSUM_ALGORITHM_FULL_CRC32;
|
|
||||||
|
|
||||||
/* Very old versions of InnoDB only stored 8 byte lsn to the
|
/* Very old versions of InnoDB only stored 8 byte lsn to the
|
||||||
start and the end of the page. */
|
start and the end of the page. */
|
||||||
|
|
||||||
@ -1157,81 +1156,33 @@ buf_page_is_corrupted(
|
|||||||
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
|
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
|
||||||
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
|
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
|
||||||
|
|
||||||
if (crc32_chksum) {
|
DBUG_EXECUTE_IF(
|
||||||
crc32 = buf_calc_page_crc32(read_buf);
|
"page_intermittent_checksum_mismatch", {
|
||||||
crc32_inited = true;
|
static int page_counter;
|
||||||
|
if (page_counter++ == 2) return true;
|
||||||
|
});
|
||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
if ((checksum_field1 != crc32
|
||||||
"page_intermittent_checksum_mismatch", {
|
|| checksum_field2 != crc32)
|
||||||
static int page_counter;
|
&& checksum_field2
|
||||||
if (page_counter++ == 2) {
|
!= buf_calc_page_old_checksum(read_buf)) {
|
||||||
crc32++;
|
return true;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (checksum_field2 != crc32
|
|
||||||
&& checksum_field2
|
|
||||||
!= buf_calc_page_old_checksum(read_buf)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ut_ad(curr_algo
|
|
||||||
== SRV_CHECKSUM_ALGORITHM_INNODB);
|
|
||||||
|
|
||||||
if (checksum_field2
|
|
||||||
!= buf_calc_page_old_checksum(read_buf)) {
|
|
||||||
crc32 = buf_calc_page_crc32(read_buf);
|
|
||||||
crc32_inited = true;
|
|
||||||
|
|
||||||
if (checksum_field2 != crc32) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checksum_field1 == 0
|
switch (checksum_field1) {
|
||||||
|| checksum_field1 == BUF_NO_CHECKSUM_MAGIC) {
|
case 0:
|
||||||
} else if (crc32_chksum) {
|
case BUF_NO_CHECKSUM_MAGIC:
|
||||||
|
break;
|
||||||
if (!crc32_inited) {
|
default:
|
||||||
crc32 = buf_calc_page_crc32(read_buf);
|
if ((checksum_field1 != crc32
|
||||||
crc32_inited = true;
|
|| checksum_field2 != crc32)
|
||||||
}
|
|
||||||
|
|
||||||
if (checksum_field1 != crc32
|
|
||||||
&& checksum_field1
|
&& checksum_field1
|
||||||
!= buf_calc_page_new_checksum(read_buf)) {
|
!= buf_calc_page_new_checksum(read_buf)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB);
|
|
||||||
|
|
||||||
if (checksum_field1
|
|
||||||
!= buf_calc_page_new_checksum(read_buf)) {
|
|
||||||
|
|
||||||
if (!crc32_inited) {
|
|
||||||
crc32 = buf_calc_page_crc32(read_buf);
|
|
||||||
crc32_inited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checksum_field1 != crc32) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc32_inited
|
|
||||||
&& ((checksum_field1 == crc32
|
|
||||||
&& checksum_field2 != crc32)
|
|
||||||
|| (checksum_field1 != crc32
|
|
||||||
&& checksum_field2 == crc32))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
|
||||||
/* should have returned false earlier */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2021, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1995, 2021, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2014, 2021, MariaDB Corporation.
|
Copyright (c) 2014, 2022, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -2625,10 +2625,11 @@ fil_make_filepath(
|
|||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
memcpy(full_name, path, path_len);
|
memcpy(full_name, path, path_len);
|
||||||
len = path_len;
|
len = path_len;
|
||||||
full_name[len] = '\0';
|
|
||||||
os_normalize_path(full_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
full_name[len] = '\0';
|
||||||
|
os_normalize_path(full_name);
|
||||||
|
|
||||||
if (trim_name) {
|
if (trim_name) {
|
||||||
/* Find the offset of the last DIR separator and set it to
|
/* Find the offset of the last DIR separator and set it to
|
||||||
null in order to strip off the old basename from this path. */
|
null in order to strip off the old basename from this path. */
|
||||||
|
@ -2273,9 +2273,7 @@ fts_trx_table_create(
|
|||||||
fts_trx_table_t* ftt;
|
fts_trx_table_t* ftt;
|
||||||
|
|
||||||
ftt = static_cast<fts_trx_table_t*>(
|
ftt = static_cast<fts_trx_table_t*>(
|
||||||
mem_heap_alloc(fts_trx->heap, sizeof(*ftt)));
|
mem_heap_zalloc(fts_trx->heap, sizeof *ftt));
|
||||||
|
|
||||||
memset(ftt, 0x0, sizeof(*ftt));
|
|
||||||
|
|
||||||
ftt->table = table;
|
ftt->table = table;
|
||||||
ftt->fts_trx = fts_trx;
|
ftt->fts_trx = fts_trx;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
Copyright (c) 2022, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License, version 2.0,
|
it under the terms of the GNU General Public License, version 2.0,
|
||||||
@ -24,6 +25,9 @@
|
|||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <pfs_global.h>
|
#include <pfs_global.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_MEMALIGN
|
||||||
|
# include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
bool pfs_initialized= false;
|
bool pfs_initialized= false;
|
||||||
|
|
||||||
@ -43,7 +47,17 @@ void *pfs_malloc(size_t size, myf)
|
|||||||
if (--stub_alloc_fails_after_count <= 0)
|
if (--stub_alloc_fails_after_count <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifndef PFS_ALIGNEMENT
|
||||||
void *ptr= malloc(size);
|
void *ptr= malloc(size);
|
||||||
|
#elif defined HAVE_MEMALIGN
|
||||||
|
void *ptr= memalign(PFS_ALIGNEMENT, size);
|
||||||
|
#elif defined HAVE_ALIGNED_MALLOC
|
||||||
|
void *ptr= _aligned_malloc(size, PFS_ALIGNEMENT);
|
||||||
|
#else
|
||||||
|
void *ptr;
|
||||||
|
if (posix_memalign(&ptr, PFS_ALIGNEMENT, size))
|
||||||
|
ptr= NULL;
|
||||||
|
#endif
|
||||||
if (ptr != NULL)
|
if (ptr != NULL)
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -1128,13 +1128,21 @@ int decimal2ulonglong(const decimal_t *from, ulonglong *to)
|
|||||||
|
|
||||||
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
||||||
{
|
{
|
||||||
ulonglong y=x;
|
/*
|
||||||
x=x*DIG_BASE + *buf++;
|
Check that the decimal is bigger than any possible integer.
|
||||||
if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
|
Do it before we do the x*=DIB_BASE to avoid integer
|
||||||
|
overflow.
|
||||||
|
*/
|
||||||
|
if (unlikely (
|
||||||
|
x >= ULONGLONG_MAX/DIG_BASE &&
|
||||||
|
(x > ULONGLONG_MAX/DIG_BASE ||
|
||||||
|
*buf > (dec1) (ULONGLONG_MAX%DIG_BASE))))
|
||||||
{
|
{
|
||||||
*to=ULONGLONG_MAX;
|
*to=ULONGLONG_MAX;
|
||||||
return E_DEC_OVERFLOW;
|
return E_DEC_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x=x*DIG_BASE + *buf++;
|
||||||
}
|
}
|
||||||
*to=x;
|
*to=x;
|
||||||
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
|
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
|
||||||
@ -1151,23 +1159,29 @@ int decimal2longlong(const decimal_t *from, longlong *to)
|
|||||||
|
|
||||||
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
||||||
{
|
{
|
||||||
longlong y=x;
|
|
||||||
/*
|
/*
|
||||||
|
Check that the decimal is less than any possible integer.
|
||||||
|
Do it before we do the x*=DIB_BASE to avoid integer
|
||||||
|
overflow.
|
||||||
Attention: trick!
|
Attention: trick!
|
||||||
we're calculating -|from| instead of |from| here
|
we're calculating -|from| instead of |from| here
|
||||||
because |LONGLONG_MIN| > LONGLONG_MAX
|
because |LONGLONG_MIN| > LONGLONG_MAX
|
||||||
so we can convert -9223372036854775808 correctly
|
so we can convert -9223372036854775808 correctly.
|
||||||
*/
|
*/
|
||||||
x=x*DIG_BASE - *buf++;
|
if (unlikely (
|
||||||
if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
|
x <= LONGLONG_MIN/DIG_BASE &&
|
||||||
|
(x < LONGLONG_MIN/DIG_BASE ||
|
||||||
|
*buf > (dec1) (-(LONGLONG_MIN%DIG_BASE)))))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
the decimal is bigger than any possible integer
|
the decimal is bigger than any possible integer
|
||||||
return border integer depending on the sign
|
return border integer depending on the sign
|
||||||
*/
|
*/
|
||||||
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
|
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
|
||||||
return E_DEC_OVERFLOW;
|
return E_DEC_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x=x*DIG_BASE - *buf++;
|
||||||
}
|
}
|
||||||
/* boundary case: 9223372036854775808 */
|
/* boundary case: 9223372036854775808 */
|
||||||
if (unlikely(from->sign==0 && x == LONGLONG_MIN))
|
if (unlikely(from->sign==0 && x == LONGLONG_MIN))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user