Skip to content

Commit c4499a0

Browse files
committed
Merge branch '5.5' into 10.0
2 parents d6dbe8e + 5cfe523 commit c4499a0

15 files changed

+228
-24
lines changed

mysql-test/r/sp-innodb.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,37 @@ SET @@innodb_lock_wait_timeout= @innodb_lock_wait_timeout_saved;
130130
#
131131
# BUG 16041903: End of test case
132132
#
133+
#
134+
# MDEV-15035: SP using query with outer join and a parameter
135+
# in ON expression
136+
#
137+
CREATE TABLE t1 (
138+
id int NOT NULL,
139+
PRIMARY KEY (id)
140+
) ENGINE=InnoDB;
141+
INSERT INTO t1 VALUES (1), (2);
142+
CREATE TABLE t2 (
143+
id int NOT NULL,
144+
id_foo int NOT NULL,
145+
PRIMARY KEY (id)
146+
) ENGINE=InnoDB;
147+
INSERT INTO t2 VALUES (1, 1);
148+
DROP PROCEDURE IF EXISTS test_proc;
149+
CREATE PROCEDURE test_proc(IN param int)
150+
LANGUAGE SQL
151+
READS SQL DATA
152+
BEGIN
153+
SELECT DISTINCT f.id
154+
FROM t1 f
155+
LEFT OUTER JOIN t2 b ON b.id_foo = f.id
156+
WHERE (param <> 0 OR b.id IS NOT NULL);
157+
END|
158+
CALL test_proc(0);
159+
id
160+
1
161+
CALL test_proc(1);
162+
id
163+
1
164+
2
165+
DROP PROCEDURE IF EXISTS test_proc;
166+
DROP TABLE t1, t2;

mysql-test/r/subselect_sj.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,4 +3155,30 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
31553155
Warnings:
31563156
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
31573157
DROP TABLE t1,t2,t3,t4;
3158+
#
3159+
# MDEV-13699: Assertion `!new_field->field_name.str ||
3160+
# strlen(new_field->field_name.str) == new_field->field_name.length'
3161+
# failed in create_tmp_table on 2nd execution of PS with semijoin
3162+
#
3163+
CREATE TABLE t1 (a INT);
3164+
INSERT INTO t1 VALUES (1),(2);
3165+
CREATE TABLE t2 (b INT);
3166+
INSERT INTO t2 VALUES (3),(4);
3167+
CREATE TABLE t3 (c INT);
3168+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
3169+
INSERT INTO t3 VALUES (5),(6);
3170+
PREPARE stmt FROM
3171+
"SELECT * FROM t1
3172+
WHERE EXISTS (
3173+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
3174+
)";
3175+
EXECUTE stmt;
3176+
a
3177+
EXECUTE stmt;
3178+
a
3179+
EXECUTE stmt;
3180+
a
3181+
drop view v3;
3182+
drop table t1,t2,t3;
3183+
# End of 5.5 test
31583184
set optimizer_switch=@subselect_sj_tmp;

mysql-test/r/subselect_sj_jcl6.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,6 +3169,32 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
31693169
Warnings:
31703170
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
31713171
DROP TABLE t1,t2,t3,t4;
3172+
#
3173+
# MDEV-13699: Assertion `!new_field->field_name.str ||
3174+
# strlen(new_field->field_name.str) == new_field->field_name.length'
3175+
# failed in create_tmp_table on 2nd execution of PS with semijoin
3176+
#
3177+
CREATE TABLE t1 (a INT);
3178+
INSERT INTO t1 VALUES (1),(2);
3179+
CREATE TABLE t2 (b INT);
3180+
INSERT INTO t2 VALUES (3),(4);
3181+
CREATE TABLE t3 (c INT);
3182+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
3183+
INSERT INTO t3 VALUES (5),(6);
3184+
PREPARE stmt FROM
3185+
"SELECT * FROM t1
3186+
WHERE EXISTS (
3187+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
3188+
)";
3189+
EXECUTE stmt;
3190+
a
3191+
EXECUTE stmt;
3192+
a
3193+
EXECUTE stmt;
3194+
a
3195+
drop view v3;
3196+
drop table t1,t2,t3;
3197+
# End of 5.5 test
31723198
set optimizer_switch=@subselect_sj_tmp;
31733199
#
31743200
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off

