Skip to content

Commit

Permalink
Merge 10.4 into 10.5
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-m committed Aug 22, 2022
2 parents 1d90d68 + b68ae6d commit 3b656ac
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 47 deletions.
22 changes: 22 additions & 0 deletions mysql-test/main/timezone2.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
15 changes: 15 additions & 0 deletions mysql-test/main/timezone2.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
80 changes: 56 additions & 24 deletions sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3687,6 +3687,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");
Expand All @@ -3705,30 +3740,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);
Expand Down Expand Up @@ -3822,6 +3834,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");
Expand Down
2 changes: 2 additions & 0 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -6424,6 +6424,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):
Expand All @@ -6436,6 +6437,7 @@ class select_max_min_finder_subselect :public select_subselect
bool cmp_decimal();
bool cmp_str();
bool cmp_time();
bool cmp_native();
};

/* EXISTS subselect interface class */
Expand Down
5 changes: 3 additions & 2 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,9 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
bool blob)
{
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 (block->index
&& !btr_search_check_marked_free_index(block)) {
ut_ad(!blob);
ut_ad(page_is_leaf(block->frame));
}
Expand Down
42 changes: 34 additions & 8 deletions storage/innobase/btr/btr0sea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
Expand Down Expand Up @@ -1246,8 +1246,11 @@ btr_search_guess_on_hash(
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;
Expand Down Expand Up @@ -1290,18 +1293,25 @@ void btr_search_drop_page_hash_index(buf_block_t* block)
auto part = btr_search_sys.get_part(index_id,
block->page.id().space());

rw_lock_s_lock(&part->latch);

dict_index_t* index = block->index;
bool is_freed = index && index->freed();

if (is_freed) {
rw_lock_s_unlock(&part->latch);
rw_lock_x_lock(&part->latch);
} else {
rw_lock_s_lock(&part->latch);
if (index != block->index) {
rw_lock_x_unlock(&part->latch);
goto retry;
}
} else if (garbage_collect) {
rw_lock_s_unlock(&part->latch);
return;
}

assert_block_ahi_valid(block);


if (!index || !btr_search_enabled) {
if (is_freed) {
rw_lock_x_unlock(&part->latch);
Expand Down Expand Up @@ -1774,12 +1784,13 @@ btr_search_move_or_delete_hash_entries(
return;
}

rw_lock_s_lock(ahi_latch);

if (index->freed()) {
rw_lock_s_unlock(ahi_latch);
goto drop_exit;
}

rw_lock_s_lock(ahi_latch);

if (block->index) {
uint16_t n_fields = block->curr_n_fields;
uint16_t n_bytes = block->curr_n_bytes;
Expand Down Expand Up @@ -2375,5 +2386,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->frame);
auto part= btr_search_sys.get_part(index_id, block->page.id().space());

rw_lock_s_lock(&part->latch);

bool is_freed= block->index && block->index->freed();

rw_lock_s_unlock(&part->latch);

return is_freed;
}
#endif /* UNIV_DEBUG */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
#endif /* BTR_CUR_HASH_ADAPT */
11 changes: 3 additions & 8 deletions storage/innobase/buf/buf0buf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2601,18 +2601,14 @@ static void buf_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type)
/* Temporarily release our S-latch. */
rw_lock_s_unlock(&block->lock);
rw_lock_x_lock(&block->lock);
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);
rw_lock_x_unlock(&block->lock);
rw_lock_s_lock(&block->lock);
break;
case MTR_MEMO_PAGE_SX_FIX:
rw_lock_sx_unlock(&block->lock);
rw_lock_x_lock(&block->lock);
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);
rw_lock_x_unlock(&block->lock);
rw_lock_sx_lock(&block->lock);
break;
Expand Down Expand Up @@ -2659,8 +2655,7 @@ static buf_block_t* buf_page_mtr_lock(buf_block_t *block,

#ifdef BTR_CUR_HASH_ADAPT
{
dict_index_t *index= block->index;
if (index && index->freed())
if (block->index)
buf_defer_drop_ahi(block, fix_type);
}
#endif /* BTR_CUR_HASH_ADAPT */
Expand Down
18 changes: 13 additions & 5 deletions storage/innobase/include/btr0sea.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, 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
Expand Down Expand Up @@ -96,8 +96,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.
Expand Down Expand Up @@ -154,21 +157,26 @@ static inline bool btr_search_own_any(ulint mode);

/** @return whether this thread holds any of the search latches */
static inline bool btr_search_own_any();

/** @return if the index is marked as freed */
bool btr_search_check_marked_free_index(const buf_block_t *block);
#endif /* UNIV_DEBUG */

/** Unlock all search latches from shared mode. */
static inline void btr_search_s_unlock_all();

#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
Expand Down

0 comments on commit 3b656ac

Please sign in to comment.