Skip to content

Commit 31deef0

Browse files
committed
MDEV-18681 Server crashes in embedding_sjm
Do not do substitution for best equal field in HAVING conditions. It's not needed.
1 parent 793f27a commit 31deef0

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

mysql-test/main/having.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,3 +847,21 @@ t r
847847
DROP TABLE t1;
848848
DROP FUNCTION next_seq_value;
849849
DROP TABLE series;
850+
# End of 10.3 tests
851+
#
852+
# MDEV-18681: AND formula in HAVING with several occurances
853+
# of the same field f in different conjuncts + f=constant
854+
#
855+
CREATE TABLE t1 (pk int, f varchar(1));
856+
INSERT INTO t1 VALUES (2,'x'), (7,'y');
857+
CREATE TABLE t2 (pk int);
858+
INSERT INTO t2 VALUES (2), (3);
859+
SELECT t.f
860+
FROM (SELECT t1.* FROM (t1 JOIN t2 ON (t2.pk = t1.pk))) t
861+
HAVING t.f != 112 AND t.f = 'x' AND t.f != 'a';
862+
f
863+
x
864+
Warnings:
865+
Warning 1292 Truncated incorrect DOUBLE value: 'x'
866+
DROP TABLE t1,t2;
867+
# End of 10.4 tests

mysql-test/main/having.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,3 +890,23 @@ SELECT t, next_seq_value() r FROM t1 FORCE INDEX(t)
890890
DROP TABLE t1;
891891
DROP FUNCTION next_seq_value;
892892
DROP TABLE series;
893+
894+
--echo # End of 10.3 tests
895+
896+
--echo #
897+
--echo # MDEV-18681: AND formula in HAVING with several occurances
898+
--echo # of the same field f in different conjuncts + f=constant
899+
--echo #
900+
901+
CREATE TABLE t1 (pk int, f varchar(1));
902+
INSERT INTO t1 VALUES (2,'x'), (7,'y');
903+
CREATE TABLE t2 (pk int);
904+
INSERT INTO t2 VALUES (2), (3);
905+
906+
SELECT t.f
907+
FROM (SELECT t1.* FROM (t1 JOIN t2 ON (t2.pk = t1.pk))) t
908+
HAVING t.f != 112 AND t.f = 'x' AND t.f != 'a';
909+
910+
DROP TABLE t1,t2;
911+
912+
--echo # End of 10.4 tests

sql/sql_select.cc

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ static COND *build_equal_items(JOIN *join, COND *cond,
159159
static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
160160
COND *cond,
161161
COND_EQUAL *cond_equal,
162-
void *table_join_idx);
162+
void *table_join_idx,
163+
bool do_substitution);
163164
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
164165
COND *conds, bool top, bool in_sj);
165166
static bool check_interleaving_with_nj(JOIN_TAB *next);
@@ -2304,7 +2305,7 @@ int JOIN::optimize_stage2()
23042305
if (conds)
23052306
{
23062307
conds= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, conds,
2307-
cond_equal, map2table);
2308+
cond_equal, map2table, true);
23082309
if (unlikely(thd->is_error()))
23092310
{
23102311
error= 1;
@@ -2320,7 +2321,7 @@ int JOIN::optimize_stage2()
23202321
if (having)
23212322
{
23222323
having= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, having,
2323-
having_equal, map2table);
2324+
having_equal, map2table, false);
23242325
if (thd->is_error())
23252326
{
23262327
error= 1;
@@ -2347,7 +2348,7 @@ int JOIN::optimize_stage2()
23472348
*tab->on_expr_ref= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB,
23482349
*tab->on_expr_ref,
23492350
tab->cond_equal,
2350-
map2table);
2351+
map2table, true);
23512352
if (unlikely(thd->is_error()))
23522353
{
23532354
error= 1;
@@ -2377,7 +2378,7 @@ int JOIN::optimize_stage2()
23772378
while (equals)
23782379
{
23792380
ref_item= substitute_for_best_equal_field(thd, tab, ref_item,
2380-
equals, map2table);
2381+
equals, map2table, true);
23812382
if (unlikely(thd->is_fatal_error))
23822383
DBUG_RETURN(1);
23832384

@@ -15418,7 +15419,8 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
1541815419
static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
1541915420
COND *cond,
1542015421
COND_EQUAL *cond_equal,
15421-
void *table_join_idx)
15422+
void *table_join_idx,
15423+
bool do_substitution)
1542215424
{
1542315425
Item_equal *item_equal;
1542415426
COND *org_cond= cond; // Return this in case of fatal error
@@ -15447,7 +15449,8 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
1544715449
{
1544815450
Item *new_item= substitute_for_best_equal_field(thd, context_tab,
1544915451
item, cond_equal,
15450-
table_join_idx);
15452+
table_join_idx,
15453+
do_substitution);
1545115454
/*
1545215455
This works OK with PS/SP re-execution as changes are made to
1545315456
the arguments of AND/OR items only
@@ -15529,7 +15532,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
1552915532
cond= eliminate_item_equal(thd, 0, cond_equal, item_equal);
1553015533
return cond ? cond : org_cond;
1553115534
}
15532-
else
15535+
else if (do_substitution)
1553315536
{
1553415537
while (cond_equal)
1553515538
{

0 commit comments

Comments
 (0)