mysql-test/t/sp-innodb.test

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,5 +158,47 @@ SET @@innodb_lock_wait_timeout= @innodb_lock_wait_timeout_saved;
158158
--echo # BUG 16041903: End of test case
159159
--echo #
160160

161+
--echo #
162+
--echo # MDEV-15035: SP using query with outer join and a parameter
163+
--echo # in ON expression
164+
--echo #
165+
166+
CREATE TABLE t1 (
167+
id int NOT NULL,
168+
PRIMARY KEY (id)
169+
) ENGINE=InnoDB;
170+
171+
INSERT INTO t1 VALUES (1), (2);
172+
173+
CREATE TABLE t2 (
174+
id int NOT NULL,
175+
id_foo int NOT NULL,
176+
PRIMARY KEY (id)
177+
) ENGINE=InnoDB;
178+
179+
INSERT INTO t2 VALUES (1, 1);
180+
181+
--disable_warnings
182+
DROP PROCEDURE IF EXISTS test_proc;
183+
--enable_warnings
184+
185+
DELIMITER |;
186+
CREATE PROCEDURE test_proc(IN param int)
187+
LANGUAGE SQL
188+
READS SQL DATA
189+
BEGIN
190+
SELECT DISTINCT f.id
191+
FROM t1 f
192+
LEFT OUTER JOIN t2 b ON b.id_foo = f.id
193+
WHERE (param <> 0 OR b.id IS NOT NULL);
194+
END|
195+
DELIMITER ;|
196+
197+
CALL test_proc(0);
198+
CALL test_proc(1);
199+
200+
DROP PROCEDURE IF EXISTS test_proc;
201+
DROP TABLE t1, t2;
202+
161203
# Wait till we reached the initial number of concurrent sessions
162204
--source include/wait_until_count_sessions.inc

mysql-test/t/subselect_sj.test

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,5 +2845,35 @@ eval EXPLAIN EXTENDED $q2;
28452845

28462846
DROP TABLE t1,t2,t3,t4;
28472847

2848+
--echo #
2849+
--echo # MDEV-13699: Assertion `!new_field->field_name.str ||
2850+
--echo # strlen(new_field->field_name.str) == new_field->field_name.length'
2851+
--echo # failed in create_tmp_table on 2nd execution of PS with semijoin
2852+
--echo #
2853+
2854+
CREATE TABLE t1 (a INT);
2855+
INSERT INTO t1 VALUES (1),(2);
2856+
2857+
CREATE TABLE t2 (b INT);
2858+
INSERT INTO t2 VALUES (3),(4);
2859+
2860+
CREATE TABLE t3 (c INT);
2861+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
2862+
INSERT INTO t3 VALUES (5),(6);
2863+
2864+
PREPARE stmt FROM
2865+
"SELECT * FROM t1
2866+
WHERE EXISTS (
2867+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
2868+
)";
2869+
EXECUTE stmt;
2870+
EXECUTE stmt;
2871+
EXECUTE stmt;
2872+
2873+
drop view v3;
2874+
drop table t1,t2,t3;
2875+
2876+
--echo # End of 5.5 test
2877+
28482878
# The following command must be the last one the file
28492879
set optimizer_switch=@subselect_sj_tmp;

sql-common/client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
15031503
else
15041504
{
15051505
cur->data[field] = to;
1506-
if (len > (ulong) (end_to - to))
1506+
if (to + len > end_to)
15071507
{
15081508
free_rows(result);
15091509
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);

sql/item.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ Item::Item():
548548
in_rollup= 0;
549549
decimals= 0; max_length= 0;
550550
with_subselect= 0;
551+
with_param= 0;
551552
cmp_context= IMPOSSIBLE_RESULT;
552553
/* Initially this item is not attached to any JOIN_TAB. */
553554
join_tab_idx= MAX_TABLES;
@@ -594,6 +595,7 @@ Item::Item(THD *thd, Item *item):
594595
null_value(item->null_value),
595596
unsigned_flag(item->unsigned_flag),
596597
with_sum_func(item->with_sum_func),
598+
with_param(item->with_param),
597599
with_field(item->with_field),
598600
fixed(item->fixed),
599601
is_autogenerated_name(item->is_autogenerated_name),
@@ -1475,6 +1477,9 @@ bool Item_sp_variable::fix_fields(THD *thd, Item **)
14751477
max_length= it->max_length;
14761478
decimals= it->decimals;
14771479
unsigned_flag= it->unsigned_flag;
1480+
with_param= 1;
1481+
if (thd->lex->current_select->master_unit()->item)
1482+
thd->lex->current_select->master_unit()->item->with_param= 1;
14781483
fixed= 1;
14791484
collation.set(it->collation.collation, it->collation.derivation);
14801485

@@ -7220,6 +7225,7 @@ void Item_ref::set_properties()
72207225
split_sum_func() doesn't try to change the reference.
72217226
*/
72227227
with_sum_func= (*ref)->with_sum_func;
7228+
with_param= (*ref)->with_param;
72237229
with_field= (*ref)->with_field;
72247230
unsigned_flag= (*ref)->unsigned_flag;
72257231
fixed= 1;
@@ -7667,6 +7673,7 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
76677673
decimals= orig_item->decimals;
76687674
collation.set(orig_item->collation);
76697675
with_sum_func= orig_item->with_sum_func;
7676+
with_param= orig_item->with_param;
76707677
with_field= orig_item->with_field;
76717678
unsigned_flag= orig_item->unsigned_flag;
76727679
name= item_arg->name;

sql/item.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ class Item {
669669
bool null_value; /* if item is null */
670670
bool unsigned_flag;
671671
bool with_sum_func; /* True if item contains a sum func */
672+
bool with_param; /* True if contains an SP parameter */
672673
/**
673674
True if any item except Item_sum_func contains a field. Set during parsing.
674675
*/

sql/item_cmpfunc.cc

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
15711571
}
15721572
eval_not_null_tables(NULL);
15731573
with_sum_func= args[0]->with_sum_func;
1574+
with_param= args[0]->with_param || args[1]->with_param;
15741575
with_field= args[0]->with_field;
15751576
if ((const_item_cache= args[0]->const_item()))
15761577
{
@@ -1620,6 +1621,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
16201621
with_subselect= 1;
16211622
with_sum_func= with_sum_func || args[1]->with_sum_func;
16221623
with_field= with_field || args[1]->with_field;
1624+
with_param= args[0]->with_param || args[1]->with_param;
16231625
used_tables_cache|= args[1]->used_tables();
16241626
const_item_cache&= args[1]->const_item();
16251627
fixed= 1;
@@ -2171,6 +2173,7 @@ void Item_func_interval::fix_length_and_dec()
21712173
used_tables_cache|= row->used_tables();
21722174
not_null_tables_cache= row->not_null_tables();
21732175
with_sum_func= with_sum_func || row->with_sum_func;
2176+
with_param= with_param || row->with_param;
21742177
with_field= with_field || row->with_field;
21752178
const_item_cache&= row->const_item();
21762179
}
@@ -4401,6 +4404,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
44014404
List_iterator<Item> li(list);
44024405
Item *item;
44034406
uchar buff[sizeof(char*)]; // Max local vars in function
4407+
bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
44044408
not_null_tables_cache= used_tables_cache= 0;
44054409
const_item_cache= 1;
44064410

@@ -4462,26 +4466,33 @@ Item_cond::fix_fields(THD *thd, Item **ref)
44624466
(item= *li.ref())->check_cols(1))
44634467
return TRUE; /* purecov: inspected */
44644468
used_tables_cache|= item->used_tables();
4465-
if (item->const_item())
4469+
if (item->const_item() && !item->with_param &&
4470+
!item->is_expensive() && !cond_has_datetime_is_null(item))
44664471
{
4467-
if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
4468-
item->val_int() == 0)
4472+
if (item->val_int() == is_and_cond && top_level())
44694473
{
44704474
/*
4471-
This is "... OR false_cond OR ..."
4475+
a. This is "... AND true_cond AND ..."
4476+
In this case, true_cond has no effect on cond_and->not_null_tables()
4477+
b. This is "... OR false_cond/null cond OR ..."
44724478
In this case, false_cond has no effect on cond_or->not_null_tables()
44734479
*/
44744480
}
44754481
else
44764482
{
44774483
/*
4478-
This is "... OR const_cond OR ..."
4484+
a. This is "... AND false_cond/null_cond AND ..."
4485+
The whole condition is FALSE/UNKNOWN.
4486+
b. This is "... OR const_cond OR ..."
44794487
In this case, cond_or->not_null_tables()=0, because the condition
44804488
const_cond might evaluate to true (regardless of whether some tables
44814489
were NULL-complemented).
44824490
*/
4491+
not_null_tables_cache= (table_map) 0;
44834492
and_tables_cache= (table_map) 0;
44844493
}
4494+
if (thd->is_error())
4495+
return TRUE;
44854496
}
44864497
else
44874498
{
@@ -4493,6 +4504,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
44934504
}
44944505

