Merge branch '10.4' into 10.4.29 release

This commit is contained in:
Oleksandr Byelkin 2023-05-11 09:07:45 +02:00
commit de703a2b21
69 changed files with 1184 additions and 448 deletions

View file

@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=4
MYSQL_VERSION_PATCH=29
MYSQL_VERSION_PATCH=30
SERVER_MATURITY=stable

View file

@ -79,3 +79,4 @@
{ "HA_ERR_ABORTED_BY_USER", HA_ERR_ABORTED_BY_USER, "" },
{ "HA_ERR_DISK_FULL", HA_ERR_DISK_FULL, "" },
{ "HA_ERR_INCOMPATIBLE_DEFINITION", HA_ERR_INCOMPATIBLE_DEFINITION, "" },
{ "HA_ERR_NO_ENCRYPTION", HA_ERR_NO_ENCRYPTION, "" },

View file

@ -48,6 +48,7 @@
#define HA_OPEN_NO_PSI_CALL 1024U /* Don't call/connect PSI */
#define HA_OPEN_MERGE_TABLE 2048U
#define HA_OPEN_FOR_CREATE 4096U
#define HA_OPEN_FOR_DROP (1U << 13) /* Open part of drop */
/*
Allow opening even if table is incompatible as this is for ALTER TABLE which
@ -516,14 +517,15 @@ enum ha_base_keytype {
#define HA_ERR_DISK_FULL 189
#define HA_ERR_INCOMPATIBLE_DEFINITION 190
#define HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE 191 /* Too many words in a phrase */
#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but decypt failed */
#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but decrypt failed */
#define HA_ERR_FK_DEPTH_EXCEEDED 193 /* FK cascade depth exceeded */
#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */
#define HA_ERR_SEQUENCE_INVALID_DATA 195
#define HA_ERR_SEQUENCE_RUN_OUT 196
#define HA_ERR_COMMIT_ERROR 197
#define HA_ERR_PARTITION_LIST 198
#define HA_ERR_LAST 198 /* Copy of last error nr * */
#define HA_ERR_NO_ENCRYPTION 199
#define HA_ERR_LAST 199 /* Copy of last error nr * */
/* Number of different errors */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

View file

@ -109,7 +109,8 @@ static const char *handler_error_messages[]=
"Sequence has been run out",
"Sequence values are conflicting",
"Error during commit",
"Cannot select partitions"
"Cannot select partitions",
"Cannot initialize encryption. Check that all encryption parameters have been set"
};
#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */

View file

@ -11,7 +11,7 @@ let $counter= 5000;
let $mysql_errno= 9999;
while ($mysql_errno)
{
--error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013
--error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013,HA_ERR_NO_ENCRYPTION
show status;
dec $counter;
@ -30,6 +30,10 @@ while ($mysql_errno)
{
let $mysql_errno=0;
}
if ($mysql_errno == 199)
{
let $mysql_errno=0;
}
--sleep 0.1
}
--enable_query_log

View file

