Skip to content

Commit fbb2b1f

Browse files
committed
Merge 10.5 into 10.6
2 parents d65a2b7 + 55c648a commit fbb2b1f

File tree

11 files changed

+177
-48
lines changed

11 files changed

+177
-48
lines changed

mysql-test/main/timezone2.result

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,25 @@ SET time_zone=DEFAULT;
654654
#
655655
# End of 10.4 tests
656656
#
657+
#
658+
# MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
659+
#
660+
SET time_zone='Europe/Moscow';
661+
CREATE TABLE t1 (a TIMESTAMP NULL);
662+
SET timestamp=1288477526;
663+
/* this is summer time, earlier */
664+
INSERT INTO t1 VALUES (NOW());
665+
SET timestamp=1288477526+3599;
666+
/* this is winter time, later */
667+
INSERT INTO t1 VALUES (NOW());
668+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
669+
a UNIX_TIMESTAMP(a)
670+
2010-10-31 02:25:26 1288477526
671+
2010-10-31 02:25:25 1288481125
672+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
673+
a UNIX_TIMESTAMP(a)
674+
2010-10-31 02:25:26 1288477526
675+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
676+
a UNIX_TIMESTAMP(a)
677+
2010-10-31 02:25:25 1288481125
678+
DROP TABLE t1;

mysql-test/main/timezone2.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,18 @@ SET time_zone=DEFAULT;
598598
--echo #
599599
--echo # End of 10.4 tests
600600
--echo #
601+
602+
--echo #
603+
--echo # MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
604+
--echo #
605+
606+
SET time_zone='Europe/Moscow';
607+
CREATE TABLE t1 (a TIMESTAMP NULL);
608+
SET timestamp=1288477526; /* this is summer time, earlier */
609+
INSERT INTO t1 VALUES (NOW());
610+
SET timestamp=1288477526+3599; /* this is winter time, later */
611+
INSERT INTO t1 VALUES (NOW());
612+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
613+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
614+
SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
615+
DROP TABLE t1;

plugin/type_inet/mysql-test/type_inet/type_inet6.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,3 +2213,19 @@ SELECT * FROM companies;
22132213
id name
22142214
DROP TABLE divisions;
22152215
DROP TABLE companies;
2216+
#
2217+
# MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
2218+
#
2219+
CREATE TABLE t1 (d INET6);
2220+
INSERT INTO t1 VALUES ('1::0'), ('12::0');
2221+
SELECT * FROM t1 ORDER BY d;
2222+
d
2223+
1::
2224+
12::
2225+
SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
2226+
d
2227+
1::
2228+
SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
2229+
d
2230+
12::
2231+
DROP TABLE t1;

plugin/type_inet/mysql-test/type_inet/type_inet6.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,3 +1630,14 @@ DELETE FROM companies WHERE id IN (SELECT company_id FROM divisions);
16301630
SELECT * FROM companies;
16311631
DROP TABLE divisions;
16321632
DROP TABLE companies;
1633+
1634+
--echo #
1635+
--echo # MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
1636+
--echo #
1637+
1638+
CREATE TABLE t1 (d INET6);
1639+
INSERT INTO t1 VALUES ('1::0'), ('12::0');
1640+
SELECT * FROM t1 ORDER BY d;
1641+
SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
1642+
SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
1643+
DROP TABLE t1;

sql/sql_class.cc

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,6 +3679,41 @@ void select_max_min_finder_subselect::cleanup()
36793679
}
36803680

36813681

