1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge branch '10.6' into 10.11

This commit is contained in:
Oleksandr Byelkin
2024-08-03 09:15:40 +02:00
40 changed files with 1270 additions and 106 deletions

View File

@@ -21018,6 +21018,577 @@ valdouble valint1
5 3289988
DROP TABLE t1,t2;
# End of 10.4 tests
# MDEV-34506 2nd execution name resolution problem with pushdown into
# unions
#
# Statements affected by this bug need all the following to be true
# 1) a derived table table or view whose specification contains a set
# operation at the top level.
# 2) a grouping operator (group by/having) operating on a column alias
# other than in the first select of the union/intersect
# 3) an outer condition that will be pushed into all selects in this
# union/intersect, either into the where or having clause
#
# When pushing a condition into all selects of a unit with more than one
# select, pushdown_cond_for_derived() renames items so we can re-use the
# condition being pushed.
# These names need to be saved and reset for correct name resolution on
# second execution of prepared statements.
create table t1 (c1 int, c2 int, c3 int);
insert into t1 values (1,2,3),(1,2,2),(4,5,6);
insert into t1 values (17,8,9),(11,11,12);
create table t2 (c4 int, c5 int, c6 int);
insert into t2 values (7,8,9),(10,11,12);
prepare stmt from 'select * from
(
select c1, sum(c3) as s from t1 group by c1
union
select c4 as c, sum(c6) as u from t2 group by c
) dt
where c1 > 6';
execute stmt;
c1 s
11 12
17 9
7 9
10 12
execute stmt;
c1 s
11 12
17 9
7 9
10 12
prepare stmt from 'explain format=json select * from
(
select c1, sum(c3) as s from t1 group by c1
union
select c4 as c, sum(c6) as u from t2 group by c
) dt
where c1 > 6';
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.c1 > 6",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"filesort": {
"sort_key": "t1.c1",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "t1.c1 > 6"
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"filesort": {
"sort_key": "t2.c4",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t2.c4 > 6"
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.c1 > 6",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"filesort": {
"sort_key": "t1.c1",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "t1.c1 > 6"
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"filesort": {
"sort_key": "t2.c4",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t2.c4 > 6"
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
prepare stmt from 'select * from
(
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
union
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
) dt
where c2 > 5';
execute stmt;
c1 c2 s
11 11 12
17 8 9
7 8 9
10 11 12
execute stmt;
c1 c2 s
11 11 12
17 8 9
7 8 9
10 11 12
prepare stmt from 'explain format=json select * from
(
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
union
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
) dt
where c2 > 5';
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.c2 > 5",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"having_condition": "s > 2",
"filesort": {
"sort_key": "t1.c1, t1.c2",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "t1.c2 > 5"
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"having_condition": "s > 3",
"filesort": {
"sort_key": "t2.c4, t2.c5",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t2.c5 > 5"
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.c2 > 5",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"having_condition": "s > 2",
"filesort": {
"sort_key": "t1.c1, t1.c2",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "t1.c2 > 5"
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"having_condition": "s > 3",
"filesort": {
"sort_key": "t2.c4, t2.c5",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t2.c5 > 5"
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
prepare stmt from 'select *
from
(
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
from t1
group by c1,c2
having max_c < 7
union
select c4, c5, max(c6) as u, avg(c6) as w
from t2
group by c4, c5
having u < 10
) dt,
t2
where dt.max_c > 6 and t2.c6 > dt.c1';
execute stmt;
c1 c2 max_c avg_c c4 c5 c6
7 8 9 9.0000 7 8 9
7 8 9 9.0000 10 11 12
execute stmt;
c1 c2 max_c avg_c c4 c5 c6
7 8 9 9.0000 7 8 9
7 8 9 9.0000 10 11 12
prepare stmt from 'explain format=json select *
from
(
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
from t1
group by c1,c2
having max_c < 7
union
select c4, c5, max(c6) as u, avg(c6) as w
from t2
group by c4, c5
having u < 10
) dt,
t2
where dt.max_c > 6 and t2.c6 > dt.c1';
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.max_c > 6"
},
"buffer_type": "flat",
"buffer_size": "173",
"join_type": "BNL",
"attached_condition": "t2.c6 > dt.c1",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"having_condition": "max_c < 7 and max_c > 6",
"filesort": {
"sort_key": "t1.c1, t1.c2",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"having_condition": "max_c < 10 and max_c > 6",
"filesort": {
"sort_key": "t2.c4, t2.c5",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
execute stmt;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 7,
"filtered": 100,
"attached_condition": "dt.max_c > 6"
},
"buffer_type": "flat",
"buffer_size": "173",
"join_type": "BNL",
"attached_condition": "t2.c6 > dt.c1",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"having_condition": "max_c < 7 and max_c > 6",
"filesort": {
"sort_key": "t1.c1, t1.c2",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
]
}
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"having_condition": "max_c < 10 and max_c > 6",
"filesort": {
"sort_key": "t2.c4, t2.c5",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100
}
}
]
}
}
}
}
]
}
}
}
}
}
]
}
}
drop table t1, t2;
# End of 10.5 tests
#
# MDEV-28958: condition pushable into view after simplification
# contains constant TRUE/FALSE as subformula

View File

@@ -4104,6 +4104,93 @@ DROP TABLE t1,t2;
--echo # End of 10.4 tests
--echo # MDEV-34506 2nd execution name resolution problem with pushdown into
--echo # unions
--echo #
--echo # Statements affected by this bug need all the following to be true
--echo # 1) a derived table table or view whose specification contains a set
--echo # operation at the top level.
--echo # 2) a grouping operator (group by/having) operating on a column alias
--echo # other than in the first select of the union/intersect
--echo # 3) an outer condition that will be pushed into all selects in this
--echo # union/intersect, either into the where or having clause
--echo #
--echo # When pushing a condition into all selects of a unit with more than one
--echo # select, pushdown_cond_for_derived() renames items so we can re-use the
--echo # condition being pushed.
--echo # These names need to be saved and reset for correct name resolution on
--echo # second execution of prepared statements.
create table t1 (c1 int, c2 int, c3 int);
insert into t1 values (1,2,3),(1,2,2),(4,5,6);
insert into t1 values (17,8,9),(11,11,12);
create table t2 (c4 int, c5 int, c6 int);
insert into t2 values (7,8,9),(10,11,12);
let $q=select * from
(
select c1, sum(c3) as s from t1 group by c1
union
select c4 as c, sum(c6) as u from t2 group by c
) dt
where c1 > 6;
eval prepare stmt from '$q';
execute stmt;
execute stmt;
eval prepare stmt from 'explain format=json $q';
--source include/analyze-format.inc
execute stmt;
--source include/analyze-format.inc
execute stmt;
let $q=select * from
(
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
union
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
) dt
where c2 > 5;
eval prepare stmt from '$q';
execute stmt;
execute stmt;
eval prepare stmt from 'explain format=json $q';
--source include/analyze-format.inc
execute stmt;
--source include/analyze-format.inc
execute stmt;
let $q=select *
from
(
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
from t1
group by c1,c2
having max_c < 7
union
select c4, c5, max(c6) as u, avg(c6) as w
from t2
group by c4, c5
having u < 10
) dt,
t2
where dt.max_c > 6 and t2.c6 > dt.c1;
eval prepare stmt from '$q';
execute stmt;
execute stmt;
eval prepare stmt from 'explain format=json $q';
--source include/analyze-format.inc
execute stmt;
--source include/analyze-format.inc
execute stmt;
drop table t1, t2;
--echo # End of 10.5 tests
--echo #
--echo # MDEV-28958: condition pushable into view after simplification
--echo # contains constant TRUE/FALSE as subformula

View File

@@ -0,0 +1,16 @@
#
# MDEV-34634 Types mismatch when cloning items causes debug assertion
#
CREATE TABLE t1 (a DATETIME);
SET optimizer_switch='derived_merge=off';
SELECT * FROM (SELECT * FROM t1) AS t1 WHERE a='';
a
Warnings:
Warning 1292 Truncated incorrect datetime value: ''
DROP TABLE t1;
CREATE TABLE t1 (c YEAR);
CREATE TABLE t2 (c INT);
SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5;
c c
DROP TABLE t1, t2;
SET optimizer_switch=default;

View File

@@ -0,0 +1,15 @@
--echo #
--echo # MDEV-34634 Types mismatch when cloning items causes debug assertion
--echo #
CREATE TABLE t1 (a DATETIME);
SET optimizer_switch='derived_merge=off';
SELECT * FROM (SELECT * FROM t1) AS t1 WHERE a='';
DROP TABLE t1;
CREATE TABLE t1 (c YEAR);
CREATE TABLE t2 (c INT);
SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5;
DROP TABLE t1, t2;
SET optimizer_switch=default;

View File

@@ -6425,3 +6425,23 @@ DROP TABLE t1,t2,t3;
#
# End of 10.4 tests
#
#
# MDEV-34580: Assertion `(key_part->key_part_flag & 4) == 0' failed key_hashnr
#
SET join_cache_level=3;
CREATE TABLE t1 ( a TIMESTAMP , b varchar(100), c varchar(10) ) ;
INSERT INTO t1 (b,c) VALUES ('GHOBS','EMLCG'),('t','p');
CREATE TABLE t2 (a varchar(100), b varchar(100), c varchar(10) , KEY b (b(66))) ;
insert into t2 select seq, seq, seq from seq_1_to_20;
explain
SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t2 hash_ALL b #hash#b 69 test.t1.b 20 Using where; Using join buffer (flat, BNLH join)
SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ;
a
set join_cache_level=default;
DROP TABLE t1, t2;
#
# End of 10.5 tests
#

View File

@@ -4299,3 +4299,25 @@ DROP TABLE t1,t2,t3;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # MDEV-34580: Assertion `(key_part->key_part_flag & 4) == 0' failed key_hashnr
--echo #
--source include/have_sequence.inc
SET join_cache_level=3;
CREATE TABLE t1 ( a TIMESTAMP , b varchar(100), c varchar(10) ) ;
INSERT INTO t1 (b,c) VALUES ('GHOBS','EMLCG'),('t','p');
CREATE TABLE t2 (a varchar(100), b varchar(100), c varchar(10) , KEY b (b(66))) ;
insert into t2 select seq, seq, seq from seq_1_to_20;
explain
SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ;
SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ;
set join_cache_level=default;
DROP TABLE t1, t2;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -1,5 +1,6 @@
-- source include/not_embedded.inc
--source include/have_debug.inc
--source include/not_asan.inc
--echo #
--echo # MDEV-28762: recursive call of some json functions without stack control

View File