@ -19,20 +19,5 @@ id select_type table type possible_keys key key_len ref rows Extra
SET GLOBAL slow_query_log = @sql_tmp;
drop table t1;
#
# MDEV-31181: Server crash in subselect_uniquesubquery_engine::print
# upon EXPLAIN EXTENDED DELETE
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (pk INT PRIMARY KEY);
INSERT INTO t2 VALUES (1),(2);
EXPLAIN EXTENDED DELETE FROM t1 WHERE a IN (SELECT pk FROM t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
Warnings:
Note 1003 /* select#1 */ delete from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a`))))
drop table t1, t2;
#
# End of 10.4 tests
#

View file

@ -19,21 +19,6 @@ SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
SET GLOBAL slow_query_log = @sql_tmp;
drop table t1;
--echo #
--echo # MDEV-31181: Server crash in subselect_uniquesubquery_engine::print
--echo # upon EXPLAIN EXTENDED DELETE
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (pk INT PRIMARY KEY);
INSERT INTO t2 VALUES (1),(2);
EXPLAIN EXTENDED DELETE FROM t1 WHERE a IN (SELECT pk FROM t2);
drop table t1, t2;
--echo #
--echo # End of 10.4 tests
--echo #

View file

@ -277,3 +277,53 @@ EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
drop table t1,t2;
#
# MDEV-31181: EXPLAIN EXTENDED for single-table DELETE with IN predicand
#
create table t1 (a int);
insert into t1 values (3), (7), (1), (3), (4);
create table t2 (pk int primary key);
insert into t2 values (3), (5), (1);
create table t3 (a int, key(a));
insert into t3 values (7), (5), (7), (3);
explain extended delete from t1 where a in (select pk from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 Using where
2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
Warnings:
Note 1003 /* select#1 */ delete from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on PRIMARY)))
delete from t1 where a in (select pk from t2);
select * from t1;
a
7
4
explain extended delete from t1 where a in (select a from t3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t3 index_subquery a a 5 func 2 100.00 Using index
Warnings:
Note 1003 /* select#1 */ delete from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t3 on a)))
delete from t1 where a in (select a from t3);
select * from t1;
a
4
drop table t1,t2,t3;
#
# MDEV-31224: EXPLAIN EXTENDED for multi-table update of system table
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3);
EXPLAIN EXTENDED UPDATE t1, t2 SET b = 4 WHERE a IN (6,2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 update `test`.`t1` set `test`.`t2`.`b` = 4 where `test`.`t1`.`a` in (6,2)
UPDATE t1, t2 SET b = 4 WHERE a IN (6,2);
SELECT * from t2;
b
4
DROP TABLE t1, t2;
# End of 10.4 tests

View file

@ -250,3 +250,50 @@ PREPARE stmt FROM 'EXPLAIN INSERT INTO t1 SELECT * FROM t2';
EXECUTE stmt;
drop table t1,t2;
--echo #
--echo # MDEV-31181: EXPLAIN EXTENDED for single-table DELETE with IN predicand
--echo #
create table t1 (a int);
insert into t1 values (3), (7), (1), (3), (4);
create table t2 (pk int primary key);
insert into t2 values (3), (5), (1);
create table t3 (a int, key(a));
insert into t3 values (7), (5), (7), (3);
let $q1=
delete from t1 where a in (select pk from t2);
eval explain extended $q1;
eval $q1;
select * from t1;
let $q2=
delete from t1 where a in (select a from t3);
eval explain extended $q2;
eval $q2;
select * from t1;
drop table t1,t2,t3;
--echo #
--echo # MDEV-31224: EXPLAIN EXTENDED for multi-table update of system table
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3);
let $q=
UPDATE t1, t2 SET b = 4 WHERE a IN (6,2);
eval EXPLAIN EXTENDED $q;
eval $q;
SELECT * from t2;
DROP TABLE t1, t2;
--echo # End of 10.4 tests

View file

@ -4025,3 +4025,116 @@ drop table t1;
#
# End of 10.1 tests
#
#
# MDEV-6768 Wrong result with agregate with join with no resultset
#
create table t1
(
PARENT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
PARENT_FIELD VARCHAR(10),
PRIMARY KEY (PARENT_ID)
) engine=innodb;
create table t2
(
CHILD_ID INT NOT NULL AUTO_INCREMENT,
PARENT_ID INT NOT NULL,
CHILD_FIELD varchar(10),
PRIMARY KEY (CHILD_ID)
)engine=innodb;
INSERT INTO t1 (PARENT_FIELD)
SELECT 'AAAA';
INSERT INTO t2 (PARENT_ID, CHILD_FIELD)
SELECT 1, 'BBBB';
explain select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
PARENT_ID min(CHILD_FIELD)
NULL NULL
select
1,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
1 min(CHILD_FIELD)
1 NULL
select
IFNULL(t1.PARENT_ID,1),
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
IFNULL(t1.PARENT_ID,1) min(CHILD_FIELD)
1 NULL
# Check that things works with MyISAM (which has different explain)
alter table t1 engine=myisam;
alter table t2 engine=myisam;
explain select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
PARENT_ID min(CHILD_FIELD)
NULL NULL
drop table t1,t2;
# Check that things works if sub queries are re-executed
create table t1 (a int primary key, b int);
create table t2 (a int primary key, b int);
create table t3 (a int primary key, b int);
insert into t1 values (1,1),(2,2),(3,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(3,3);
explain
select *,
(select
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
from t2,t3
where t2.a=1 and t1.b = t3.a) as s1
from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t2 const PRIMARY PRIMARY 4 const 1 Using index
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1
select *,
(select
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
from t2,t3
where t2.a=1 and t1.b = t3.a) as s1
from t1;
a b s1
1 1 t2:1;min_t3_b:1
2 2 t2:t2a-null;min_t3_b:t3b-null
3 3 t2:1;min_t3_b:3
drop table t1,t2,t3;
#
# End of 10.4 tests
#

View file

@ -5,6 +5,7 @@
--source include/no_valgrind_without_big.inc
--source include/default_optimizer_switch.inc
--source include/have_innodb.inc
#
# TODO:
@ -1688,3 +1689,117 @@ drop table t1;
--echo #
--echo # End of 10.1 tests
--echo #
--echo #
--echo # MDEV-6768 Wrong result with agregate with join with no resultset
--echo #
create table t1
(
PARENT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
PARENT_FIELD VARCHAR(10),
PRIMARY KEY (PARENT_ID)
) engine=innodb;
create table t2
(
CHILD_ID INT NOT NULL AUTO_INCREMENT,
PARENT_ID INT NOT NULL,
CHILD_FIELD varchar(10),
PRIMARY KEY (CHILD_ID)
)engine=innodb;
INSERT INTO t1 (PARENT_FIELD)
SELECT 'AAAA';
INSERT INTO t2 (PARENT_ID, CHILD_FIELD)
SELECT 1, 'BBBB';
explain select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
select
1,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
select
IFNULL(t1.PARENT_ID,1),
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
--echo # Check that things works with MyISAM (which has different explain)
alter table t1 engine=myisam;
alter table t2 engine=myisam;
explain select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
select
t1.PARENT_ID,
min(CHILD_FIELD)
from t1 straight_join t2
where t1.PARENT_ID = 1
and t1.PARENT_ID = t2.PARENT_ID
and t2.CHILD_FIELD = "ZZZZ";
drop table t1,t2;
--echo # Check that things works if sub queries are re-executed
create table t1 (a int primary key, b int);
create table t2 (a int primary key, b int);
create table t3 (a int primary key, b int);
insert into t1 values (1,1),(2,2),(3,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(3,3);
explain
select *,
(select
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
from t2,t3
where t2.a=1 and t1.b = t3.a) as s1
from t1;
select *,
(select
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
from t2,t3
where t2.a=1 and t1.b = t3.a) as s1
from t1;
drop table t1,t2,t3;
--echo #
--echo # End of 10.4 tests
--echo #

View file

@ -3781,9 +3781,9 @@ id1 num3 text1 id4 id3 dummy
228808822 6 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 18 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 17 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 50 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
228808822 89 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
228808822 19 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
@ -5655,13 +5655,13 @@ EXPLAIN
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
a a b b c
3 3 32 32 302
3 3 30 30 300
3 3 31 NULL NULL
3 3 32 32 302
set join_buffer_space_limit=@save_join_buffer_space_limit;
set join_buffer_size=@save_join_buffer_size;
set join_cache_level=@save_join_cache_level;

View file

@ -0,0 +1,27 @@
#
# MDEV-28217 Incorrect Join Execution When Controlling Join Buffer Size
#
CREATE TABLE t1 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t1 VALUES (1332945389);
CREATE TABLE t2 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t2 VALUES (1180244875), (1951338178);
SET SESSION join_buffer_size= X;
Warnings:
Warning X Truncated incorrect join_buffer_size value: 'X'
SET SESSION join_cache_level = 4;
SET optimizer_switch='optimize_join_buffer_size=on';
SELECT t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
i
SET optimizer_switch='optimize_join_buffer_size=off';
SELECT t1.i,t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
ERROR HYX: Could not create a join buffer. Please check and adjust the value of the variables 'JOIN_BUFFER_SIZE (X)' and 'JOIN_BUFFER_SPACE_LIMIT (X)'
SET SESSION join_buffer_size= 10000000;
SELECT t1.i,t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
i i
SET SESSION optimizer_switch= default;
SET SESSION join_buffer_size= default;
SET SESSION join_cache_level= default;
drop table t1,t2;
#
# End of 10.4 tests
#

View file

@ -0,0 +1,35 @@
#
# Tests that should be in join_cache but cannot be run with ASAN
--source include/not_asan.inc
--source include/have_innodb.inc
--echo #
--echo # MDEV-28217 Incorrect Join Execution When Controlling Join Buffer Size
--echo #
# This test tries to allocate a too big bufffer, for which ASAN gives an error
CREATE TABLE t1 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t1 VALUES (1332945389);
CREATE TABLE t2 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t2 VALUES (1180244875), (1951338178);
--replace_regex /[0-9][0-9]+/X/
SET SESSION join_buffer_size= 5250229460064350213;
SET SESSION join_cache_level = 4;
SET optimizer_switch='optimize_join_buffer_size=on';
SELECT t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
SET optimizer_switch='optimize_join_buffer_size=off';
--replace_regex /[0-9][0-9]+/X/
--error ER_OUTOFMEMORY
SELECT t1.i,t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
SET SESSION join_buffer_size= 10000000;
SELECT t1.i,t2.i FROM t2 LEFT JOIN t1 ON t1.i = t2.i WHERE t1.i;
SET SESSION optimizer_switch= default;
SET SESSION join_buffer_size= default;
SET SESSION join_cache_level= default;
drop table t1,t2;
--echo #
--echo # End of 10.4 tests
--echo #

View file

@ -2,6 +2,8 @@
drop table if exists t0,t1,t2,t3;
--enable_warnings
--source include/have_innodb.inc
--echo #
--echo # BUG#38049 incorrect rows estimations with references from preceding table
--echo #

View file

@ -0,0 +1 @@
--lower-case-table-names=2

View file

@ -14,7 +14,7 @@ SHOW CREATE TABLE T1;
Table Create Table
T1 CREATE TABLE `T1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
RENAME TABLE T1 TO T2;
SHOW TABLES LIKE "T2";
Tables_in_test (T2)
@ -70,7 +70,7 @@ SHOW CREATE TABLE T1;
Table Create Table
T1 CREATE TABLE `T1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
RENAME TABLE T1 TO T2;
SHOW TABLES LIKE "T2";
Tables_in_test (T2)
@ -319,18 +319,42 @@ Database (mysql_t%)
mysql_TEST
show create database mysql_test;
Database Create Database
mysql_test CREATE DATABASE `mysql_test` /*!40100 DEFAULT CHARACTER SET latin1 */
mysql_test CREATE DATABASE `mysql_test` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */
show create database mysql_TEST;
Database Create Database
mysql_TEST CREATE DATABASE `mysql_TEST` /*!40100 DEFAULT CHARACTER SET latin1 */
mysql_TEST CREATE DATABASE `mysql_TEST` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */
show create table mysql_TEST.T1;
Table Create Table
T1 CREATE TABLE `T1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
show create table mysql_test.t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop database mysql_TEST;
# MDEV-30765 SHOW TABLES not working properly with
# lower_case_table_names=2
#
create database db1;
use db1;
# lowercase table name
create table `a` (a int);
# uppercase table name
create table `B` (a int);
create user 'mysqltest_1'@'localhost' identified by 'password';
grant select, show view on db1.`a` to 'mysqltest_1'@'localhost';
grant select, show view on db1.`B` to 'mysqltest_1'@'localhost';
connect conn1, localhost, mysqltest_1, password, test;
connection conn1;
use db1;
show tables;
Tables_in_db1
B
a
connection default;
disconnect conn1;
drop user 'mysqltest_1'@'localhost';
drop tables a, B;
drop database db1;

View file

@ -288,3 +288,29 @@ show create database mysql_TEST;
show create table mysql_TEST.T1;
show create table mysql_test.t1;
drop database mysql_TEST;
--echo # MDEV-30765 SHOW TABLES not working properly with
--echo # lower_case_table_names=2
--echo #
create database db1;
use db1;
--echo # lowercase table name
create table `a` (a int);
--echo # uppercase table name
create table `B` (a int);
create user 'mysqltest_1'@'localhost' identified by 'password';
grant select, show view on db1.`a` to 'mysqltest_1'@'localhost';
grant select, show view on db1.`B` to 'mysqltest_1'@'localhost';
connect (conn1, localhost, mysqltest_1, password, test);
connection conn1;
use db1;
show tables;
connection default;
disconnect conn1;
drop user 'mysqltest_1'@'localhost';
drop tables a, B;
drop database db1;

View file

@ -2689,7 +2689,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1003 update `test`.`t1` set NULL = 10
Note 1003 update `test`.`t1` set `test`.`t2`.`c2` = 10
# Status of EXPLAIN EXTENDED query
Variable_name Value
Handler_read_key 7
@ -2734,7 +2734,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 update `test`.`t1` set NULL = 10 where `test`.`t1`.`c3` = 10
Note 1003 update `test`.`t1` set `test`.`t2`.`c2` = 10 where `test`.`t1`.`c3` = 10
# Status of EXPLAIN EXTENDED query
Variable_name Value
Handler_read_key 7

View file

@ -1230,6 +1230,8 @@ SELECT * FROM t1 HAVING MIN(t1.c1) >= ALL(SELECT 'a' UNION SELECT 'r');
c1
Warnings:
Warning 1292 Truncated incorrect datetime value: 'r'
SELECT * FROM t1 HAVING MIN(t1.c1) > 0;
c1
DROP TABLE t1;
CREATE TABLE t1 (c1 timestamp);
INSERT INTO t1 VALUES ('2010-01-01 00:00:00');

View file

@ -810,6 +810,7 @@ DROP TABLE t1;
CREATE TABLE t1 (c1 timestamp);
SELECT MIN(t1.c1) AS k1 FROM t1 HAVING (k1 >= ALL(SELECT 'a' UNION SELECT 'r'));
SELECT * FROM t1 HAVING MIN(t1.c1) >= ALL(SELECT 'a' UNION SELECT 'r');
SELECT * FROM t1 HAVING MIN(t1.c1) > 0;
DROP TABLE t1;
CREATE TABLE t1 (c1 timestamp);

View file

@ -1,10 +1,10 @@
connection node_2;
connection node_1;
connection node_1;
connection node_2;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
connection node_2;
connection node_1;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -2,11 +2,11 @@ connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
connection node_2;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
connection node_2;
connection node_1;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -2,11 +2,11 @@ connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
connection node_2;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
connection node_2;
connection node_1;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -1,10 +1,10 @@
connection node_2;
connection node_1;
connection node_1;
connection node_2;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
connection node_2;
connection node_1;
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -1,11 +1,11 @@
--source include/galera_cluster.inc
--source include/force_restart.inc
--connection node_1
--connection node_2
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
--connection node_2
--connection node_1
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -6,11 +6,11 @@
--let $node_2=node_2
--source include/auto_increment_offset_save.inc
--connection node_1
--connection node_2
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;
--connection node_2
--connection node_1
set global wsrep_on=OFF;
reset master;
set global wsrep_on=ON;

View file

@ -1,15 +1,27 @@
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression("Initialization of encryption failed.*");
set global aria_encrypt_tables= 1;
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
alter table t1 enable keys;
ERROR HY000: Unknown key id 1. Can't continue!
repair table t1 use_frm;
Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair status OK
drop table t1;
ERROR HY000: Initialization of encryption failed for ./test/t1
set global aria_encrypt_tables= default;
#
# MDEV-26258 Various crashes/asserts/corruptions when Aria encryption is
# enabled/used, but the encryption plugin is not loaded
#
SET GLOBAL aria_encrypt_tables=ON;
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
ERROR HY000: Initialization of encryption failed for ./test/t1
# Restart with encryption enabled
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
INSERT INTO t1 VALUES (4,0);
LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
LOAD INDEX INTO CACHE t1;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
SELECT * FROM t1;
ERROR HY000: Initialization of encryption failed for ./test/t1.MAD
DROP TABLE t1;
Warnings:
Warning 199 Initialization of encryption failed for ./test/t1.MAD
Cleanup

View file

@ -1,14 +1,56 @@
--source include/not_embedded.inc
#
# MDEV-18496 Crash when Aria encryption is enabled but plugin not available
#
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression("Initialization of encryption failed.*");
set global aria_encrypt_tables= 1;
--error HA_ERR_NO_ENCRYPTION
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
error 192;
alter table t1 enable keys;
repair table t1 use_frm;
drop table t1;
set global aria_encrypt_tables= default;
--echo #
--echo # MDEV-26258 Various crashes/asserts/corruptions when Aria encryption is
--echo # enabled/used, but the encryption plugin is not loaded
--echo #
SET GLOBAL aria_encrypt_tables=ON;
--write_file $MYSQLTEST_VARDIR/keys1.txt
1;770A8A65DA156D24EE2A093277530142
EOF
--replace_result \\ /
--error HA_ERR_NO_ENCRYPTION
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
--echo # Restart with encryption enabled
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
--exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
INSERT INTO t1 VALUES (4,0);
LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
LOAD INDEX INTO CACHE t1;
# Restart without encryption. Above table should be unreadable
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
--exec echo "restart:--aria-encrypt-tables=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--replace_result \\ /
--error HA_ERR_NO_ENCRYPTION
SELECT * FROM t1;
DROP TABLE t1;
--echo Cleanup
--remove_file $MYSQLTEST_VARDIR/keys1.txt

View file

@ -1,16 +1,16 @@
call mtr.add_suppression("file_key_management");
call mtr.add_suppression("System key id 1 is missing");
call mtr.add_suppression("Unknown key id 1");
call mtr.add_suppression("Failed to decrypt");
call mtr.add_suppression("Initialization of encryption failed.*");
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=Aria;
INSERT INTO t1 VALUES (1);
repair table t1;
Table Op Msg_type Msg_text
test.t1 repair info Wrong CRC on datapage at 1
test.t1 repair warning Number of rows changed from 1 to 0
test.t1 repair status OK
test.t1 repair Error Initialization of encryption failed for ./test/t1.MAD
test.t1 repair error Corrupt
INSERT INTO t1 VALUES (2);
ERROR HY000: Initialization of encryption failed for ./test/t1.MAD
select * from t1;
ERROR HY000: failed to decrypt './test/t1' rc: -1 dstlen: 0 size: 8172
i
1
drop table t1;

View file

@ -7,7 +7,7 @@
call mtr.add_suppression("file_key_management");
call mtr.add_suppression("System key id 1 is missing");
call mtr.add_suppression("Unknown key id 1");
call mtr.add_suppression("Failed to decrypt");
call mtr.add_suppression("Initialization of encryption failed.*");
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
@ -36,8 +36,11 @@ EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--replace_result \\ /
repair table t1;
--replace_result \\ /
--error HA_ERR_NO_ENCRYPTION
INSERT INTO t1 VALUES (2);
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@ -48,8 +51,6 @@ INSERT INTO t1 VALUES (2);
--enable_reconnect
--source include/wait_until_connected_again.inc
--replace_result \\ /
--error 192
select * from t1;
drop table t1;
--remove_file $MYSQLTEST_VARDIR/keys1.txt

View file

@ -2814,7 +2814,7 @@ DROP TABLE t1;
# cardinalities=1
#
SET aria_repair_threads=2;
SET aria_sort_buffer_size=8192;
SET aria_sort_buffer_size=16384;
CREATE TABLE t1(a CHAR(255), KEY(a), KEY(a), KEY(a));
Warnings:
Note 1831 Duplicate index `a_2`. This is deprecated and will be disallowed in a future release
@ -2839,19 +2839,8 @@ SET aria_repair_threads=@@global.aria_repair_threads;
# low myisam_sort_buffer_size
#
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
(6,'0'),(7,'0');
INSERT INTO t1 SELECT a+10,b FROM t1;
INSERT INTO t1 SELECT a+20,b FROM t1;
INSERT INTO t1 SELECT a+40,b FROM t1;
INSERT INTO t1 SELECT a+80,b FROM t1;
INSERT INTO t1 SELECT a+160,b FROM t1;
INSERT INTO t1 SELECT a+320,b FROM t1;
INSERT INTO t1 SELECT a+640,b FROM t1;
INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET aria_sort_buffer_size=4096;
INSERT INTO t1 select seq,'0' from seq_1_to_65536;
SET aria_sort_buffer_size=16384;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error aria_sort_buffer_size is too small. X

View file

@ -5,6 +5,7 @@
-- source include/have_maria.inc
-- source include/have_partition.inc
-- source include/have_sequence.inc
call mtr.add_suppression("Can't find record in '.*'");
@ -2034,7 +2035,7 @@ DROP TABLE t1;
--echo # cardinalities=1
--echo #
SET aria_repair_threads=2;
SET aria_sort_buffer_size=8192;
SET aria_sort_buffer_size=16384;
CREATE TABLE t1(a CHAR(255), KEY(a), KEY(a), KEY(a));
INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(0),(1),(2),(3);
--replace_regex /Current aria_sort_buffer_size.*/X/
@ -2050,19 +2051,8 @@ SET aria_repair_threads=@@global.aria_repair_threads;
--echo # low myisam_sort_buffer_size
--echo #
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
(6,'0'),(7,'0');
INSERT INTO t1 SELECT a+10,b FROM t1;
INSERT INTO t1 SELECT a+20,b FROM t1;
INSERT INTO t1 SELECT a+40,b FROM t1;
INSERT INTO t1 SELECT a+80,b FROM t1;
INSERT INTO t1 SELECT a+160,b FROM t1;
INSERT INTO t1 SELECT a+320,b FROM t1;
INSERT INTO t1 SELECT a+640,b FROM t1;
INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET aria_sort_buffer_size=4096;
INSERT INTO t1 select seq,'0' from seq_1_to_65536;
SET aria_sort_buffer_size=16384;
--replace_regex /Current aria_sort_buffer_size.*/X/
REPAIR TABLE t1;
CHECK TABLE t1;

View file

@ -0,0 +1,81 @@
SET sql_mode='';
CREATE TEMPORARY TABLE t1 (a tinyINT,b CHAR(1)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 VALUES (1,1),(3,3),(2,2);
SET SESSION tmp_table_size=True;
Warnings:
Warning 1292 Truncated incorrect tmp_table_size value: '1'
CREATE TABLE t2 (c INT, d DATE) ENGINE=InnoDB PARTITION BY RANGE (YEAR (d)) SUBPARTITION BY HASH (TO_DAYS (d)) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0, SUBPARTITION s1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION s4, SUBPARTITION s5));
SET SESSION aria_sort_buffer_size=CAST(-1 AS UNSIGNED INT);
Warnings:
Note 1105 Cast to unsigned converted negative integer to it's positive complement
Note 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '18446744073709551615'
INSERT INTO t1 SELECT '', SEQ FROM seq_1_to_258;
Warnings:
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 1
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 2
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 3
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 4
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 5
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 6
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 7
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 8
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 9
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 10
Warning 1265 Data truncated for column 'b' at row 10
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 11
Warning 1265 Data truncated for column 'b' at row 11
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 12
Warning 1265 Data truncated for column 'b' at row 12
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 13
Warning 1265 Data truncated for column 'b' at row 13
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 14
Warning 1265 Data truncated for column 'b' at row 14
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 15
Warning 1265 Data truncated for column 'b' at row 15
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 16
Warning 1265 Data truncated for column 'b' at row 16
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 17
Warning 1265 Data truncated for column 'b' at row 17
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 18
Warning 1265 Data truncated for column 'b' at row 18
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 19
Warning 1265 Data truncated for column 'b' at row 19
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 20
Warning 1265 Data truncated for column 'b' at row 20
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 21
Warning 1265 Data truncated for column 'b' at row 21
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 22
Warning 1265 Data truncated for column 'b' at row 22
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 23
Warning 1265 Data truncated for column 'b' at row 23
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 24
Warning 1265 Data truncated for column 'b' at row 24
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 25
Warning 1265 Data truncated for column 'b' at row 25
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 26
Warning 1265 Data truncated for column 'b' at row 26
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 27
Warning 1265 Data truncated for column 'b' at row 27
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 28
Warning 1265 Data truncated for column 'b' at row 28
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 29
Warning 1265 Data truncated for column 'b' at row 29
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 30
Warning 1265 Data truncated for column 'b' at row 30
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 31
Warning 1265 Data truncated for column 'b' at row 31
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 32
Warning 1265 Data truncated for column 'b' at row 32
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 33
Warning 1265 Data truncated for column 'b' at row 33
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 34
Warning 1265 Data truncated for column 'b' at row 34
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 35
Warning 1265 Data truncated for column 'b' at row 35
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 36
Warning 1265 Data truncated for column 'b' at row 36
Warning 1366 Incorrect integer value: '' for column `test`.`t1`.`a` at row 37
SET SESSION aria_repair_threads=4;
UPDATE t1 SET a=( (SELECT MAX(a) FROM t1));
drop table t1,t2;