3682+
void select_max_min_finder_subselect::set_op(const Type_handler *th)
3683+
{
3684+
if (th->is_val_native_ready())
3685+
{
3686+
op= &select_max_min_finder_subselect::cmp_native;
3687+
return;
3688+
}
3689+
3690+
switch (th->cmp_type()) {
3691+
case REAL_RESULT:
3692+
op= &select_max_min_finder_subselect::cmp_real;
3693+
break;
3694+
case INT_RESULT:
3695+
op= &select_max_min_finder_subselect::cmp_int;
3696+
break;
3697+
case STRING_RESULT:
3698+
op= &select_max_min_finder_subselect::cmp_str;
3699+
break;
3700+
case DECIMAL_RESULT:
3701+
op= &select_max_min_finder_subselect::cmp_decimal;
3702+
break;
3703+
case TIME_RESULT:
3704+
if (th->field_type() == MYSQL_TYPE_TIME)
3705+
op= &select_max_min_finder_subselect::cmp_time;
3706+
else
3707+
op= &select_max_min_finder_subselect::cmp_str;
3708+
break;
3709+
case ROW_RESULT:
3710+
// This case should never be chosen
3711+
DBUG_ASSERT(0);
3712+
op= 0;
3713+
}
3714+
}
3715+
3716+
36823717
int select_max_min_finder_subselect::send_data(List<Item> &items)
36833718
{
36843719
DBUG_ENTER("select_max_min_finder_subselect::send_data");
@@ -3697,30 +3732,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
36973732
if (!cache)
36983733
{
36993734
cache= val_item->get_cache(thd);
3700-
switch (val_item->cmp_type()) {
3701-
case REAL_RESULT:
3702-
op= &select_max_min_finder_subselect::cmp_real;
3703-
break;
3704-
case INT_RESULT:
3705-
op= &select_max_min_finder_subselect::cmp_int;
3706-
break;
3707-
case STRING_RESULT:
3708-
op= &select_max_min_finder_subselect::cmp_str;
3709-
break;
3710-
case DECIMAL_RESULT:
3711-
op= &select_max_min_finder_subselect::cmp_decimal;
3712-
break;
3713-
case TIME_RESULT:
3714-
if (val_item->field_type() == MYSQL_TYPE_TIME)
3715-
op= &select_max_min_finder_subselect::cmp_time;
3716-
else
3717-
op= &select_max_min_finder_subselect::cmp_str;
3718-
break;
3719-
case ROW_RESULT:
3720-
// This case should never be chosen
3721-
DBUG_ASSERT(0);
3722-
op= 0;
3723-
}
3735+
set_op(val_item->type_handler());
37243736
}
37253737
cache->store(val_item);
37263738
it->store(0, cache);
@@ -3814,6 +3826,26 @@ bool select_max_min_finder_subselect::cmp_str()
38143826
return (sortcmp(val1, val2, cache->collation.collation) < 0);
38153827
}
38163828

3829+
3830+
bool select_max_min_finder_subselect::cmp_native()
3831+
{
3832+
NativeBuffer<STRING_BUFFER_USUAL_SIZE> cvalue, mvalue;
3833+
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
3834+
bool cvalue_is_null= cache->val_native(thd, &cvalue);
3835+
bool mvalue_is_null= maxmin->val_native(thd, &mvalue);
3836+
3837+
/* Ignore NULLs for ANY and keep them for ALL subqueries */
3838+
if (cvalue_is_null)
3839+
return (is_all && !mvalue_is_null) || (!is_all && mvalue_is_null);
3840+
if (mvalue_is_null)
3841+
return !is_all;
3842+
3843+
const Type_handler *th= cache->type_handler();
3844+
return fmax ? th->cmp_native(cvalue, mvalue) > 0 :
3845+
th->cmp_native(cvalue, mvalue) < 0;
3846+
}
3847+
3848+
38173849
int select_exists_subselect::send_data(List<Item> &items)
38183850
{
38193851
DBUG_ENTER("select_exists_subselect::send_data");

sql/sql_class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6721,6 +6721,7 @@ class select_max_min_finder_subselect :public select_subselect
67216721
bool (select_max_min_finder_subselect::*op)();
67226722
bool fmax;
67236723
bool is_all;
6724+
void set_op(const Type_handler *ha);
67246725
public:
67256726
select_max_min_finder_subselect(THD *thd_arg, Item_subselect *item_arg,
67266727
bool mx, bool all):
@@ -6733,6 +6734,7 @@ class select_max_min_finder_subselect :public select_subselect
67336734
bool cmp_decimal();
67346735
bool cmp_str();
67356736
bool cmp_time();
6737+
bool cmp_native();
67366738
};
67376739

67386740
/* EXISTS subselect interface class */

