Merge 10.5 into 10.6
This commit is contained in:
commit
fbb2b1f55f
@ -654,3 +654,25 @@ SET time_zone=DEFAULT;
|
||||
#
|
||||
# End of 10.4 tests
|
||||
#
|
||||
#
|
||||
# MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
|
||||
#
|
||||
SET time_zone='Europe/Moscow';
|
||||
CREATE TABLE t1 (a TIMESTAMP NULL);
|
||||
SET timestamp=1288477526;
|
||||
/* this is summer time, earlier */
|
||||
INSERT INTO t1 VALUES (NOW());
|
||||
SET timestamp=1288477526+3599;
|
||||
/* this is winter time, later */
|
||||
INSERT INTO t1 VALUES (NOW());
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
|
||||
a UNIX_TIMESTAMP(a)
|
||||
2010-10-31 02:25:26 1288477526
|
||||
2010-10-31 02:25:25 1288481125
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
|
||||
a UNIX_TIMESTAMP(a)
|
||||
2010-10-31 02:25:26 1288477526
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
|
||||
a UNIX_TIMESTAMP(a)
|
||||
2010-10-31 02:25:25 1288481125
|
||||
DROP TABLE t1;
|
||||
|
@ -598,3 +598,18 @@ SET time_zone=DEFAULT;
|
||||
--echo #
|
||||
--echo # End of 10.4 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
|
||||
--echo #
|
||||
|
||||
SET time_zone='Europe/Moscow';
|
||||
CREATE TABLE t1 (a TIMESTAMP NULL);
|
||||
SET timestamp=1288477526; /* this is summer time, earlier */
|
||||
INSERT INTO t1 VALUES (NOW());
|
||||
SET timestamp=1288477526+3599; /* this is winter time, later */
|
||||
INSERT INTO t1 VALUES (NOW());
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
|
||||
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
|
||||
DROP TABLE t1;
|
||||
|
@ -2213,3 +2213,19 @@ SELECT * FROM companies;
|
||||
id name
|
||||
DROP TABLE divisions;
|
||||
DROP TABLE companies;
|
||||
#
|
||||
# MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
|
||||
#
|
||||
CREATE TABLE t1 (d INET6);
|
||||
INSERT INTO t1 VALUES ('1::0'), ('12::0');
|
||||
SELECT * FROM t1 ORDER BY d;
|
||||
d
|
||||
1::
|
||||
12::
|
||||
SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
|
||||
d
|
||||
1::
|
||||
SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
|
||||
d
|
||||
12::
|
||||
DROP TABLE t1;
|
||||
|
@ -1630,3 +1630,14 @@ DELETE FROM companies WHERE id IN (SELECT company_id FROM divisions);
|
||||
SELECT * FROM companies;
|
||||
DROP TABLE divisions;
|
||||
DROP TABLE companies;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (d INET6);
|
||||
INSERT INTO t1 VALUES ('1::0'), ('12::0');
|
||||
SELECT * FROM t1 ORDER BY d;
|
||||
SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
|
||||
SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
|
||||
DROP TABLE t1;
|
||||
|
@ -3679,6 +3679,41 @@ void select_max_min_finder_subselect::cleanup()
|
||||
}
|
||||
|
||||
|
||||
void select_max_min_finder_subselect::set_op(const Type_handler *th)
|
||||
{
|
||||
if (th->is_val_native_ready())
|
||||
{
|
||||
op= &select_max_min_finder_subselect::cmp_native;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (th->cmp_type()) {
|
||||
case REAL_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_real;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_int;
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_str;
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_decimal;
|
||||
break;
|
||||
case TIME_RESULT:
|
||||
if (th->field_type() == MYSQL_TYPE_TIME)
|
||||
op= &select_max_min_finder_subselect::cmp_time;
|
||||
else
|
||||
op= &select_max_min_finder_subselect::cmp_str;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
// This case should never be chosen
|
||||
DBUG_ASSERT(0);
|
||||
op= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int select_max_min_finder_subselect::send_data(List<Item> &items)
|
||||
{
|
||||
DBUG_ENTER("select_max_min_finder_subselect::send_data");
|
||||
@ -3697,30 +3732,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
|
||||
if (!cache)
|
||||
{
|
||||
cache= val_item->get_cache(thd);
|
||||
switch (val_item->cmp_type()) {
|
||||
case REAL_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_real;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_int;
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_str;
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
op= &select_max_min_finder_subselect::cmp_decimal;
|
||||
break;
|
||||
case TIME_RESULT:
|
||||
if (val_item->field_type() == MYSQL_TYPE_TIME)
|
||||
op= &select_max_min_finder_subselect::cmp_time;
|
||||
else
|
||||
op= &select_max_min_finder_subselect::cmp_str;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
// This case should never be chosen
|
||||
DBUG_ASSERT(0);
|
||||
op= 0;
|
||||
}
|
||||
set_op(val_item->type_handler());
|
||||
}
|
||||
cache->store(val_item);
|
||||
it->store(0, cache);
|
||||
@ -3814,6 +3826,26 @@ bool select_max_min_finder_subselect::cmp_str()
|
||||
return (sortcmp(val1, val2, cache->collation.collation) < 0);
|
||||
}
|
||||
|
||||
|
||||
bool select_max_min_finder_subselect::cmp_native()
|
||||
{
|
||||
NativeBuffer<STRING_BUFFER_USUAL_SIZE> cvalue, mvalue;
|
||||
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
|
||||
bool cvalue_is_null= cache->val_native(thd, &cvalue);
|
||||
bool mvalue_is_null= maxmin->val_native(thd, &mvalue);
|
||||
|
||||
/* Ignore NULLs for ANY and keep them for ALL subqueries */
|
||||
if (cvalue_is_null)
|
||||
return (is_all && !mvalue_is_null) || (!is_all && mvalue_is_null);
|
||||
if (mvalue_is_null)
|
||||
return !is_all;
|
||||
|
||||
const Type_handler *th= cache->type_handler();
|
||||
return fmax ? th->cmp_native(cvalue, mvalue) > 0 :
|
||||
th->cmp_native(cvalue, mvalue) < 0;
|
||||
}
|
||||
|
||||
|
||||
int select_exists_subselect::send_data(List<Item> &items)
|
||||
{
|
||||
DBUG_ENTER("select_exists_subselect::send_data");
|
||||
|
@ -6721,6 +6721,7 @@ class select_max_min_finder_subselect :public select_subselect
|
||||
bool (select_max_min_finder_subselect::*op)();
|
||||
bool fmax;
|
||||
bool is_all;
|
||||
void set_op(const Type_handler *ha);
|
||||
public:
|
||||
select_max_min_finder_subselect(THD *thd_arg, Item_subselect *item_arg,
|
||||
bool mx, bool all):
|
||||
@ -6733,6 +6734,7 @@ public:
|
||||
bool cmp_decimal();
|
||||
bool cmp_str();
|
||||
bool cmp_time();
|
||||
bool cmp_native();
|
||||
};
|
||||
|
||||
/* EXISTS subselect interface class */
|
||||
|
@ -584,8 +584,8 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
|
||||
bool blob, bool space_latched)
|
||||
{
|
||||
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (block->index && !block->index->freed())
|
||||
#if defined BTR_CUR_HASH_ADAPT && defined UNIV_DEBUG
|
||||
if (btr_search_check_marked_free_index(block))
|
||||
{
|
||||
ut_ad(!blob);
|
||||
ut_ad(page_is_leaf(block->page.frame));
|
||||
|
@ -283,7 +283,7 @@ latch_block:
|
||||
block->page.fix();
|
||||
block->page.lock.x_lock();
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!block->index || !block->index->freed());
|
||||
ut_ad(!btr_search_check_marked_free_index(block));
|
||||
#endif
|
||||
|
||||
if (UNIV_LIKELY_NULL(rtr_info)) {
|
||||
@ -7024,7 +7024,7 @@ btr_store_big_rec_extern_fields(
|
||||
rec_block->page.fix();
|
||||
rec_block->page.lock.x_lock();
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!rec_block->index || !rec_block->index->freed());
|
||||
ut_ad(!btr_search_check_marked_free_index(rec_block));
|
||||
#endif
|
||||
|
||||
uint32_t hint_prev = prev_page_no;
|
||||
@ -7401,7 +7401,7 @@ skip_free:
|
||||
block->fix();
|
||||
block->page.lock.x_lock();
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!block->index || !block->index->freed());
|
||||
ut_ad(!btr_search_check_marked_free_index(block));
|
||||
#endif
|
||||
|
||||
const page_t* page = buf_block_get_frame(ext_block);
|
||||
|
@ -1279,8 +1279,11 @@ fail_and_release_page:
|
||||
index page for which we know that
|
||||
block->buf_fix_count == 0 or it is an index page which
|
||||
has already been removed from the buf_pool.page_hash
|
||||
i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
|
||||
void btr_search_drop_page_hash_index(buf_block_t* block)
|
||||
i.e.: it is in state BUF_BLOCK_REMOVE_HASH
|
||||
@param[in] garbage_collect drop ahi only if the index is marked
|
||||
as freed */
|
||||
void btr_search_drop_page_hash_index(buf_block_t* block,
|
||||
bool garbage_collect)
|
||||
{
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
@ -1316,13 +1319,21 @@ retry:
|
||||
auto part = btr_search_sys.get_part(index_id,
|
||||
block->page.id().space());
|
||||
|
||||
part->latch.rd_lock(SRW_LOCK_CALL);
|
||||
|
||||
dict_index_t* index = block->index;
|
||||
bool is_freed = index && index->freed();
|
||||
|
||||
if (is_freed) {
|
||||
part->latch.rd_unlock();
|
||||
part->latch.wr_lock(SRW_LOCK_CALL);
|
||||
} else {
|
||||
part->latch.rd_lock(SRW_LOCK_CALL);
|
||||
if (index != block->index) {
|
||||
part->latch.wr_unlock();
|
||||
goto retry;
|
||||
}
|
||||
} else if (garbage_collect) {
|
||||
part->latch.rd_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
assert_block_ahi_valid(block);
|
||||
@ -1797,12 +1808,13 @@ drop_exit:
|
||||
return;
|
||||
}
|
||||
|
||||
ahi_latch->rd_lock(SRW_LOCK_CALL);
|
||||
|
||||
if (index->freed()) {
|
||||
ahi_latch->rd_unlock();
|
||||
goto drop_exit;
|
||||
}
|
||||
|
||||
ahi_latch->rd_lock(SRW_LOCK_CALL);
|
||||
|
||||
if (block->index) {
|
||||
uint16_t n_fields = block->curr_n_fields;
|
||||
uint16_t n_bytes = block->curr_n_bytes;
|
||||
@ -2394,5 +2406,20 @@ btr_search_validate()
|
||||
return(true);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
bool btr_search_check_marked_free_index(const buf_block_t *block)
|
||||
{
|
||||
const index_id_t index_id= btr_page_get_index_id(block->page.frame);
|
||||
auto part= btr_search_sys.get_part(index_id, block->page.id().space());
|
||||
|
||||
part->latch.rd_lock(SRW_LOCK_CALL);
|
||||
|
||||
bool is_freed= block->index && block->index->freed();
|
||||
|
||||
part->latch.rd_unlock();
|
||||
|
||||
return is_freed;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
@ -2761,11 +2761,7 @@ re_evict:
|
||||
&& state < buf_page_t::WRITE_FIX));
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (dict_index_t* index = block->index) {
|
||||
if (index->freed()) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
}
|
||||
}
|
||||
btr_search_drop_page_hash_index(block, true);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
dberr_t e;
|
||||
@ -2823,10 +2819,8 @@ get_latch:
|
||||
}
|
||||
get_latch_valid:
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (dict_index_t* index = block->index) {
|
||||
if (index->freed()) {
|
||||
mtr_t::defer_drop_ahi(block, fix_type);
|
||||
}
|
||||
if (block->index) {
|
||||
mtr_t::defer_drop_ahi(block, fix_type);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr->memo_push(block, fix_type);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -100,8 +100,11 @@ btr_search_move_or_delete_hash_entries(
|
||||
index page for which we know that
|
||||
block->buf_fix_count == 0 or it is an index page which
|
||||
has already been removed from the buf_pool.page_hash
|
||||
i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
|
||||
void btr_search_drop_page_hash_index(buf_block_t* block);
|
||||
i.e.: it is in state BUF_BLOCK_REMOVE_HASH
|
||||
@param[in] garbage_collect drop ahi only if the index is marked
|
||||
as freed */
|
||||
void btr_search_drop_page_hash_index(buf_block_t* block,
|
||||
bool garbage_collect= false);
|
||||
|
||||
/** Drop possible adaptive hash index entries when a page is evicted
|
||||
from the buffer pool or freed in a file, or the index is being dropped.
|
||||
@ -146,16 +149,23 @@ static inline void btr_search_s_lock_all();
|
||||
/** Unlock all search latches from shared mode. */
|
||||
static inline void btr_search_s_unlock_all();
|
||||
|
||||
# ifdef UNIV_DEBUG
|
||||
/** @return if the index is marked as freed */
|
||||
bool btr_search_check_marked_free_index(const buf_block_t *block);
|
||||
# endif /* UNIV_DEBUG */
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define btr_search_sys_create()
|
||||
# define btr_search_sys_free()
|
||||
# define btr_search_drop_page_hash_index(block)
|
||||
# define btr_search_drop_page_hash_index(block, garbage_collect)
|
||||
# define btr_search_s_lock_all(index)
|
||||
# define btr_search_s_unlock_all(index)
|
||||
# define btr_search_info_update(index, cursor)
|
||||
# define btr_search_move_or_delete_hash_entries(new_block, block)
|
||||
# define btr_search_update_hash_on_insert(cursor, ahi_latch)
|
||||
# define btr_search_update_hash_on_delete(cursor)
|
||||
# ifdef UNIV_DEBUG
|
||||
# define btr_search_check_marked_free_index(block)
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
|
Loading…
x
Reference in New Issue
Block a user