Skip to content
Permalink
Browse files
Merge 10.3 into 10.4
  • Loading branch information
dr-m committed Jun 9, 2022
2 parents 5efadf8 + 9829313 commit c89e3b7
Show file tree
Hide file tree
Showing 18 changed files with 185 additions and 98 deletions.
@@ -274,12 +274,16 @@ delete from mysql.help_relation where help_keyword_id=@keyword1_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topic_id=@topic1_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
End of 4.1 tests.
DROP TABLE IF EXISTS t1;
flush tables;
#
# End of 4.1 tests.
#
CREATE TABLE t1 (i INT);
LOCK TABLES t1 WRITE;
HELP no_such_topic;
name is_it_category
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests.
#
# End of 5.1 tests.
#
@@ -122,25 +122,22 @@ delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;

--echo End of 4.1 tests.
flush tables;
--echo #
--echo # End of 4.1 tests.
--echo #

#
# Test that we can use HELP even under LOCK TABLES. See bug#9953:
# CONVERT_TZ requires mysql.time_zone_name to be locked.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings

CREATE TABLE t1 (i INT);

LOCK TABLES t1 WRITE;

HELP no_such_topic;

UNLOCK TABLES;

DROP TABLE t1;


--echo End of 5.1 tests.
--echo #
--echo # End of 5.1 tests.
--echo #
@@ -5458,6 +5458,11 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"rows_for_plan": 729,
"cost_for_plan": 451.86,
"semijoin_strategy_choice": [
{
"strategy": "FirstMatch",
"records": 27,
"read_time": 665.23
},
{
"strategy": "DuplicateWeedout",
"records": 27,
@@ -5634,16 +5639,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
},
"rows_for_plan": 2187,
"cost_for_plan": 611.85,
"semijoin_strategy_choice": [
{
"strategy": "FirstMatch",
"records": 81,
"read_time": 2232.8
},
{
"chosen_strategy": "FirstMatch"
}
],
"semijoin_strategy_choice": [],
"pruned_by_cost": true
},
{
@@ -2178,10 +2178,10 @@ INSERT INTO t5 VALUES (7,0),(9,0);
explain
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
a
0
@@ -2189,10 +2189,10 @@ INSERT INTO t5 VALUES (7,0),(9,0);
explain
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (incremental, BNL join)
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
a
0
@@ -3,7 +3,7 @@
#
# restart
FOUND 1 /InnoDB: New log files created, LSN=175964\d{8}/ in mysqld.1.err
CREATE TABLE t(i INT) ENGINE INNODB;
CREATE TABLE t(i INT) ENGINE=INNODB ENCRYPTED=YES;
INSERT INTO t VALUES(1);
# xtrabackup backup
SET GLOBAL innodb_flush_log_at_trx_commit=1;
@@ -16,6 +16,14 @@ INSERT INTO t VALUES(2);
SELECT * FROM t;
i
1
FLUSH TABLE t FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
ALTER TABLE t IMPORT TABLESPACE;
FLUSH TABLE t FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
ALTER TABLE t IMPORT TABLESPACE;
DROP TABLE t;
# shutdown server
# remove datadir
@@ -42,7 +42,7 @@ let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= InnoDB: New log files created, LSN=175964\d{8}
--source include/search_pattern_in_file.inc

CREATE TABLE t(i INT) ENGINE INNODB;
CREATE TABLE t(i INT) ENGINE=INNODB ENCRYPTED=YES;
INSERT INTO t VALUES(1);

echo # xtrabackup backup;
@@ -58,6 +58,22 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir;
--source include/restart_and_restore.inc
--enable_result_log
SELECT * FROM t;
FLUSH TABLE t FOR EXPORT;
copy_file $_datadir/test/t.ibd $_datadir/test/t_copy.ibd;
copy_file $_datadir/test/t.cfg $_datadir/test/t_copy.cfg;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
move_file $_datadir/test/t_copy.ibd $_datadir/test/t.ibd;
move_file $_datadir/test/t_copy.cfg $_datadir/test/t.cfg;
ALTER TABLE t IMPORT TABLESPACE;
FLUSH TABLE t FOR EXPORT;
copy_file $_datadir/test/t.ibd $_datadir/test/t_copy.ibd;
copy_file $_datadir/test/t.cfg $_datadir/test/t_copy.cfg;
UNLOCK TABLES;
ALTER TABLE t DISCARD TABLESPACE;
move_file $_datadir/test/t_copy.ibd $_datadir/test/t.ibd;
move_file $_datadir/test/t_copy.cfg $_datadir/test/t.cfg;
ALTER TABLE t IMPORT TABLESPACE;
DROP TABLE t;
rmdir $targetdir;
let $targetdir= $targetdir_old;
@@ -842,7 +842,7 @@ EOF
fi

if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then
if grep -m1 -qE "^$BYPASS_TAG([[space]]+.*)?\$" -- "$MAGIC_FILE"; then
if grep -m1 -qE "^$BYPASS_TAG([[:space:]]+.*)?\$" -- "$MAGIC_FILE"; then
readonly WSREP_SST_OPT_BYPASS=1
readonly WSREP_TRANSFER_TYPE='IST'
fi
@@ -180,7 +180,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- optimize_semijoin_nests() does pre-optimization
- during join optimization, the join has one JOIN_TAB (or is it POSITION?)
array, and suffix-based detection is used, see advance_sj_state()
array, and suffix-based detection is used, see optimize_semi_joins()
- after join optimization is done, get_best_combination() switches
the data-structure to prefix-based, multiple JOIN_TAB ranges format.
@@ -2735,7 +2735,7 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
Do semi-join optimization step after we've added a new tab to join prefix
SYNOPSIS
advance_sj_state()
optimize_semi_joins()
join The join we're optimizing
remaining_tables Tables not in the join prefix
new_join_tab Join tab we've just added to the join prefix
@@ -2795,9 +2795,9 @@ bool is_multiple_semi_joins(JOIN *join, POSITION *prefix, uint idx, table_map in
}


void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count, double *current_read_time,
POSITION *loose_scan_pos)
void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count,
double *current_read_time, POSITION *loose_scan_pos)
{
POSITION *pos= join->positions + idx;
const JOIN_TAB *new_join_tab= pos->table;
@@ -2988,19 +2988,36 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
}
}