storage/innobase/btr/btr0btr.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,8 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
584584
bool blob, bool space_latched)
585585
{
586586
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
587-
#ifdef BTR_CUR_HASH_ADAPT
588-
if (block->index && !block->index->freed())
587+
#if defined BTR_CUR_HASH_ADAPT && defined UNIV_DEBUG
588+
if (btr_search_check_marked_free_index(block))
589589
{
590590
ut_ad(!blob);
591591
ut_ad(page_is_leaf(block->page.frame));

storage/innobase/btr/btr0cur.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ btr_cur_latch_leaves(
283283
block->page.fix();
284284
block->page.lock.x_lock();
285285
#ifdef BTR_CUR_HASH_ADAPT
286-
ut_ad(!block->index || !block->index->freed());
286+
ut_ad(!btr_search_check_marked_free_index(block));
287287
#endif
288288

289289
if (UNIV_LIKELY_NULL(rtr_info)) {
@@ -7024,7 +7024,7 @@ btr_store_big_rec_extern_fields(
70247024
rec_block->page.fix();
70257025
rec_block->page.lock.x_lock();
70267026
#ifdef BTR_CUR_HASH_ADAPT
7027-
ut_ad(!rec_block->index || !rec_block->index->freed());
7027+
ut_ad(!btr_search_check_marked_free_index(rec_block));
70287028
#endif
70297029

70307030
uint32_t hint_prev = prev_page_no;
@@ -7401,7 +7401,7 @@ btr_free_externally_stored_field(
74017401
block->fix();
74027402
block->page.lock.x_lock();
74037403
#ifdef BTR_CUR_HASH_ADAPT
7404-
ut_ad(!block->index || !block->index->freed());
7404+
ut_ad(!btr_search_check_marked_free_index(block));
74057405
#endif
74067406

74077407
const page_t* page = buf_block_get_frame(ext_block);

storage/innobase/btr/btr0sea.cc

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,8 +1279,11 @@ btr_search_guess_on_hash(
12791279
index page for which we know that
12801280
block->buf_fix_count == 0 or it is an index page which
12811281
has already been removed from the buf_pool.page_hash
1282-
i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
1283-
void btr_search_drop_page_hash_index(buf_block_t* block)
1282+
i.e.: it is in state BUF_BLOCK_REMOVE_HASH
1283+
@param[in] garbage_collect drop ahi only if the index is marked
1284+
as freed */
1285+
void btr_search_drop_page_hash_index(buf_block_t* block,
1286+
bool garbage_collect)
12841287
{
12851288
ulint n_fields;
12861289
ulint n_bytes;
@@ -1316,13 +1319,21 @@ void btr_search_drop_page_hash_index(buf_block_t* block)
13161319
auto part = btr_search_sys.get_part(index_id,
13171320
block->page.id().space());
13181321

1322+
part->latch.rd_lock(SRW_LOCK_CALL);
1323+
13191324
dict_index_t* index = block->index;
13201325
bool is_freed = index && index->freed();
13211326

13221327
if (is_freed) {
1328+
part->latch.rd_unlock();
13231329
part->latch.wr_lock(SRW_LOCK_CALL);
1324-
} else {
1325-
part->latch.rd_lock(SRW_LOCK_CALL);
1330+
if (index != block->index) {
1331+
part->latch.wr_unlock();
1332+
goto retry;
1333+
}
1334+
} else if (garbage_collect) {
1335+
part->latch.rd_unlock();
1336+
return;
13261337
}
13271338

13281339
assert_block_ahi_valid(block);
@@ -1797,12 +1808,13 @@ btr_search_move_or_delete_hash_entries(
17971808
return;
17981809
}
17991810

1811+
ahi_latch->rd_lock(SRW_LOCK_CALL);
1812+
18001813
if (index->freed()) {
1814+
ahi_latch->rd_unlock();
18011815
goto drop_exit;
18021816
}
18031817

1804-
ahi_latch->rd_lock(SRW_LOCK_CALL);
1805-
18061818
if (block->index) {
18071819
uint16_t n_fields = block->curr_n_fields;
18081820
uint16_t n_bytes = block->curr_n_bytes;
@@ -2394,5 +2406,20 @@ btr_search_validate()
23942406
return(true);
23952407
}
23962408

2409+
#ifdef UNIV_DEBUG
2410+
bool btr_search_check_marked_free_index(const buf_block_t *block)
2411+
{
2412+
const index_id_t index_id= btr_page_get_index_id(block->page.frame);
2413+
auto part= btr_search_sys.get_part(index_id, block->page.id().space());
2414+
2415+
part->latch.rd_lock(SRW_LOCK_CALL);
2416+
2417+
bool is_freed= block->index && block->index->freed();
2418+
2419+
part->latch.rd_unlock();
2420+
2421+
return is_freed;
2422+
}
2423+
#endif /* UNIV_DEBUG */
23972424
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
23982425
#endif /* BTR_CUR_HASH_ADAPT */

storage/innobase/buf/buf0buf.cc

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2761,11 +2761,7 @@ buf_page_get_low(
27612761
&& state < buf_page_t::WRITE_FIX));
27622762

27632763
#ifdef BTR_CUR_HASH_ADAPT
2764-
if (dict_index_t* index = block->index) {
2765-
if (index->freed()) {
2766-
btr_search_drop_page_hash_index(block);
2767-
}
2768-
}
2764+
btr_search_drop_page_hash_index(block, true);
27692765
#endif /* BTR_CUR_HASH_ADAPT */
27702766

27712767
dberr_t e;
@@ -2823,10 +2819,8 @@ buf_page_get_low(
28232819
}
28242820
get_latch_valid:
28252821
#ifdef BTR_CUR_HASH_ADAPT
2826-
if (dict_index_t* index = block->index) {
2827-
if (index->freed()) {
2828-
mtr_t::defer_drop_ahi(block, fix_type);
2829-
}
2822+
if (block->index) {
2823+
mtr_t::defer_drop_ahi(block, fix_type);
28302824
}
28312825
#endif /* BTR_CUR_HASH_ADAPT */
28322826
mtr->memo_push(block, fix_type);

0 commit comments

Comments
 (0)