View file

@ -0,0 +1,15 @@
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_sequence.inc
SET sql_mode='';
CREATE TEMPORARY TABLE t1 (a tinyINT,b CHAR(1)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 VALUES (1,1),(3,3),(2,2);
SET SESSION tmp_table_size=True;
CREATE TABLE t2 (c INT, d DATE) ENGINE=InnoDB PARTITION BY RANGE (YEAR (d)) SUBPARTITION BY HASH (TO_DAYS (d)) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0, SUBPARTITION s1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION s4, SUBPARTITION s5));
SET SESSION aria_sort_buffer_size=CAST(-1 AS UNSIGNED INT);
INSERT INTO t1 SELECT '', SEQ FROM seq_1_to_258;
SET SESSION aria_repair_threads=4;
UPDATE t1 SET a=( (SELECT MAX(a) FROM t1));
drop table t1,t2;

View file

@ -22,13 +22,13 @@ Warnings:
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '10'
select @@global.aria_sort_buffer_size;
@@global.aria_sort_buffer_size
4096
16376
set session aria_sort_buffer_size=10;
Warnings:
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '10'
select @@session.aria_sort_buffer_size;
@@session.aria_sort_buffer_size
4096
16376
set global aria_sort_buffer_size=1.1;
ERROR 42000: Incorrect argument type to variable 'aria_sort_buffer_size'
set session aria_sort_buffer_size=1e1;
@ -40,9 +40,9 @@ Warnings:
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '0'
select @@global.aria_sort_buffer_size;
@@global.aria_sort_buffer_size
4096
16376
set session aria_sort_buffer_size=cast(-1 as unsigned int);
select @@session.aria_sort_buffer_size;
@@session.aria_sort_buffer_size
18446744073709551615
1152921504606846975
SET @@global.aria_sort_buffer_size = @start_global_value;

View file

@ -223,8 +223,8 @@ DEFAULT_VALUE 268434432
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_MIN_VALUE 16376
NUMERIC_MAX_VALUE 1152921504606846975
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO

View file