if ((emb_sj_nest= new_join_tab->emb_sj_nest))
update_sj_state(join, new_join_tab, idx, remaining_tables);

pos->prefix_cost.convert_from_cost(*current_read_time);
pos->prefix_record_count= *current_record_count;
pos->dups_producing_tables= dups_producing_tables;
}


/*
Update JOIN's semi-join optimization state after the join tab new_tab
has been added into the join prefix.
@seealso restore_prev_sj_state() does the reverse actoion
*/

void update_sj_state(JOIN *join, const JOIN_TAB *new_tab,
uint idx, table_map remaining_tables)
{
if (TABLE_LIST *emb_sj_nest= new_tab->emb_sj_nest)
{
join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;

/* Remove the sj_nest if all of its SJ-inner tables are in cur_table_map */
if (!(remaining_tables &
emb_sj_nest->sj_inner_tables & ~new_join_tab->table->map))
emb_sj_nest->sj_inner_tables & ~new_tab->table->map))
join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
}

pos->prefix_cost.convert_from_cost(*current_read_time);
pos->prefix_record_count= *current_record_count;
pos->dups_producing_tables= dups_producing_tables;
#ifndef DBUG_OFF
join->dbug_verify_sj_inner_tables(idx + 1);
#endif
}


@@ -3553,10 +3570,45 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join,
return FALSE;
}

