Commit abe4c7bf authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents 7e31a8e7 c6e58a8d
......@@ -4083,6 +4083,18 @@ MIN(pk)
1
DROP TABLE t1, t2;
#
# MDEV-30605 Wrong result while using index for group-by
#
CREATE TABLE t1 (pk INT primary key, a int, key(a)) engine=innodb;
INSERT INTO t1 VALUES (1,-1),(2,8),(3,5),(4,-1),(5,10), (6,-1);
SELECT MIN(pk), a FROM t1 WHERE pk <> 1 GROUP BY a;
MIN(pk) a
4 -1
3 5
2 8
5 10
DROP TABLE t1;
#
# End of 10.5 tests
#
#
......
......@@ -1738,6 +1738,17 @@ SELECT SQL_BUFFER_RESULT MIN(pk) FROM t1, t2;
SELECT MIN(pk) FROM t1, t2;
DROP TABLE t1, t2;
--echo #
--echo # MDEV-30605 Wrong result while using index for group-by
--echo #
CREATE TABLE t1 (pk INT primary key, a int, key(a)) engine=innodb;
INSERT INTO t1 VALUES (1,-1),(2,8),(3,5),(4,-1),(5,10), (6,-1);
SELECT MIN(pk), a FROM t1 WHERE pk <> 1 GROUP BY a;
DROP TABLE t1;
--echo #
--echo # End of 10.5 tests
--echo #
......
connection node_2;
connection node_1;
CREATE TABLE t (a INT) ENGINE=Aria;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
START TRANSACTION;
INSERT INTO t VALUES ('1');
INSERT INTO t1 VALUES ('1');
COMMIT;
ERROR HY000: Transactional commit not supported by involved engine(s)
DROP TABLE t;
DROP TABLE t1;
!include ../galera_2nodes.cnf
[mysqld.1]
log-bin
[mysqld.2]
log-bin
#
# Test that transaction requiring two-phase commit and involving
# storage engines not supporting it rolls back with a message.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_aria.inc
CREATE TABLE t (a INT) ENGINE=Aria;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
START TRANSACTION;
INSERT INTO t VALUES ('1');
INSERT INTO t1 VALUES ('1');
--error ER_ERROR_DURING_COMMIT
COMMIT;
DROP TABLE t;
DROP TABLE t1;
......@@ -1824,7 +1824,19 @@ int ha_commit_trans(THD *thd, bool all)
ordering is normally done. Commit ordering must be done here.
*/
if (run_wsrep_hooks)
error= wsrep_before_commit(thd, all);
{
// This commit involves more than one storage engine and requires
// two phases, but some engines don't support it.
// Issue a message to the client and roll back the transaction.
if (trans->no_2pc && rw_ha_count > 1)
{
my_message(ER_ERROR_DURING_COMMIT, "Transactional commit not supported "
"by involved engine(s)", MYF(0));
error= 1;
}
else
error= wsrep_before_commit(thd, all);
}
if (error)
{
ha_rollback_trans(thd, FALSE);
......
......@@ -461,7 +461,7 @@ void print_range_for_non_indexed_field(String *out, Field *field,
static void print_min_range_operator(String *out, const ha_rkey_function flag);
static void print_max_range_operator(String *out, const ha_rkey_function flag);
static bool is_field_an_unique_index(RANGE_OPT_PARAM *param, Field *field);
static bool is_field_an_unique_index(Field *field);
/*
SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
......@@ -7752,8 +7752,13 @@ SEL_TREE *Item_func_ne::get_func_mm_tree(RANGE_OPT_PARAM *param,
If this condition is a "col1<>...", where there is a UNIQUE KEY(col1),
do not construct a SEL_TREE from it. A condition that excludes just one
row in the table is not selective (unless there are only a few rows)
Note: this logic must be in sync with code in
check_group_min_max_predicates(). That function walks an Item* condition
and checks if the range optimizer would produce an equivalent range for
it.
*/
if (is_field_an_unique_index(param, field))
if (param->using_real_indexes && is_field_an_unique_index(field))
DBUG_RETURN(NULL);
DBUG_RETURN(get_ne_mm_tree(param, field, value, value));
}
......@@ -7865,7 +7870,7 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param,
- if there are a lot of constants, the overhead of building and
processing enormous range list is not worth it.
*/
if (is_field_an_unique_index(param, field))
if (param->using_real_indexes && is_field_an_unique_index(field))
DBUG_RETURN(0);
/* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
......@@ -8574,24 +8579,18 @@ SEL_TREE *Item_equal::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
In the future we could also add "almost unique" indexes where any value is
present only in a few rows (but necessarily exactly one row)
*/
static bool is_field_an_unique_index(RANGE_OPT_PARAM *param, Field *field)
static bool is_field_an_unique_index(Field *field)
{
DBUG_ENTER("is_field_an_unique_index");
// The check for using_real_indexes is there because of the heuristics
// this function is used for.
if (param->using_real_indexes)
key_map::Iterator it(field->key_start);
uint key_no;
while ((key_no= it++) != key_map::Iterator::BITMAP_END)
{
key_map::Iterator it(field->key_start);
uint key_no;
while ((key_no= it++) != key_map::Iterator::BITMAP_END)
KEY *key_info= &field->table->key_info[key_no];
if (key_info->user_defined_key_parts == 1 &&
(key_info->flags & HA_NOSAME))
{
KEY *key_info= &field->table->key_info[key_no];
if (key_info->user_defined_key_parts == 1 &&
(key_info->flags & HA_NOSAME))
{
DBUG_RETURN(true);
}
DBUG_RETURN(true);
}
}
DBUG_RETURN(false);
......@@ -13475,7 +13474,7 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
- (C between const_i and const_j)
- C IS NULL
- C IS NOT NULL
- C != const
- C != const (unless C is the primary key)
SA4. If Q has a GROUP BY clause, there are no other aggregate functions
except MIN and MAX. For queries with DISTINCT, aggregate functions
are allowed.
......@@ -14358,6 +14357,17 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
if (!simple_pred(pred, args, &inv))
DBUG_RETURN(FALSE);
/*
Follow the logic in Item_func_ne::get_func_mm_tree(): condition
in form "tbl.primary_key <> const" is not used to produce intervals.
If the condition doesn't have an equivalent interval, this means we
fail LooseScan's condition SA3. Return FALSE to indicate this.
*/
if (pred_type == Item_func::NE_FUNC &&
is_field_an_unique_index(min_max_arg_item->field))
DBUG_RETURN(FALSE);
if (args[0] && args[1]) // this is a binary function or BETWEEN
{
DBUG_ASSERT(pred->fixed_type_handler());
......
......@@ -428,18 +428,28 @@ trx_purge_free_segment(mtr_t &mtr, trx_rseg_t* rseg, fil_addr_t hdr_addr)
block->page.frame, &mtr))
{
block->fix();
const page_id_t id{block->page.id()};
mtr.commit();
/* NOTE: If the server is killed after the log that was produced
up to this point was written, and before the log from the mtr.commit()
in our caller is written, then the pages belonging to the
undo log will become unaccessible garbage.
This does not matters when using multiple innodb_undo_tablespaces;
This does not matter when using multiple innodb_undo_tablespaces;
innodb_undo_log_truncate=ON will be able to reclaim the space. */
log_free_check();
mtr.start();
block->page.lock.x_lock();
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
if (UNIV_UNLIKELY(block->page.id() != id))
{
block->unfix();
block->page.lock.x_unlock();
block= buf_page_get_gen(id, 0, RW_X_LATCH, nullptr, BUF_GET, &mtr, &err);
if (!block)
return err;
}
else
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
}
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
......
for master_1
for child2
for child3
MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int);
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"';
alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"';
select * from t0;
ERROR HY000: An infinite loop is detected when opening table test.t0
select * from t1;
ERROR HY000: An infinite loop is detected when opening table test.t0
select * from t2;
ERROR HY000: An infinite loop is detected when opening table test.t0
drop table t0, t1, t2;
for master_1
for child2
for child3
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
--echo
--echo MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever
--echo
--replace_regex /SOCKET ".*"/SOCKET "$MASTER_1_MYSOCK"/
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int);
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"';
alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"';
--error 12719
select * from t0;
--error 12719
select * from t1;
--error 12719
select * from t2;
drop table t0, t1, t2;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment