Merge branch '10.5' into bb-10.5-release
This commit is contained in:
commit
34c5019698
2
VERSION
2
VERSION
@ -1,4 +1,4 @@
|
||||
MYSQL_VERSION_MAJOR=10
|
||||
MYSQL_VERSION_MINOR=5
|
||||
MYSQL_VERSION_PATCH=14
|
||||
MYSQL_VERSION_PATCH=15
|
||||
SERVER_MATURITY=stable
|
||||
|
@ -31,7 +31,7 @@ extern ulong my_time_to_wait_for_lock;
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_SIGHANDLER_T
|
||||
#define sig_return sighandler_t
|
||||
#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__) || defined(_AIX)
|
||||
typedef void (*sig_return)(int); /* Returns type from signal */
|
||||
#else
|
||||
typedef void (*sig_return)(void); /* Returns type from signal */
|
||||
|
@ -39,6 +39,28 @@ MDL_INTENTION_EXCLUSIVE Schema metadata lock test
|
||||
select * from t1;
|
||||
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||
backup unlock;
|
||||
connection con1;
|
||||
connection default;
|
||||
#
|
||||
# Check that BACKUP LOCK blocks some operations
|
||||
#
|
||||
create sequence seq1;
|
||||
create sequence seq2;
|
||||
backup lock seq1;
|
||||
connection con1;
|
||||
CREATE OR REPLACE SEQUENCE seq1 START -28;
|
||||
ERROR HY000: Sequence 'test.seq1' values are conflicting
|
||||
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
|
||||
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;
|
||||
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000;
|
||||
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||
SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1;
|
||||
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||
connection default;
|
||||
backup unlock;
|
||||
drop table seq1,seq2;
|
||||
#
|
||||
# BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
||||
#
|
||||
@ -141,7 +163,6 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
|
||||
SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
|
||||
# restart
|
||||
#
|
||||
connection con1;
|
||||
connection default;
|
||||
disconnect con1;
|
||||
show tables;
|
||||
|
@ -43,10 +43,39 @@ SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.me
|
||||
--error ER_LOCK_DEADLOCK
|
||||
select * from t1;
|
||||
backup unlock;
|
||||
connection con1;
|
||||
--reap
|
||||
connection default;
|
||||
|
||||
--echo #
|
||||
--echo # Check that BACKUP LOCK blocks some operations
|
||||
--echo #
|
||||
|
||||
# These test has to be done with timeouts as we want to ensure that the tables
|
||||
# doesn't change
|
||||
|
||||
create sequence seq1;
|
||||
create sequence seq2;
|
||||
backup lock seq1;
|
||||
connection con1;
|
||||
--error ER_SEQUENCE_INVALID_DATA
|
||||
CREATE OR REPLACE SEQUENCE seq1 START -28;
|
||||
--error ER_STATEMENT_TIMEOUT
|
||||
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
|
||||
--error ER_STATEMENT_TIMEOUT
|
||||
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;
|
||||
--error ER_STATEMENT_TIMEOUT
|
||||
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000;
|
||||
--error ER_STATEMENT_TIMEOUT
|
||||
SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1;
|
||||
connection default;
|
||||
backup unlock;
|
||||
drop table seq1,seq2;
|
||||
|
||||
--echo #
|
||||
--echo # BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
||||
--echo #
|
||||
|
||||
delimiter |;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
CREATE PROCEDURE p_BACKUP_LOCK()
|
||||
@ -162,8 +191,6 @@ SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
|
||||
|
||||
--echo #
|
||||
|
||||
connection con1;
|
||||
--reap
|
||||
connection default;
|
||||
disconnect con1;
|
||||
show tables;
|
||||
|
@ -4027,3 +4027,40 @@ drop table t1;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
||||
#
|
||||
# MDEV-27442 Wrong result upon query with DISTINCT and EXISTS subquery
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int, KEY b (b,a)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,100),(2,100),(2,101),(3,102);
|
||||
# Must not use Using index for group-by
|
||||
explain SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL b 10 NULL 4 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||
b
|
||||
100
|
||||
101
|
||||
102
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-26585 Wrong query results when `using index for group-by`
|
||||
#
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`owner_id` int(11) DEFAULT NULL,
|
||||
`foo` tinyint(1) DEFAULT 0,
|
||||
`whatever` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `index_t1_on_owner_id_and_foo` (`owner_id`,`foo`)
|
||||
) engine=InnoDB DEFAULT CHARSET=utf8;
|
||||
INSERT INTO t1 (owner_id, foo, whatever)
|
||||
VALUES (1, TRUE, "yello"), (1, FALSE, "yello"), (2, TRUE, "yello"),
|
||||
(2, TRUE, "yello"), (2, FALSE, "yello");
|
||||
EXPLAIN SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL index_t1_on_owner_id_and_foo 7 NULL 5 Using where; Using index
|
||||
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
owner_id
|
||||
1
|
||||
DROP TABLE t1;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
--source include/default_optimizer_switch.inc
|
||||
|
||||
--source include/have_innodb.inc
|
||||
#
|
||||
# TODO:
|
||||
# Add queries with:
|
||||
@ -1689,3 +1689,34 @@ drop table t1;
|
||||
--echo #
|
||||
--echo # End of 10.1 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27442 Wrong result upon query with DISTINCT and EXISTS subquery
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a int, b int, KEY b (b,a)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,100),(2,100),(2,101),(3,102);
|
||||
--echo # Must not use Using index for group-by
|
||||
explain SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||
SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26585 Wrong query results when `using index for group-by`
|
||||
--echo #
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`owner_id` int(11) DEFAULT NULL,
|
||||
`foo` tinyint(1) DEFAULT 0,
|
||||
`whatever` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `index_t1_on_owner_id_and_foo` (`owner_id`,`foo`)
|
||||
) engine=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO t1 (owner_id, foo, whatever)
|
||||
VALUES (1, TRUE, "yello"), (1, FALSE, "yello"), (2, TRUE, "yello"),
|
||||
(2, TRUE, "yello"), (2, FALSE, "yello");
|
||||
EXPLAIN SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
DROP TABLE t1;
|
||||
|
@ -5,6 +5,7 @@ c INT,
|
||||
INDEX(b))
|
||||
ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||
SET GLOBAL innodb_change_buffering=all;
|
||||
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024;
|
||||
# restart: --innodb-force-recovery=6 --innodb-change-buffer-dump
|
||||
check table t1;
|
||||
|
@ -13,6 +13,7 @@ c INT,
|
||||
INDEX(b))
|
||||
ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||
SET GLOBAL innodb_change_buffering = all;
|
||||
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
|
||||
BEGIN;
|
||||
SELECT b FROM t1 LIMIT 3;
|
||||
|
@ -24,6 +24,7 @@ ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||
# change buffering is possible, so that the change buffer will be used
|
||||
# whenever possible.
|
||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||
SET GLOBAL innodb_change_buffering=all;
|
||||
|
||||
# Create enough rows for the table, so that the change buffer will be
|
||||
# used for modifying the secondary index page. There must be multiple
|
||||
|
@ -33,6 +33,7 @@ ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||
# change buffering is possible, so that the change buffer will be used
|
||||
# whenever possible.
|
||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||
SET GLOBAL innodb_change_buffering = all;
|
||||
let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||
|
||||
# Create enough rows for the table, so that the change buffer will be
|
||||
|
@ -1,6 +1,8 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/big_test.inc
|
||||
--source include/not_embedded.inc
|
||||
# Valgrind is to slow for this test
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
set global innodb_defragment_stats_accuracy = 80;
|
||||
|
||||
|
@ -1,28 +1,28 @@
|
||||
SET @start_global_value = @@global.innodb_change_buffering;
|
||||
SELECT @start_global_value;
|
||||
@start_global_value
|
||||
all
|
||||
none
|
||||
Valid values are 'all', 'deletes', 'changes', 'inserts', 'none', 'purges'
|
||||
select @@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges');
|
||||
@@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges')
|
||||
1
|
||||
select @@global.innodb_change_buffering;
|
||||
@@global.innodb_change_buffering
|
||||
all
|
||||
none
|
||||
select @@session.innodb_change_buffering;
|
||||
ERROR HY000: Variable 'innodb_change_buffering' is a GLOBAL variable
|
||||
show global variables like 'innodb_change_buffering';
|
||||
Variable_name Value
|
||||
innodb_change_buffering all
|
||||
innodb_change_buffering none
|
||||
show session variables like 'innodb_change_buffering';
|
||||
Variable_name Value
|
||||
innodb_change_buffering all
|
||||
innodb_change_buffering none
|
||||
select * from information_schema.global_variables where variable_name='innodb_change_buffering';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_CHANGE_BUFFERING all
|
||||
INNODB_CHANGE_BUFFERING none
|
||||
select * from information_schema.session_variables where variable_name='innodb_change_buffering';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_CHANGE_BUFFERING all
|
||||
INNODB_CHANGE_BUFFERING none
|
||||
set global innodb_change_buffering='none';
|
||||
select @@global.innodb_change_buffering;
|
||||
@@global.innodb_change_buffering
|
||||
@ -62,4 +62,4 @@ ERROR 42000: Variable 'innodb_change_buffering' can't be set to the value of 'so
|
||||
SET @@global.innodb_change_buffering = @start_global_value;
|
||||
SELECT @@global.innodb_change_buffering;
|
||||
@@global.innodb_change_buffering
|
||||
all
|
||||
none
|
||||
|
@ -311,7 +311,7 @@ READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
VARIABLE_NAME INNODB_CHANGE_BUFFERING
|
||||
SESSION_VALUE NULL
|
||||
DEFAULT_VALUE all
|
||||
DEFAULT_VALUE none
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE ENUM
|
||||
VARIABLE_COMMENT Buffer changes to secondary indexes.
|
||||
|
@ -170,6 +170,7 @@ static pid_t pid;
|
||||
static char addr2line_binary[1024];
|
||||
static char output[1024];
|
||||
static struct pollfd poll_fds;
|
||||
static void *addr_offset;
|
||||
|
||||
int start_addr2line_fork(const char *binary_path)
|
||||
{
|
||||
@ -297,7 +298,6 @@ static int addr_resolve(void *ptr, my_addr_loc *loc)
|
||||
int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
||||
{
|
||||
Dl_info info;
|
||||
int error;
|
||||
|
||||
if (!dladdr(ptr, &info))
|
||||
return 1;
|
||||
@ -307,7 +307,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
||||
/*
|
||||
We use dli_fname in case the path is longer than the length of
|
||||
our static string. We don't want to allocate anything
|
||||
dynamicaly here as we are in a "crashed" state.
|
||||
dynamically here as we are in a "crashed" state.
|
||||
*/
|
||||
if (start_addr2line_fork(info.dli_fname))
|
||||
{
|
||||
@ -318,10 +318,22 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
||||
}
|
||||
/* Save result for future comparisons. */
|
||||
strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
|
||||
|
||||
/*
|
||||
Check if we should use info.dli_fbase as an offset or not
|
||||
for the base program. This is depending on if the compilation is
|
||||
done with PIE or not.
|
||||
*/
|
||||
addr_offset= (void*) info.dli_fbase;
|
||||
#ifndef __PIE__
|
||||
if (strcmp(info.dli_fname, my_progname) == 0 &&
|
||||
addr_resolve((void*) my_addr_resolve, loc) == 0 &&
|
||||
strcmp(loc->func, "my_addr_resolve") == 0)
|
||||
addr_offset= 0;
|
||||
#endif
|
||||
}
|
||||
if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc)))
|
||||
return 0;
|
||||
return error;
|
||||
|
||||
return addr_resolve((void*) (ptr - addr_offset), loc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#ifndef MAIN
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
|
||||
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
||||
{
|
||||
uint i, res= 1;
|
||||
@ -32,6 +33,7 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
||||
res= 0;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#include <net/ethernet.h>
|
||||
@ -195,4 +197,3 @@ int main(int argc __attribute__((unused)),char **argv)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -233,8 +233,12 @@ static bool backup_flush(THD *thd)
|
||||
This will probably require a callback from the InnoDB code.
|
||||
*/
|
||||
|
||||
/* Retry to get inital lock for 0.1 + 0.5 + 2.25 + 11.25 + 56.25 = 70.35 sec */
|
||||
#define MAX_RETRY_COUNT 5
|
||||
|
||||
static bool backup_block_ddl(THD *thd)
|
||||
{
|
||||
uint sleep_time;
|
||||
DBUG_ENTER("backup_block_ddl");
|
||||
|
||||
kill_delayed_threads();
|
||||
@ -275,17 +279,32 @@ static bool backup_block_ddl(THD *thd)
|
||||
block new DDL's, in addition to all previous blocks
|
||||
We didn't do this lock above, as we wanted DDL's to be executed while
|
||||
we wait for non transactional tables (which may take a while).
|
||||
|
||||
We do this lock in a loop as we can get a deadlock if there are multi-object
|
||||
ddl statements like
|
||||
RENAME TABLE t1 TO t2, t3 TO t3
|
||||
and the MDL happens in the middle of it.
|
||||
*/
|
||||
if (thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
|
||||
MDL_BACKUP_WAIT_DDL,
|
||||
thd->variables.lock_wait_timeout))
|
||||
sleep_time= 100; // Start with 0.1 seconds
|
||||
for (uint i= 0 ; i <= MAX_RETRY_COUNT ; i++)
|
||||
{
|
||||
/*
|
||||
Could be a timeout. Downgrade lock to what is was before this function
|
||||
was called so that this function can be called again
|
||||
*/
|
||||
backup_flush_ticket->downgrade_lock(MDL_BACKUP_FLUSH);
|
||||
DBUG_RETURN(1);
|
||||
if (!thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
|
||||
MDL_BACKUP_WAIT_DDL,
|
||||
thd->variables.lock_wait_timeout))
|
||||
break;
|
||||
if (thd->get_stmt_da()->sql_errno() != ER_LOCK_DEADLOCK || thd->killed ||
|
||||
i == MAX_RETRY_COUNT)
|
||||
{
|
||||
/*
|
||||
Could be a timeout. Downgrade lock to what is was before this function
|
||||
was called so that this function can be called again
|
||||
*/
|
||||
backup_flush_ticket->downgrade_lock(MDL_BACKUP_FLUSH);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->clear_error(); // Forget the DEADLOCK error
|
||||
my_sleep(sleep_time);
|
||||
sleep_time*= 5; // Wait a bit longer next time
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -14039,7 +14039,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
|
||||
key_part_range[1]= last_part;
|
||||
|
||||
/* Check if cur_part is referenced in the WHERE clause. */
|
||||
if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
|
||||
if (join->conds->walk(&Item::find_item_in_field_list_processor, true,
|
||||
key_part_range))
|
||||
{
|
||||
cause= "keypart reference from where clause";
|
||||
|
@ -1589,7 +1589,8 @@ bool JOIN::prepare_stage2()
|
||||
#endif
|
||||
if (select_lex->olap == ROLLUP_TYPE && rollup_init())
|
||||
goto err;
|
||||
if (alloc_func_list())
|
||||
if (alloc_func_list() ||
|
||||
make_sum_func_list(all_fields, fields_list, false))
|
||||
goto err;
|
||||
|
||||
res= FALSE;
|
||||
@ -2204,7 +2205,21 @@ JOIN::optimize_inner()
|
||||
If all items were resolved by opt_sum_query, there is no need to
|
||||
open any tables.
|
||||
*/
|
||||
if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds)))
|
||||
|
||||
/*
|
||||
The following resetting and restoring of sum_funcs is needed to
|
||||
go around a bug in spider where it assumes that
|
||||
make_sum_func_list() has not been called yet and do logical
|
||||
choices based on this if special handling of min/max functions should
|
||||
be done. We disable this special handling while we are trying to find
|
||||
out if we can replace MIN/MAX values with constants.
|
||||
*/
|
||||
Item_sum **save_func_sums= sum_funcs, *tmp_sum_funcs= 0;
|
||||
sum_funcs= &tmp_sum_funcs;
|
||||
res= opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds);
|
||||
sum_funcs= save_func_sums;
|
||||
|
||||
if (res)
|
||||
{
|
||||
DBUG_ASSERT(res >= 0);
|
||||
if (res == HA_ERR_KEY_NOT_FOUND)
|
||||
@ -2776,13 +2791,15 @@ int JOIN::optimize_stage2()
|
||||
calc_group_buffer(this, group_list);
|
||||
}
|
||||
|
||||
if (test_if_subpart(group_list, order) ||
|
||||
(!group_list && tmp_table_param.sum_func_count))
|
||||
{
|
||||
/*
|
||||
We can ignore ORDER BY if it's a prefix of the GROUP BY list
|
||||
(as MariaDB is by default sorting on GROUP BY) or
|
||||
if there is no GROUP BY and aggregate functions are used
|
||||
(as the result will only contain one row).
|
||||
*/
|
||||
if (order && (test_if_subpart(group_list, order) ||
|
||||
(!group_list && tmp_table_param.sum_func_count)))
|
||||
order=0;
|
||||
if (is_indexed_agg_distinct(this, NULL))
|
||||
sort_and_group= 0;
|
||||
}
|
||||
|
||||
// Can't use sort on head table if using join buffering
|
||||
if (full_join || hash_join)
|
||||
@ -2814,7 +2831,6 @@ int JOIN::optimize_stage2()
|
||||
if (select_lex->have_window_funcs())
|
||||
simple_order= FALSE;
|
||||
|
||||
|
||||
/*
|
||||
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
|
||||
whose columns are required to be returned in a sorted order, then
|
||||
@ -3548,7 +3564,7 @@ bool JOIN::make_aggr_tables_info()
|
||||
// for the first table
|
||||
if (group_list || tmp_table_param.sum_func_count)
|
||||
{
|
||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
|
||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
|
||||
DBUG_RETURN(true);
|
||||
if (prepare_sum_aggregators(sum_funcs,
|
||||
!join_tab->is_using_agg_loose_index_scan()))
|
||||
@ -3658,7 +3674,7 @@ bool JOIN::make_aggr_tables_info()
|
||||
last_tab->all_fields= &tmp_all_fields3;
|
||||
last_tab->fields= &tmp_fields_list3;
|
||||
}
|
||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
|
||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
|
||||
DBUG_RETURN(true);
|
||||
if (prepare_sum_aggregators(sum_funcs,
|
||||
!join_tab ||
|
||||
@ -3854,8 +3870,6 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (make_sum_func_list(all_fields, fields_list, false))
|
||||
goto err;
|
||||
if (prepare_sum_aggregators(sum_funcs,
|
||||
!join_tab->is_using_agg_loose_index_scan()))
|
||||
goto err;
|
||||
@ -7097,8 +7111,7 @@ void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
|
||||
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
|
||||
to loose index scan.
|
||||
|
||||
|
||||
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
|
||||
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
|
||||
(QUICK_GROUP_MIN_MAX_SELECT).
|
||||
Optionally (if out_args is supplied) will push the arguments of
|
||||
AGGFN(DISTINCT) to the list
|
||||
@ -7131,14 +7144,11 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
|
||||
Item_sum **sum_item_ptr;
|
||||
bool result= false;
|
||||
|
||||
if (join->table_count != 1 || /* reference more than 1 table */
|
||||
if (join->table_count != 1 || /* reference more than 1 table */
|
||||
join->select_distinct || /* or a DISTINCT */
|
||||
join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
|
||||
return false;
|
||||
|
||||
if (join->make_sum_func_list(join->all_fields, join->fields_list, true))
|
||||
return false;
|
||||
|
||||
Bitmap<MAX_FIELDS> first_aggdistinct_fields;
|
||||
bool first_aggdistinct_fields_initialized= false;
|
||||
for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++)
|
||||
@ -7240,16 +7250,23 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
|
||||
while ((item= select_items_it++))
|
||||
item->walk(&Item::collect_item_field_processor, 0, &indexed_fields);
|
||||
}
|
||||
else if (join->tmp_table_param.sum_func_count &&
|
||||
is_indexed_agg_distinct(join, &indexed_fields))
|
||||
else if (!join->tmp_table_param.sum_func_count ||
|
||||
!is_indexed_agg_distinct(join, &indexed_fields))
|
||||
{
|
||||
join->sort_and_group= 1;
|
||||
}
|
||||
else
|
||||
/*
|
||||
There where no GROUP BY fields and also either no aggregate
|
||||
functions or not all aggregate functions where used with the
|
||||
same DISTINCT (or MIN() / MAX() that works similarly).
|
||||
Nothing to do there.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexed_fields.elements == 0)
|
||||
{
|
||||
/* There where no index we could use to satisfy the GROUP BY */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Intersect the keys of all group fields. */
|
||||
cur_item= indexed_fields_it++;
|
||||
@ -25693,16 +25710,13 @@ bool JOIN::alloc_func_list()
|
||||
|
||||
bool JOIN::make_sum_func_list(List<Item> &field_list,
|
||||
List<Item> &send_result_set_metadata,
|
||||
bool before_group_by, bool recompute)
|
||||
bool before_group_by)
|
||||
{
|
||||
List_iterator_fast<Item> it(field_list);
|
||||
Item_sum **func;
|
||||
Item *item;
|
||||
DBUG_ENTER("make_sum_func_list");
|
||||
|
||||
if (*sum_funcs && !recompute)
|
||||
DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */
|
||||
|
||||
func= sum_funcs;
|
||||
while ((item=it++))
|
||||
{
|
||||
@ -25849,7 +25863,7 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
Change all funcs to be fields in tmp table.
|
||||
|
||||
@param thd THD pointer
|
||||
@param ref_pointer_array array of pointers to top elements of filed list
|
||||
@param ref_pointer_array array of pointers to top elements of field list
|
||||
@param res_selected_fields new list of items of select item list
|
||||
@param res_all_fields new list of all items
|
||||
@param elements number of elements in select item list
|
||||
|
@ -1196,7 +1196,17 @@ public:
|
||||
Indicates that grouping will be performed on the result set during
|
||||
query execution. This field belongs to query execution.
|
||||
|
||||
@see make_group_fields, alloc_group_fields, JOIN::exec
|
||||
If 'sort_and_group' is set, then the optimizer is going to use on of
|
||||
the following algorithms to resolve GROUP BY.
|
||||
|
||||
- If one table, sort the table and then calculate groups on the fly.
|
||||
- If more than one table, create a temporary table to hold the join,
|
||||
sort it and then resolve group by on the fly.
|
||||
|
||||
The 'on the fly' calculation is done in end_send_group()
|
||||
|
||||
@see make_group_fields, alloc_group_fields, JOIN::exec,
|
||||
setup_end_select_func
|
||||
*/
|
||||
bool sort_and_group;
|
||||
bool first_record,full_join, no_field_update;
|
||||
@ -1654,7 +1664,7 @@ public:
|
||||
bool make_range_rowid_filters();
|
||||
bool init_range_rowid_filters();
|
||||
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
|
||||
bool before_group_by, bool recompute= FALSE);
|
||||
bool before_group_by);
|
||||
|
||||
/// Initialzes a slice, see comments for ref_ptrs above.
|
||||
Ref_ptr_array ref_ptr_array_slice(size_t slice_num)
|
||||
|
@ -19659,7 +19659,7 @@ static MYSQL_SYSVAR_BOOL(numa_interleave, srv_numa_interleave,
|
||||
static MYSQL_SYSVAR_ENUM(change_buffering, innodb_change_buffering,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Buffer changes to secondary indexes.",
|
||||
NULL, NULL, IBUF_USE_ALL, &innodb_change_buffering_typelib);
|
||||
NULL, NULL, IBUF_USE_NONE, &innodb_change_buffering_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_UINT(change_buffer_max_size,
|
||||
srv_change_buffer_max_size,
|
||||
|
@ -639,8 +639,7 @@ loop:
|
||||
}
|
||||
}
|
||||
|
||||
/** Flush the recently written changes to the log file.
|
||||
and invoke mysql_mutex_lock(&log_sys.mutex). */
|
||||
/** Flush the recently written changes to the log file.*/
|
||||
static void log_write_flush_to_disk_low(lsn_t lsn)
|
||||
{
|
||||
if (!log_sys.log.writes_are_durable())
|
||||
@ -780,10 +779,6 @@ static void log_write(bool rotate_key)
|
||||
start_offset - area_start);
|
||||
srv_stats.log_padded.add(pad_size);
|
||||
log_sys.write_lsn = write_lsn;
|
||||
if (log_sys.log.writes_are_durable()) {
|
||||
log_sys.set_flushed_lsn(write_lsn);
|
||||
log_flush_notify(write_lsn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user