#ifndef DBUG_OFF
/*
Verify the value of JOIN::cur_sj_inner_tables by recomputing it
*/
void JOIN::dbug_verify_sj_inner_tables(uint prefix_size) const
{
table_map cur_map= const_table_map;
table_map nests_entered= 0;
if (emb_sjm_nest)
{
DBUG_ASSERT(cur_sj_inner_tables == 0);
return;
}

for (uint i= const_tables; i < prefix_size; i++)
{
JOIN_TAB *tab= positions[i].table;
cur_map |= tab->table->map;
if (TABLE_LIST *sj_nest= tab->emb_sj_nest)
{
nests_entered |= sj_nest->sj_inner_tables;
if (!(sj_nest->sj_inner_tables & ~cur_map))
{
// all nest tables are in the prefix already
nests_entered &= ~sj_nest->sj_inner_tables;
}
}
}
DBUG_ASSERT(nests_entered == cur_sj_inner_tables);
}
#endif

/*
Remove the last join tab from from join->cur_sj_inner_tables bitmap
we assume remaining_tables doesnt contain @tab.
@note
remaining_tables contains @tab.
@seealso update_sj_state() does the reverse
*/

void restore_prev_sj_state(const table_map remaining_tables,
@@ -3570,15 +3622,30 @@ void restore_prev_sj_state(const table_map remaining_tables,
tab->join->sjm_lookup_tables &= ~subq_tables;
}

if ((emb_sj_nest= tab->emb_sj_nest))
if (!tab->join->emb_sjm_nest && (emb_sj_nest= tab->emb_sj_nest))
{
table_map subq_tables= emb_sj_nest->sj_inner_tables &
~tab->join->const_table_map;
/* If we're removing the last SJ-inner table, remove the sj-nest */
if ((remaining_tables & emb_sj_nest->sj_inner_tables) ==
(emb_sj_nest->sj_inner_tables & ~tab->table->map))
if ((remaining_tables & subq_tables) == subq_tables)
{
// All non-const tables of the SJ nest are in the remaining_tables.
// we are not in the nest anymore.
tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
}
else
{
// Semi-join nest has:
// - a table being removed (not in the prefix)
// - some tables in the prefix.
tab->join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;
}
}

#ifndef DBUG_OFF
/* positions[idx] has been removed. Verify the state for [0...idx-1] */
tab->join->dbug_verify_sj_inner_tables(idx);
#endif
}


@@ -3805,8 +3872,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
join->best_positions[first].n_sj_tables= sjm->tables;
/*
Do what advance_sj_state did: re-run best_access_path for every table
in the [last_inner_table + 1; pos..) range
Do what optimize_semi_joins did: re-run best_access_path for every
table in the [last_inner_table + 1; pos..) range
*/
double prefix_rec_count;
/* Get the prefix record count */
@@ -5032,7 +5099,7 @@ int setup_semijoin_loosescan(JOIN *join)
The choice between the strategies is made by the join optimizer (see
advance_sj_state() and fix_semijoin_strategies_for_picked_join_order()).
optimize_semi_joins() and fix_semijoin_strategies_for_picked_join_order()).
This function sets up all fields/structures/etc needed for execution except
for setup/initialization of semi-join materialization which is done in
setup_sj_materialization() (todo: can't we move that to here also?)
@@ -314,9 +314,11 @@ class Loose_scan_opt
};


void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count, double *current_read_time,
POSITION *loose_scan_pos);
void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx,
double *current_record_count,
double *current_read_time, POSITION *loose_scan_pos);
void update_sj_state(JOIN *join, const JOIN_TAB *new_tab,
uint idx, table_map remaining_tables);
void restore_prev_sj_state(const table_map remaining_tables,
const JOIN_TAB *tab, uint idx);

@@ -8671,7 +8671,7 @@ ER_JSON_ESCAPING
eng "Incorrect escaping in JSON text in argument %d to function '%s' at position %d"
ER_JSON_DEPTH
chi "超过JSON嵌套深度的%d限制 参数%d 函数'%s' 位置%d的"
eng "Limit of %d on JSON nested strucures depth is reached in argument %d to function '%s' at position %d"
eng "Limit of %d on JSON nested structures depth is reached in argument %d to function '%s' at position %d"
ER_JSON_PATH_EOS
chi "JSON文本路径错误 参数%d 函数'%s'"
eng "Unexpected end of JSON path in argument %d to function '%s'"

0 comments on commit c89e3b7

Please sign in to comment.