mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge 10.5 into 10.6
This commit is contained in:
@ -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 #
|
||||
|
11
mysql-test/suite/galera/r/MDEV-30804.result
Normal file
11
mysql-test/suite/galera/r/MDEV-30804.result
Normal file
@ -0,0 +1,11 @@
|
||||
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;
|
7
mysql-test/suite/galera/t/MDEV-30804.cnf
Normal file
7
mysql-test/suite/galera/t/MDEV-30804.cnf
Normal file
@ -0,0 +1,7 @@
|
||||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
log-bin
|
||||
|
||||
[mysqld.2]
|
||||
log-bin
|
21
mysql-test/suite/galera/t/MDEV-30804.test
Normal file
21
mysql-test/suite/galera/t/MDEV-30804.test
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# 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 +
|
||||
|
@ -0,0 +1,21 @@
|
||||
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
|
@ -0,0 +1,29 @@
|
||||
--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
|
Reference in New Issue
Block a user