@@ -743,9 +743,10 @@ The following specify which files/extra groups are read (specified before remain
costs. disable_max_seek = Disable 'max_seek optimization'
for secondary keys and slight adjustment of filter cost.
disable_forced_index_in_group_by = Disable automatic
forced index in GROUP BY. This variable will be deleted
in MariaDB 11.0 as it is not needed with the new 11.0
optimizer.
forced index in GROUP BY. fix_innodb_cardinality =
Disable doubling of the Cardinality for InnoDB secondary
keys. This variable will be deleted in MariaDB 11.0 as it
is not needed with the new 11.0 optimizer.
Use 'ALL' to set all combinations.
--optimizer-extra-pruning-depth=#
If the optimizer needs to enumerate join prefix of this

View File

@@ -115,3 +115,66 @@ b sum(d)
6 125005000
8 125015000
drop table t1;
#
# MDEV-34664: fix_innodb_cardinality
#
set @save_userstat=@@global.userstat;
set @save_ispsp=@@global.innodb_stats_persistent_sample_pages;
set @@global.innodb_stats_persistent_sample_pages=20;
set @@global.userstat=on;
set use_stat_tables=PREFERABLY_FOR_QUERIES;
create or replace table t1 (a int primary key, b int, c int, d int, key(b,c,d)) engine=innodb;
insert into t1 select seq,seq/100,seq/60,seq/10 from seq_1_to_1000;
create or replace table t2 (a int);
insert into t2 values (1),(2),(3);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
select count(distinct b),count(distinct b,c), count(distinct b,c,d) from t1;
count(distinct b) count(distinct b,c) count(distinct b,c,d)
11 25 125
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
t1 0 PRIMARY 1 a A 1000 NULL NULL BTREE NO
t1 1 b 1 b A 22 NULL NULL YES BTREE NO
t1 1 b 2 c A 50 NULL NULL YES BTREE NO
t1 1 b 3 d A 250 NULL NULL YES BTREE NO
explain select * from t1,t2 where t1.b=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
1 SIMPLE t1 ref b b 5 test.t2.a 45 Using index
set @@optimizer_adjust_secondary_key_costs=8;
explain select * from t1,t2 where t1.b=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
1 SIMPLE t1 ref b b 5 test.t2.a 45 Using index
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
t1 0 PRIMARY 1 a A 1000 NULL NULL BTREE NO
t1 1 b 1 b A 11 NULL NULL YES BTREE NO
t1 1 b 2 c A 25 NULL NULL YES BTREE NO
t1 1 b 3 d A 125 NULL NULL YES BTREE NO
flush tables;
explain select * from t1,t2 where t1.b=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
1 SIMPLE t1 ref b b 5 test.t2.a 90 Using index
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
t1 0 PRIMARY 1 a A 1000 NULL NULL BTREE NO
t1 1 b 1 b A 11 NULL NULL YES BTREE NO
t1 1 b 2 c A 25 NULL NULL YES BTREE NO
t1 1 b 3 d A 125 NULL NULL YES BTREE NO
connect user2, localhost, root,,;
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
t1 0 PRIMARY 1 a A 1000 NULL NULL BTREE NO
t1 1 b 1 b A 22 NULL NULL YES BTREE NO
t1 1 b 2 c A 50 NULL NULL YES BTREE NO
t1 1 b 3 d A 250 NULL NULL YES BTREE NO
connection default;
disconnect user2;
drop table t1,t2;
set global userstat=@save_userstat;
set global innodb_stats_persistent_sample_pages=@save_ispsp;
set @@optimizer_adjust_secondary_key_costs=default;

View File

@@ -1,6 +1,8 @@
--source include/have_sequence.inc
--source include/not_embedded.inc
--source include/have_innodb.inc
# Testcase for MDEV-33306 takes ~6 minutes with valgrind:
--source include/not_valgrind.inc
#
# Show the costs for rowid filter
@@ -72,3 +74,39 @@ set @@optimizer_adjust_secondary_key_costs="disable_forced_index_in_group_by";
explain select b, sum(d) from t1 where c=0 group by b;
select b, sum(d) from t1 where c=0 group by b;
drop table t1;
--echo #
--echo # MDEV-34664: fix_innodb_cardinality
--echo #
set @save_userstat=@@global.userstat;
set @save_ispsp=@@global.innodb_stats_persistent_sample_pages;
set @@global.innodb_stats_persistent_sample_pages=20;
set @@global.userstat=on;
set use_stat_tables=PREFERABLY_FOR_QUERIES;
create or replace table t1 (a int primary key, b int, c int, d int, key(b,c,d)) engine=innodb;
insert into t1 select seq,seq/100,seq/60,seq/10 from seq_1_to_1000;
create or replace table t2 (a int);
insert into t2 values (1),(2),(3);
analyze table t1;
select count(distinct b),count(distinct b,c), count(distinct b,c,d) from t1;
show index from t1;
explain select * from t1,t2 where t1.b=t2.a;
set @@optimizer_adjust_secondary_key_costs=8;
explain select * from t1,t2 where t1.b=t2.a;
show index from t1;
# Flush tables or show index is needed to refresh the data in table share
flush tables;
explain select * from t1,t2 where t1.b=t2.a;
show index from t1;
# Check that the option does not affect other usage
connect (user2, localhost, root,,);
show index from t1;
connection default;
disconnect user2;
drop table t1,t2;
set global userstat=@save_userstat;
set global innodb_stats_persistent_sample_pages=@save_ispsp;
set @@optimizer_adjust_secondary_key_costs=default;

View File

@@ -1247,15 +1247,10 @@ insert into t1 values (1,1,'foo');
insert into t1 values (2,2,'bar');
select
count(*) over (order by a,b
range between unbounded preceding and current row) as count
range between 1 preceding and current row) as count
from t1;
ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key
select
count(*) over (order by c
range between unbounded preceding and current row) as count
from t1;
ERROR HY000: Numeric datatype is required for RANGE-type frame
select
count(*) over (order by a
range between 'abcd' preceding and current row) as count
from t1;
@@ -1277,6 +1272,56 @@ rows between current row and 3.14 following) as count
from t1;
ERROR HY000: Integer is required for ROWS-type frame
#
# MDEV-19052 Range-type window frame supports only numeric datatype
#
select
count(*) over (order by c
range between unbounded preceding and current row) as r
from t1;
r
1
2
select
count(*) over (order by c
range between current row and unbounded following) as r
from t1;
r
2
1
select
count(*) over (order by c
range between unbounded preceding and unbounded following) as r
from t1;
r
2
2
create table t2 (a int, b varchar(5));
insert into t2 values (1,'a'), (2, 'b'), (3, 'c');
select sum(a) over (order by b range between unbounded preceding and current row) as r from t2;
r
1
3
6
insert into t1 values (3,3,'goo');
insert into t1 values (3,1,'har');
insert into t1 values (1,4,'har');
select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1;
a b r
1 4 4
1 1 5
2 2 7
3 3 10
3 1 11
select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1;
a b r
3 1 1
3 3 4
2 2 6
1 1 7
1 4 11
drop table t2;
delete from t1 where a >= 3 or b = 4;
#
# EXCLUDE clause is parsed but not supported
#
select

View File