@ -97,9 +97,9 @@
@@ -207,7 +207,7 @@ VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.
NUMERIC_MIN_VALUE 4096
NUMERIC_MIN_VALUE 16376
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_MAX_VALUE 268435455
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@ -684,8 +684,8 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
NUMERIC_MIN_VALUE 4096
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 4294967295
-NUMERIC_MAX_VALUE 1152921504606846975
+NUMERIC_MAX_VALUE 268435455
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO

View file

@ -216,8 +216,8 @@ VARIABLE_NAME ARIA_SORT_BUFFER_SIZE
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_MIN_VALUE 16376
NUMERIC_MAX_VALUE 1152921504606846975
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@ -2127,7 +2127,7 @@ VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_MAX_VALUE 1152921504606846975
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO

View file

@ -216,8 +216,8 @@ VARIABLE_NAME ARIA_SORT_BUFFER_SIZE
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_MIN_VALUE 16376
NUMERIC_MAX_VALUE 1152921504606846975
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@ -2287,7 +2287,7 @@ VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_MAX_VALUE 1152921504606846975
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO

View file

@ -140,7 +140,7 @@ Create_func_trt_trx_sees<X> Create_func_trt_trx_sees<X>::s_singleton;
#define BUILDER(F) & F::s_singleton
static Native_func_registry func_array[] =
static const Native_func_registry func_array_vers[] =
{
{ { C_STRING_WITH_LEN("TRT_BEGIN_TS") }, BUILDER(Create_func_trt<TR_table::FLD_BEGIN_TS>)},
{ { C_STRING_WITH_LEN("TRT_COMMIT_ID") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_ID>)},
@ -164,7 +164,7 @@ static int versioning_plugin_init(void *p __attribute__ ((unused)))
{
DBUG_ENTER("versioning_plugin_init");
// No need in locking since we so far single-threaded
int res= item_create_append(func_array);
int res= native_functions_hash.append(func_array_vers);
if (res)
{
my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
@ -177,7 +177,7 @@ static int versioning_plugin_init(void *p __attribute__ ((unused)))
static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
{
DBUG_ENTER("versioning_plugin_deinit");
(void) item_create_remove(func_array);
(void) native_functions_hash.remove(func_array_vers);
DBUG_RETURN(0);
}

View file

@ -7249,7 +7249,7 @@ Create_func_year_week::create_native(THD *thd, const LEX_CSTRING *name,
- keep 1 line per entry, it makes grep | sort easier
*/
Native_func_registry func_array[] =
const Native_func_registry func_array[] =
{
{ { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
{ { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
@ -7609,9 +7609,10 @@ Native_func_registry func_array[] =
{ {0, 0}, NULL}
};
size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1;
static HASH native_functions_hash;
const size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1;
Native_functions_hash native_functions_hash;
extern "C" uchar*
get_native_fct_hash_key(const uchar *buff, size_t *length,
@ -7628,85 +7629,89 @@ get_native_fct_hash_key(const uchar *buff, size_t *length,
startup only (before going multi-threaded)
*/
int item_create_init()
bool Native_functions_hash::init(size_t count)
{
DBUG_ENTER("item_create_init");
DBUG_ENTER("Native_functions_hash::init");
if (my_hash_init(& native_functions_hash,
if (my_hash_init(this,
system_charset_info,
array_elements(func_array),
(ulong) count,
0,
0,
(my_hash_get_key) get_native_fct_hash_key,
NULL, /* Nothing to free */
MYF(0)))
DBUG_RETURN(1);
DBUG_RETURN(true);
DBUG_RETURN(item_create_append(func_array));
DBUG_RETURN(false);
}
int item_create_append(Native_func_registry array[])
{
Native_func_registry *func;
DBUG_ENTER("item_create_append");
bool Native_functions_hash::append(const Native_func_registry array[])
{
const Native_func_registry *func;
DBUG_ENTER("Native_functions_hash::append");
for (func= array; func->builder != NULL; func++)
{
if (my_hash_insert(& native_functions_hash, (uchar*) func))
DBUG_RETURN(1);
if (my_hash_insert(this, (uchar*) func))
DBUG_RETURN(true);
}
#ifndef DBUG_OFF
for (uint i=0 ; i < native_functions_hash.records ; i++)
for (uint i=0 ; i < records ; i++)
{
func= (Native_func_registry*) my_hash_element(& native_functions_hash, i);
func= (Native_func_registry*) my_hash_element(this, i);
DBUG_PRINT("info", ("native function: %s length: %u",
func->name.str, (uint) func->name.length));
}
#endif
DBUG_RETURN(0);
DBUG_RETURN(false);
}
int item_create_remove(Native_func_registry array[])
{
Native_func_registry *func;
DBUG_ENTER("item_create_remove");
bool Native_functions_hash::remove(const Native_func_registry array[])
{
const Native_func_registry *func;
DBUG_ENTER("Native_functions_hash::remove");
for (func= array; func->builder != NULL; func++)
{
if (my_hash_delete(& native_functions_hash, (uchar*) func))
DBUG_RETURN(1);
if (my_hash_delete(this, (uchar*) func))
DBUG_RETURN(true);
}
DBUG_RETURN(0);
DBUG_RETURN(false);
}
/*
Empty the hash table for native functions.
Note: this code is not thread safe, and is intended to be used at server
shutdown only (after thread requests have been executed).
*/
void item_create_cleanup()
void Native_functions_hash::cleanup()
{
DBUG_ENTER("item_create_cleanup");
my_hash_free(& native_functions_hash);
DBUG_ENTER("Native_functions_hash::cleanup");
my_hash_free(this);
DBUG_VOID_RETURN;
}
Create_func *
find_native_function_builder(THD *thd, const LEX_CSTRING *name)
Native_functions_hash::find(THD *thd, const LEX_CSTRING &name) const
{
Native_func_registry *func;
Create_func *builder= NULL;
/* Thread safe */
func= (Native_func_registry*) my_hash_search(&native_functions_hash,
(uchar*) name->str,
name->length);
func= (Native_func_registry*) my_hash_search(this,
(uchar*) name.str,
name.length);
if (func)
{
@ -7716,6 +7721,19 @@ find_native_function_builder(THD *thd, const LEX_CSTRING *name)
return builder;
}
int item_create_init()
{
return native_functions_hash.init(func_array, array_elements(func_array));
}
void item_create_cleanup()
{
native_functions_hash.cleanup();
}
Create_qfunc *
find_qualified_function_builder(THD *thd)
{

View file

@ -144,16 +144,6 @@ protected:
};
/**
Find the native function builder associated with a given function name.
@param thd The current thread
@param name The native function name
@return The native function builder associated with the name, or NULL
*/
extern Create_func *find_native_function_builder(THD *thd,
const LEX_CSTRING *name);
/**
Find the function builder for qualified functions.
@param thd The current thread
@ -200,9 +190,52 @@ struct Native_func_registry
Create_func *builder;
};
class Native_functions_hash: public HASH
{
public:
Native_functions_hash()
{
bzero(this, sizeof(*this));
}
~Native_functions_hash()
{
/*
No automatic free because objects of this type
are expected to be declared statically.
The code in cleanup() calls my_hash_free() which may not work correctly
at the very end of mariadbd shutdown.
The the upper level code should call cleanup() explicitly.
Unfortunatelly, it's not possible to use DBUG_ASSERT(!records) here,
because the server terminates using exit() in some cases,
e.g. in the test main.named_pipe with the "Create named pipe failed"
error.
*/
}
bool init(size_t count);
bool init(const Native_func_registry array[], size_t count)
{
return init(count) || append(array);
}
bool append(const Native_func_registry array[]);
bool remove(const Native_func_registry array[]);
void cleanup();
/**
Find the native function builder associated with a given function name.
@param thd The current thread
@param name The native function name
@return The native function builder associated with the name, or NULL
*/
Create_func *find(THD *thd, const LEX_CSTRING &name) const;
};
extern MYSQL_PLUGIN_IMPORT Native_functions_hash native_functions_hash;
extern const Native_func_registry func_array[];
extern const size_t func_array_length;
int item_create_init();
int item_create_append(Native_func_registry array[]);
int item_create_remove(Native_func_registry array[]);
void item_create_cleanup();
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);

View file

@ -381,7 +381,7 @@ public:
{
for (uint i= 0; i < arg_count; i++)
{
args[i]->no_rows_in_result();
args[i]->restore_to_before_no_rows_in_result();
}
}
void convert_const_compared_to_int_field(THD *thd);

View file

@ -4536,16 +4536,11 @@ void subselect_union_engine::print(String *str, enum_query_type query_type)
void subselect_uniquesubquery_engine::print(String *str,
enum_query_type query_type)
{
TABLE *table= tab->tab_list ? tab->tab_list->table : tab->table;
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
tab->ref.items[0]->print(str, query_type);
if (!tab->table)
{
// table is not opened so unknown
str->append(')');
return;
}
str->append(STRING_WITH_LEN(" in "));
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
if (table->s->table_category == TABLE_CATEGORY_TEMPORARY)
{
/*
Temporary tables' names change across runs, so they can't be used for
@ -4554,8 +4549,8 @@ void subselect_uniquesubquery_engine::print(String *str,
str->append(STRING_WITH_LEN("<temporary table>"));
}
else
str->append(&tab->table->s->table_name);
KEY *key_info= tab->table->key_info+ tab->ref.key;
str->append(&table->s->table_name);
KEY *key_info= table->key_info+ tab->ref.key;
str->append(STRING_WITH_LEN(" on "));
str->append(&key_info->name);
if (cond)
@ -4573,12 +4568,13 @@ all other tests pass.
void subselect_uniquesubquery_engine::print(String *str)
{
KEY *key_info= tab->table->key_info + tab->ref.key;
TABLE *table= tab->tab_list ? tab->tab_list->table : tab->table;
KEY *key_info= table->key_info + tab->ref.key;
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
for (uint i= 0; i < key_info->user_defined_key_parts; i++)
tab->ref.items[i]->print(str);
str->append(STRING_WITH_LEN(" in "));
str->append(&tab->table->s->table_name);
str->append(&table->s->table_name);
str->append(STRING_WITH_LEN(" on "));
str->append(&key_info->name);
if (cond)
@ -4593,11 +4589,12 @@ void subselect_uniquesubquery_engine::print(String *str)
void subselect_indexsubquery_engine::print(String *str,
enum_query_type query_type)
{
TABLE *table= tab->tab_list ? tab->tab_list->table : tab->table;
str->append(STRING_WITH_LEN("<index_lookup>("));
tab->ref.items[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" in "));
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
KEY *key_info= tab->table->key_info+ tab->ref.key;
str->append(&table->s->table_name);
KEY *key_info= table->key_info+ tab->ref.key;
str->append(STRING_WITH_LEN(" on "));
str->append(&key_info->name);
if (check_null)
@ -5277,6 +5274,7 @@ subselect_hash_sj_engine::make_unique_engine()
DBUG_RETURN(NULL);
tab->table= tmp_table;
tab->tab_list= 0;
tab->preread_init_done= FALSE;
tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);

View file

@ -4128,6 +4128,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
sjm->materialized= FALSE;
sjm_tab->table= sjm->table;
sjm_tab->tab_list= emb_sj_nest;
sjm->table->pos_in_table_list= emb_sj_nest;
DBUG_RETURN(FALSE);

View file

@ -2317,9 +2317,7 @@ rpl_parallel::find(uint32 domain_id)
mysql_cond_init(key_COND_parallel_entry, &e->COND_parallel_entry, NULL);
if (my_hash_insert(&domain_hash, (uchar *)e))
{
mysql_cond_destroy(&e->COND_parallel_entry);
mysql_mutex_destroy(&e->LOCK_parallel_entry);
my_free(e);
free_rpl_parallel_entry(e);
return NULL;
}
}

View file

@ -5462,7 +5462,7 @@ table_hash_search(const char *host, const char *ip, const char *db,
const char *user, const char *tname, bool exact)
{
return (GRANT_TABLE*) name_hash_search(&column_priv_hash, host, ip, db,
user, tname, exact, FALSE);
user, tname, exact, (lower_case_table_names > 0));
}
static bool column_priv_insert(GRANT_TABLE *grant)

View file

@ -634,7 +634,7 @@ void JOIN_CACHE::create_remaining_fields()
/*
Calculate and set all cache constants
Calculate and set all cache constants
SYNOPSIS
set_constants()
@ -694,16 +694,22 @@ void JOIN_CACHE::set_constants()
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
length + fields*sizeof(uint);
pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *);
min_buff_size= 0;
min_records= 1;
min_buff_size= get_min_join_buffer_size();
buff_size= (size_t)MY_MAX(join->thd->variables.join_buff_size,
get_min_join_buffer_size());
min_buff_size);
size_of_rec_ofs= offset_size(buff_size);
size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len);
size_of_fld_ofs= size_of_rec_len;
base_prefix_length= (with_length ? size_of_rec_len : 0) +
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
/*
/*
Call ge_min_join_buffer_size() again as the size may have got smaller
if size_of_rec_ofs or some other variable changed since last call.
*/
min_buff_size= 0;
min_buff_size= get_min_join_buffer_size();
/*
The size of the offsets for referenced fields will be added later.
The values of 'pack_length' and 'pack_length_with_blob_ptrs' are adjusted
every time when the first reference to the referenced field is registered.
@ -767,30 +773,29 @@ uint JOIN_CACHE::get_record_max_affix_length()
size_t JOIN_CACHE::get_min_join_buffer_size()
{
if (!min_buff_size)
if (min_buff_size)
return min_buff_size; // use cached value
size_t len= 0, len_last= 0, len_addon, min_sz, add_sz= 0;
for (JOIN_TAB *tab= start_tab; tab != join_tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
size_t len= 0;
size_t len_last= 0;
for (JOIN_TAB *tab= start_tab; tab != join_tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
len+= tab->get_max_used_fieldlength();
len_last+= tab->get_used_fieldlength();
}
size_t len_addon= get_record_max_affix_length() +
get_max_key_addon_space_per_record();
len+= len_addon;
len_last+= len_addon;
size_t min_sz= len*(min_records-1) + len_last;
min_sz+= pack_length_with_blob_ptrs;
size_t add_sz= 0;
for (uint i=0; i < min_records; i++)
add_sz+= join_tab_scan->aux_buffer_incr(i+1);
avg_aux_buffer_incr= add_sz/min_records;
min_sz+= add_sz;
set_if_bigger(min_sz, 1);
min_buff_size= min_sz;
len+= tab->get_max_used_fieldlength();
len_last+= tab->get_used_fieldlength();
}
len_addon= (get_record_max_affix_length() +
get_max_key_addon_space_per_record());
len+= len_addon;
len_last+= len_addon;
min_sz= len*(min_records-1) + len_last;
min_sz+= pack_length_with_blob_ptrs;
for (uint i=0; i < min_records; i++)
add_sz+= join_tab_scan->aux_buffer_incr(i+1);
avg_aux_buffer_incr= add_sz/min_records;
min_sz+= add_sz;
set_if_bigger(min_sz, 1);
min_buff_size= min_sz;
return min_buff_size;
}
@ -805,61 +810,67 @@ size_t JOIN_CACHE::get_min_join_buffer_size()
the estimated number of records in the partial join
DESCRIPTION
At the first its invocation for the cache the function calculates the
maximum possible size of join buffer for the cache. If the parameter
optimize_buff_size true then this value does not exceed the size of the
space needed for the estimated number of records 'max_records' in the
partial join that joins tables from the first one through join_tab. This
value is also capped off by the value of join_tab->join_buffer_size_limit,
if it has been set a to non-zero value, and by the value of the system
parameter join_buffer_size - otherwise. After the calculation of the
interesting size the function saves the value in the field 'max_buff_size'
in order to use it directly at the next invocations of the function.
NOTES
Currently the value of join_tab->join_buffer_size_limit is initialized
to 0 and is never reset.
At the first its invocation for the cache the function calculates
the maximum possible size of join buffer for the cache. If the
parameter optimize_buff_size true then this value does not exceed
the size of the space needed for the estimated number of records
'max_records' in the partial join that joins tables from the first
one through join_tab. This value is also capped off by the value
of the system parameter join_buffer_size. After the calculation of
the interesting size the function saves the value in the field
'max_buff_size' in order to use it directly at the next
invocations of the function.
RETURN VALUE
The maximum possible size of the join buffer of this cache
*/
size_t JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
size_t JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size,
size_t min_sz)
{
if (!max_buff_size)
if (max_buff_size)
return max_buff_size; // use cached value
size_t limit_sz= (size_t) join->thd->variables.join_buff_size;
if (!optimize_buff_size)
return max_buff_size= limit_sz;
size_t max_sz;
size_t len= 0;
double max_records, partial_join_cardinality=
(join_tab-1)->get_partial_join_cardinality();
/* Expected join buffer space used for one record */
size_t space_per_record;
for (JOIN_TAB *tab= start_tab; tab != join_tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
size_t max_sz;
size_t min_sz= get_min_join_buffer_size();
size_t len= 0;
for (JOIN_TAB *tab= start_tab; tab != join_tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
len+= tab->get_used_fieldlength();
}
len+= get_record_max_affix_length();
avg_record_length= len;
len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
space_per_record= len;
size_t limit_sz= (size_t)join->thd->variables.join_buff_size;
if (join_tab->join_buffer_size_limit)
set_if_smaller(limit_sz, join_tab->join_buffer_size_limit);
if (!optimize_buff_size)
max_sz= limit_sz;
else
{
if (limit_sz / max_records > space_per_record)
max_sz= space_per_record * max_records;
else
max_sz= limit_sz;
max_sz+= pack_length_with_blob_ptrs;
set_if_smaller(max_sz, limit_sz);
}
set_if_bigger(max_sz, min_sz);
max_buff_size= max_sz;
len+= tab->get_used_fieldlength();
}
len+= get_record_max_affix_length();
avg_record_length= len;
len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
space_per_record= len;
/* Note that space_per_record can be 0 if no table fields where used */
max_records= (double) (limit_sz / MY_MAX(space_per_record, 1));
set_if_smaller(max_records, partial_join_cardinality);
set_if_bigger(max_records, 10.0);
if ((size_t) (limit_sz / max_records) > space_per_record)
max_sz= space_per_record * (size_t) max_records;
else
max_sz= limit_sz;
max_sz+= pack_length_with_blob_ptrs;
set_if_smaller(max_sz, limit_sz);
set_if_bigger(max_sz, min_sz);
max_buff_size= max_sz;
return max_buff_size;
}
}
/*
@ -899,16 +910,8 @@ int JOIN_CACHE::alloc_buffer()
join->thd->variables.join_buff_space_limit;
bool optimize_buff_size=
optimizer_flag(join->thd, OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE);
double partial_join_cardinality= (join_tab-1)->get_partial_join_cardinality();
buff= NULL;
min_buff_size= 0;
max_buff_size= 0;
min_records= 1;
max_records= (size_t) (partial_join_cardinality <= join_buff_space_limit ?
(ulonglong) partial_join_cardinality : join_buff_space_limit);
set_if_bigger(max_records, 10);
min_buff_size= get_min_join_buffer_size();
buff_size= get_max_join_buffer_size(optimize_buff_size);
buff_size= get_max_join_buffer_size(optimize_buff_size, min_buff_size);
for (tab= start_tab; tab!= join_tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
@ -923,13 +926,25 @@ int JOIN_CACHE::alloc_buffer()
curr_min_buff_space_sz+= min_buff_size;
curr_buff_space_sz+= buff_size;
if (curr_min_buff_space_sz > join_buff_space_limit ||
(curr_buff_space_sz > join_buff_space_limit &&
(!optimize_buff_size ||
if (optimize_buff_size)
{
/*
optimize_join_buffer_size=on used. We should limit the join
buffer space to join_buff_space_limit if possible.
*/
if (curr_min_buff_space_sz > join_buff_space_limit)
{
/*
Increase buffer size to minimum needed, to be able to use the
join buffer.
*/
join_buff_space_limit= curr_min_buff_space_sz;
}
if (curr_buff_space_sz > join_buff_space_limit &&
join->shrink_join_buffers(join_tab, curr_buff_space_sz,
join_buff_space_limit))))
goto fail;
join_buff_space_limit))
goto fail; // Fatal error
}
if (for_explain_only)
return 0;
@ -1079,18 +1094,19 @@ int JOIN_CACHE::init(bool for_explain)
/*
Check the possibility to read the access keys directly from the join buffer
Check the possibility to read the access keys directly from the join buffer
SYNOPSIS
check_emb_key_usage()
DESCRIPTION
The function checks some conditions at which the key values can be read
directly from the join buffer. This is possible when the key values can be
composed by concatenation of the record fields stored in the join buffer.
Sometimes when the access key is multi-component the function has to re-order
the fields written into the join buffer to make keys embedded. If key
values for the key access are detected as embedded then 'use_emb_key'
is set to TRUE.
The function checks some conditions at which the key values can be
read directly from the join buffer. This is possible when the key
values can be composed by concatenation of the record fields
stored in the join buffer. Sometimes when the access key is
multi-component the function has to re-order the fields written
into the join buffer to make keys embedded. If key values for the
key access are detected as embedded then 'use_emb_key' is set to
TRUE.
EXAMPLE
Let table t2 has an index defined on the columns a,b . Let's assume also
@ -1243,7 +1259,7 @@ bool JOIN_CACHE::check_emb_key_usage()
trailing spaces
- significant part of fixed length fields that can have trailing spaces
with the prepanded length
- data of non-blob variable length fields with the prepanded data length
- data of non-blob variable length fields with the prepanded data length
- blob data from blob fields with the prepanded data length
(5) record offset values for the data fields that are referred to from
other caches
@ -1314,7 +1330,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
Check whether we won't be able to add any new record into the cache after
this one because the cache will be full. Set last_record to TRUE if it's so.
The assume that the cache will be full after the record has been written
into it if either the remaining space of the cache is not big enough for the
into it if either the remaining space of the cache is not big enough for the
record's blob values or if there is a chance that not all non-blob fields
of the next record can be placed there.
This function is called only in the case when there is enough space left in
@ -1336,7 +1352,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
/*
Put a reference to the fields of the record that are stored in the previous
cache if there is any. This reference is passed by the 'link' parameter.
cache if there is any. This reference is passed by the 'link' parameter.
*/
if (prev_cache)
{
@ -2766,7 +2782,6 @@ bool JOIN_CACHE_BKAH::save_explain_data(EXPLAIN_BKA_TYPE *explain)
int JOIN_CACHE_HASHED::init(bool for_explain)
{
int rc= 0;
TABLE_REF *ref= &join_tab->ref;
DBUG_ENTER("JOIN_CACHE_HASHED::init");
@ -2776,8 +2791,21 @@ int JOIN_CACHE_HASHED::init(bool for_explain)
key_length= ref->key_length;
if ((rc= JOIN_CACHE::init(for_explain)) || for_explain)
DBUG_RETURN (rc);
if (JOIN_CACHE::init(for_explain))
{
THD *thd= join->thd;
const char *errmsg=
"Could not create a join buffer. Please check and "
"adjust the value of the variables 'JOIN_BUFFER_SIZE (%llu)' and "
"'JOIN_BUFFER_SPACE_LIMIT (%llu)'";
my_printf_error(ER_OUTOFMEMORY, errmsg, MYF(0),
thd->variables.join_buff_size,
thd->variables.join_buff_space_limit);
DBUG_RETURN (1);
}
if (for_explain)
DBUG_RETURN(0);
if (!(key_buff= (uchar*) join->thd->alloc(key_length)))
DBUG_RETURN(1);

View file

@ -248,9 +248,6 @@ protected:
/* The expected size of the space per record in the auxiliary buffer */
size_t avg_aux_buffer_incr;
/* Expected join buffer space used for one record */
size_t space_per_record;
/* Pointer to the beginning of the join buffer */
uchar *buff;
/*
@ -272,11 +269,6 @@ protected:
the minimal size equal to min_buff_size
*/
size_t min_records;
/*
The maximum expected number of records to be put in the join buffer
at one refill
*/
size_t max_records;
/*
Pointer to the current position in the join buffer.
@ -542,6 +534,7 @@ protected:
join_tab= tab;
prev_cache= next_cache= 0;
buff= 0;
min_buff_size= max_buff_size= 0; // Caches
}
/*
@ -557,6 +550,7 @@ protected:
next_cache= 0;
prev_cache= prev;
buff= 0;
min_buff_size= max_buff_size= 0; // Caches
if (prev)
prev->next_cache= this;
}
@ -608,9 +602,10 @@ public:
void set_join_buffer_size(size_t sz) { buff_size= sz; }
/* Get the minimum possible size of the cache join buffer */
virtual size_t get_min_join_buffer_size();
size_t get_min_join_buffer_size();
/* Get the maximum possible size of the cache join buffer */
virtual size_t get_max_join_buffer_size(bool optimize_buff_size);
size_t get_max_join_buffer_size(bool optimize_buff_size,
size_t min_buffer_size_arg);
/* Shrink the size if the cache join buffer in a given ratio */
bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);

View file

@ -943,7 +943,7 @@ bool is_lex_native_function(const LEX_CSTRING *name)
bool is_native_function(THD *thd, const LEX_CSTRING *name)
{
if (find_native_function_builder(thd, name))
if (native_functions_hash.find(thd, *name))
return true;
if (is_lex_native_function(name))

View file

@ -142,10 +142,10 @@ static void update_depend_map_for_order(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool change_list, bool *simple_order);
static int return_zero_rows(JOIN *join, select_result *res,
List<TABLE_LIST> &tables,
List<Item> &fields, bool send_row,
List<TABLE_LIST> *tables,
List<Item> *fields, bool send_row,
ulonglong select_options, const char *info,
Item *having, List<Item> &all_fields);
Item *having, List<Item> *all_fields);
static COND *build_equal_items(JOIN *join, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
@ -1157,11 +1157,40 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
DBUG_RETURN(0);
}
/*****************************************************************************
Check fields, find best join, do the select and output fields.
mysql_select assumes that all tables are already opened
*****************************************************************************/
/*
Check if we have a field reference. If yes, we have to use
mixed_implicit_grouping.
*/
static bool check_list_for_field(List<Item> *items)
{
List_iterator_fast <Item> select_it(*items);
Item *select_el;
while ((select_el= select_it++))
{
if (select_el->with_field)
return true;
}
return false;
}
static bool check_list_for_field(ORDER *order)
{
for (; order; order= order->next)
{
if (order->item[0]->with_field)
return true;
}
return false;
}
/**
Prepare of whole select (including sub queries in future).
@ -1241,53 +1270,45 @@ JOIN::prepare(TABLE_LIST *tables_init,
DBUG_RETURN(-1);
/*
TRUE if the SELECT list mixes elements with and without grouping,
and there is no GROUP BY clause. Mixing non-aggregated fields with
aggregate functions in the SELECT list is a MySQL extenstion that
is allowed only if the ONLY_FULL_GROUP_BY sql mode is not set.
mixed_implicit_grouping will be set to TRUE if the SELECT list
mixes elements with and without grouping, and there is no GROUP BY
clause.
Mixing non-aggregated fields with aggregate functions in the
SELECT list or HAVING is a MySQL extension that is allowed only if
the ONLY_FULL_GROUP_BY sql mode is not set.
*/
mixed_implicit_grouping= false;
if ((~thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) &&
select_lex->with_sum_func && !group_list)
{
List_iterator_fast <Item> select_it(fields_list);
Item *select_el; /* Element of the SELECT clause, can be an expression. */
bool found_field_elem= false;
bool found_sum_func_elem= false;
while ((select_el= select_it++))
if (check_list_for_field(&fields_list) ||
check_list_for_field(order))
{
if (select_el->with_sum_func())
found_sum_func_elem= true;
if (select_el->with_field)
found_field_elem= true;
if (found_sum_func_elem && found_field_elem)
TABLE_LIST *tbl;
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
mixed_implicit_grouping= true; // mark for future
while ((tbl= li++))
{
mixed_implicit_grouping= true;
break;
/*
If the query uses implicit grouping where the select list
contains both aggregate functions and non-aggregate fields,
any non-aggregated field may produce a NULL value. Set all
fields of each table as nullable before semantic analysis to
take into account this change of nullability.
Note: this loop doesn't touch tables inside merged
semi-joins, because subquery-to-semijoin conversion has not
been done yet. This is intended.
*/
if (tbl->table)
tbl->table->maybe_null= 1;
}
}
}
table_count= select_lex->leaf_tables.elements;
TABLE_LIST *tbl;
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
while ((tbl= li++))
{
/*
If the query uses implicit grouping where the select list contains both
aggregate functions and non-aggregate fields, any non-aggregated field
may produce a NULL value. Set all fields of each table as nullable before
semantic analysis to take into account this change of nullability.
Note: this loop doesn't touch tables inside merged semi-joins, because
subquery-to-semijoin conversion has not been done yet. This is intended.
*/
if (mixed_implicit_grouping && tbl->table)
tbl->table->maybe_null= 1;
}
uint real_og_num= og_num;
if (skip_order_by &&
select_lex != select_lex->master_unit()->global_parameters())
@ -3838,7 +3859,7 @@ bool JOIN::make_aggr_tables_info()
set_items_ref_array(items0);
if (join_tab)
join_tab[exec_join_tab_cnt() + aggr_tables - 1].next_select=
setup_end_select_func(this, NULL);
setup_end_select_func(this);
group= has_group_by;
DBUG_RETURN(false);
@ -4220,13 +4241,7 @@ JOIN::reinit()
}
}
/* Reset of sum functions */
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
while ((func= *(func_ptr++)))
func->clear();
}
clear_sum_funcs();
if (no_rows_in_result_called)
{
@ -4510,12 +4525,12 @@ void JOIN::exec_inner()
}
else
{
(void) return_zero_rows(this, result, select_lex->leaf_tables,
*columns_list,
(void) return_zero_rows(this, result, &select_lex->leaf_tables,
columns_list,
send_row_on_empty_set(),
select_options,
zero_result_cause,
having ? having : tmp_having, all_fields);
having ? having : tmp_having, &all_fields);
DBUG_VOID_RETURN;
}
}
@ -14642,10 +14657,36 @@ ORDER *simple_remove_const(ORDER *order, COND *where)
}
/*
Set all fields in the table to have a null value
@param tables Table list
*/
static void make_tables_null_complemented(List<TABLE_LIST> *tables)
{
List_iterator<TABLE_LIST> ti(*tables);
TABLE_LIST *table;
while ((table= ti++))
{
/*
Don't touch semi-join materialization tables, as the a join_free()
call may have freed them (and HAVING clause can't have references to
them anyway).
*/
if (!table->is_jtbm())
{
TABLE *tbl= table->table;
mark_as_null_row(tbl); // Set fields to NULL
}
}
}
static int
return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
List<Item> &fields, bool send_row, ulonglong select_options,
const char *info, Item *having, List<Item> &all_fields)
return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> *tables,
List<Item> *fields, bool send_row, ulonglong select_options,
const char *info, Item *having, List<Item> *all_fields)
{
DBUG_ENTER("return_zero_rows");
@ -14661,24 +14702,15 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
Set all tables to have NULL row. This is needed as we will be evaluating
HAVING condition.
*/
List_iterator<TABLE_LIST> ti(tables);
TABLE_LIST *table;
while ((table= ti++))
{
/*
Don't touch semi-join materialization tables, as the above join_free()
call has freed them (and HAVING clause can't have references to them
anyway).
*/
if (!table->is_jtbm())
mark_as_null_row(table->table); // All fields are NULL
}
List_iterator_fast<Item> it(all_fields);
make_tables_null_complemented(tables);
List_iterator_fast<Item> it(*all_fields);
Item *item;
/*
Inform all items (especially aggregating) to calculate HAVING correctly,
also we will need it for sending results.
*/
join->no_rows_in_result_called= 1;
while ((item= it++))
item->no_rows_in_result();
if (having && having->val_int() == 0)
@ -14692,12 +14724,12 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
join->thd->limit_found_rows= 0;
}
if (!(result->send_result_set_metadata(fields,
if (!(result->send_result_set_metadata(*fields,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
{
bool send_error= FALSE;
if (send_row)
send_error= result->send_data(fields) > 0;
send_error= result->send_data(*fields) > 0;
if (likely(!send_error))
result->send_eof(); // Should be safe
}
@ -14713,49 +14745,42 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
}
/**
used only in JOIN::clear (always) and in do_select()
(if there where no matching rows)
Reset table rows to contain a null-complement row (all fields are null)
Used only in JOIN::clear() 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.
@param cleared_tables Used to mark all cleared tables in the map. Needed for
unclear_tables() to know which tables to restore to
their original state.
*/
static void clear_tables(JOIN *join, table_map *cleared_tables)
{
/*
must clear only the non-const tables as const tables are not re-calculated.
*/
DBUG_ASSERT(cleared_tables);
for (uint i= 0 ; i < join->table_count ; i++)
{
TABLE *table= join->table[i];
if (table->null_row)
continue; // Nothing more to do
if (!(table->map & join->const_table_map) || cleared_tables)
(*cleared_tables)|= (((table_map) 1) << i);
if (table->s->null_bytes)
{
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
/*
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.
This return the tables to the state of before clear_tables().
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
@ -20235,9 +20260,9 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab)
end_select function to use. This function can't fail.
*/
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab)
Next_select_func setup_end_select_func(JOIN *join)
{
TMP_TABLE_PARAM *tmp_tbl= tab ? tab->tmp_table_param : &join->tmp_table_param;
TMP_TABLE_PARAM *tmp_tbl= &join->tmp_table_param;
/*
Choose method for presenting result to user. Use end_send_group
@ -20308,7 +20333,7 @@ do_select(JOIN *join, Procedure *procedure)
join->duplicate_rows= join->send_records=0;
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);
/*
HAVING will be checked after processing aggregate functions,
@ -20793,6 +20818,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
}
}
/* Restore state if mark_as_null_row() have been called */
if (join_tab->last_inner)
{
JOIN_TAB *last_inner_tab= join_tab->last_inner;
@ -22155,11 +22181,18 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
int idx= -1;
enum_nested_loop_state ok_code= NESTED_LOOP_OK;
/*
join_tab can be 0 in the case all tables are const tables and we did not
need a temporary table to store the result.
In this case we use the original given fields, which is stored in
join->fields.
*/
List<Item> *fields= join_tab ? (join_tab-1)->fields : join->fields;
DBUG_ENTER("end_send_group");
if (!join->items3.is_null() && !join->set_group_rpa)
{
/* Move ref_pointer_array to points to items3 */
join->set_group_rpa= true;
join->set_items_ref_array(join->items3);
}
@ -22167,10 +22200,12 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->first_record || end_of_records ||
(idx=test_if_group_changed(join->group_fields)) >= 0)
{
if (!join->group_sent &&
(join->first_record ||
(end_of_records && !join->group && !join->group_optimized_away)))
{
table_map cleared_tables= (table_map) 0;
if (join->procedure)
join->procedure->end_group();
if (idx < (int) join->send_group_parts)
@ -22193,11 +22228,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!join->first_record)
{
List_iterator_fast<Item> it(*join->fields);
Item *item;
/* No matching rows for group function */
join->clear();
List_iterator_fast<Item> it(*fields);
Item *item;
join->no_rows_in_result_called= 1;
join->clear(&cleared_tables);
while ((item= it++))
item->no_rows_in_result();
}
@ -22223,7 +22260,14 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (join->rollup_send_data((uint) (idx+1)))
error= 1;
}
}
if (join->no_rows_in_result_called)
{
/* Restore null tables to original state */
join->no_rows_in_result_called= 0;
if (cleared_tables)
unclear_tables(join, &cleared_tables);
}
}
if (unlikely(error > 0))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if (end_of_records)
@ -22525,6 +22569,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (join->first_record || (end_of_records && !join->group))
{
table_map cleared_tables= (table_map) 0;
if (join->procedure)
join->procedure->end_group();
int send_group_parts= join->send_group_parts;
@ -22533,7 +22578,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->first_record)
{
/* No matching rows for group function */
join->clear();
join->clear(&cleared_tables);
}
copy_sum_funcs(join->sum_funcs,
join->sum_funcs_end[send_group_parts]);
@ -22556,6 +22601,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_ERROR);
}
}
if (cleared_tables)
unclear_tables(join, &cleared_tables);
if (end_of_records)
goto end;
}
@ -26658,11 +26705,8 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg, TABL
(end_send_group/end_write_group)
*/
void JOIN::clear()
void inline JOIN::clear_sum_funcs()
{
clear_tables(this, 0);
copy_fields(&tmp_table_param);
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
@ -26672,6 +26716,22 @@ void JOIN::clear()
}
/*
Prepare for returning 'empty row' when there is no matching row.
- Mark all tables with mark_as_null_row()
- Make a copy of of all simple SELECT items
- Reset all sum functions to NULL or 0.
*/
void JOIN::clear(table_map *cleared_tables)
{
clear_tables(this, cleared_tables);
copy_fields(&tmp_table_param);
clear_sum_funcs();
}
/**
Print an EXPLAIN line with all NULLs and given message in the 'Extra' column
@ -28138,7 +28198,7 @@ void st_select_lex::print_set_clause(THD *thd, String *str,
else
str->append(',');
item->print(str, query_type);
item->print(str, (enum_query_type) (query_type | QT_NO_DATA_EXPANSION));
str->append(STRING_WITH_LEN(" = "));
val->print(str, query_type);
}

View file

@ -227,7 +227,7 @@ enum sj_strategy_enum
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab);
Next_select_func setup_end_select_func(JOIN *join);
int rr_sequential(READ_RECORD *info);
int rr_sequential_and_unpack(READ_RECORD *info);
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond);
@ -397,7 +397,6 @@ typedef struct st_join_table {
/* TRUE <=> it is prohibited to join this table using join buffer */
bool no_forced_join_cache;
uint used_join_cache_level;
ulong join_buffer_size_limit;
JOIN_CACHE *cache;
/*
Index condition for BKA access join
@ -1755,7 +1754,8 @@ public:
void join_free();
/** Cleanup this JOIN, possibly for reuse */
void cleanup(bool full);
void clear();
void clear(table_map *cleared_tables);
void inline clear_sum_funcs();
bool send_row_on_empty_set()
{
return (do_send_rows && implicit_grouping && !group_optimized_away &&

View file

@ -76,9 +76,6 @@ extern size_t symbols_length;
extern SYMBOL sql_functions[];
extern size_t sql_functions_length;
extern Native_func_registry func_array[];
extern size_t func_array_length;
enum enum_i_s_events_fields
{
ISE_EVENT_CATALOG= 0,

View file

@ -11485,7 +11485,7 @@ function_call_generic:
This will be revised with WL#2128 (SQL PATH)
*/
builder= find_native_function_builder(thd, &$1);
builder= native_functions_hash.find(thd, $1);
if (builder)
{
item= builder->create_func(thd, &$1, $4);

View file

@ -11600,7 +11600,7 @@ function_call_generic:
This will be revised with WL#2128 (SQL PATH)
*/
builder= find_native_function_builder(thd, &$1);
builder= native_functions_hash.find(thd, $1);
if (builder)
{
item= builder->create_func(thd, &$1, $4);

View file

@ -3337,10 +3337,16 @@ inline void mark_as_null_row(TABLE *table)
bfill(table->null_flags,table->s->null_bytes,255);
}
/*
Restore table to state before mark_as_null_row() call.
This assumes that the caller has restored table->null_flags,
as is done in unclear_tables().
*/
inline void unmark_as_null_row(TABLE *table)
{
table->null_row=0;
table->status= STATUS_NO_RECORD;
table->null_row= 0;
table->status&= ~STATUS_NULL_ROW;
}
bool is_simple_order(ORDER *order);

View file

@ -269,7 +269,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing a "
"REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", NULL, NULL,
SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX, 1);
SORT_BUFFER_INIT, MARIA_MIN_SORT_MEMORY, SIZE_T_MAX/16, 1);
static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG,
"Specifies how Aria index statistics collection code should treat "
@ -292,7 +292,8 @@ static MYSQL_SYSVAR_BOOL(used_for_temp_tables,
"Whether temporary tables should be MyISAM or Aria", 0, 0,
1);
static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables, PLUGIN_VAR_OPCMDARG,
static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables,
PLUGIN_VAR_OPCMDARG,
"Encrypt tables (only for tables with ROW_FORMAT=PAGE (default) "
"and not FIXED/DYNAMIC)",
0, 0, 0);

View file

@ -3903,6 +3903,16 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
{
sort_param.key_read= sort_key_read;
sort_param.key_write= sort_key_write;
/*
Limit usage of sort memory
We assume we don't need more memory than data file length * 2
(There is a pointer overhead for each key, but this is hard to
estimae as we cannot be sure how many records we have in file to
be repaired).
*/
set_if_smaller(param->sort_buffer_length, sort_info.filelength*2);
set_if_bigger(param->sort_buffer_length, MARIA_MIN_SORT_MEMORY);
}
if (sort_info.new_info->s->data_file_type == BLOCK_RECORD)
@ -4505,6 +4515,16 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
DBUG_PRINT("io_cache_share", ("thread: %u read_cache: %p",
i, &sort_param[i].read_cache));
/*
Limit usage of sort memory
We assume we don't need more memory than data file length * 2
(There is a pointer overhead for each key, but this is hard to
estimae as we cannot be sure how many records we have in file to
be repaired).
*/
set_if_smaller(param->sort_buffer_length, sort_info.filelength*2);
set_if_bigger(param->sort_buffer_length, MARIA_MIN_SORT_MEMORY);
/*
two approaches: the same amount of memory for each thread
or the memory for the same number of keys for each thread...
@ -4517,6 +4537,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
#else
param->sort_buffer_length*sort_param[i].key_length/total_key_length;
#endif
set_if_bigger(sort_param[i].sortbuff_size, MARIA_MIN_SORT_MEMORY);
if (mysql_thread_create(key_thread_find_all_keys,
&sort_param[i].thr, &thr_attr,
_ma_thr_find_all_keys, (void *) (sort_param+i)))

View file

@ -1062,6 +1062,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (encrypted)
{
DBUG_ASSERT(share.data_file_name.length == 0);
share.data_file_name.str= (char*) name; /* For error reporting */
if (ma_crypt_create(&share) ||
ma_crypt_write(&share, file))
goto err;

View file

@ -100,6 +100,7 @@ static void crypt_data_scheme_locker(struct st_encryption_scheme *scheme,
int
ma_crypt_create(MARIA_SHARE* share)
{
uint key_version;
MARIA_CRYPT_DATA *crypt_data=
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
crypt_data->scheme.type= CRYPT_SCHEME_1;
@ -110,6 +111,16 @@ ma_crypt_create(MARIA_SHARE* share)
my_random_bytes((uchar*)&crypt_data->space, sizeof(crypt_data->space));
share->crypt_data= crypt_data;
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
if (unlikely(key_version == ENCRYPTION_KEY_VERSION_INVALID))
{
my_errno= HA_ERR_NO_ENCRYPTION;
my_printf_error(HA_ERR_NO_ENCRYPTION,
"Initialization of encryption failed for %s", MYF(0),
share->data_file_name.str);
return 1;
}
return 0;
}
@ -145,7 +156,7 @@ ma_crypt_write(MARIA_SHARE* share, File file)
}
uchar*
ma_crypt_read(MARIA_SHARE* share, uchar *buff)
ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent)
{
uchar type= buff[0];
uchar iv_length= buff[1];
@ -155,9 +166,9 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
iv_length != sizeof(((MARIA_CRYPT_DATA*)1)->scheme.iv) + 4)
{
my_printf_error(HA_ERR_UNSUPPORTED,
"Unsupported crypt scheme! type: %d iv_length: %d\n",
MYF(ME_FATAL|ME_ERROR_LOG),
type, iv_length);
"Unsupported crypt scheme type: %d iv_length: %d\n",
MYF(ME_ERROR_LOG | (silent ? ME_WARNING : ME_FATAL)),
type, iv_length);
return 0;
}
@ -166,6 +177,7 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
/* opening a table */
MARIA_CRYPT_DATA *crypt_data=
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
uint key_version;
crypt_data->scheme.type= type;
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock,
@ -175,6 +187,17 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
crypt_data->space= uint4korr(buff + 2);
memcpy(crypt_data->scheme.iv, buff + 6, sizeof(crypt_data->scheme.iv));
share->crypt_data= crypt_data;
key_version= encryption_key_get_latest_version(crypt_data->scheme.key_id);
if (unlikely(key_version == ENCRYPTION_KEY_VERSION_INVALID))
{
my_errno= HA_ERR_NO_ENCRYPTION;
my_printf_error(HA_ERR_NO_ENCRYPTION,
"Initialization of encryption failed for %s",
MYF(ME_ERROR_LOG | (silent ? ME_WARNING : ME_FATAL)),
share->data_file_name.str);
return 0;
}
}
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
@ -462,7 +485,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
uint32 dstlen= 0; /* Must be set because of error message */
*key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
if (*key_version == ENCRYPTION_KEY_VERSION_INVALID)
if (unlikely(*key_version == ENCRYPTION_KEY_VERSION_INVALID))
{
/*
We use this error for both encryption and decryption, as in normal
@ -470,7 +493,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
*/
my_errno= HA_ERR_DECRYPTION_FAILED;
my_printf_error(HA_ERR_DECRYPTION_FAILED,
"Unknown key id %u. Can't continue!",
"Unknown encryption key id %u. Can't continue!",
MYF(ME_FATAL|ME_ERROR_LOG),
crypt_data->scheme.key_id);
return 1;

View file

@ -26,7 +26,8 @@ uint ma_crypt_get_index_page_header_space(struct st_maria_share *);
uint ma_crypt_get_file_length(); /* bytes needed in file */
int ma_crypt_create(struct st_maria_share *); /* create encryption data */
int ma_crypt_write(struct st_maria_share *, File); /* write encryption data */
uchar* ma_crypt_read(struct st_maria_share *, uchar *buff); /* read crypt data*/
uchar* ma_crypt_read(struct st_maria_share *, uchar *buff,
my_bool silent); /* read crypt data*/
void ma_crypt_set_data_pagecache_callbacks(struct st_pagecache_file *file,
struct st_maria_share *share);

View file

@ -43,12 +43,13 @@ int maria_delete_table(const char *name)
'open_for_repair' to be able to open even a crashed table.
*/
my_errno= 0;
if (!(info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
if (!(info= maria_open(name, O_RDONLY, (HA_OPEN_FOR_DROP | HA_OPEN_FOR_REPAIR))))
{
sync_dir= 0;
/* Ignore not found errors and wrong symlink errors */
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION)
got_error= my_errno;;
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION &&
my_errno != HA_ERR_NO_ENCRYPTION)
got_error= my_errno;
}
else
{

View file

@ -863,7 +863,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if (MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED))
{
if (!(disk_pos= ma_crypt_read(share, disk_pos)))
if (!(disk_pos= ma_crypt_read(share, disk_pos,
MY_TEST(open_flags & HA_OPEN_FOR_DROP))))
goto err;
}

View file

@ -29,12 +29,10 @@
/* static variables */
#undef MIN_SORT_MEMORY
#undef DISK_BUFFER_SIZE
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
#define DISK_BUFFER_SIZE (IO_SIZE*128)
/* How many keys we can keep in memory */
@ -145,11 +143,11 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
memavl=MY_MAX(sortbuff_size,MIN_SORT_MEMORY);
memavl=MY_MAX(sortbuff_size,MARIA_MIN_SORT_MEMORY);
records= info->sort_info->max_records;
sort_length= info->key_length;
while (memavl >= MIN_SORT_MEMORY)
while (memavl >= MARIA_MIN_SORT_MEMORY)
{
/* Check if we can fit all keys into memory */
if (((ulonglong) (records + 1) *
@ -208,10 +206,10 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
break;
}
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
memavl=MIN_SORT_MEMORY;
if ((memavl=memavl/4*3) < MARIA_MIN_SORT_MEMORY && old_memavl > MARIA_MIN_SORT_MEMORY)
memavl=MARIA_MIN_SORT_MEMORY;
}
if (memavl < MIN_SORT_MEMORY)
if (memavl < MARIA_MIN_SORT_MEMORY)
{
/* purecov: begin inspected */
_ma_check_print_error(info->sort_info->param,
@ -387,12 +385,12 @@ static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param)
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sortbuff_size= sort_param->sortbuff_size;
memavl= MY_MAX(sortbuff_size, MIN_SORT_MEMORY);
memavl= MY_MAX(sortbuff_size, MARIA_MIN_SORT_MEMORY);
idx= (ha_keys) sort_param->sort_info->max_records;
sort_length= sort_param->key_length;
maxbuffer= 1;
while (memavl >= MIN_SORT_MEMORY)
while (memavl >= MARIA_MIN_SORT_MEMORY)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl)
keys= idx+1;
@ -442,11 +440,11 @@ static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param)
break;
}
old_memavl= memavl;
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
old_memavl > MIN_SORT_MEMORY)
memavl= MIN_SORT_MEMORY;
if ((memavl= memavl/4*3) < MARIA_MIN_SORT_MEMORY &&
old_memavl > MARIA_MIN_SORT_MEMORY)
memavl= MARIA_MIN_SORT_MEMORY;
}
if (memavl < MIN_SORT_MEMORY)
if (memavl < MARIA_MIN_SORT_MEMORY)
{
/* purecov: begin inspected */
_ma_check_print_error(sort_param->sort_info->param,
@ -626,7 +624,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
if (!mergebuf)
{
length=(size_t)param->sort_buffer_length;
while (length >= MIN_SORT_MEMORY)
while (length >= MARIA_MIN_SORT_MEMORY)
{
if ((mergebuf= my_malloc((size_t) length, MYF(0))))
break;

View file

@ -424,7 +424,8 @@ static struct my_option my_long_options[] =
"Size of sort buffer. Used by --recover",
&check_param.sort_buffer_length,
&check_param.sort_buffer_length, 0, GET_ULL, REQUIRED_ARG,
SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX, MALLOC_OVERHEAD, 1L, 0},
SORT_BUFFER_INIT, MARIA_MIN_SORT_MEMORY, SIZE_T_MAX/10, MALLOC_OVERHEAD,
1L, 0},
{ "sort_key_blocks", OPT_SORT_KEY_BLOCKS,
"Internal buffer for sorting keys; Don't touch :)",
&check_param.sort_key_blocks,

View file

@ -45,6 +45,8 @@
#define MARIA_MAX_TREE_LEVELS 32
#define MARIA_MAX_RECORD_ON_STACK 16384
#define MARIA_MIN_SORT_MEMORY (16384-MALLOC_OVERHEAD)
/* maria_open() flag, specific for maria_pack */
#define HA_OPEN_IGNORE_MOVED_STATE (1U << 30)
@ -1273,7 +1275,6 @@ typedef struct st_maria_block_info
#define PAGE_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L*256L-MALLOC_OVERHEAD, 8192)
#define READ_BUFFER_INIT MY_ALIGN_DOWN(1024L*256L-MALLOC_OVERHEAD, 1024)
#define SORT_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L*256L-MALLOC_OVERHEAD, 1024)
#define MIN_SORT_BUFFER 4096U
#define fast_ma_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _ma_writeinfo((INFO),0)
#define fast_ma_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _ma_readinfo((INFO),F_RDLCK,1)

View file

@ -80,7 +80,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing "
"a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL,
SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX, 1);
SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX/16, 1);
static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG,
"Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE);