--source include/have_sequence.inc
--source include/have_innodb.inc
--source include/big_test.inc
--source include/not_valgrind.inc
--source include/have_log_bin.inc

call mtr.add_suppression("Write to binary log failed: .* temporary space limit reached. An incident event is written to binary log.*");

#
# Test tmp_space_usage
#

# flush global status is needed because of max_tmp_space_used
flush status;
flush global status;
show session status like "max_tmp_space_used";
show global status like  "max_tmp_space_used";

--echo #
--echo # MDEV-9101 Limit size of total size of created disk temporary files
--echo #           and tables.

# Print variables that can affect the test result
show session status like "tmp_space_used";
show global status like "tmp_space_used";
select @@global.max_tmp_session_space_usage, @@global.max_tmp_total_space_usage;
select @@binlog_stmt_cache_size,@@binlog_format;

create table t1 (a int primary key, v varchar(256), c int default(0)) engine=innodb;
--error 41
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_65536;
set @@max_tmp_session_space_usage=1024*1024*1024;
--error 42
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_65536;
set @@max_tmp_session_space_usage=default;

set @@binlog_format="statement";
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_65536;
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_65537_to_131072;
select count(*) from t1;

create table t2 (a int, b int) engine=innodb select seq as a, 0 as b from seq_1_to_131072;

# Force usage of on disk tmp tables
set @@binlog_format="row";
set @@tmp_memory_table_size=32*1024;

--echo # The following queries should fail because of tmp_space_usage
--error 41
select * from t1 order by a,v;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
select v,count(*) from t1 group by v limit 2;
--error 41
update t1 set v=right(v,2);

set @@binlog_format="statement";
set @@max_tmp_session_space_usage=65536;
set @@tmp_memory_table_size=0;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
update t1,t2 set t1.c=t2.a, t2.b=1 where t1.a=t2.a;
set @@binlog_format="row";
set @@max_tmp_session_space_usage=default;

drop table t1,t2;

--echo #
--echo # Check max_tmp_total_space_usage & processlist
--echo #

# We have to set tmp_memory_table_size to ensure we do not use disk for
# the following two show commands.
set @@tmp_memory_table_size=1024*1024;
show session status like "tmp_space_used";
# The following is disabled until we can do "show status" without using
# temporary files
# show global status like "tmp_space_used";
set @@tmp_memory_table_size=0;

let $tmp_usage1=`select variable_value from information_schema.session_status where variable_name="max_tmp_space_used"`;
flush status;
let $tmp_usage2=`select variable_value from information_schema.global_status where variable_name="max_tmp_space_used"`;

--disable_query_log
if ($tmp_usage1 <= $tmp_usage2)
{
--echo # session.max_tmp_session_space_usage <= global.max_tmp_session_space_usage
}
if ($tmp_usage1 != $tmp_usage2)
{
--echo session.max_tmp_session_space_usage ($tmp_usage1) > global.max_tmp_session_space_usage ($tmp_usage2)
}
--enable_query_log


connect(c1, localhost, root,,);
connection default;

create table t1 (a int primary key, v varchar(256), c int default(0)) engine=innodb;
create table t2 (a int primary key, v varchar(256), c int default(0)) engine=innodb;

begin;
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_3000;

let $id=`select connection_id()`;
let $tmp_usage1=`select variable_value from information_schema.session_status where variable_name="tmp_space_used"`;
# Wait for the previous statement to finish cleanup before reading processlist.
--ping

connection c1;
--disable_query_log
let $tmp_usage2=`select tmp_space_used from information_schema.processlist where id=$id`;
if ($tmp_usage1 == $tmp_usage2)
{
--echo # information_schema.process_list.tmp_space_used == status.tmp_space_used
}
if ($tmp_usage1 != $tmp_usage2)
{
--echo tmp_space_used difference: $tmp_usage1 != $tmp_usage2
}
--enable_query_log

--error 42
insert into t2 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_3000;
--echo # Test setting tmp_space_usage to 0 to disable quotas
set @save_max_tmp_total_space_usage=@@global.max_tmp_total_space_usage;
set @@global.max_tmp_total_space_usage=0;
set @@max_tmp_session_space_usage=0;
insert into t2 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_3000;
set @@global.max_tmp_total_space_usage=@save_max_tmp_total_space_usage;
set @@max_tmp_session_space_usage=0;
connection default;
insert into t1 (a,v) values(9999990,0);
commit;
select count(*) from t1;

disconnect c1;
drop table t1,t2;

--echo #
--echo # Test case from Elena
--echo #

SET @@max_tmp_session_space_usage= 64*1024;
set @@binlog_format="statement";

CREATE OR REPLACE TABLE t1 (a INT, b INT);
INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100000;
--error 41
ALTER TABLE t1 ORDER BY a, b;

# Cleanup
DROP TABLE t1;

--echo #
--echo # Show that setting max tmp space too low value can stop binary logging
--echo # if non transactional tables are used.
--echo #

set @save_max_tmp_total_space_usage=@@global.max_tmp_total_space_usage;
SET @@global.max_tmp_total_space_usage=64*1024;
set @@binlog_format="row";

create table t1 (a int primary key, v varchar(256)) engine=myisam;
--error 41,42
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_65536;
show warnings;
select count(*) <> 0 from t1;

# Show that this problem does not exists with transactional tables
truncate table t1;
alter table t1 engine=innodb;
--error 41,42
insert into t1 (a,v) select seq, repeat(char(64+mod(seq,32)),mod(seq,254)+1) from seq_1_to_65536;
show warnings;
select count(*) <> 0 from t1;
drop table t1;