@@ -784,13 +784,7 @@ insert into t1 values (2,2,'bar');
--error ER_RANGE_FRAME_NEEDS_SIMPLE_ORDERBY
select
count(*) over (order by a,b
range between unbounded preceding and current row) as count
from t1;
--error ER_WRONG_TYPE_FOR_RANGE_FRAME
select
count(*) over (order by c
range between unbounded preceding and current row) as count
range between 1 preceding and current row) as count
from t1;
--error ER_WRONG_TYPE_FOR_RANGE_FRAME
@@ -818,6 +812,41 @@ select
rows between current row and 3.14 following) as count
from t1;
--echo #
--echo # MDEV-19052 Range-type window frame supports only numeric datatype
--echo #
select
count(*) over (order by c
range between unbounded preceding and current row) as r
from t1;
select
count(*) over (order by c
range between current row and unbounded following) as r
from t1;
select
count(*) over (order by c
range between unbounded preceding and unbounded following) as r
from t1;
create table t2 (a int, b varchar(5));
insert into t2 values (1,'a'), (2, 'b'), (3, 'c');
select sum(a) over (order by b range between unbounded preceding and current row) as r from t2;
insert into t1 values (3,3,'goo');
insert into t1 values (3,1,'har');
insert into t1 values (1,4,'har');
select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1;
select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1;
drop table t2;
delete from t1 where a >= 3 or b = 4;
--echo #
--echo # EXCLUDE clause is parsed but not supported
--echo #
@@ -843,6 +872,9 @@ select
exclude group) as count
from t1;
# EXCLUDE NO OTHERS means 'don't exclude anything'
select
count(*) over (order by a

View File

@@ -1,3 +1,5 @@
SET @start_encr_threads = @@global.innodb_encryption_threads;
SET @start_encrypt_tables = @@global.innodb_encrypt_tables;
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes;
CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB;
CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes;
@@ -116,3 +118,42 @@ NOT FOUND /temp/ in t2.ibd
# t3 ... on expecting NOT FOUND
UNLOCK TABLES;
DROP TABLE t1, t2, t3;
#
# MDEV-34670 IMPORT TABLESPACE unnecessary traverses
# tablespace list
#
SET GLOBAL innodb_encrypt_tables= OFF;
SET GLOBAL innodb_encryption_threads= 0;
CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "InnoDB");
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 DISCARD TABLESPACE;
FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t2 IMPORT TABLESPACE;
SET GLOBAL innodb_encryption_threads=2;
SET GLOBAL innodb_encrypt_tables = ON;
# Wait max 10 min for key encryption threads to encrypt all spaces
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
NAME
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
NAME
innodb_system
test/t1
test/t2
SET GLOBAL innodb_encrypt_tables = OFF;
# Wait max 10 min for key encryption threads to decrypt all spaces
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
NAME
innodb_system
test/t1
test/t2
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
NAME
DROP TABLE t1, t2;
SET GLOBAL innodb_encryption_threads=@start_encr_threads;
SET GLOBAL innodb_encrypt_tables=@start_encrypt_tables;

View File

@@ -1253,15 +1253,10 @@ insert into t1 values (1,1,'foo');
insert into t1 values (2,2,'bar');
select
count(*) over (order by a,b
range between unbounded preceding and current row) as count
range between 1 preceding and current row) as count
from t1;
ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key
select
count(*) over (order by c
range between unbounded preceding and current row) as count
from t1;
ERROR HY000: Numeric datatype is required for RANGE-type frame
select
count(*) over (order by a
range between 'abcd' preceding and current row) as count
from t1;
@@ -1283,6 +1278,56 @@ rows between current row and 3.14 following) as count
from t1;
ERROR HY000: Integer is required for ROWS-type frame
#
# MDEV-19052 Range-type window frame supports only numeric datatype
#
select
count(*) over (order by c
range between unbounded preceding and current row) as r
from t1;
r
1
2
select
count(*) over (order by c
range between current row and unbounded following) as r
from t1;
r
2
1
select
count(*) over (order by c
range between unbounded preceding and unbounded following) as r
from t1;
r
2
2
create table t2 (a int, b varchar(5));
insert into t2 values (1,'a'), (2, 'b'), (3, 'c');
select sum(a) over (order by b range between unbounded preceding and current row) as r from t2;
r
1
3
6
insert into t1 values (3,3,'goo');
insert into t1 values (3,1,'har');
insert into t1 values (1,4,'har');
select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1;
a b r
1 4 4
1 1 5
2 2 7
3 3 10
3 1 11
select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1;
a b r
3 1 1
3 3 4
2 2 6
1 1 7
1 4 11
drop table t2;
delete from t1 where a >= 3 or b = 4;
#
# EXCLUDE clause is parsed but not supported
#
select

View File

@@ -2,7 +2,8 @@
-- source include/have_example_key_management_plugin.inc
-- source include/not_valgrind.inc
-- source include/not_embedded.inc
SET @start_encr_threads = @@global.innodb_encryption_threads;
SET @start_encrypt_tables = @@global.innodb_encrypt_tables;
let MYSQLD_DATADIR = `SELECT @@datadir`;
--let SEARCH_RANGE = 10000000
@@ -124,3 +125,56 @@ FLUSH TABLES t1, t2, t3 FOR EXPORT;
UNLOCK TABLES;
DROP TABLE t1, t2, t3;
--echo #
--echo # MDEV-34670 IMPORT TABLESPACE unnecessary traverses
--echo # tablespace list
--echo #
SET GLOBAL innodb_encrypt_tables= OFF;
SET GLOBAL innodb_encryption_threads= 0;
CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "InnoDB");
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 DISCARD TABLESPACE;
FLUSH TABLES t1 FOR EXPORT;
--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg
--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd
UNLOCK TABLES;
ALTER TABLE t2 IMPORT TABLESPACE;
SET GLOBAL innodb_encryption_threads=2;
SET GLOBAL innodb_encrypt_tables = ON;
--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces + 1 from information_schema.tables where engine = 'InnoDB'`
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--let $wait_timeout= 600
--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--source include/wait_condition.inc
--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
SET GLOBAL innodb_encrypt_tables = OFF;
--echo # Wait max 10 min for key encryption threads to decrypt all spaces
--let $wait_timeout= 600
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--source include/wait_condition.inc
--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
DROP TABLE t1, t2;
SET GLOBAL innodb_encryption_threads=@start_encr_threads;
SET GLOBAL innodb_encrypt_tables=@start_encrypt_tables;

View File

@@ -65,6 +65,32 @@ id
4
5
DROP TABLE t2;
#
# MDEV-34181 Instant table aborts after discard tablespace
#
CREATE TABLE t1(c3 INT, c2 INT, c1 INT KEY)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 1, 1), (2, 2, 2);
CREATE TABLE t2 (c1 INT KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES(1);
ALTER TABLE t2 ADD c2 INT;
FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t2 DISCARD TABLESPACE;
ALTER TABLE t2 ADD c3 INT FIRST;
Warnings:
Warning 1814 Tablespace has been discarded for table `t2`
ALTER TABLE t2 IMPORT TABLESPACE;
Warnings:
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`c3` int(11) DEFAULT NULL,
`c1` int(11) NOT NULL,
`c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2, t1;
# End of 10.5 tests
#
# MDEV-27006 Assertion `!lock_trx_has_sys_table_locks(trx)'

View File

