Skip to content

Commit f8bf2a0

Browse files
committed
MDEV-25108: Running of the EXPLAIN EXTENDED statement produces extra warning in case it is executed in PS (prepared statement) mode
The EXPLAIN EXTENDED statement run as a prepared statement can produce extra warning comparing with a case when EXPLAIN EXTENDED statement is run as a regular statement. For example, the following test case CREATE TABLE t1 (c int); CREATE TABLE t2 (d int); EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1; produces the extra warning "Field or reference 'c' of SELECT #2 was resolved in SELECT #1" in case the above mentioned "EXPLAIN EXTENDED" statement is executed in PS mode, that is by submitting the following statements: PREPARE stmt FROM "EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1"; EXECUTE stmt; The reason of the extra warning emittion is in a way items are handled (being fixed) during execution of the JOIN::prepare() method. The method Item_field::fix_fields() calls the find_field_in_tables() function in case a field hasn't been associated yet with the item. Implementation of the find_field_in_tables() function first checks whether a table containing the required field was already opened and cached. It is done by checking the data member item->cached_table. This data member is set on handling the PRERARE FROM statement and checked on executing the EXECUTE statement. If the data member item->cached_table is set the find_field_in_tables() function invoked and the mark_select_range_as_dependent() function called if the field is an outer referencee. The mark_select_range_as_dependent() function calls the mark_as_dependent() function that finally invokes the push_warning_printf() function that produces extra warning. To fix the issue, calling of push_warning_printf() is elimited in case it was run indirectly in result of hanlding already opened table from the Item_field::fix_fields() method.
1 parent e95cdc4 commit f8bf2a0

File tree

6 files changed

+80
-15
lines changed

6 files changed

+80
-15
lines changed

mysql-test/r/ps.result

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5419,5 +5419,42 @@ id select_type table type possible_keys key key_len ref rows Extra
54195419
DEALLOCATE PREPARE stmt;
54205420
DROP TABLE t1;
54215421
#
5422+
# MDEV-25108: Running of the EXPLAIN EXTENDED statement produces extra warning
5423+
# in case it is executed in PS (prepared statement) mode
5424+
#
5425+
CREATE TABLE t1 (c int);
5426+
CREATE TABLE t2 (d int);
5427+
# EXPLAIN EXTENDED in regular way (not PS mode)
5428+
EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1;
5429+
id select_type table type possible_keys key key_len ref rows filtered Extra
5430+
1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
5431+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
5432+
Warnings:
5433+
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
5434+
Note 1003 select (select 1 from `test`.`t2` where 0) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1`
5435+
SHOW WARNINGS;
5436+
Level Code Message
5437+
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
5438+
Note 1003 select (select 1 from `test`.`t2` where 0) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1`
5439+
# Now run the same EXPLAIN EXTENDED in PS mode. Number of warnings
5440+
# and their content must be the same as in case running the statement
5441+
# in regular way
5442+
PREPARE stmt FROM "EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1";
5443+
Warnings:
5444+
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
5445+
EXECUTE stmt;
5446+
id select_type table type possible_keys key key_len ref rows filtered Extra
5447+
1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
5448+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
5449+
Warnings:
5450+
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
5451+
Note 1003 select (select 1 from `test`.`t2` where 0) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1`
5452+
SHOW WARNINGS;
5453+
Level Code Message
5454+
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
5455+
Note 1003 select (select 1 from `test`.`t2` where 0) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1`
5456+
DEALLOCATE PREPARE stmt;
5457+
DROP TABLE t1, t2;
5458+
#
54225459
# End of 10.2 tests
54235460
#

mysql-test/t/ps.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4926,6 +4926,26 @@ EXECUTE stmt;
49264926
DEALLOCATE PREPARE stmt;
49274927
DROP TABLE t1;
49284928

4929+
--echo #
4930+
--echo # MDEV-25108: Running of the EXPLAIN EXTENDED statement produces extra warning
4931+
--echo # in case it is executed in PS (prepared statement) mode
4932+
--echo #
4933+
CREATE TABLE t1 (c int);
4934+
CREATE TABLE t2 (d int);
4935+
4936+
--echo # EXPLAIN EXTENDED in regular way (not PS mode)
4937+
EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1;
4938+
SHOW WARNINGS;
4939+
4940+
--echo # Now run the same EXPLAIN EXTENDED in PS mode. Number of warnings
4941+
--echo # and their content must be the same as in case running the statement
4942+
--echo # in regular way
4943+
PREPARE stmt FROM "EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1";
4944+
EXECUTE stmt;
4945+
SHOW WARNINGS;
4946+
4947+
DEALLOCATE PREPARE stmt;
4948+
DROP TABLE t1, t2;
49294949
--echo #
49304950
--echo # End of 10.2 tests
49314951
--echo #

sql/item.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4668,11 +4668,14 @@ bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
46684668
@param resolved_item item which was resolved in outer SELECT(for warning)
46694669
@param mark_item item which should be marked (can be differ in case of
46704670
substitution)
4671+
@param suppress_warning_output flag specifying whether to suppress output of
4672+
a warning message
46714673
*/
46724674