set @@global.max_tmp_total_space_usage=@save_max_tmp_total_space_usage;

--echo #
--echo # Check updating non transactional table
--echo #

SET max_tmp_session_space_usage= 64*1024;
 
CREATE TABLE t1 (
  a varchar(1024), b varchar(1024), c varchar(1024), d varchar(1024), e varchar(1024), f varchar(1024), g varchar(1024)
) ENGINE=MyISAM;
 
INSERT INTO t1 VALUES
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
(REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024),REPEAT('x',1024)),
('x','x','x','x','x','x','x');
 
--error 41
UPDATE t1 SET a = '' LIMIT 100;

DROP TABLE t1;

--echo #
--echo # MDEV-33680 Server hangs or assertion fails upon SELECT with limited
--echo # max_tmp_space_usage
--echo #

set max_tmp_session_space_usage = 1024*1024;
--error HA_ERR_GLOBAL_TMP_SPACE_FULL
select count(distinct concat(seq,repeat('x',1000))) from seq_1_to_1000;

--echo #
--echo # MDEV-33751 Assertion `thd' failed in int
--echo # temp_file_size_cb_func(tmp_file_tracking*, int)
--echo #

set @save_max_tmp_total_space_usage=@@global.max_tmp_total_space_usage;
set @@global.max_tmp_total_space_usage=64*1024*1024;
# Binlog cache reserve 4096 bytes at the begin of the temporary file.
set @@max_tmp_session_space_usage=1179648+65536;
select @@max_tmp_session_space_usage;
set @save_aria_repair_threads=@@aria_repair_threads;
set @@aria_repair_threads=2;
set @save_max_heap_table_size=@@max_heap_table_size;
set @@max_heap_table_size=16777216;

CREATE TABLE t1 (a CHAR(255),b INT,INDEX (b));
INSERT INTO t1 SELECT SEQ,SEQ FROM seq_1_to_100000;
set @@max_tmp_session_space_usage=1179648;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
SELECT * FROM t1 UNION SELECT * FROM t1;
DROP TABLE t1;

set @@aria_repair_threads=@save_aria_repair_threads;
set @@max_heap_table_size=@save_max_heap_table_size;
set @@global.max_tmp_total_space_usage=@save_max_tmp_total_space_usage;

--echo #
--echo # MDEV-34016 Assertion `info->key_del_used == 0' failed in maria_close
--echo # with limited tmp space
--echo #

set @save_max_tmp_total_space_usage=@@global.max_tmp_total_space_usage;
connect(c1, localhost, root,,);
CREATE TABLE t1 (a varchar(1024)) engine=aria CHARSET=latin1;
INSERT INTO t1 VALUES ('this'),('is'),('just'),('a'),('filling'),('for'),(REPEAT('a',500));
set @@global.max_tmp_total_space_usage=2*1024*1024;
SET max_tmp_session_space_usage= 1024*1024, max_heap_table_size= 4*1024*1024;
--error ER_NOT_KEYFILE
SELECT DISTINCT a, seq FROM t1 JOIN seq_1_to_600;
DROP TABLE t1;
connection default;
disconnect c1;
set @@global.max_tmp_total_space_usage=@save_max_tmp_total_space_usage;

--echo #
--echo # MDEV-34054
--echo # Memory leak in Window_func_runner::exec after encountering
--echo # "temporary space limit reached" error

SET max_tmp_session_space_usage= 64*1024;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
SELECT MIN(VARIABLE_VALUE) OVER (), NTILE(1) OVER (), MAX(VARIABLE_NAME) OVER () FROM information_schema.SESSION_STATUS;

--echo #
--echo # MDEV-34060 Unexpected behavior upon reading I_S.ALL_PLUGINS under
--echo # limited tmp space
--echo #

connect(c1, localhost, root,,);
set @@binlog_format=row;
CREATE OR REPLACE TABLE t1 (a DATETIME) ENGINE=InnoDB;
# Binlog cache file will be truncated at commit, thus keep the the transaction
# to keep binlog cache temporary file large enough
BEGIN;
INSERT INTO t1 SELECT NOW() FROM seq_1_to_6000;

SET max_tmp_session_space_usage = 64*1024;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
SELECT * FROM information_schema.ALL_PLUGINS LIMIT 2;
ROLLBACK;
drop table t1;
connection default;
disconnect c1;

--echo #
--echo # MDEV-34142 Server crashes in create_internal_tmp_table with low tmp
--echo # space limit
--echo #

SET MAX_TMP_SESSION_SPACE_USAGE = 128*1024, MAX_HEAP_TABLE_SIZE= 16*1024*1024;
CREATE TABLE t1 (a varchar(1024)) DEFAULT CHARACTER SET utf8mb3;
INSERT INTO t1 SELECT 'x' FROM seq_1_to_50;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
SELECT * FROM t1 JOIN seq_1_to_200 INTERSECT ALL SELECT * FROM t1 JOIN seq_1_to_200;
drop table t1;

--echo #
--echo # MDEV-34149 Corruption-like errors are produced when temporary space
--echo # limit is reached
--echo #

SET MAX_TMP_SESSION_SPACE_USAGE = 400*1024;
--error HA_ERR_LOCAL_TMP_SPACE_FULL
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100
INTERSECT ALL
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100;

--echo # End of 11.5 tests