@@ -82,6 +82,26 @@ INSERT INTO t2() VALUES();
SELECT * FROM t2 ORDER BY id;
DROP TABLE t2;
--echo #
--echo # MDEV-34181 Instant table aborts after discard tablespace
--echo #
CREATE TABLE t1(c3 INT, c2 INT, c1 INT KEY)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 1, 1), (2, 2, 2);
CREATE TABLE t2 (c1 INT KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES(1);
ALTER TABLE t2 ADD c2 INT;
FLUSH TABLES t1 FOR EXPORT;
let $datadir=`select @@datadir`;
--copy_file $datadir/test/t1.ibd $datadir/test/imp_t1.ibd
UNLOCK TABLES;
ALTER TABLE t2 DISCARD TABLESPACE;
ALTER TABLE t2 ADD c3 INT FIRST;
--copy_file $datadir/test/imp_t1.ibd $datadir/test/t2.ibd
--replace_regex /opening '.*\/test\//opening '.\/test\//
ALTER TABLE t2 IMPORT TABLESPACE;
SHOW CREATE TABLE t2;
DROP TABLE t2, t1;
--echo # End of 10.5 tests
--echo #

View File

@@ -2325,11 +2325,11 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET
VARIABLE_COMMENT A bit field with the following values: adjust_secondary_key_cost = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. disable_max_seek = Disable 'max_seek optimization' for secondary keys and slight adjustment of filter cost. disable_forced_index_in_group_by = Disable automatic forced index in GROUP BY. This variable will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer.
VARIABLE_COMMENT A bit field with the following values: adjust_secondary_key_cost = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. disable_max_seek = Disable 'max_seek optimization' for secondary keys and slight adjustment of filter cost. disable_forced_index_in_group_by = Disable automatic forced index in GROUP BY. fix_innodb_cardinality = Disable doubling of the Cardinality for InnoDB secondary keys. This variable will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST adjust_secondary_key_cost,disable_max_seek,disable_forced_index_in_group_by
ENUM_VALUE_LIST adjust_secondary_key_cost,disable_max_seek,disable_forced_index_in_group_by,fix_innodb_cardinality
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_EXTRA_PRUNING_DEPTH

View File

@@ -2495,11 +2495,11 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET
VARIABLE_COMMENT A bit field with the following values: adjust_secondary_key_cost = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. disable_max_seek = Disable 'max_seek optimization' for secondary keys and slight adjustment of filter cost. disable_forced_index_in_group_by = Disable automatic forced index in GROUP BY. This variable will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer.
VARIABLE_COMMENT A bit field with the following values: adjust_secondary_key_cost = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. disable_max_seek = Disable 'max_seek optimization' for secondary keys and slight adjustment of filter cost. disable_forced_index_in_group_by = Disable automatic forced index in GROUP BY. fix_innodb_cardinality = Disable doubling of the Cardinality for InnoDB secondary keys. This variable will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST adjust_secondary_key_cost,disable_max_seek,disable_forced_index_in_group_by
ENUM_VALUE_LIST adjust_secondary_key_cost,disable_max_seek,disable_forced_index_in_group_by,fix_innodb_cardinality
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_EXTRA_PRUNING_DEPTH

View File

@@ -28,7 +28,8 @@
# elif __GNUC__ >= 14 || (defined __clang_major__ && __clang_major__ >= 18)
# define TARGET "pclmul,evex512,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq"
# define USE_VPCLMULQDQ __attribute__((target(TARGET)))
# elif __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 8)
# elif __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 9)
/* clang 8 does not support _xgetbv(), which we also need */
# define TARGET "pclmul,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq"
# define USE_VPCLMULQDQ __attribute__((target(TARGET)))
# endif
@@ -38,6 +39,7 @@ extern "C" unsigned crc32c_sse42(unsigned crc, const void* buf, size_t size);
constexpr uint32_t cpuid_ecx_SSE42= 1U << 20;
constexpr uint32_t cpuid_ecx_SSE42_AND_PCLMUL= cpuid_ecx_SSE42 | 1U << 1;
constexpr uint32_t cpuid_ecx_XSAVE= 1U << 26;
static uint32_t cpuid_ecx()
{
@@ -382,8 +384,19 @@ static unsigned crc32_avx512(unsigned crc, const char *buf, size_t size,
}
}
static ATTRIBUTE_NOINLINE int have_vpclmulqdq()
#ifdef __GNUC__
__attribute__((target("xsave")))
#endif
static bool os_have_avx512()
{
// The following flags must be set: SSE, AVX, OPMASK, ZMM_HI256, HI16_ZMM
return !(~_xgetbv(0 /*_XCR_XFEATURE_ENABLED_MASK*/) & 0xe6);
}
static ATTRIBUTE_NOINLINE bool have_vpclmulqdq(uint32_t cpuid_ecx)
{
if (!(cpuid_ecx & cpuid_ecx_XSAVE) || !os_have_avx512())
return false;
# ifdef _MSC_VER
int regs[4];
__cpuidex(regs, 7, 0);
@@ -410,10 +423,11 @@ static unsigned crc32c_vpclmulqdq(unsigned crc, const void *buf, size_t size)
extern "C" my_crc32_t crc32_pclmul_enabled(void)
{
if (~cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL)
const uint32_t ecx= cpuid_ecx();
if (~ecx & cpuid_ecx_SSE42_AND_PCLMUL)
return nullptr;
#ifdef USE_VPCLMULQDQ
if (have_vpclmulqdq())
if (have_vpclmulqdq(ecx))
return crc32_vpclmulqdq;
#endif
return crc32_pclmul;
@@ -421,19 +435,20 @@ extern "C" my_crc32_t crc32_pclmul_enabled(void)
extern "C" my_crc32_t crc32c_x86_available(void)
{
const uint32_t ecx= cpuid_ecx();
#ifdef USE_VPCLMULQDQ
if (have_vpclmulqdq())
if (have_vpclmulqdq(ecx))
return crc32c_vpclmulqdq;
#endif
#if SIZEOF_SIZE_T == 8
switch (cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) {
switch (ecx & cpuid_ecx_SSE42_AND_PCLMUL) {
case cpuid_ecx_SSE42_AND_PCLMUL:
return crc32c_3way;
case cpuid_ecx_SSE42:
return crc32c_sse42;
}
#else
if (cpuid_ecx() & cpuid_ecx_SSE42)
if (ecx & cpuid_ecx_SSE42)
return crc32c_sse42;
#endif
return nullptr;

View File

@@ -2214,8 +2214,9 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
*/
if ((thd->where == THD_WHERE::WHERE_CLAUSE ||
thd->where == THD_WHERE::ON_CLAUSE) &&
(value_item->type() == FUNC_ITEM ||
value_item->type() == CONST_ITEM))
(value_item->type() == CONST_ITEM ||
value_item->type() == FUNC_ITEM) &&
!thd->lex->is_ps_or_view_context_analysis())
{
thd->change_item_tree(ref, value_item);
@@ -3921,7 +3922,7 @@ void Item_decimal::set_decimal_value(my_decimal *value_par)
}
Item *Item_decimal::do_clone_const_item(THD *thd) const
Item *Item_decimal::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_decimal(thd, name.str, &decimal_value, decimals,
max_length);
@@ -3942,7 +3943,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
}
Item *Item_float::do_clone_const_item(THD *thd) const
Item *Item_float::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_float(thd, name.str, value, decimals,
max_length);
@@ -4106,7 +4107,7 @@ Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
return this;
}
Item *Item_null::do_clone_const_item(THD *thd) const
Item *Item_null::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_null(thd, name.str);
}
@@ -4966,7 +4967,7 @@ Item *Item_param::value_clone_item(THD *thd) const
/* see comments in the header file */
Item *
Item_param::do_clone_const_item(THD *thd) const
Item_param::clone_item(THD *thd) const
{
// There's no "default". See comments in Item_param::save_in_field().
switch (state) {
@@ -7057,7 +7058,7 @@ int Item_string::save_in_field(Field *field, bool no_conversions)
}
Item *Item_string::do_clone_const_item(THD *thd) const
Item *Item_string::clone_item(THD *thd) const
{
LEX_CSTRING val;
str_value.get_value(&val);
@@ -7121,7 +7122,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions)
}
Item *Item_int::do_clone_const_item(THD *thd) const
Item *Item_int::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_int(thd, name.str, value, max_length, unsigned_flag);
}
@@ -7150,7 +7151,7 @@ int Item_decimal::save_in_field(Field *field, bool no_conversions)
}
Item *Item_int_with_ref::do_clone_const_item(THD *thd) const
Item *Item_int_with_ref::clone_item(THD *thd) const
{
DBUG_ASSERT(ref->const_item());
/*
@@ -7246,7 +7247,7 @@ Item *Item_uint::neg(THD *thd)
}
Item *Item_uint::do_clone_const_item(THD *thd) const
Item *Item_uint::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_uint(thd, name.str, value, max_length);
}
@@ -7484,7 +7485,7 @@ void Item_date_literal::print(String *str, enum_query_type query_type)
}
Item *Item_date_literal::do_clone_const_item(THD *thd) const
Item *Item_date_literal::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_date_literal(thd, &cached_time);
}
@@ -7509,7 +7510,7 @@ void Item_datetime_literal::print(String *str, enum_query_type query_type)
}
Item *Item_datetime_literal::do_clone_const_item(THD *thd) const
Item *Item_datetime_literal::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_datetime_literal(thd, &cached_time, decimals);
}
@@ -7534,7 +7535,7 @@ void Item_time_literal::print(String *str, enum_query_type query_type)
}
Item *Item_time_literal::do_clone_const_item(THD *thd) const
Item *Item_time_literal::clone_item(THD *thd) const
{
return new (thd->mem_root) Item_time_literal(thd, &cached_time, decimals);
}
@@ -10501,7 +10502,7 @@ void Item_cache_temporal::store_packed(longlong val_arg, Item *example_arg)
}
Item *Item_cache_temporal::do_clone_const_item(THD *thd) const
Item *Item_cache_temporal::clone_item(THD *thd) const
{
Item_cache *tmp= type_handler()->Item_get_cache(thd, this);
Item_cache_temporal *item= static_cast<Item_cache_temporal*>(tmp);

View File

@@ -1935,21 +1935,17 @@ public:
}
/*
Clones the constant item
Clones the constant item (not necessary returning the same item type)
Return value:
- pointer to a clone of the Item
- nullptr if the item is not clonable */
Item *clone_const_item(THD *thd) const
{
Item *clone= do_clone_const_item(thd);
if (clone)
{
// Make sure the clone is of same type as this item
DBUG_ASSERT(typeid(*clone) == typeid(*this));
}
return clone;
}
- nullptr if the item is not clonable
Note: the clone may have item type different from this
(i.e., instance of another basic constant class may be returned).
For real clones look at build_clone()/get_copy() methods
*/
virtual Item *clone_item(THD *thd) const { return nullptr; }
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
@@ -2808,12 +2804,6 @@ protected:
deep copies (clones) of the item where possible
*/
virtual Item* do_build_clone(THD *thd) const = 0;
/*
Service function for public method clone_const_item(). See comments for
clone_const_item() above
*/
virtual Item *do_clone_const_item(THD *thd) const { return nullptr; }
};
MEM_ROOT *get_thd_memroot(THD *thd);
@@ -3972,7 +3962,7 @@ public:
const Type_handler *type_handler() const override
{ return &type_handler_null; }
bool basic_const_item() const override { return true; }
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
bool const_is_null() const override { return true; }
bool is_null() override { return true; }
@@ -4449,7 +4439,7 @@ public:
basic_const_item returned TRUE.
*/
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override;
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
void set_param_type_and_swap_value(Item_param *from);
Rewritable_query_parameter *get_rewritable_query_parameter() override
@@ -4551,7 +4541,7 @@ public:
String *val_str(String*) override;
int save_in_field(Field *field, bool no_conversions) override;
bool is_order_clause_position() const override { return true; }
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
void print(String *str, enum_query_type query_type) override;
Item *neg(THD *thd) override;
decimal_digits_t decimal_precision() const override
@@ -4620,8 +4610,8 @@ public:
Item_uint(THD *thd, const char *str_arg, size_t length);
Item_uint(THD *thd, ulonglong i): Item_int(thd, i, 10) {}
Item_uint(THD *thd, const char *str_arg, longlong i, uint length);
double val_real() override { return ulonglong2double((ulonglong)value); }
Item *do_clone_const_item(THD *thd) const override;
double val_real() override { return ulonglong2double((ulonglong)value); }
Item *clone_item(THD *thd) const override;
Item *neg(THD *thd) override;
decimal_digits_t decimal_precision() const override
{ return decimal_digits_t(max_length); }
@@ -4676,7 +4666,7 @@ public:
const my_decimal *const_ptr_my_decimal() const override
{ return &decimal_value; }
int save_in_field(Field *field, bool no_conversions) override;
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
void print(String *str, enum_query_type query_type) override
{
decimal_value.to_string(&str_value);
@@ -4730,7 +4720,7 @@ public:
}
String *val_str(String*) override;
my_decimal *val_decimal(my_decimal *) override;
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
Item *neg(THD *thd) override;
void print(String *str, enum_query_type query_type) override;
Item *do_get_copy(THD *thd) const override
@@ -4851,7 +4841,7 @@ public:
int save_in_field(Field *field, bool no_conversions) override;
const Type_handler *type_handler() const override
{ return &type_handler_varchar; }
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override
{
return const_charset_converter(thd, tocs, true);
@@ -5275,7 +5265,7 @@ public:
{
return cached_time.get_mysql_time();
}
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
longlong val_int() override
{
return update_null() ? 0 : cached_time.to_longlong();
@@ -5325,7 +5315,7 @@ public:
{
return cached_time.get_mysql_time();
}
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
longlong val_int() override { return cached_time.to_longlong(); }
double val_real() override { return cached_time.to_double(); }
String *val_str(String *to) override
@@ -5379,7 +5369,7 @@ public:
{
return cached_time.get_mysql_time();
}
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
longlong val_int() override
{
return update_null() ? 0 : cached_time.to_longlong();
@@ -5468,6 +5458,9 @@ public:
cached_time.copy_to_mysql_time(ltime);
return (null_value= false);
}
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_datetime_literal_for_invalid_dates>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
};
@@ -6536,8 +6529,11 @@ public:
{
return ref->save_in_field(field, no_conversions);
}
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
Item *real_item() override { return ref; }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_int_with_ref>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
};
#ifdef MYSQL_SERVER
@@ -7459,7 +7455,7 @@ public:
is a constant and need not be optimized further.
Important when storing packed datetime values.
*/
Item *do_clone_const_item(THD *thd) const override;
Item *clone_item(THD *thd) const override;
Item *convert_to_basic_const_item(THD *thd) override;
virtual Item *make_literal(THD *) =0;
};