46734675
static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
46744676
Item_ident *resolved_item,
4675-
Item_ident *mark_item)
4677+
Item_ident *mark_item,
4678+
bool suppress_warning_output)
46764679
{
46774680
DBUG_ENTER("mark_as_dependent");
46784681

@@ -4685,7 +4688,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
46854688
if (current->mark_as_dependent(thd, last,
46864689
/** resolved_item psergey-thu **/ mark_item))
46874690
DBUG_RETURN(TRUE);
4688-
if (thd->lex->describe & DESCRIBE_EXTENDED)
4691+
if ((thd->lex->describe & DESCRIBE_EXTENDED) && !suppress_warning_output)
46894692
{
46904693
const char *db_name= (resolved_item->db_name ?
46914694
resolved_item->db_name : "");
@@ -4714,6 +4717,8 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
47144717
@param found_item Item which was found during resolving (if resolved
47154718
identifier belongs to VIEW)
47164719
@param resolved_item Identifier which was resolved
4720+
@param suppress_warning_output flag specifying whether to suppress output of
4721+
a warning message
47174722
47184723
@note
47194724
We have to mark all items between current_sel (including) and
@@ -4727,7 +4732,8 @@ void mark_select_range_as_dependent(THD *thd,
47274732
SELECT_LEX *last_select,
47284733
SELECT_LEX *current_sel,
47294734
Field *found_field, Item *found_item,
4730-
Item_ident *resolved_item)
4735+
Item_ident *resolved_item,
4736+
bool suppress_warning_output)
47314737
{
47324738
/*
47334739
Go from current SELECT to SELECT where field was resolved (it
@@ -4762,7 +4768,7 @@ void mark_select_range_as_dependent(THD *thd,
47624768
found_field->table->map;
47634769
prev_subselect_item->const_item_cache= 0;
47644770
mark_as_dependent(thd, last_select, current_sel, resolved_item,
4765-
dependent);
4771+
dependent, suppress_warning_output);
47664772
}
47674773
}
47684774

@@ -5228,7 +5234,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
52285234
context->select_lex, this,
52295235
((ref_type == REF_ITEM ||
52305236
ref_type == FIELD_ITEM) ?
5231-
(Item_ident*) (*reference) : 0));
5237+
(Item_ident*) (*reference) : 0), false);
52325238
return 0;
52335239
}
52345240
}
@@ -5240,7 +5246,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
52405246
context->select_lex, this,
52415247
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
52425248
(Item_ident*) (*reference) :
5243-
0));
5249+
0), false);
52445250
if (thd->lex->in_sum_func &&
52455251
thd->lex->in_sum_func->nest_level >= select->nest_level)
52465252
{
@@ -5354,7 +5360,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
53545360
set_max_sum_func_level(thd, select);
53555361
mark_as_dependent(thd, last_checked_context->select_lex,
53565362
context->select_lex, rf,
5357-
rf);
5363+
rf, false);
53585364

53595365
return 0;
53605366
}
@@ -5367,7 +5373,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
53675373
set_max_sum_func_level(thd, select);
53685374
mark_as_dependent(thd, last_checked_context->select_lex,
53695375
context->select_lex,
5370-
this, (Item_ident*)*reference);
5376+
this, (Item_ident*)*reference, false);
53715377
if (last_checked_context->select_lex->having_fix_field)
53725378
{
53735379
Item_ref *rf;
@@ -7401,7 +7407,7 @@ class Dependency_marker: public Field_enumerator
74017407
if (tbl->table == item->field->table)
74027408
{
74037409
if (sel != current_select)
7404-
mark_as_dependent(thd, sel, current_select, item, item);
7410+
mark_as_dependent(thd, sel, current_select, item, item, false);
74057411
return;
74067412
}
74077413
}
@@ -7596,7 +7602,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
75967602
((refer_type == REF_ITEM ||
75977603
refer_type == FIELD_ITEM) ?
75987604
(Item_ident*) (*reference) :
7599-
0));
7605+
0), false);
76007606
/*
76017607
view reference found, we substituted it instead of this
76027608
Item, so can quit
@@ -7646,7 +7652,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
76467652
goto error;
76477653
thd->change_item_tree(reference, fld);
76487654
mark_as_dependent(thd, last_checked_context->select_lex,
7649-
current_sel, fld, fld);
7655+
current_sel, fld, fld, false);
76507656
/*
76517657
A reference is resolved to a nest level that's outer or the same as
76527658
the nest level of the enclosing set function : adjust the value of
@@ -7669,7 +7675,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
76697675
/* Should be checked in resolve_ref_in_select_and_group(). */
76707676
DBUG_ASSERT(*ref && (*ref)->fixed);
76717677
mark_as_dependent(thd, last_checked_context->select_lex,
7672-
context->select_lex, this, this);
7678+
context->select_lex, this, this, false);
76737679
/*
76747680
A reference is resolved to a nest level that's outer or the same as
76757681
the nest level of the enclosing set function : adjust the value of

sql/item.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6088,7 +6088,8 @@ void mark_select_range_as_dependent(THD *thd,
60886088
st_select_lex *last_select,
60896089
st_select_lex *current_sel,
60906090
Field *found_field, Item *found_item,
6091-
Item_ident *resolved_item);
6091+
Item_ident *resolved_item,
6092+
bool suppress_warning_output);
60926093

60936094
extern Cached_item *new_Cached_item(THD *thd, Item *item,
60946095
bool pass_through_ref);

sql/item_subselect.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ class Item_subselect :public Item_result_field,
283283
friend bool Item_ref::fix_fields(THD *, Item **);
284284
friend void mark_select_range_as_dependent(THD*,
285285
st_select_lex*, st_select_lex*,
286-
Field*, Item*, Item_ident*);
286+
Field*, Item*, Item_ident*,
287+
bool);
287288
friend bool convert_join_subqueries_to_semijoins(JOIN *join);
288289
};
289290

sql/sql_base.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6046,7 +6046,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
60466046
if (!all_merged && current_sel != last_select)
60476047
{
60486048
mark_select_range_as_dependent(thd, last_select, current_sel,
6049-
found, *ref, item);
6049+
found, *ref, item, true);
60506050
}
60516051
}
60526052
return found;

0 commit comments

Comments
 (0)