Merge 10.5 into 10.6
This commit is contained in:
commit
03ff588d15
@ -218,8 +218,6 @@ enum ha_extra_function {
|
|||||||
HA_EXTRA_BEGIN_ALTER_COPY,
|
HA_EXTRA_BEGIN_ALTER_COPY,
|
||||||
/** Finish writing rows during ALTER TABLE...ALGORITHM=COPY. */
|
/** Finish writing rows during ALTER TABLE...ALGORITHM=COPY. */
|
||||||
HA_EXTRA_END_ALTER_COPY,
|
HA_EXTRA_END_ALTER_COPY,
|
||||||
/** Fake the start of a statement after wsrep_load_data_splitting hack */
|
|
||||||
HA_EXTRA_FAKE_START_STMT,
|
|
||||||
/** IGNORE is being used for the insert statement */
|
/** IGNORE is being used for the insert statement */
|
||||||
HA_EXTRA_IGNORE_INSERT
|
HA_EXTRA_IGNORE_INSERT
|
||||||
};
|
};
|
||||||
|
@ -74,7 +74,8 @@ my %debuggers = (
|
|||||||
options => '-f -o {log} {exe} {args}',
|
options => '-f -o {log} {exe} {args}',
|
||||||
},
|
},
|
||||||
rr => {
|
rr => {
|
||||||
options => 'record -o {log} {exe} {args}',
|
options => '_RR_TRACE_DIR={log} rr record {exe} {args}',
|
||||||
|
run => 'env',
|
||||||
pre => sub {
|
pre => sub {
|
||||||
::mtr_error('rr requires kernel.perf_event_paranoid <= 1')
|
::mtr_error('rr requires kernel.perf_event_paranoid <= 1')
|
||||||
if ::mtr_grab_file('/proc/sys/kernel/perf_event_paranoid') > 1;
|
if ::mtr_grab_file('/proc/sys/kernel/perf_event_paranoid') > 1;
|
||||||
|
@ -20,3 +20,14 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
|||||||
connection default;
|
connection default;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
# Second test from MDEV-23843
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
ANALYZE TABLE t;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t;
|
||||||
|
@ -27,3 +27,17 @@ FLUSH TABLES;
|
|||||||
--connection default
|
--connection default
|
||||||
--disconnect con1
|
--disconnect con1
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
|
||||||
|
--echo # Second test from MDEV-23843
|
||||||
|
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
--connect (con1,localhost,root,,)
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
|
ANALYZE TABLE t;
|
||||||
|
# Cleanup
|
||||||
|
--disconnect con1
|
||||||
|
--connection default
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t;
|
||||||
|
@ -2958,5 +2958,34 @@ f COUNT(*)
|
|||||||
NULL 1
|
NULL 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-24710 Uninitialized value upon CREATE .. SELECT ... VALUE
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(8) NOT NULL DEFAULT '');
|
||||||
|
INSERT INTO t1 (a) VALUES ('foo');
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE VALUE(a) IS NOT NULL;
|
||||||
|
SELECT * from t2;
|
||||||
|
f1 f2
|
||||||
|
NULL NULL
|
||||||
|
SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE VALUE(a) IS NOT NULL;
|
||||||
|
f1 f2
|
||||||
|
NULL NULL
|
||||||
|
SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE 1=0;
|
||||||
|
f1 f2
|
||||||
|
NULL NULL
|
||||||
|
drop table t1,t2;
|
||||||
|
# Extra test by to check the fix for MDEV-24710
|
||||||
|
create table t20 (pk int primary key, a int);
|
||||||
|
insert into t20 values (1,1);
|
||||||
|
create table t21 (pk int primary key, b int not null);
|
||||||
|
insert into t21 values (1,1);
|
||||||
|
create table t22 (a int);
|
||||||
|
insert into t22 values (1),(2);
|
||||||
|
select a, (select max(t21.b) from t20 left join t21 on t21.pk=t20.a+10
|
||||||
|
where t20.pk=1 and rand(123) < 0.5) as SUBQ from t22;
|
||||||
|
a SUBQ
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
drop table t20, t21, t22;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@ -2061,6 +2061,29 @@ INSERT INTO t1 VALUES ('2032-10-08');
|
|||||||
SELECT d != '2023-03-04' AS f, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP;
|
SELECT d != '2023-03-04' AS f, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24710 Uninitialized value upon CREATE .. SELECT ... VALUE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(8) NOT NULL DEFAULT '');
|
||||||
|
INSERT INTO t1 (a) VALUES ('foo');
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE VALUE(a) IS NOT NULL;
|
||||||
|
SELECT * from t2;
|
||||||
|
SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE VALUE(a) IS NOT NULL;
|
||||||
|
SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE 1=0;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo # Extra test by to check the fix for MDEV-24710
|
||||||
|
|
||||||
|
create table t20 (pk int primary key, a int);
|
||||||
|
insert into t20 values (1,1);create table t21 (pk int primary key, b int not null);
|
||||||
|
insert into t21 values (1,1);
|
||||||
|
create table t22 (a int);
|
||||||
|
insert into t22 values (1),(2);
|
||||||
|
select a, (select max(t21.b) from t20 left join t21 on t21.pk=t20.a+10
|
||||||
|
where t20.pk=1 and rand(123) < 0.5) as SUBQ from t22;
|
||||||
|
drop table t20, t21, t22;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -847,6 +847,39 @@ t r
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP FUNCTION next_seq_value;
|
DROP FUNCTION next_seq_value;
|
||||||
DROP TABLE series;
|
DROP TABLE series;
|
||||||
|
#
|
||||||
|
# MDEV-24958 Server crashes in my_strtod /
|
||||||
|
# Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob)
|
||||||
|
#
|
||||||
|
# MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with
|
||||||
|
# DEFAULT() on BLOB
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A');
|
||||||
|
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||||
|
SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f);
|
||||||
|
f
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5;
|
||||||
|
h
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: 'A'
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0;
|
||||||
|
h
|
||||||
|
A
|
||||||
|
A
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: 'A'
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A';
|
||||||
|
h
|
||||||
|
A
|
||||||
|
A
|
||||||
|
alter table t1 add column b int default (rand()+1+3);
|
||||||
|
select default(b) AS h FROM t1 HAVING h > "2";
|
||||||
|
h
|
||||||
|
#
|
||||||
|
#
|
||||||
|
drop table t1;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
# MDEV-18681: AND formula in HAVING with several occurances
|
# MDEV-18681: AND formula in HAVING with several occurances
|
||||||
|
@ -891,6 +891,27 @@ DROP TABLE t1;
|
|||||||
DROP FUNCTION next_seq_value;
|
DROP FUNCTION next_seq_value;
|
||||||
DROP TABLE series;
|
DROP TABLE series;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24958 Server crashes in my_strtod /
|
||||||
|
--echo # Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob)
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with
|
||||||
|
--echo # DEFAULT() on BLOB
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A');
|
||||||
|
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||||
|
SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f);
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5;
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0;
|
||||||
|
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A';
|
||||||
|
|
||||||
|
alter table t1 add column b int default (rand()+1+3);
|
||||||
|
--replace_column 1 #
|
||||||
|
select default(b) AS h FROM t1 HAVING h > "2";
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -5497,6 +5497,23 @@ EXISTS(SELECT 1 FROM t1 GROUP BY a IN (select a from t1))
|
|||||||
0
|
0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-25006: Failed assertion on executing EXPLAIN DELETE statement as a prepared statement
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(c1 CHAR(255) PRIMARY KEY);
|
||||||
|
PREPARE stmt FROM 'EXPLAIN DELETE b FROM t1 AS a JOIN t1 AS b';
|
||||||
|
EXECUTE stmt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE a system NULL NULL NULL NULL 0 Const row not found
|
||||||
|
1 SIMPLE b system NULL NULL NULL NULL 0 Const row not found
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1.* USING t1';
|
||||||
|
EXECUTE stmt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -4941,6 +4941,20 @@ EXECUTE stmt;
|
|||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25006: Failed assertion on executing EXPLAIN DELETE statement as a prepared statement
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1(c1 CHAR(255) PRIMARY KEY);
|
||||||
|
PREPARE stmt FROM 'EXPLAIN DELETE b FROM t1 AS a JOIN t1 AS b';
|
||||||
|
EXECUTE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1.* USING t1';
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -1217,6 +1217,31 @@ set @rnd=1;
|
|||||||
select @rnd;
|
select @rnd;
|
||||||
@rnd
|
@rnd
|
||||||
0
|
0
|
||||||
|
#
|
||||||
|
# MDEV-24860: Incorrect behaviour of SET STATEMENT in case
|
||||||
|
# it is executed as a prepared statement
|
||||||
|
#
|
||||||
|
PREPARE stmt FROM "SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR CREATE TABLE t1 AS SELECT CONCAT('abc') AS c1";
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
# Show definition of the table t1 created using Prepared Statement
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` varchar(3) NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
# Create the table t1 with the same definition as it used before
|
||||||
|
# using regular statement execution mode.
|
||||||
|
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR CREATE TABLE t1 AS SELECT CONCAT('abc') AS c1;
|
||||||
|
# Show that the table has the same definition as it is in case the table
|
||||||
|
# created in prepared statement mode.
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` varchar(3) NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
create table t (a int);
|
create table t (a int);
|
||||||
SET sql_mode=ORACLE;
|
SET sql_mode=ORACLE;
|
||||||
SET STATEMENT myisam_sort_buffer_size=800000 FOR OPTIMIZE TABLE t;
|
SET STATEMENT myisam_sort_buffer_size=800000 FOR OPTIMIZE TABLE t;
|
||||||
@ -1234,3 +1259,4 @@ SET sql_mode=ORACLE;
|
|||||||
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
||||||
SET sql_mode=default;
|
SET sql_mode=default;
|
||||||
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
||||||
|
# End of 10.4 tests
|
||||||
|
@ -1137,6 +1137,30 @@ while ($1)
|
|||||||
--echo # @rnd should be 0
|
--echo # @rnd should be 0
|
||||||
select @rnd;
|
select @rnd;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24860: Incorrect behaviour of SET STATEMENT in case
|
||||||
|
--echo # it is executed as a prepared statement
|
||||||
|
--echo #
|
||||||
|
PREPARE stmt FROM "SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR CREATE TABLE t1 AS SELECT CONCAT('abc') AS c1";
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
--echo # Show definition of the table t1 created using Prepared Statement
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # Create the table t1 with the same definition as it used before
|
||||||
|
--echo # using regular statement execution mode.
|
||||||
|
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR CREATE TABLE t1 AS SELECT CONCAT('abc') AS c1;
|
||||||
|
|
||||||
|
--echo # Show that the table has the same definition as it is in case the table
|
||||||
|
--echo # created in prepared statement mode.
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
create table t (a int);
|
create table t (a int);
|
||||||
SET sql_mode=ORACLE;
|
SET sql_mode=ORACLE;
|
||||||
SET STATEMENT myisam_sort_buffer_size=800000 FOR OPTIMIZE TABLE t;
|
SET STATEMENT myisam_sort_buffer_size=800000 FOR OPTIMIZE TABLE t;
|
||||||
@ -1152,3 +1176,5 @@ SET sql_mode=ORACLE;
|
|||||||
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
||||||
SET sql_mode=default;
|
SET sql_mode=default;
|
||||||
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
SET STATEMENT max_statement_time=30 FOR DELETE FROM mysql.user where user = 'unknown';
|
||||||
|
|
||||||
|
--echo # End of 10.4 tests
|
||||||
|
@ -2880,8 +2880,12 @@ deallocate prepare stmt;
|
|||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
#
|
#
|
||||||
# End of 10.3 tests
|
# MDEV-24919: subselect formed by TVC and used in set function
|
||||||
#
|
#
|
||||||
|
select sum((values(1)));
|
||||||
|
sum((values(1)))
|
||||||
|
1
|
||||||
|
End of 10.3 tests
|
||||||
#
|
#
|
||||||
# MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
|
# MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
|
||||||
#
|
#
|
||||||
|
@ -1517,9 +1517,13 @@ drop view v1;
|
|||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # MDEV-24919: subselect formed by TVC and used in set function
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
select sum((values(1)));
|
||||||
|
|
||||||
|
--echo End of 10.3 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
|
--echo # MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -5000,7 +5000,7 @@ sub mysqld_start ($$) {
|
|||||||
$ENV{'MYSQLD_LAST_CMD'}= "$exe @$args";
|
$ENV{'MYSQLD_LAST_CMD'}= "$exe @$args";
|
||||||
|
|
||||||
My::Debugger::setup_args(\$args, \$exe, $mysqld->name());
|
My::Debugger::setup_args(\$args, \$exe, $mysqld->name());
|
||||||
$ENV{'VALGRIND_TEST'}= $opt_valgrind = int($exe && $exe eq 'valgrind');
|
$ENV{'VALGRIND_TEST'}= $opt_valgrind = int(($exe || '') eq 'valgrind');
|
||||||
|
|
||||||
# Remove the old pidfile if any
|
# Remove the old pidfile if any
|
||||||
unlink($mysqld->value('pid-file'));
|
unlink($mysqld->value('pid-file'));
|
||||||
|
@ -57,3 +57,14 @@ disconnect dml;
|
|||||||
connection default;
|
connection default;
|
||||||
SET DEBUG_SYNC = RESET;
|
SET DEBUG_SYNC = RESET;
|
||||||
DROP TABLE child, parent;
|
DROP TABLE child, parent;
|
||||||
|
#
|
||||||
|
# MDEV-24532 Table corruption ER_NO_SUCH_TABLE_IN_ENGINE or
|
||||||
|
# ER_CRASHED_ON_USAGE after ALTER on table with foreign key
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 ADD FOREIGN KEY (b) REFERENCES t1 (a) ON UPDATE CASCADE;
|
||||||
|
LOCK TABLE t1 WRITE;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ALTER TABLE t1 ADD c INT;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -67,3 +67,16 @@ connection default;
|
|||||||
SET DEBUG_SYNC = RESET;
|
SET DEBUG_SYNC = RESET;
|
||||||
|
|
||||||
DROP TABLE child, parent;
|
DROP TABLE child, parent;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24532 Table corruption ER_NO_SUCH_TABLE_IN_ENGINE or
|
||||||
|
--echo # ER_CRASHED_ON_USAGE after ALTER on table with foreign key
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 ADD FOREIGN KEY (b) REFERENCES t1 (a) ON UPDATE CASCADE;
|
||||||
|
LOCK TABLE t1 WRITE;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ALTER TABLE t1 ADD c INT;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -118,6 +118,7 @@ CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
|||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
|
ALTER USER u3 IDENTIFIED BY 'pwd-456';
|
||||||
drop user u1, u2, u3;
|
drop user u1, u2, u3;
|
||||||
set global server_audit_events='query_ddl';
|
set global server_audit_events='query_ddl';
|
||||||
create table t1(id int);
|
create table t1(id int);
|
||||||
@ -393,6 +394,8 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
||||||
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
|
||||||
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'ALTER USER u3 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
|
||||||
|
@ -95,6 +95,7 @@ CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
|||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
|
ALTER USER u3 IDENTIFIED BY 'pwd-456';
|
||||||
drop user u1, u2, u3;
|
drop user u1, u2, u3;
|
||||||
|
|
||||||
set global server_audit_events='query_ddl';
|
set global server_audit_events='query_ddl';
|
||||||
|
@ -20,7 +20,6 @@ sub start_test {
|
|||||||
($path, $args) = ($cmd, , [ ])
|
($path, $args) = ($cmd, , [ ])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my $oldpwd=getcwd();
|
my $oldpwd=getcwd();
|
||||||
chdir $::opt_vardir;
|
chdir $::opt_vardir;
|
||||||
my $proc=My::SafeProcess->new
|
my $proc=My::SafeProcess->new
|
||||||
@ -49,12 +48,12 @@ sub start_test {
|
|||||||
my ($command, %tests, $prefix);
|
my ($command, %tests, $prefix);
|
||||||
for (@ctest_list) {
|
for (@ctest_list) {
|
||||||
chomp;
|
chomp;
|
||||||
if (/^\d+: Test command: +/) {
|
if (/^\d+: Test command: +([^ \t]+)/) {
|
||||||
$command= $';
|
$command= $1;
|
||||||
$prefix= /libmariadb/ ? 'conc_' : '';
|
$prefix= /libmariadb/ ? 'conc_' : '';
|
||||||
} elsif (/^ +Test +#\d+: +/) {
|
} elsif (/^ +Test +#\d+: ([^ \t]+)/) {
|
||||||
if ($command ne "NOT_AVAILABLE") {
|
if ($command ne "NOT_AVAILABLE" && $command ne "/bin/sh") {
|
||||||
$tests{$prefix.$'}=$command;
|
$tests{$prefix.$1}=$command;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,23 +151,34 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return 1 if we should rotate the log
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool logger_time_to_rotate(LOGGER_HANDLE *log)
|
||||||
|
{
|
||||||
|
my_off_t filesize;
|
||||||
|
if (log->rotations > 0 &&
|
||||||
|
(filesize= my_tell(log->file, MYF(0))) != (my_off_t) -1 &&
|
||||||
|
((ulonglong) filesize >= log->size_limit))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
|
int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
my_off_t filesize;
|
|
||||||
char cvtbuf[1024];
|
char cvtbuf[1024];
|
||||||
size_t n_bytes;
|
size_t n_bytes;
|
||||||
|
|
||||||
flogger_mutex_lock(&log->lock);
|
flogger_mutex_lock(&log->lock);
|
||||||
if (log->rotations > 0)
|
if (logger_time_to_rotate(log) && do_rotate(log))
|
||||||
if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
|
{
|
||||||
((unsigned long long)filesize >= log->size_limit &&
|
result= -1;
|
||||||
do_rotate(log)))
|
errno= my_errno;
|
||||||
{
|
goto exit; /* Log rotation needed but failed */
|
||||||
result= -1;
|
}
|
||||||
errno= my_errno;
|
|
||||||
goto exit; /* Log rotation needed but failed */
|
|
||||||
}
|
|
||||||
|
|
||||||
n_bytes= my_vsnprintf(cvtbuf, sizeof(cvtbuf), fmt, ap);
|
n_bytes= my_vsnprintf(cvtbuf, sizeof(cvtbuf), fmt, ap);
|
||||||
if (n_bytes >= sizeof(cvtbuf))
|
if (n_bytes >= sizeof(cvtbuf))
|
||||||
@ -181,21 +192,18 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size)
|
static int logger_write_r(LOGGER_HANDLE *log, my_bool allow_rotations,
|
||||||
|
const char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
my_off_t filesize;
|
|
||||||
|
|
||||||
flogger_mutex_lock(&log->lock);
|
flogger_mutex_lock(&log->lock);
|
||||||
if (log->rotations > 0)
|
if (allow_rotations && logger_time_to_rotate(log) && do_rotate(log))
|
||||||
if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
|
{
|
||||||
((unsigned long long)filesize >= log->size_limit &&
|
result= -1;
|
||||||
do_rotate(log)))
|
errno= my_errno;
|
||||||
{
|
goto exit; /* Log rotation needed but failed */
|
||||||
result= -1;
|
}
|
||||||
errno= my_errno;
|
|
||||||
goto exit; /* Log rotation needed but failed */
|
|
||||||
}
|
|
||||||
|
|
||||||
result= (int)my_write(log->file, (uchar *) buffer, size, MYF(0));
|
result= (int)my_write(log->file, (uchar *) buffer, size, MYF(0));
|
||||||
|
|
||||||
@ -205,6 +213,11 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
return logger_write_r(log, TRUE, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
int logger_rotate(LOGGER_HANDLE *log)
|
int logger_rotate(LOGGER_HANDLE *log)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define PLUGIN_VERSION 0x104
|
#define PLUGIN_VERSION 0x104
|
||||||
#define PLUGIN_STR_VERSION "1.4.10"
|
#define PLUGIN_STR_VERSION "1.4.11"
|
||||||
|
|
||||||
#define _my_thread_var loc_thread_var
|
#define _my_thread_var loc_thread_var
|
||||||
|
|
||||||
@ -140,6 +140,7 @@ static int loc_file_errno;
|
|||||||
#define logger_write loc_logger_write
|
#define logger_write loc_logger_write
|
||||||
#define logger_rotate loc_logger_rotate
|
#define logger_rotate loc_logger_rotate
|
||||||
#define logger_init_mutexts loc_logger_init_mutexts
|
#define logger_init_mutexts loc_logger_init_mutexts
|
||||||
|
#define logger_time_to_rotate loc_logger_time_to_rotate
|
||||||
|
|
||||||
|
|
||||||
static size_t loc_write(File Filedes, const uchar *Buffer, size_t Count)
|
static size_t loc_write(File Filedes, const uchar *Buffer, size_t Count)
|
||||||
@ -554,22 +555,22 @@ static struct st_mysql_show_var audit_status[]=
|
|||||||
{0,0,0}
|
{0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI)
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
/* These belong to the service initialization */
|
|
||||||
static PSI_mutex_key key_LOCK_operations;
|
static PSI_mutex_key key_LOCK_operations;
|
||||||
static PSI_mutex_key key_LOCK_atomic;
|
|
||||||
static PSI_mutex_key key_LOCK_bigbuffer;
|
|
||||||
static PSI_mutex_info mutex_key_list[]=
|
static PSI_mutex_info mutex_key_list[]=
|
||||||
{
|
{
|
||||||
{ &key_LOCK_operations, "SERVER_AUDIT_plugin::lock_operations",
|
{ &key_LOCK_operations, "SERVER_AUDIT_plugin::lock_operations",
|
||||||
PSI_FLAG_GLOBAL},
|
PSI_FLAG_GLOBAL}
|
||||||
|
#ifndef FLOGGER_NO_PSI
|
||||||
|
,
|
||||||
{ &key_LOCK_atomic, "SERVER_AUDIT_plugin::lock_atomic",
|
{ &key_LOCK_atomic, "SERVER_AUDIT_plugin::lock_atomic",
|
||||||
PSI_FLAG_GLOBAL},
|
PSI_FLAG_GLOBAL},
|
||||||
{ &key_LOCK_bigbuffer, "SERVER_AUDIT_plugin::lock_bigbuffer",
|
{ &key_LOCK_bigbuffer, "SERVER_AUDIT_plugin::lock_bigbuffer",
|
||||||
PSI_FLAG_GLOBAL}
|
PSI_FLAG_GLOBAL}
|
||||||
|
#endif /*FLOGGER_NO_PSI*/
|
||||||
};
|
};
|
||||||
#endif
|
#endif /*HAVE_PSI_INTERFACE*/
|
||||||
static mysql_mutex_t lock_operations;
|
static mysql_prlock_t lock_operations;
|
||||||
static mysql_mutex_t lock_atomic;
|
static mysql_mutex_t lock_atomic;
|
||||||
static mysql_mutex_t lock_bigbuffer;
|
static mysql_mutex_t lock_bigbuffer;
|
||||||
|
|
||||||
@ -819,6 +820,7 @@ enum sa_keywords
|
|||||||
SQLCOM_DML,
|
SQLCOM_DML,
|
||||||
SQLCOM_GRANT,
|
SQLCOM_GRANT,
|
||||||
SQLCOM_CREATE_USER,
|
SQLCOM_CREATE_USER,
|
||||||
|
SQLCOM_ALTER_USER,
|
||||||
SQLCOM_CHANGE_MASTER,
|
SQLCOM_CHANGE_MASTER,
|
||||||
SQLCOM_CREATE_SERVER,
|
SQLCOM_CREATE_SERVER,
|
||||||
SQLCOM_SET_OPTION,
|
SQLCOM_SET_OPTION,
|
||||||
@ -926,6 +928,7 @@ struct sa_keyword passwd_keywords[]=
|
|||||||
{
|
{
|
||||||
{3, "SET", &password_word, SQLCOM_SET_OPTION},
|
{3, "SET", &password_word, SQLCOM_SET_OPTION},
|
||||||
{5, "ALTER", &server_word, SQLCOM_ALTER_SERVER},
|
{5, "ALTER", &server_word, SQLCOM_ALTER_SERVER},
|
||||||
|
{5, "ALTER", &user_word, SQLCOM_ALTER_USER},
|
||||||
{5, "GRANT", 0, SQLCOM_GRANT},
|
{5, "GRANT", 0, SQLCOM_GRANT},
|
||||||
{6, "CREATE", &user_word, SQLCOM_CREATE_USER},
|
{6, "CREATE", &user_word, SQLCOM_CREATE_USER},
|
||||||
{6, "CREATE", &server_word, SQLCOM_CREATE_SERVER},
|
{6, "CREATE", &server_word, SQLCOM_CREATE_SERVER},
|
||||||
@ -1320,19 +1323,41 @@ static void change_connection(struct connection_info *cn,
|
|||||||
event->ip, event->ip_length);
|
event->ip, event->ip_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write to the log
|
||||||
|
|
||||||
|
@param take_lock If set, take a read lock (or write lock on rotate).
|
||||||
|
If not set, the caller has a already taken a write lock
|
||||||
|
*/
|
||||||
|
|
||||||
static int write_log(const char *message, size_t len, int take_lock)
|
static int write_log(const char *message, size_t len, int take_lock)
|
||||||
{
|
{
|
||||||
int result= 0;
|
int result= 0;
|
||||||
if (take_lock)
|
if (take_lock)
|
||||||
flogger_mutex_lock(&lock_operations);
|
{
|
||||||
|
/* Start by taking a read lock */
|
||||||
|
mysql_prlock_rdlock(&lock_operations);
|
||||||
|
}
|
||||||
|
|
||||||
if (output_type == OUTPUT_FILE)
|
if (output_type == OUTPUT_FILE)
|
||||||
{
|
{
|
||||||
if (logfile &&
|
if (logfile)
|
||||||
(is_active= (logger_write(logfile, message, len) == (int) len)))
|
{
|
||||||
goto exit;
|
my_bool allow_rotate= !take_lock; /* Allow rotate if caller write lock */
|
||||||
++log_write_failures;
|
if (take_lock && logger_time_to_rotate(logfile))
|
||||||
result= 1;
|
{
|
||||||
|
/* We have to rotate the log, change above read lock to write lock */
|
||||||
|
mysql_prlock_unlock(&lock_operations);
|
||||||
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
|
allow_rotate= 1;
|
||||||
|
}
|
||||||
|
if (!(is_active= (logger_write_r(logfile, allow_rotate, message, len) ==
|
||||||
|
(int) len)))
|
||||||
|
{
|
||||||
|
++log_write_failures;
|
||||||
|
result= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (output_type == OUTPUT_SYSLOG)
|
else if (output_type == OUTPUT_SYSLOG)
|
||||||
{
|
{
|
||||||
@ -1340,9 +1365,8 @@ static int write_log(const char *message, size_t len, int take_lock)
|
|||||||
syslog_priority_codes[syslog_priority],
|
syslog_priority_codes[syslog_priority],
|
||||||
"%s %.*s", syslog_info, (int) len, message);
|
"%s %.*s", syslog_info, (int) len, message);
|
||||||
}
|
}
|
||||||
exit:
|
|
||||||
if (take_lock)
|
if (take_lock)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1590,7 +1614,7 @@ static int do_log_user(const char *name, int len,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (take_lock)
|
if (take_lock)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_rdlock(&lock_operations);
|
||||||
|
|
||||||
if (incl_user_coll.n_users)
|
if (incl_user_coll.n_users)
|
||||||
{
|
{
|
||||||
@ -1606,7 +1630,7 @@ static int do_log_user(const char *name, int len,
|
|||||||
result= 1;
|
result= 1;
|
||||||
|
|
||||||
if (take_lock)
|
if (take_lock)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1824,6 +1848,7 @@ do_log_query:
|
|||||||
{
|
{
|
||||||
case SQLCOM_GRANT:
|
case SQLCOM_GRANT:
|
||||||
case SQLCOM_CREATE_USER:
|
case SQLCOM_CREATE_USER:
|
||||||
|
case SQLCOM_ALTER_USER:
|
||||||
csize+= escape_string_hide_passwords(query, query_len,
|
csize+= escape_string_hide_passwords(query, query_len,
|
||||||
uh_buffer, uh_buffer_size,
|
uh_buffer, uh_buffer_size,
|
||||||
"IDENTIFIED", 10, "BY", 2, 0);
|
"IDENTIFIED", 10, "BY", 2, 0);
|
||||||
@ -2502,11 +2527,11 @@ static int server_audit_init(void *p __attribute__((unused)))
|
|||||||
servhost_len= (uint)strlen(servhost);
|
servhost_len= (uint)strlen(servhost);
|
||||||
|
|
||||||
logger_init_mutexes();
|
logger_init_mutexes();
|
||||||
#if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI)
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
if (PSI_server)
|
if (PSI_server)
|
||||||
PSI_server->register_mutex("server_audit", mutex_key_list, 1);
|
PSI_server->register_mutex("server_audit", mutex_key_list, 1);
|
||||||
#endif
|
#endif
|
||||||
flogger_mutex_init(key_LOCK_operations, &lock_operations, MY_MUTEX_INIT_FAST);
|
mysql_prlock_init(key_LOCK_operations, &lock_operations);
|
||||||
flogger_mutex_init(key_LOCK_operations, &lock_atomic, MY_MUTEX_INIT_FAST);
|
flogger_mutex_init(key_LOCK_operations, &lock_atomic, MY_MUTEX_INIT_FAST);
|
||||||
flogger_mutex_init(key_LOCK_operations, &lock_bigbuffer, MY_MUTEX_INIT_FAST);
|
flogger_mutex_init(key_LOCK_operations, &lock_bigbuffer, MY_MUTEX_INIT_FAST);
|
||||||
|
|
||||||
@ -2594,7 +2619,7 @@ static int server_audit_deinit(void *p __attribute__((unused)))
|
|||||||
closelog();
|
closelog();
|
||||||
|
|
||||||
(void) free(big_buffer);
|
(void) free(big_buffer);
|
||||||
flogger_mutex_destroy(&lock_operations);
|
mysql_prlock_destroy(&lock_operations);
|
||||||
flogger_mutex_destroy(&lock_atomic);
|
flogger_mutex_destroy(&lock_atomic);
|
||||||
flogger_mutex_destroy(&lock_bigbuffer);
|
flogger_mutex_destroy(&lock_bigbuffer);
|
||||||
|
|
||||||
@ -2705,7 +2730,7 @@ static void update_file_path(MYSQL_THD thd,
|
|||||||
fprintf(stderr, "Log file name was changed to '%s'.\n", new_name);
|
fprintf(stderr, "Log file name was changed to '%s'.\n", new_name);
|
||||||
|
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
|
|
||||||
if (logging)
|
if (logging)
|
||||||
log_current_query(thd);
|
log_current_query(thd);
|
||||||
@ -2737,7 +2762,7 @@ static void update_file_path(MYSQL_THD thd,
|
|||||||
file_path= path_buffer;
|
file_path= path_buffer;
|
||||||
exit_func:
|
exit_func:
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
ADD_ATOMIC(internal_stop_logging, -1);
|
ADD_ATOMIC(internal_stop_logging, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2753,9 +2778,9 @@ static void update_file_rotations(MYSQL_THD thd __attribute__((unused)),
|
|||||||
if (!logging || output_type != OUTPUT_FILE)
|
if (!logging || output_type != OUTPUT_FILE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
logfile->rotations= rotations;
|
logfile->rotations= rotations;
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2771,9 +2796,9 @@ static void update_file_rotate_size(MYSQL_THD thd __attribute__((unused)),
|
|||||||
if (!logging || output_type != OUTPUT_FILE)
|
if (!logging || output_type != OUTPUT_FILE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
logfile->size_limit= file_rotate_size;
|
logfile->size_limit= file_rotate_size;
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2818,7 +2843,7 @@ static void update_incl_users(MYSQL_THD thd,
|
|||||||
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
|
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
|
||||||
size_t new_len= strlen(new_users) + 1;
|
size_t new_len= strlen(new_users) + 1;
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
mark_always_logged(thd);
|
mark_always_logged(thd);
|
||||||
|
|
||||||
if (new_len > sizeof(incl_user_buffer))
|
if (new_len > sizeof(incl_user_buffer))
|
||||||
@ -2832,7 +2857,7 @@ static void update_incl_users(MYSQL_THD thd,
|
|||||||
error_header();
|
error_header();
|
||||||
fprintf(stderr, "server_audit_incl_users set to '%s'.\n", incl_users);
|
fprintf(stderr, "server_audit_incl_users set to '%s'.\n", incl_users);
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2843,7 +2868,7 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)),
|
|||||||
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
|
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
|
||||||
size_t new_len= strlen(new_users) + 1;
|
size_t new_len= strlen(new_users) + 1;
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
mark_always_logged(thd);
|
mark_always_logged(thd);
|
||||||
|
|
||||||
if (new_len > sizeof(excl_user_buffer))
|
if (new_len > sizeof(excl_user_buffer))
|
||||||
@ -2857,7 +2882,7 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)),
|
|||||||
error_header();
|
error_header();
|
||||||
fprintf(stderr, "server_audit_excl_users set to '%s'.\n", excl_users);
|
fprintf(stderr, "server_audit_excl_users set to '%s'.\n", excl_users);
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2870,7 +2895,7 @@ static void update_output_type(MYSQL_THD thd,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ADD_ATOMIC(internal_stop_logging, 1);
|
ADD_ATOMIC(internal_stop_logging, 1);
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
if (logging)
|
if (logging)
|
||||||
{
|
{
|
||||||
log_current_query(thd);
|
log_current_query(thd);
|
||||||
@ -2884,7 +2909,7 @@ static void update_output_type(MYSQL_THD thd,
|
|||||||
|
|
||||||
if (logging)
|
if (logging)
|
||||||
start_logging();
|
start_logging();
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
ADD_ATOMIC(internal_stop_logging, -1);
|
ADD_ATOMIC(internal_stop_logging, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2914,9 +2939,9 @@ static void update_syslog_priority(MYSQL_THD thd __attribute__((unused)),
|
|||||||
if (syslog_priority == new_priority)
|
if (syslog_priority == new_priority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
mark_always_logged(thd);
|
mark_always_logged(thd);
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
error_header();
|
error_header();
|
||||||
fprintf(stderr, "SysLog priority was changed from '%s' to '%s'.\n",
|
fprintf(stderr, "SysLog priority was changed from '%s' to '%s'.\n",
|
||||||
syslog_priority_names[syslog_priority],
|
syslog_priority_names[syslog_priority],
|
||||||
@ -2935,7 +2960,7 @@ static void update_logging(MYSQL_THD thd,
|
|||||||
|
|
||||||
ADD_ATOMIC(internal_stop_logging, 1);
|
ADD_ATOMIC(internal_stop_logging, 1);
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
if ((logging= new_logging))
|
if ((logging= new_logging))
|
||||||
{
|
{
|
||||||
start_logging();
|
start_logging();
|
||||||
@ -2952,7 +2977,7 @@ static void update_logging(MYSQL_THD thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
ADD_ATOMIC(internal_stop_logging, -1);
|
ADD_ATOMIC(internal_stop_logging, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2967,13 +2992,13 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)),
|
|||||||
|
|
||||||
ADD_ATOMIC(internal_stop_logging, 1);
|
ADD_ATOMIC(internal_stop_logging, 1);
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
mark_always_logged(thd);
|
mark_always_logged(thd);
|
||||||
error_header();
|
error_header();
|
||||||
fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode);
|
fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode);
|
||||||
mode= new_mode;
|
mode= new_mode;
|
||||||
if (!maria_55_started || !debug_server_started)
|
if (!maria_55_started || !debug_server_started)
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
ADD_ATOMIC(internal_stop_logging, -1);
|
ADD_ATOMIC(internal_stop_logging, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2988,14 +3013,14 @@ static void update_syslog_ident(MYSQL_THD thd __attribute__((unused)),
|
|||||||
syslog_ident= syslog_ident_buffer;
|
syslog_ident= syslog_ident_buffer;
|
||||||
error_header();
|
error_header();
|
||||||
fprintf(stderr, "SYSYLOG ident was changed to '%s'\n", syslog_ident);
|
fprintf(stderr, "SYSYLOG ident was changed to '%s'\n", syslog_ident);
|
||||||
flogger_mutex_lock(&lock_operations);
|
mysql_prlock_wrlock(&lock_operations);
|
||||||
mark_always_logged(thd);
|
mark_always_logged(thd);
|
||||||
if (logging && output_type == OUTPUT_SYSLOG)
|
if (logging && output_type == OUTPUT_SYSLOG)
|
||||||
{
|
{
|
||||||
stop_logging();
|
stop_logging();
|
||||||
start_logging();
|
start_logging();
|
||||||
}
|
}
|
||||||
flogger_mutex_unlock(&lock_operations);
|
mysql_prlock_unlock(&lock_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9182,7 +9182,6 @@ int ha_partition::extra(enum ha_extra_function operation)
|
|||||||
case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN:
|
case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN:
|
||||||
case HA_EXTRA_BEGIN_ALTER_COPY:
|
case HA_EXTRA_BEGIN_ALTER_COPY:
|
||||||
case HA_EXTRA_END_ALTER_COPY:
|
case HA_EXTRA_END_ALTER_COPY:
|
||||||
case HA_EXTRA_FAKE_START_STMT:
|
|
||||||
case HA_EXTRA_IGNORE_INSERT:
|
case HA_EXTRA_IGNORE_INSERT:
|
||||||
DBUG_RETURN(loop_partitions(extra_cb, &operation));
|
DBUG_RETURN(loop_partitions(extra_cb, &operation));
|
||||||
default:
|
default:
|
||||||
|
@ -1805,6 +1805,12 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
|
|||||||
*/
|
*/
|
||||||
#define HTON_TRANSACTIONAL_AND_NON_TRANSACTIONAL (1 << 17)
|
#define HTON_TRANSACTIONAL_AND_NON_TRANSACTIONAL (1 << 17)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Table requires and close and reopen after truncate
|
||||||
|
If the handler has HTON_CAN_RECREATE, this flag is not used
|
||||||
|
*/
|
||||||
|
#define HTON_REQUIRES_CLOSE_AFTER_TRUNCATE (1 << 18)
|
||||||
|
|
||||||
class Ha_trx_info;
|
class Ha_trx_info;
|
||||||
|
|
||||||
struct THD_TRANS
|
struct THD_TRANS
|
||||||
|
53
sql/item.cc
53
sql/item.cc
@ -9372,7 +9372,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
|
|||||||
def_field->reset_fields();
|
def_field->reset_fields();
|
||||||
// If non-constant default value expression or a blob
|
// If non-constant default value expression or a blob
|
||||||
if (def_field->default_value &&
|
if (def_field->default_value &&
|
||||||
(def_field->default_value->flags || def_field->flags & BLOB_FLAG))
|
(def_field->default_value->flags || (def_field->flags & BLOB_FLAG)))
|
||||||
{
|
{
|
||||||
uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length());
|
uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length());
|
||||||
if (!newptr)
|
if (!newptr)
|
||||||
@ -9476,11 +9476,60 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
|||||||
return Item_field::save_in_field(field_arg, no_conversions);
|
return Item_field::save_in_field(field_arg, no_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Item_default_value::val_result()
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::val_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
longlong Item_default_value::val_int_result()
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::val_int_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
String *Item_default_value::str_result(String* tmp)
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::str_result(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_default_value::val_bool_result()
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::val_bool_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_default_value::is_null_result()
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::is_null_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
my_decimal *Item_default_value::val_decimal_result(my_decimal *decimal_value)
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::val_decimal_result(decimal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_default_value::get_date_result(THD *thd, MYSQL_TIME *ltime,
|
||||||
|
date_mode_t fuzzydate)
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::get_date_result(thd, ltime, fuzzydate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_default_value::val_native_result(THD *thd, Native *to)
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::val_native_result(thd, to);
|
||||||
|
}
|
||||||
|
|
||||||
table_map Item_default_value::used_tables() const
|
table_map Item_default_value::used_tables() const
|
||||||
{
|
{
|
||||||
if (!field || !field->default_value)
|
if (!field || !field->default_value)
|
||||||
return static_cast<table_map>(0);
|
return static_cast<table_map>(0);
|
||||||
if (!field->default_value->expr) // not fully parsed field
|
if (!field->default_value->expr) // not fully parsed field
|
||||||
return static_cast<table_map>(RAND_TABLE_BIT);
|
return static_cast<table_map>(RAND_TABLE_BIT);
|
||||||
return field->default_value->expr->used_tables();
|
return field->default_value->expr->used_tables();
|
||||||
}
|
}
|
||||||
|
1812
sql/item.h
1812
sql/item.h
File diff suppressed because it is too large
Load Diff
@ -1395,7 +1395,9 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
|
|||||||
/*
|
/*
|
||||||
Presumably, ANALYZE and binlog writing doesn't require synchronization
|
Presumably, ANALYZE and binlog writing doesn't require synchronization
|
||||||
*/
|
*/
|
||||||
|
thd->get_stmt_da()->set_overwrite_status(true);
|
||||||
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
||||||
|
thd->get_stmt_da()->set_overwrite_status(false);
|
||||||
}
|
}
|
||||||
m_lex->first_select_lex()->table_list.first= first_table;
|
m_lex->first_select_lex()->table_list.first= first_table;
|
||||||
m_lex->query_tables= first_table;
|
m_lex->query_tables= first_table;
|
||||||
|
268
sql/sql_parse.cc
268
sql/sql_parse.cc
@ -3262,6 +3262,146 @@ bool Sql_cmd_call::execute(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the SQL statement being processed is prepended by
|
||||||
|
SET STATEMENT clause and handle variables assignment if it is.
|
||||||
|
|
||||||
|
@param thd thread handle
|
||||||
|
@param lex current lex
|
||||||
|
|
||||||
|
@return false in case of success, true in case of error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool run_set_statement_if_requested(THD *thd, LEX *lex)
|
||||||
|
{
|
||||||
|
if (!lex->stmt_var_list.is_empty() && !thd->slave_thread)
|
||||||
|
{
|
||||||
|
Query_arena backup;
|
||||||
|
DBUG_PRINT("info", ("SET STATEMENT %d vars", lex->stmt_var_list.elements));
|
||||||
|
|
||||||
|
lex->old_var_list.empty();
|
||||||
|
List_iterator_fast<set_var_base> it(lex->stmt_var_list);
|
||||||
|
set_var_base *var;
|
||||||
|
|
||||||
|
if (lex->set_arena_for_set_stmt(&backup))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
MEM_ROOT *mem_root= thd->mem_root;
|
||||||
|
while ((var= it++))
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(var->is_system());
|
||||||
|
set_var *o= NULL, *v= (set_var*)var;
|
||||||
|
if (!v->var->is_set_stmt_ok())
|
||||||
|
{
|
||||||
|
my_error(ER_SET_STATEMENT_NOT_SUPPORTED, MYF(0), v->var->name.str);
|
||||||
|
lex->reset_arena_for_set_stmt(&backup);
|
||||||
|
lex->old_var_list.empty();
|
||||||
|
lex->free_arena_for_set_stmt();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (v->var->session_is_default(thd))
|
||||||
|
o= new set_var(thd,v->type, v->var, &v->base, NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (v->var->option.var_type & GET_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case GET_BOOL:
|
||||||
|
case GET_INT:
|
||||||
|
case GET_LONG:
|
||||||
|
case GET_LL:
|
||||||
|
{
|
||||||
|
bool null_value;
|
||||||
|
longlong val= v->var->val_int(&null_value, thd, v->type, &v->base);
|
||||||
|
o= new set_var(thd, v->type, v->var, &v->base,
|
||||||
|
(null_value ?
|
||||||
|
(Item *) new (mem_root) Item_null(thd) :
|
||||||
|
(Item *) new (mem_root) Item_int(thd, val)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_UINT:
|
||||||
|
case GET_ULONG:
|
||||||
|
case GET_ULL:
|
||||||
|
{
|
||||||
|
bool null_value;
|
||||||
|
ulonglong val= v->var->val_int(&null_value, thd, v->type, &v->base);
|
||||||
|
o= new set_var(thd, v->type, v->var, &v->base,
|
||||||
|
(null_value ?
|
||||||
|
(Item *) new (mem_root) Item_null(thd) :
|
||||||
|
(Item *) new (mem_root) Item_uint(thd, val)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_DOUBLE:
|
||||||
|
{
|
||||||
|
bool null_value;
|
||||||
|
double val= v->var->val_real(&null_value, thd, v->type, &v->base);
|
||||||
|
o= new set_var(thd, v->type, v->var, &v->base,
|
||||||
|
(null_value ?
|
||||||
|
(Item *) new (mem_root) Item_null(thd) :
|
||||||
|
(Item *) new (mem_root) Item_float(thd, val, 1)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case GET_NO_ARG:
|
||||||
|
case GET_DISABLED:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
/* fall through */
|
||||||
|
case 0:
|
||||||
|
case GET_FLAGSET:
|
||||||
|
case GET_ENUM:
|
||||||
|
case GET_SET:
|
||||||
|
case GET_STR:
|
||||||
|
case GET_STR_ALLOC:
|
||||||
|
{
|
||||||
|
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
String tmp(buff, sizeof(buff), v->var->charset(thd)),*val;
|
||||||
|
val= v->var->val_str(&tmp, thd, v->type, &v->base);
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
Item_string *str=
|
||||||
|
new (mem_root) Item_string(thd, v->var->charset(thd),
|
||||||
|
val->ptr(), val->length());
|
||||||
|
o= new set_var(thd, v->type, v->var, &v->base, str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
o= new set_var(thd, v->type, v->var, &v->base,
|
||||||
|
new (mem_root) Item_null(thd));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(o);
|
||||||
|
lex->old_var_list.push_back(o, thd->mem_root);
|
||||||
|
}
|
||||||
|
lex->reset_arena_for_set_stmt(&backup);
|
||||||
|
|
||||||
|
if (lex->old_var_list.is_empty())
|
||||||
|
lex->free_arena_for_set_stmt();
|
||||||
|
|
||||||
|
if (thd->is_error() ||
|
||||||
|
sql_set_variables(thd, &lex->stmt_var_list, false))
|
||||||
|
{
|
||||||
|
if (!thd->is_error())
|
||||||
|
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET");
|
||||||
|
lex->restore_set_statement_var();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
The value of last_insert_id is remembered in THD to be written to binlog
|
||||||
|
when it's used *the first time* in the statement. But SET STATEMENT
|
||||||
|
must read the old value of last_insert_id to be able to restore it at
|
||||||
|
the end. This should not count at "reading of last_insert_id" and
|
||||||
|
should not remember last_insert_id for binlog. That is, it should clear
|
||||||
|
stmt_depends_on_first_successful_insert_id_in_prev_stmt flag.
|
||||||
|
*/
|
||||||
|
if (!thd->in_sub_stmt)
|
||||||
|
{
|
||||||
|
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Execute command saved in thd and lex->sql_command.
|
Execute command saved in thd and lex->sql_command.
|
||||||
|
|
||||||
@ -3548,127 +3688,13 @@ mysql_execute_command(THD *thd)
|
|||||||
thd->get_binlog_format(&orig_binlog_format,
|
thd->get_binlog_format(&orig_binlog_format,
|
||||||
&orig_current_stmt_binlog_format);
|
&orig_current_stmt_binlog_format);
|
||||||
|
|
||||||
if (!lex->stmt_var_list.is_empty() && !thd->slave_thread)
|
/*
|
||||||
{
|
Assign system variables with values specified by the clause
|
||||||
Query_arena backup;
|
SET STATEMENT var1=value1 [, var2=value2, ...] FOR <statement>
|
||||||
DBUG_PRINT("info", ("SET STATEMENT %d vars", lex->stmt_var_list.elements));
|
if they are any.
|
||||||
|
*/
|
||||||
lex->old_var_list.empty();
|
if (run_set_statement_if_requested(thd, lex))
|
||||||
List_iterator_fast<set_var_base> it(lex->stmt_var_list);
|
goto error;
|
||||||
set_var_base *var;
|
|
||||||
|
|
||||||
if (lex->set_arena_for_set_stmt(&backup))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
MEM_ROOT *mem_root= thd->mem_root;
|
|
||||||
while ((var= it++))
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(var->is_system());
|
|
||||||
set_var *o= NULL, *v= (set_var*)var;
|
|
||||||
if (!v->var->is_set_stmt_ok())
|
|
||||||
{
|
|
||||||
my_error(ER_SET_STATEMENT_NOT_SUPPORTED, MYF(0), v->var->name.str);
|
|
||||||
lex->reset_arena_for_set_stmt(&backup);
|
|
||||||
lex->old_var_list.empty();
|
|
||||||
lex->free_arena_for_set_stmt();
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (v->var->session_is_default(thd))
|
|
||||||
o= new set_var(thd,v->type, v->var, &v->base, NULL);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (v->var->option.var_type & GET_TYPE_MASK)
|
|
||||||
{
|
|
||||||
case GET_BOOL:
|
|
||||||
case GET_INT:
|
|
||||||
case GET_LONG:
|
|
||||||
case GET_LL:
|
|
||||||
{
|
|
||||||
bool null_value;
|
|
||||||
longlong val= v->var->val_int(&null_value, thd, v->type, &v->base);
|
|
||||||
o= new set_var(thd, v->type, v->var, &v->base,
|
|
||||||
(null_value ?
|
|
||||||
(Item *) new (mem_root) Item_null(thd) :
|
|
||||||
(Item *) new (mem_root) Item_int(thd, val)));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GET_UINT:
|
|
||||||
case GET_ULONG:
|
|
||||||
case GET_ULL:
|
|
||||||
{
|
|
||||||
bool null_value;
|
|
||||||
ulonglong val= v->var->val_int(&null_value, thd, v->type, &v->base);
|
|
||||||
o= new set_var(thd, v->type, v->var, &v->base,
|
|
||||||
(null_value ?
|
|
||||||
(Item *) new (mem_root) Item_null(thd) :
|
|
||||||
(Item *) new (mem_root) Item_uint(thd, val)));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GET_DOUBLE:
|
|
||||||
{
|
|
||||||
bool null_value;
|
|
||||||
double val= v->var->val_real(&null_value, thd, v->type, &v->base);
|
|
||||||
o= new set_var(thd, v->type, v->var, &v->base,
|
|
||||||
(null_value ?
|
|
||||||
(Item *) new (mem_root) Item_null(thd) :
|
|
||||||
(Item *) new (mem_root) Item_float(thd, val, 1)));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case GET_NO_ARG:
|
|
||||||
case GET_DISABLED:
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
/* fall through */
|
|
||||||
case 0:
|
|
||||||
case GET_FLAGSET:
|
|
||||||
case GET_ENUM:
|
|
||||||
case GET_SET:
|
|
||||||
case GET_STR:
|
|
||||||
case GET_STR_ALLOC:
|
|
||||||
{
|
|
||||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
|
||||||
String tmp(buff, sizeof(buff), v->var->charset(thd)),*val;
|
|
||||||
val= v->var->val_str(&tmp, thd, v->type, &v->base);
|
|
||||||
if (val)
|
|
||||||
{
|
|
||||||
Item_string *str= new (mem_root) Item_string(thd, v->var->charset(thd),
|
|
||||||
val->ptr(), val->length());
|
|
||||||
o= new set_var(thd, v->type, v->var, &v->base, str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
o= new set_var(thd, v->type, v->var, &v->base,
|
|
||||||
new (mem_root) Item_null(thd));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBUG_ASSERT(o);
|
|
||||||
lex->old_var_list.push_back(o, thd->mem_root);
|
|
||||||
}
|
|
||||||
lex->reset_arena_for_set_stmt(&backup);
|
|
||||||
if (lex->old_var_list.is_empty())
|
|
||||||
lex->free_arena_for_set_stmt();
|
|
||||||
if (thd->is_error() ||
|
|
||||||
(res= sql_set_variables(thd, &lex->stmt_var_list, false)))
|
|
||||||
{
|
|
||||||
if (!thd->is_error())
|
|
||||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET");
|
|
||||||
lex->restore_set_statement_var();
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
The value of last_insert_id is remembered in THD to be written to binlog
|
|
||||||
when it's used *the first time* in the statement. But SET STATEMENT
|
|
||||||
must read the old value of last_insert_id to be able to restore it at
|
|
||||||
the end. This should not count at "reading of last_insert_id" and
|
|
||||||
should not remember last_insert_id for binlog. That is, it should clear
|
|
||||||
stmt_depends_on_first_successful_insert_id_in_prev_stmt flag.
|
|
||||||
*/
|
|
||||||
if (!thd->in_sub_stmt)
|
|
||||||
{
|
|
||||||
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thd->lex->mi.connection_name.str == NULL)
|
if (thd->lex->mi.connection_name.str == NULL)
|
||||||
thd->lex->mi.connection_name= thd->variables.default_master_connection;
|
thd->lex->mi.connection_name= thd->variables.default_master_connection;
|
||||||
|
@ -99,6 +99,7 @@ void mysql_init_multi_delete(LEX *lex);
|
|||||||
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
|
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
|
||||||
void create_table_set_open_action_and_adjust_tables(LEX *lex);
|
void create_table_set_open_action_and_adjust_tables(LEX *lex);
|
||||||
int bootstrap(MYSQL_FILE *file);
|
int bootstrap(MYSQL_FILE *file);
|
||||||
|
bool run_set_statement_if_requested(THD *thd, LEX *lex);
|
||||||
int mysql_execute_command(THD *thd);
|
int mysql_execute_command(THD *thd);
|
||||||
enum dispatch_command_return
|
enum dispatch_command_return
|
||||||
{
|
{
|
||||||
|
@ -4273,6 +4273,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
*/
|
*/
|
||||||
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
|
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set variables specified by
|
||||||
|
SET STATEMENT var1=value1 [, var2=value2, ...] FOR <statement>
|
||||||
|
clause for duration of prepare phase. Original values of variable
|
||||||
|
listed in the SET STATEMENT clause is restored right after return
|
||||||
|
from the function check_prepared_statement()
|
||||||
|
*/
|
||||||
|
if (likely(error == 0))
|
||||||
|
error= run_set_statement_if_requested(thd, lex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The only case where we should have items in the thd->free_list is
|
The only case where we should have items in the thd->free_list is
|
||||||
after stmt->set_params_from_vars(), which may in some cases create
|
after stmt->set_params_from_vars(), which may in some cases create
|
||||||
@ -4291,6 +4301,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
|
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Restore original values of variables modified on handling
|
||||||
|
SET STATEMENT clause.
|
||||||
|
*/
|
||||||
|
thd->lex->restore_set_statement_var();
|
||||||
|
|
||||||
/* The order is important */
|
/* The order is important */
|
||||||
lex->unit.cleanup();
|
lex->unit.cleanup();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB Corporation.
|
Copyright (c) 2009, 2021, 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
|
||||||
@ -4692,6 +4692,9 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (thd->lex->describe)
|
||||||
|
select_options|= SELECT_DESCRIBE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When in EXPLAIN, delay deleting the joins so that they are still
|
When in EXPLAIN, delay deleting the joins so that they are still
|
||||||
available when we're producing EXPLAIN EXTENDED warning text.
|
available when we're producing EXPLAIN EXTENDED warning text.
|
||||||
@ -14483,22 +14486,71 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
used only in JOIN::clear
|
used only in JOIN::clear (always) and in do_select()
|
||||||
|
(if there where no matching rows)
|
||||||
|
|
||||||
|
@param join JOIN
|
||||||
|
@param cleared_tables If not null, clear also const tables and mark all
|
||||||
|
cleared tables in the map. cleared_tables is only
|
||||||
|
set when called from do_select() when there is a
|
||||||
|
group function and there where no matching rows.
|
||||||
*/
|
*/
|
||||||
static void clear_tables(JOIN *join)
|
|
||||||
|
static void clear_tables(JOIN *join, table_map *cleared_tables)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
must clear only the non-const tables, as const tables
|
must clear only the non-const tables as const tables are not re-calculated.
|
||||||
are not re-calculated.
|
|
||||||
*/
|
*/
|
||||||
for (uint i= 0 ; i < join->table_count ; i++)
|
for (uint i= 0 ; i < join->table_count ; i++)
|
||||||
{
|
{
|
||||||
if (!(join->table[i]->map & join->const_table_map))
|
TABLE *table= join->table[i];
|
||||||
mark_as_null_row(join->table[i]); // All fields are NULL
|
|
||||||
|
if (table->null_row)
|
||||||
|
continue; // Nothing more to do
|
||||||
|
if (!(table->map & join->const_table_map) || cleared_tables)
|
||||||
|
{
|
||||||
|
if (cleared_tables)
|
||||||
|
{
|
||||||
|
(*cleared_tables)|= (((table_map) 1) << i);
|
||||||
|
if (table->s->null_bytes)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Remember null bits for the record so that we can restore the
|
||||||
|
original const record in unclear_tables()
|
||||||
|
*/
|
||||||
|
memcpy(table->record[1], table->null_flags, table->s->null_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mark_as_null_row(table); // All fields are NULL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reverse null marking for tables and restore null bits.
|
||||||
|
|
||||||
|
We have to do this because the tables may be re-used in a sub query
|
||||||
|
and the subquery will assume that the const tables contains the original
|
||||||
|
data before clear_tables().
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void unclear_tables(JOIN *join, table_map *cleared_tables)
|
||||||
|
{
|
||||||
|
for (uint i= 0 ; i < join->table_count ; i++)
|
||||||
|
{
|
||||||
|
if ((*cleared_tables) & (((table_map) 1) << i))
|
||||||
|
{
|
||||||
|
TABLE *table= join->table[i];
|
||||||
|
if (table->s->null_bytes)
|
||||||
|
memcpy(table->null_flags, table->record[1], table->s->null_bytes);
|
||||||
|
unmark_as_null_row(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Make som simple condition optimization:
|
Make som simple condition optimization:
|
||||||
If there is a test 'field = const' change all refs to 'field' to 'const'
|
If there is a test 'field = const' change all refs to 'field' to 'const'
|
||||||
@ -17969,17 +18021,34 @@ Field *Item_field::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
|||||||
src->set_field(field);
|
src->set_field(field);
|
||||||
if (!(result= create_tmp_field_from_item_field(root, table, NULL, param)))
|
if (!(result= create_tmp_field_from_item_field(root, table, NULL, param)))
|
||||||
return NULL;
|
return NULL;
|
||||||
/*
|
if (field->eq_def(result))
|
||||||
Fields that are used as arguments to the DEFAULT() function already have
|
|
||||||
their data pointers set to the default value during name resolution. See
|
|
||||||
Item_default_value::fix_fields.
|
|
||||||
*/
|
|
||||||
if (type() != Item::DEFAULT_VALUE_ITEM && field->eq_def(result))
|
|
||||||
src->set_default_field(field);
|
src->set_default_field(field);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_default_value::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
if (field->default_value && (field->flags & BLOB_FLAG))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We have to use a copy function when using a blob with default value
|
||||||
|
as the we have to calculate the default value before we can use it.
|
||||||
|
*/
|
||||||
|
get_tmp_field_src(src, param);
|
||||||
|
return tmp_table_field_from_field_type(root, table);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Same code as in Item_field::create_tmp_field_ex, except no default field
|
||||||
|
handling
|
||||||
|
*/
|
||||||
|
src->set_field(field);
|
||||||
|
return create_tmp_field_from_item_field(root, table, nullptr, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Field *Item_ref::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
Field *Item_ref::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
||||||
Tmp_field_src *src,
|
Tmp_field_src *src,
|
||||||
const Tmp_field_param *param)
|
const Tmp_field_param *param)
|
||||||
@ -18081,7 +18150,13 @@ Field *Item_func_sp::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
|||||||
the record in the original table.
|
the record in the original table.
|
||||||
If modify_item is 0 then fill_record() will update
|
If modify_item is 0 then fill_record() will update
|
||||||
the temporary table
|
the temporary table
|
||||||
|
@param table_cant_handle_bit_fields
|
||||||
|
Set to 1 if the temporary table cannot handle bit
|
||||||
|
fields. Only set for heap tables when the bit field
|
||||||
|
is part of an index.
|
||||||
|
@param make_copy_field
|
||||||
|
Set when using with rollup when we want to have
|
||||||
|
an exact copy of the field.
|
||||||
@retval
|
@retval
|
||||||
0 on error
|
0 on error
|
||||||
@retval
|
@retval
|
||||||
@ -20146,6 +20221,7 @@ do_select(JOIN *join, Procedure *procedure)
|
|||||||
if (join->only_const_tables() && !join->need_tmp)
|
if (join->only_const_tables() && !join->need_tmp)
|
||||||
{
|
{
|
||||||
Next_select_func end_select= setup_end_select_func(join, NULL);
|
Next_select_func end_select= setup_end_select_func(join, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
HAVING will be checked after processing aggregate functions,
|
HAVING will be checked after processing aggregate functions,
|
||||||
But WHERE should checked here (we alredy have read tables).
|
But WHERE should checked here (we alredy have read tables).
|
||||||
@ -20172,6 +20248,17 @@ do_select(JOIN *join, Procedure *procedure)
|
|||||||
}
|
}
|
||||||
else if (join->send_row_on_empty_set())
|
else if (join->send_row_on_empty_set())
|
||||||
{
|
{
|
||||||
|
table_map cleared_tables= (table_map) 0;
|
||||||
|
if (end_select == end_send_group)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Was a grouping query but we did not find any rows. In this case
|
||||||
|
we clear all tables to get null in any referenced fields,
|
||||||
|
like in case of:
|
||||||
|
SELECT MAX(a) AS f1, a AS f2 FROM t1 WHERE VALUE(a) IS NOT NULL
|
||||||
|
*/
|
||||||
|
clear_tables(join, &cleared_tables);
|
||||||
|
}
|
||||||
if (!join->having || join->having->val_int())
|
if (!join->having || join->having->val_int())
|
||||||
{
|
{
|
||||||
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
|
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
|
||||||
@ -20179,6 +20266,12 @@ do_select(JOIN *join, Procedure *procedure)
|
|||||||
rc= join->result->send_data_with_check(*columns_list,
|
rc= join->result->send_data_with_check(*columns_list,
|
||||||
join->unit, 0) > 0;
|
join->unit, 0) > 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
We have to remove the null markings from the tables as this table
|
||||||
|
may be part of a sub query that is re-evaluated
|
||||||
|
*/
|
||||||
|
if (cleared_tables)
|
||||||
|
unclear_tables(join, &cleared_tables);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
An error can happen when evaluating the conds
|
An error can happen when evaluating the conds
|
||||||
@ -21146,8 +21239,8 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos)
|
|||||||
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0)))
|
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0)))
|
||||||
mark_as_null_row(table);
|
mark_as_null_row(table);
|
||||||
}
|
}
|
||||||
if (!table->null_row)
|
if (!table->null_row && ! tab->join->mixed_implicit_grouping)
|
||||||
table->maybe_null=0;
|
table->maybe_null= 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
JOIN *join= tab->join;
|
JOIN *join= tab->join;
|
||||||
@ -26313,7 +26406,7 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg, TABL
|
|||||||
|
|
||||||
void JOIN::clear()
|
void JOIN::clear()
|
||||||
{
|
{
|
||||||
clear_tables(this);
|
clear_tables(this, 0);
|
||||||
copy_fields(&tmp_table_param);
|
copy_fields(&tmp_table_param);
|
||||||
|
|
||||||
if (sum_funcs)
|
if (sum_funcs)
|
||||||
|
@ -477,6 +477,15 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
|
|||||||
*/
|
*/
|
||||||
error= handler_truncate(thd, table_ref, FALSE);
|
error= handler_truncate(thd, table_ref, FALSE);
|
||||||
|
|
||||||
|
if (error == TRUNCATE_OK && thd->locked_tables_mode &&
|
||||||
|
(table_ref->table->file->ht->flags &
|
||||||
|
HTON_REQUIRES_CLOSE_AFTER_TRUNCATE))
|
||||||
|
{
|
||||||
|
thd->locked_tables_list.mark_table_for_reopen(thd, table_ref->table);
|
||||||
|
if (unlikely(thd->locked_tables_list.reopen_tables(thd, true)))
|
||||||
|
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
All effects of a TRUNCATE TABLE operation are committed even if
|
All effects of a TRUNCATE TABLE operation are committed even if
|
||||||
truncation fails in the case of non transactional tables. Thus, the
|
truncation fails in the case of non transactional tables. Thus, the
|
||||||
|
@ -679,7 +679,7 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
|
|||||||
st_select_lex *parent_select)
|
st_select_lex *parent_select)
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
select_result *save_result= thd->lex->result;
|
select_result *save_result= lex->result;
|
||||||
uint8 save_derived_tables= lex->derived_tables;
|
uint8 save_derived_tables= lex->derived_tables;
|
||||||
thd->lex->result= NULL;
|
thd->lex->result= NULL;
|
||||||
|
|
||||||
@ -760,13 +760,13 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
|
|||||||
|
|
||||||
if (arena)
|
if (arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
thd->lex->result= save_result;
|
lex->result= save_result;
|
||||||
return wrapper_sl;
|
return wrapper_sl;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (arena)
|
if (arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
thd->lex->result= save_result;
|
lex->result= save_result;
|
||||||
lex->derived_tables= save_derived_tables;
|
lex->derived_tables= save_derived_tables;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -851,14 +851,9 @@ Item_subselect::wrap_tvc_into_select(THD *thd, st_select_lex *tvc_sl)
|
|||||||
{
|
{
|
||||||
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
|
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
|
||||||
((subselect_single_select_engine *) engine)->change_select(wrapper_sl);
|
((subselect_single_select_engine *) engine)->change_select(wrapper_sl);
|
||||||
lex->current_select= wrapper_sl;
|
|
||||||
return wrapper_sl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lex->current_select= parent_select;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
lex->current_select= parent_select;
|
||||||
|
return wrapper_sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3209,6 +3209,12 @@ inline void mark_as_null_row(TABLE *table)
|
|||||||
bfill(table->null_flags,table->s->null_bytes,255);
|
bfill(table->null_flags,table->s->null_bytes,255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void unmark_as_null_row(TABLE *table)
|
||||||
|
{
|
||||||
|
table->null_row=0;
|
||||||
|
table->status= STATUS_NO_RECORD;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_simple_order(ORDER *order);
|
bool is_simple_order(ORDER *order);
|
||||||
|
|
||||||
class Open_tables_backup;
|
class Open_tables_backup;
|
||||||
|
@ -2417,18 +2417,6 @@ trx_is_registered_for_2pc(
|
|||||||
return(trx->is_registered == 1);
|
return(trx->is_registered == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Note that a transaction has been registered with MySQL 2PC coordinator. */
|
|
||||||
static inline
|
|
||||||
void
|
|
||||||
trx_register_for_2pc(
|
|
||||||
/*==================*/
|
|
||||||
trx_t* trx) /* in: transaction */
|
|
||||||
{
|
|
||||||
trx->is_registered = 1;
|
|
||||||
ut_ad(!trx->active_commit_ordered);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Note that a transaction has been deregistered. */
|
Note that a transaction has been deregistered. */
|
||||||
static inline
|
static inline
|
||||||
@ -3631,8 +3619,10 @@ static int innodb_init(void* p)
|
|||||||
innobase_hton->show_status = innobase_show_status;
|
innobase_hton->show_status = innobase_show_status;
|
||||||
innobase_hton->notify_tabledef_changed= innodb_notify_tabledef_changed;
|
innobase_hton->notify_tabledef_changed= innodb_notify_tabledef_changed;
|
||||||
innobase_hton->flags =
|
innobase_hton->flags =
|
||||||
HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS
|
HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS |
|
||||||
| HTON_NATIVE_SYS_VERSIONING | HTON_WSREP_REPLICATION;
|
HTON_NATIVE_SYS_VERSIONING |
|
||||||
|
HTON_WSREP_REPLICATION |
|
||||||
|
HTON_REQUIRES_CLOSE_AFTER_TRUNCATE;
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
innobase_hton->abort_transaction=wsrep_abort_transaction;
|
innobase_hton->abort_transaction=wsrep_abort_transaction;
|
||||||
@ -15150,10 +15140,6 @@ ha_innobase::extra(
|
|||||||
case HA_EXTRA_END_ALTER_COPY:
|
case HA_EXTRA_END_ALTER_COPY:
|
||||||
m_prebuilt->table->skip_alter_undo = 0;
|
m_prebuilt->table->skip_alter_undo = 0;
|
||||||
break;
|
break;
|
||||||
case HA_EXTRA_FAKE_START_STMT:
|
|
||||||
trx_register_for_2pc(m_prebuilt->trx);
|
|
||||||
m_prebuilt->sql_stat_start = true;
|
|
||||||
goto stmt_boundary;
|
|
||||||
default:/* Do nothing */
|
default:/* Do nothing */
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ ibuf_bitmap_get_map_page(
|
|||||||
{
|
{
|
||||||
return buf_page_get_gen(
|
return buf_page_get_gen(
|
||||||
ibuf_bitmap_page_no_calc(page_id, zip_size),
|
ibuf_bitmap_page_no_calc(page_id, zip_size),
|
||||||
zip_size, RW_X_LATCH, NULL, BUF_GET, mtr);
|
zip_size, RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************//**
|
/************************************************************************//**
|
||||||
@ -697,9 +697,12 @@ ibuf_set_free_bits_low(
|
|||||||
#endif /* UNIV_IBUF_DEBUG */
|
#endif /* UNIV_IBUF_DEBUG */
|
||||||
const page_id_t id(block->page.id());
|
const page_id_t id(block->page.id());
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
if (buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
ibuf_bitmap_get_map_page(id, block->zip_size(), mtr),
|
id, block->zip_size(), mtr)) {
|
||||||
id, block->physical_size(), val, mtr);
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
|
bitmap_page, id, block->physical_size(),
|
||||||
|
val, mtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************//**
|
/************************************************************************//**
|
||||||
@ -843,10 +846,13 @@ ibuf_update_free_bits_zip(
|
|||||||
buf_page_make_young(&block->page);
|
buf_page_make_young(&block->page);
|
||||||
}
|
}
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
if (buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
ibuf_bitmap_get_map_page(block->page.id(), block->zip_size(),
|
block->page.id(), block->zip_size(), mtr)) {
|
||||||
mtr),
|
|
||||||
block->page.id(), block->physical_size(), after, mtr);
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
|
bitmap_page, block->page.id(),
|
||||||
|
block->physical_size(), after, mtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
@ -3612,14 +3618,15 @@ ibuf_insert_to_index_page_low(
|
|||||||
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
|
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
|
||||||
"InnoDB: that table.\n", stderr);
|
"InnoDB: that table.\n", stderr);
|
||||||
|
|
||||||
ib::error() << "page " << block->page.id() << ", size "
|
if (buf_block_t *bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
<< block->physical_size() << ", bitmap bits "
|
block->page.id(), block->zip_size(), mtr)) {
|
||||||
<< ibuf_bitmap_page_get_bits(
|
|
||||||
ibuf_bitmap_get_map_page(block->page.id(),
|
ib::error() << "page " << block->page.id() << ", size "
|
||||||
block->zip_size(),
|
<< block->physical_size() << ", bitmap bits "
|
||||||
mtr)->frame,
|
<< ibuf_bitmap_page_get_bits(bitmap_page->frame,
|
||||||
block->page.id(), block->zip_size(),
|
block->page.id(), block->zip_size(),
|
||||||
IBUF_BITMAP_FREE, mtr);
|
IBUF_BITMAP_FREE, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
ib::error() << BUG_REPORT_MSG;
|
ib::error() << BUG_REPORT_MSG;
|
||||||
|
|
||||||
|
@ -1233,7 +1233,7 @@ inline void trx_t::commit_tables()
|
|||||||
const trx_id_t max_trx_id= trx_sys.get_max_trx_id();
|
const trx_id_t max_trx_id= trx_sys.get_max_trx_id();
|
||||||
const auto now= start_time;
|
const auto now= start_time;
|
||||||
|
|
||||||
for (const auto& p : mod_tables)
|
for (const auto &p : mod_tables)
|
||||||
{
|
{
|
||||||
dict_table_t *table= p.first;
|
dict_table_t *table= p.first;
|
||||||
table->update_time= now;
|
table->update_time= now;
|
||||||
@ -1337,7 +1337,6 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
|
|||||||
|
|
||||||
release_locks();
|
release_locks();
|
||||||
id= 0;
|
id= 0;
|
||||||
|
|
||||||
DEBUG_SYNC_C("after_trx_committed_in_memory");
|
DEBUG_SYNC_C("after_trx_committed_in_memory");
|
||||||
|
|
||||||
while (dict_table_t *table= UT_LIST_GET_FIRST(lock.evicted_tables))
|
while (dict_table_t *table= UT_LIST_GET_FIRST(lock.evicted_tables))
|
||||||
|
@ -1464,6 +1464,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
|
|||||||
}
|
}
|
||||||
if (maria_is_crashed(info))
|
if (maria_is_crashed(info))
|
||||||
{
|
{
|
||||||
|
tprint(tracef, "\n");
|
||||||
eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with"
|
eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with"
|
||||||
" aria_chk -r", share->open_file_name.str);
|
" aria_chk -r", share->open_file_name.str);
|
||||||
recovery_found_crashed_tables++;
|
recovery_found_crashed_tables++;
|
||||||
|
@ -98,6 +98,7 @@ void eprint(FILE *trace_file __attribute__ ((unused)),
|
|||||||
fputc('\n', trace_file);
|
fputc('\n', trace_file);
|
||||||
if (trace_file != stderr)
|
if (trace_file != stderr)
|
||||||
{
|
{
|
||||||
|
va_start(args, format);
|
||||||
my_printv_error(HA_ERR_INITIALIZATION, format, MYF(0), args);
|
my_printv_error(HA_ERR_INITIALIZATION, format, MYF(0), args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
@ -550,9 +550,6 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
|
|||||||
case HA_EXTRA_END_ALTER_COPY:
|
case HA_EXTRA_END_ALTER_COPY:
|
||||||
inspected = "HA_EXTRA_END_ALTER_COPY";
|
inspected = "HA_EXTRA_END_ALTER_COPY";
|
||||||
break;
|
break;
|
||||||
case HA_EXTRA_FAKE_START_STMT:
|
|
||||||
inspected = "HA_EXTRA_FAKE_START_STMT";
|
|
||||||
break;
|
|
||||||
#ifdef MRN_HAVE_HA_EXTRA_EXPORT
|
#ifdef MRN_HAVE_HA_EXTRA_EXPORT
|
||||||
case HA_EXTRA_EXPORT:
|
case HA_EXTRA_EXPORT:
|
||||||
inspected = "HA_EXTRA_EXPORT";
|
inspected = "HA_EXTRA_EXPORT";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user