mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge 10.4 into 10.5
This commit is contained in:
@ -16679,7 +16679,7 @@ EXPLAIN EXTENDED
|
|||||||
SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
|
SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
3 LATERAL DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 /* select#1 */ select NULL AS `f`,`v2`.`f` AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0
|
Note 1003 /* select#1 */ select NULL AS `f`,`v2`.`f` AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0
|
||||||
DROP VIEW v1,v2;
|
DROP VIEW v1,v2;
|
||||||
|
@ -176,3 +176,68 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
3 LATERAL DERIVED t1 ref a,a_2 a 5 test.t1.a 1 Using where; Using temporary; Using filesort
|
3 LATERAL DERIVED t1 ref a,a_2 a 5 test.t1.a 1 Using where; Using temporary; Using filesort
|
||||||
3 LATERAL DERIVED t2 ref c c 5 test.t1.b 1 Using index
|
3 LATERAL DERIVED t2 ref c c 5 test.t1.b 1 Using index
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-25714: usage non-splitting covering index is cheaper than
|
||||||
|
# usage of the best splitting index for one group
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
id int not null, itemid int not null, index idx (itemid)
|
||||||
|
) engine=innodb;
|
||||||
|
insert into t1 values (1, 2), (2,2), (4,2), (4,2), (0,3), (3,3);
|
||||||
|
create table t2 (id int not null) engine=innodb;
|
||||||
|
insert into t2 values (2);
|
||||||
|
create table t3 (
|
||||||
|
id int not null, itemid int not null, userid int not null, primary key (id),
|
||||||
|
index idx1 (userid, itemid), index idx2 (itemid)
|
||||||
|
) engine innodb;
|
||||||
|
insert into t3 values (1,1,1), (2,1,1), (3,2,1), (4,2,1), (5,3,1);
|
||||||
|
set use_stat_tables='never';
|
||||||
|
set optimizer_use_condition_selectivity=1;
|
||||||
|
analyze table t1,t2,t3;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status OK
|
||||||
|
test.t2 analyze status OK
|
||||||
|
test.t3 analyze status OK
|
||||||
|
set optimizer_switch='split_materialized=on';
|
||||||
|
explain select t1.id, t1.itemid, dt.id, t2.id
|
||||||
|
from t1,
|
||||||
|
(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt,
|
||||||
|
t2
|
||||||
|
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
|
||||||
|
1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2
|
||||||
|
1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
||||||
|
2 DERIVED t3 ref idx1,idx2 idx1 4 const 5 Using where; Using index
|
||||||
|
select t1.id, t1.itemid, dt.id, t2.id
|
||||||
|
from t1,
|
||||||
|
(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt,
|
||||||
|
t2
|
||||||
|
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
|
||||||
|
id itemid id id
|
||||||
|
4 2 4 2
|
||||||
|
4 2 4 2
|
||||||
|
set optimizer_switch='split_materialized=off';
|
||||||
|
explain select t1.id, t1.itemid, dt.id, t2.id
|
||||||
|
from t1,
|
||||||
|
(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt,
|
||||||
|
t2
|
||||||
|
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
|
||||||
|
1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2
|
||||||
|
1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
||||||
|
2 DERIVED t3 ref idx1 idx1 4 const 5 Using where; Using index
|
||||||
|
select t1.id, t1.itemid, dt.id, t2.id
|
||||||
|
from t1,
|
||||||
|
(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt,
|
||||||
|
t2
|
||||||
|
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
|
||||||
|
id itemid id id
|
||||||
|
4 2 4 2
|
||||||
|
4 2 4 2
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
set optimizer_switch='split_materialized=default';
|
||||||
|
set use_stat_tables=default;
|
||||||
|
set optimizer_use_condition_selectivity=default;
|
||||||
|
# End of 10.3 tests
|
||||||
|
@ -152,3 +152,44 @@ eval set statement optimizer_switch='split_materialized=on' for $query;
|
|||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug mdev-25714: usage non-splitting covering index is cheaper than
|
||||||
|
--echo # usage of the best splitting index for one group
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1 (
|
||||||
|
id int not null, itemid int not null, index idx (itemid)
|
||||||
|
) engine=innodb;
|
||||||
|
insert into t1 values (1, 2), (2,2), (4,2), (4,2), (0,3), (3,3);
|
||||||
|
create table t2 (id int not null) engine=innodb;
|
||||||
|
insert into t2 values (2);
|
||||||
|
create table t3 (
|
||||||
|
id int not null, itemid int not null, userid int not null, primary key (id),
|
||||||
|
index idx1 (userid, itemid), index idx2 (itemid)
|
||||||
|
) engine innodb;
|
||||||
|
insert into t3 values (1,1,1), (2,1,1), (3,2,1), (4,2,1), (5,3,1);
|
||||||
|
set use_stat_tables='never';
|
||||||
|
set optimizer_use_condition_selectivity=1;
|
||||||
|
analyze table t1,t2,t3;
|
||||||
|
|
||||||
|
let $q=
|
||||||
|
select t1.id, t1.itemid, dt.id, t2.id
|
||||||
|
from t1,
|
||||||
|
(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt,
|
||||||
|
t2
|
||||||
|
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
|
||||||
|
|
||||||
|
set optimizer_switch='split_materialized=on';
|
||||||
|
eval explain $q;
|
||||||
|
eval $q;
|
||||||
|
|
||||||
|
set optimizer_switch='split_materialized=off';
|
||||||
|
eval explain $q;
|
||||||
|
eval $q;
|
||||||
|
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
set optimizer_switch='split_materialized=default';
|
||||||
|
set use_stat_tables=default;
|
||||||
|
set optimizer_use_condition_selectivity=default;
|
||||||
|
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
@ -17,7 +17,7 @@ LOCK TABLE t1 WRITE;
|
|||||||
eval KILL $conid;
|
eval KILL $conid;
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
--connection con1
|
--connection con1
|
||||||
--error 0,2013,ER_CONNECTION_KILLED
|
--error 0,2006,2013,ER_CONNECTION_KILLED
|
||||||
reap;
|
reap;
|
||||||
--connection default
|
--connection default
|
||||||
--disconnect con1
|
--disconnect con1
|
||||||
@ -35,7 +35,7 @@ LOCK TABLE t1 WRITE, t2 WRITE;
|
|||||||
eval KILL $conid;
|
eval KILL $conid;
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
--connection con1
|
--connection con1
|
||||||
--error 0,2013,ER_CONNECTION_KILLED
|
--error 0,2006,2013,ER_CONNECTION_KILLED
|
||||||
reap;
|
reap;
|
||||||
--connection default
|
--connection default
|
||||||
--disconnect con1
|
--disconnect con1
|
||||||
|
@ -7857,7 +7857,7 @@ bool Field_varstring::send(Protocol *protocol)
|
|||||||
#ifdef HAVE_MEM_CHECK
|
#ifdef HAVE_MEM_CHECK
|
||||||
void Field_varstring::mark_unused_memory_as_defined()
|
void Field_varstring::mark_unused_memory_as_defined()
|
||||||
{
|
{
|
||||||
uint used_length= get_length();
|
uint used_length __attribute__((unused)) = get_length();
|
||||||
MEM_MAKE_DEFINED(get_data() + used_length, field_length - used_length);
|
MEM_MAKE_DEFINED(get_data() + used_length, field_length - used_length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -958,11 +958,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
|
|||||||
in the cache
|
in the cache
|
||||||
*/
|
*/
|
||||||
spl_plan= spl_opt_info->find_plan(best_table, best_key, best_key_parts);
|
spl_plan= spl_opt_info->find_plan(best_table, best_key, best_key_parts);
|
||||||
if (!spl_plan &&
|
if (!spl_plan)
|
||||||
(spl_plan= (SplM_plan_info *) thd->alloc(sizeof(SplM_plan_info))) &&
|
|
||||||
(spl_plan->best_positions=
|
|
||||||
(POSITION *) thd->alloc(sizeof(POSITION) * join->table_count)) &&
|
|
||||||
!spl_opt_info->plan_cache.push_back(spl_plan))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The plan for the chosen key has not been found in the cache.
|
The plan for the chosen key has not been found in the cache.
|
||||||
@ -972,6 +968,27 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
|
|||||||
reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table,
|
reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table,
|
||||||
best_key, remaining_tables, true);
|
best_key, remaining_tables, true);
|
||||||
choose_plan(join, all_table_map & ~join->const_table_map);
|
choose_plan(join, all_table_map & ~join->const_table_map);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check that the chosen plan is really a splitting plan.
|
||||||
|
If not or if there is not enough memory to save the plan in the cache
|
||||||
|
then just return with no splitting plan.
|
||||||
|
*/
|
||||||
|
POSITION *first_non_const_pos= join->best_positions + join->const_tables;
|
||||||
|
TABLE *table= first_non_const_pos->table->table;
|
||||||
|
key_map spl_keys= table->keys_usable_for_splitting;
|
||||||
|
if (!(first_non_const_pos->key &&
|
||||||
|
spl_keys.is_set(first_non_const_pos->key->key)) ||
|
||||||
|
!(spl_plan= (SplM_plan_info *) thd->alloc(sizeof(SplM_plan_info))) ||
|
||||||
|
!(spl_plan->best_positions=
|
||||||
|
(POSITION *) thd->alloc(sizeof(POSITION) * join->table_count)) ||
|
||||||
|
spl_opt_info->plan_cache.push_back(spl_plan))
|
||||||
|
{
|
||||||
|
reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table,
|
||||||
|
best_key, remaining_tables, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
spl_plan->keyuse_ext_start= best_key_keyuse_ext_start;
|
spl_plan->keyuse_ext_start= best_key_keyuse_ext_start;
|
||||||
spl_plan->table= best_table;
|
spl_plan->table= best_table;
|
||||||
spl_plan->key= best_key;
|
spl_plan->key= best_key;
|
||||||
|
@ -639,7 +639,7 @@ Use MONITOR_DEC if appropriate mutex protection exists.
|
|||||||
|
|
||||||
#ifdef HAVE_MEM_CHECK
|
#ifdef HAVE_MEM_CHECK
|
||||||
# define MONITOR_CHECK_DEFINED(value) do { \
|
# define MONITOR_CHECK_DEFINED(value) do { \
|
||||||
mon_type_t m = value; \
|
mon_type_t m __attribute__((unused))= value; \
|
||||||
MEM_CHECK_DEFINED(&m, sizeof m); \
|
MEM_CHECK_DEFINED(&m, sizeof m); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else /* HAVE_MEM_CHECK */
|
#else /* HAVE_MEM_CHECK */
|
||||||
|
@ -1315,8 +1315,10 @@ page_cur_insert_rec_low(
|
|||||||
|
|
||||||
#ifdef HAVE_MEM_CHECK
|
#ifdef HAVE_MEM_CHECK
|
||||||
{
|
{
|
||||||
const void *rec_start= rec - rec_offs_extra_size(offsets);
|
const void *rec_start __attribute__((unused))=
|
||||||
ulint extra_size= rec_offs_extra_size(offsets) -
|
rec - rec_offs_extra_size(offsets);
|
||||||
|
ulint extra_size __attribute__((unused))=
|
||||||
|
rec_offs_extra_size(offsets) -
|
||||||
(page_is_comp(block->frame)
|
(page_is_comp(block->frame)
|
||||||
? REC_N_NEW_EXTRA_BYTES
|
? REC_N_NEW_EXTRA_BYTES
|
||||||
: REC_N_OLD_EXTRA_BYTES);
|
: REC_N_OLD_EXTRA_BYTES);
|
||||||
@ -1722,8 +1724,10 @@ page_cur_insert_rec_zip(
|
|||||||
|
|
||||||
#ifdef HAVE_MEM_CHECK
|
#ifdef HAVE_MEM_CHECK
|
||||||
{
|
{
|
||||||
const void *rec_start= rec - rec_offs_extra_size(offsets);
|
const void *rec_start __attribute__((unused))=
|
||||||
ulint extra_size= rec_offs_extra_size(offsets) - REC_N_NEW_EXTRA_BYTES;
|
rec - rec_offs_extra_size(offsets);
|
||||||
|
ulint extra_size __attribute__((unused))=
|
||||||
|
rec_offs_extra_size(offsets) - REC_N_NEW_EXTRA_BYTES;
|
||||||
/* All data bytes of the record must be valid. */
|
/* All data bytes of the record must be valid. */
|
||||||
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
|
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
|
||||||
/* The variable-length header must be valid. */
|
/* The variable-length header must be valid. */
|
||||||
|
Reference in New Issue
Block a user