View File

@@ -759,10 +759,12 @@ ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key)
if (is_string)
{
/*
Prefix keys are not possible in BNLH joins.
Use the whole string to calculate the hash.
Surprisingly, BNL-H joins may use prefix keys. This may happen
when there is a real index on the column used in equi-join.
In this case, the passed key tuple is already a prefix, no
special handling is required.
*/
DBUG_ASSERT((key_part->key_part_flag & HA_PART_KEY_SEG) == 0);
cs->hash_sort(pos+pack_length, length, &nr, &nr2);
key+= pack_length;
}
@@ -866,10 +868,10 @@ bool key_buf_cmp(KEY *key_info, uint used_key_parts,
if (is_string)
{
/*
Prefix keys are not possible in BNLH joins.
Compare whole strings.
Surprisingly, BNL-H joins may use prefix keys. This may happen
when there is a real index on the column used in equi-join.
In this case, we get properly truncated prefixes here.
*/
DBUG_ASSERT((key_part->key_part_flag & HA_PART_KEY_SEG) == 0);
if (cs->strnncollsp(pos1 + pack_length, length1,
pos2 + pack_length, length2))
return true;

View File

@@ -5358,6 +5358,17 @@ extern "C" int thd_current_status(MYSQL_THD thd)
}
extern "C" int thd_double_innodb_cardinality(MYSQL_THD thd)
{
/*
The original behavior was to double the cardinality.
OPTIMIZER_FIX_INNODB_CARDINALITY means do not double.
*/
return !(thd->variables.optimizer_adjust_secondary_key_costs &
OPTIMIZER_FIX_INNODB_CARDINALITY);
}
extern "C" enum enum_server_command thd_current_command(MYSQL_THD thd)
{
return thd->get_command();

View File

@@ -218,6 +218,7 @@ extern "C" const char *thd_client_ip(MYSQL_THD thd);
extern "C" LEX_CSTRING *thd_current_db(MYSQL_THD thd);
extern "C" int thd_current_status(MYSQL_THD thd);
extern "C" enum enum_server_command thd_current_command(MYSQL_THD thd);
extern "C" int thd_double_innodb_cardinality(MYSQL_THD thd);
/**
@class CSET_STRING

View File

@@ -1574,6 +1574,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
if (sl != first_sl)
{
DBUG_ASSERT(sl->item_list.elements == first_sl->item_list.elements);
sl->save_item_list_names(thd);
List_iterator_fast<Item> it(sl->item_list);
List_iterator_fast<Item> nm_it(unit->types);
while (Item *item= it++)

View File

@@ -8355,7 +8355,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
}
bool has_alias_ptr= alias != nullptr;
void *memregion= thd->calloc(sizeof(TABLE_LIST));
void *memregion= thd->alloc(sizeof(TABLE_LIST));
TABLE_LIST *ptr= new (memregion) TABLE_LIST(thd, db, fqtn, alias_str,
has_alias_ptr, table, lock_type,
mdl_type, table_options,

View File

@@ -278,6 +278,7 @@
#define OPTIMIZER_ADJ_SEC_KEY_COST (1)
#define OPTIMIZER_ADJ_DISABLE_MAX_SEEKS (2)
#define OPTIMIZER_ADJ_DISABLE_FORCE_INDEX_GROUP_BY (4)
#define OPTIMIZER_FIX_INNODB_CARDINALITY (8)
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you

View File

@@ -17680,7 +17680,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
if (can_change_cond_ref_to_const(func, right_item, left_item,
field_value_owner, field, value))
{
Item *tmp=value->clone_const_item(thd);
Item *tmp=value->clone_item(thd);
if (tmp)
{
tmp->collation.set(right_item->collation);
@@ -17710,7 +17710,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
else if (can_change_cond_ref_to_const(func, left_item, right_item,
field_value_owner, field, value))
{
Item *tmp= value->clone_const_item(thd);
Item *tmp= value->clone_item(thd);
if (tmp)
{
tmp->collation.set(left_item->collation);

View File

@@ -262,9 +262,12 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
For "win_func() OVER (ORDER BY order_list RANGE BETWEEN ...)",
- ORDER BY order_list must not be ommitted
- the list must have a single element.
But it really only matters if the frame is bounded.
*/
if (win_spec->window_frame &&
win_spec->window_frame->units == Window_frame::UNITS_RANGE)
win_spec->window_frame->units == Window_frame::UNITS_RANGE &&
!(win_spec->window_frame->top_bound->is_unbounded() &&
win_spec->window_frame->bottom_bound->is_unbounded()))
{
if (win_spec->order_list->elements != 1)
{

View File

@@ -2944,18 +2944,21 @@ static Sys_var_ulong Sys_optimizer_trace_max_mem_size(
*/
static const char *adjust_secondary_key_cost[]=
{
"adjust_secondary_key_cost", "disable_max_seek", "disable_forced_index_in_group_by", 0
"adjust_secondary_key_cost", "disable_max_seek", "disable_forced_index_in_group_by", "fix_innodb_cardinality",0
};
static Sys_var_set Sys_optimizer_adjust_secondary_key_costs(
"optimizer_adjust_secondary_key_costs",
"A bit field with the following values: "
"adjust_secondary_key_cost = Update secondary key costs for ranges to be at least "
"5x of clustered primary key costs. "
"disable_max_seek = Disable 'max_seek optimization' for secondary keys and slight "
"adjustment of filter cost. "
"disable_forced_index_in_group_by = Disable automatic forced index in GROUP BY. "
"adjust_secondary_key_cost = Update secondary key costs for ranges to be "
"at least 5x of clustered primary key costs. "
"disable_max_seek = Disable 'max_seek optimization' for secondary keys and "
"slight adjustment of filter cost. "
"disable_forced_index_in_group_by = Disable automatic forced index in "
"GROUP BY. "
"fix_innodb_cardinality = Disable doubling of the Cardinality for InnoDB "
"secondary keys. "
"This variable will be deleted in MariaDB 11.0 as it is not needed with the "
"new 11.0 optimizer.",
SESSION_VAR(optimizer_adjust_secondary_key_costs), CMD_LINE(REQUIRED_ARG),

View File

@@ -5883,6 +5883,7 @@ TABLE_LIST::TABLE_LIST(THD *thd,
List<Index_hint> *index_hints_ptr,
LEX_STRING *option_ptr)
{
reset();
db= db_str;
is_fqtn= fqtn;
alias= alias_str;

View File

@@ -1348,6 +1348,8 @@ inline bool fil_space_t::acquire_if_not_stopped()
bool fil_crypt_must_default_encrypt()
{
/* prevents a race condition with fil_crypt_set_rotate_key_age() */
mysql_mutex_assert_owner(&fil_system.mutex);
return !srv_fil_crypt_rotate_key_age || !srv_encrypt_rotate;
}
@@ -2201,6 +2203,27 @@ void fil_crypt_set_rotation_iops(uint val)
mysql_mutex_unlock(&fil_crypt_threads_mutex);
}
/** Add the import tablespace to default_encrypt list
if necessary and signal fil_crypt_threads
@param space imported tablespace */
void fil_crypt_add_imported_space(fil_space_t *space)
{
mysql_mutex_lock(&fil_crypt_threads_mutex);
mysql_mutex_lock(&fil_system.mutex);
if (fil_crypt_must_default_encrypt())
{
fil_system.default_encrypt_tables.push_back(*space);
space->is_in_default_encrypt= true;
}
mysql_mutex_unlock(&fil_system.mutex);
pthread_cond_broadcast(&fil_crypt_threads_cond);
mysql_mutex_unlock(&fil_crypt_threads_mutex);
}
/*********************************************************************
Adjust encrypt tables
@param[in] val New setting for innodb-encrypt-tables */

View File

@@ -13335,7 +13335,7 @@ ha_innobase::discard_or_import_tablespace(
| HA_STATUS_VARIABLE
| HA_STATUS_AUTO);
fil_crypt_set_encrypt_tables(srv_encrypt_tables);
fil_crypt_add_imported_space(m_prebuilt->table->space);
}
}
@@ -14949,7 +14949,8 @@ ha_innobase::info_low(
index selectivity is 2 times better than
our estimate: */
rec_per_key_int = rec_per_key_int / 2;
rec_per_key_int /= 1
+ thd_double_innodb_cardinality(m_user_thd);
if (rec_per_key_int == 0) {
rec_per_key_int = 1;

View File

@@ -374,10 +374,12 @@ found_j:
}
}
/* In case of discarded tablespace, InnoDB can't
read the root page. So assign the null bytes based
on nullabled fields */
if (!oindex.table->space) {
/* Discard tablespace doesn't remove the instantness
from the table definition. if n_core_null_bytes wasn't
initialized then assign it based on nullable fields */
if (!oindex.table->space
&& oindex.n_core_null_bytes
== dict_index_t::NO_CORE_NULL_BYTES) {
oindex.n_core_null_bytes = static_cast<uint8_t>(
UT_BITS_IN_BYTES(unsigned(oindex.n_nullable)));
}

View File

@@ -337,6 +337,11 @@ Adjust rotation iops
@param[in] val New max roation iops */
void fil_crypt_set_rotation_iops(uint val);
/** Add the import tablespace to default_encrypt list
if necessary and signal fil_crypt_threads
@param space imported tablespace */
void fil_crypt_add_imported_space(fil_space_t *space);
/*********************************************************************
Adjust encrypt tables
@param[in] val New setting for innodb-encrypt-tables */

View File

@@ -25,6 +25,7 @@ to the machine format.
Created 11/28/1995 Heikki Tuuri
***********************************************************************/
#include "my_valgrind.h"
#ifndef UNIV_INNOCHECKSUM
#include "mtr0types.h"
@@ -39,7 +40,7 @@ mach_write_to_1(
byte* b, /*!< in: pointer to byte where to store */
ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */
{
#ifndef HAVE_valgrind
#if !defined HAVE_valgrind || __has_feature(memory_sanitizer)
ut_ad((n & ~0xFFUL) == 0);
#endif
@@ -58,7 +59,7 @@ mach_write_to_2(
byte* b, /*!< in: pointer to two bytes where to store */
ulint n) /*!< in: ulint integer to be stored */
{
#ifndef HAVE_valgrind
#if !defined HAVE_valgrind || __has_feature(memory_sanitizer)
ut_ad((n & ~0xFFFFUL) == 0);
#endif

View File

@@ -5015,7 +5015,7 @@ void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx,
if (const lock_t* wait_lock = trx->lock.wait_lock) {
const my_hrtime_t suspend_time= trx->lock.suspend_time;
fprintf(file,
"------- TRX HAS BEEN WAITING %llu ns"
"------- TRX HAS BEEN WAITING %llu us"
" FOR THIS LOCK TO BE GRANTED:\n",
now.val - suspend_time.val);

View File

@@ -811,11 +811,11 @@ zip_reorganize:
the predefined infimum record, then it would
still be the infimum, and we would have
ret_pos == 0. */
if (UNIV_UNLIKELY(!ret_pos
|| ret_pos == ULINT_UNDEFINED)) {
if (UNIV_UNLIKELY(ret_pos == ULINT_UNDEFINED)) {
*err = DB_CORRUPTION;
return nullptr;
}
*err = page_zip_reorganize(new_block, index,
page_zip_level, mtr);
switch (*err) {