44954506
with_sum_func= with_sum_func || item->with_sum_func;
4507+
with_param= with_param || item->with_param;
44964508
with_field= with_field || item->with_field;
44974509
with_subselect|= item->has_subquery();
44984510
if (item->maybe_null)
@@ -4509,30 +4521,36 @@ bool
45094521
Item_cond::eval_not_null_tables(uchar *opt_arg)
45104522
{
45114523
Item *item;
4524+
bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
45124525
List_iterator<Item> li(list);
45134526
not_null_tables_cache= (table_map) 0;
45144527
and_tables_cache= ~(table_map) 0;
45154528
while ((item=li++))
45164529
{
45174530
table_map tmp_table_map;
4518-
if (item->const_item())
4531+
if (item->const_item() && !item->with_param &&
4532+
!item->is_expensive() && !cond_has_datetime_is_null(item))
45194533
{
4520-
if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
4521-
item->val_int() == 0)
4534+
if (item->val_int() == is_and_cond && top_level())
45224535
{
45234536
/*
4524-
This is "... OR false_cond OR ..."
4537+
a. This is "... AND true_cond AND ..."
4538+
In this case, true_cond has no effect on cond_and->not_null_tables()
4539+
b. This is "... OR false_cond/null cond OR ..."
45254540
In this case, false_cond has no effect on cond_or->not_null_tables()
45264541
*/
45274542
}
45284543
else
45294544
{
45304545
/*
4531-
This is "... OR const_cond OR ..."
4546+
a. This is "... AND false_cond/null_cond AND ..."
4547+
The whole condition is FALSE/UNKNOWN.
4548+
b. This is "... OR const_cond OR ..."
45324549
In this case, cond_or->not_null_tables()=0, because the condition
4533-
some_cond_or might be true regardless of what tables are
4534-
NULL-complemented.
4550+
const_cond might evaluate to true (regardless of whether some tables
4551+
were NULL-complemented).
45354552
*/
4553+
not_null_tables_cache= (table_map) 0;
45364554
and_tables_cache= (table_map) 0;
45374555
}
45384556
}

sql/item_func.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
220220
maybe_null=1;
221221

222222
with_sum_func= with_sum_func || item->with_sum_func;
223+
with_param= with_param || item->with_param;
223224
with_field= with_field || item->with_field;
224225
used_tables_cache|= item->used_tables();
225226
const_item_cache&= item->const_item();

0 commit comments

Comments
 (0)