Skip to content

Commit fe4ccc4

Browse files
committed
Bug#36533080: Remove the field cached_table from class Item_ident
Removed the field cached_table from class Item_ident. Replaced its use with a new field m_table_ref in the same class. Also removed the field table_ref from class Item_field. The field Item_ident::cached_table was used to reference a base table if the column reference was against a base table, and it was used to reference a view or derived table if the column reference was against a view or derived table. The same purpose is now handled by m_table_ref. Some obsolete code in Item_field::fix_fields() that was used for repeated resolving when cached_table was set, was removed. This also made it possible to remove the "outer_fixed" local variable. Commented-out code in transform_table_subquery_to_join_with_derived() was also deleted. The field m_cached_table in class copy_field_info was also obsolete and could be deleted. Change-Id: I51565ad744060d3342e8fbb881fd1e32f652db08
1 parent ddbc4b4 commit fe4ccc4

18 files changed

+202
-262
lines changed

sql/aggregate_check.cc

+4-8
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ bool Group_check::is_fd_on_source(Item *item) {
399399

400400
Item_field *const item_field = down_cast<Item_field *>(item2);
401401
/**
402-
@todo make table_ref non-NULL for gcols, then use it for 'tl'.
402+
@todo make m_table_ref non-NULL for gcols, then use it for 'tl'.
403403
Do the same in Item_field::used_tables_for_level().
404404
*/
405405
Table_ref *const tl = item_field->field->table->pos_in_table_list;
@@ -767,11 +767,7 @@ bool Group_check::is_in_fd_of_underlying(Item_ident *item) {
767767
Used_tables ut(select);
768768
(void)item->walk(&Item::used_tables_for_level, enum_walk::POSTFIX,
769769
pointer_cast<uchar *>(&ut));
770-
/*
771-
todo When we eliminate all uses of cached_table, we can probably add a
772-
derived_table_ref field to Item_view_ref objects and use it here.
773-
*/
774-
Table_ref *const tl = item->cached_table;
770+
Table_ref *const tl = item->m_table_ref;
775771
assert(tl->is_view_or_derived());
776772
/*
777773
We might find expression-based FDs in the result of the view's query
@@ -801,7 +797,7 @@ bool Group_check::is_in_fd_of_underlying(Item_ident *item) {
801797
else if (item->type() == Item::FIELD_ITEM) {
802798
Item_field *const item_field = down_cast<Item_field *>(item);
803799
/**
804-
@todo make table_ref non-NULL for gcols, then use it for 'tl'.
800+
@todo make m_table_ref non-NULL for gcols, then use it for 'tl'.
805801
Do the same in Item_field::used_tables_for_level().
806802
*/
807803
Table_ref *const tl = item_field->field->table->pos_in_table_list;
@@ -1216,7 +1212,7 @@ bool Group_check::do_ident_check(Item_ident *i, table_map tm,
12161212
switch (type) {
12171213
case CHECK_GROUP:
12181214
if (i->type() == Item::FIELD_ITEM &&
1219-
down_cast<Item_field *>(i)->table_ref->m_was_scalar_subquery) {
1215+
down_cast<Item_field *>(i)->m_table_ref->m_was_scalar_subquery) {
12201216
// The table has exactly one row, thus this column is FD
12211217
return false;
12221218
}

sql/item.cc

+68-109
Large diffs are not rendered by default.

sql/item.h

+28-35
Original file line numberDiff line numberDiff line change
@@ -4185,16 +4185,23 @@ class Item_ident : public Item {
41854185
field_name is normally identical to Item::item_name.
41864186
*/
41874187
const char *field_name;
4188-
4189-
/*
4190-
Cached pointer to table which contains this field, used for the same reason
4191-
by prep. stmt. too in case then we have not-fully qualified field.
4192-
0 - means no cached value.
4193-
@todo Notice that this is usually the same as Item_field::table_ref.
4194-
cached_table should be replaced by table_ref ASAP.
4188+
/**
4189+
Points to the Table_ref object of the table or view that the column or
4190+
reference is resolved against (only valid after resolving).
4191+
Notice that for the following types of "tables", no Table_ref object is
4192+
assigned and hence m_table_ref is NULL:
4193+
- Temporary tables assigned by join optimizer for sorting and aggregation.
4194+
- Stored procedure dummy tables.
4195+
For fields referencing such tables, table number is always 0, and other
4196+
uses of m_table_ref is not needed.
41954197
*/
4196-
Table_ref *cached_table;
4197-
Query_block *depended_from;
4198+
Table_ref *m_table_ref{nullptr};
4199+
/**
4200+
For a column or reference that is an outer reference, depended_from points
4201+
to the qualifying query block, otherwise it is NULL
4202+
(only valid after resolving).
4203+
*/
4204+
Query_block *depended_from{nullptr};
41984205

41994206
Item_ident(Name_resolution_context *context_arg, const char *db_name_arg,
42004207
const char *table_name_arg, const char *field_name_arg)
@@ -4205,9 +4212,7 @@ class Item_ident : public Item {
42054212
context(context_arg),
42064213
db_name(db_name_arg),
42074214
table_name(table_name_arg),
4208-
field_name(field_name_arg),
4209-
cached_table(nullptr),
4210-
depended_from(nullptr) {
4215+
field_name(field_name_arg) {
42114216
item_name.set(field_name_arg);
42124217
}
42134218

@@ -4220,9 +4225,7 @@ class Item_ident : public Item {
42204225
m_alias_of_expr(false),
42214226
db_name(db_name_arg),
42224227
table_name(table_name_arg),
4223-
field_name(field_name_arg),
4224-
cached_table(nullptr),
4225-
depended_from(nullptr) {
4228+
field_name(field_name_arg) {
42264229
item_name.set(field_name_arg);
42274230
}
42284231

@@ -4238,7 +4241,7 @@ class Item_ident : public Item {
42384241
db_name(item->db_name),
42394242
table_name(item->table_name),
42404243
field_name(item->field_name),
4241-
cached_table(item->cached_table),
4244+
m_table_ref(item->m_table_ref),
42424245
depended_from(item->depended_from) {}
42434246

42444247
bool do_itemize(Parse_context *pc, Item **res) override;
@@ -4380,16 +4383,6 @@ class Item_field : public Item_ident {
43804383
bool no_conversions) override;
43814384

43824385
public:
4383-
/**
4384-
Table containing this resolved field. This is required e.g for calculation
4385-
of table map. Notice that for the following types of "tables",
4386-
no Table_ref object is assigned and hence table_ref is NULL:
4387-
- Temporary tables assigned by join optimizer for sorting and aggregation.
4388-
- Stored procedure dummy tables.
4389-
For fields referencing such tables, table number is always 0, and other
4390-
uses of table_ref is not needed.
4391-
*/
4392-
Table_ref *table_ref{nullptr};
43934386
/// Source field
43944387
Field *field{nullptr};
43954388

@@ -4581,7 +4574,7 @@ class Item_field : public Item_ident {
45814574
enum_query_type query_type) const override;
45824575
bool is_outer_field() const override {
45834576
assert(fixed);
4584-
return table_ref->outer_join || table_ref->outer_join_nest();
4577+
return m_table_ref->outer_join || m_table_ref->outer_join_nest();
45854578
}
45864579
Field::geometry_type get_geometry_type() const override {
45874580
assert(data_type() == MYSQL_TYPE_GEOMETRY);
@@ -6147,21 +6140,21 @@ class Item_view_ref final : public Item_ref {
61476140
Item_view_ref(Name_resolution_context *context_arg, Item **item,
61486141
const char *db_name_arg, const char *alias_name_arg,
61496142
const char *table_name_arg, const char *field_name_arg,
6150-
Table_ref *tl)
6143+
Table_ref *tr)
61516144
: Item_ref(context_arg, item, db_name_arg, alias_name_arg,
61526145
field_name_arg),
61536146
first_inner_table(nullptr) {
6154-
if (tl->is_view()) {
6147+
if (tr->is_view()) {
61556148
m_orig_db_name = db_name_arg;
61566149
m_orig_table_name = table_name_arg;
61576150
} else {
61586151
assert(db_name_arg == nullptr);
61596152
m_orig_table_name = table_name_arg;
61606153
}
6161-
cached_table = tl;
6162-
if (cached_table->is_inner_table_of_outer_join()) {
6154+
m_table_ref = tr;
6155+
if (m_table_ref->is_inner_table_of_outer_join()) {
61636156
set_nullable(true);
6164-
first_inner_table = cached_table->any_outer_leaf_table();
6157+
first_inner_table = m_table_ref->any_outer_leaf_table();
61656158
}
61666159
}
61676160

@@ -6198,7 +6191,7 @@ class Item_view_ref final : public Item_ref {
61986191
return !(inner_map & ~INNER_TABLE_BIT) && first_inner_table != nullptr
61996192
? ref_item()->real_item()->type() == FIELD_ITEM
62006193
? down_cast<Item_field *>(ref_item()->real_item())
6201-
->table_ref->map()
6194+
->m_table_ref->map()
62026195
: first_inner_table->map()
62036196
: inner_map;
62046197
}
@@ -6899,8 +6892,8 @@ class Item_cache : public Item_basic_constant {
68996892
add_accum_properties(item);
69006893
if (item->type() == FIELD_ITEM) {
69016894
cached_field = down_cast<Item_field *>(item);
6902-
if (cached_field->table_ref != nullptr)
6903-
used_table_map = cached_field->table_ref->map();
6895+
if (cached_field->m_table_ref != nullptr)
6896+
used_table_map = cached_field->m_table_ref->map();
69046897
} else {
69056898
used_table_map = item->used_tables();
69066899
}

sql/item_func.cc

+5-4
Original file line numberDiff line numberDiff line change
@@ -7719,7 +7719,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) {
77197719
my_error(ER_WRONG_ARGUMENTS, MYF(0), "MATCH");
77207720
return true;
77217721
}
7722-
table_ref = ((Item_field *)item)->table_ref;
7722+
table_ref = down_cast<Item_field *>(item)->m_table_ref;
77237723

77247724
if (table_ref != nullptr) table_ref->set_fulltext_searched();
77257725

@@ -7732,8 +7732,9 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) {
77327732
a generated column's generation expression it's not. Thus
77337733
we use field's table, at this moment it's already available.
77347734
*/
7735-
TABLE *const table =
7736-
table_ref ? table_ref->table : ((Item_field *)item)->field->table;
7735+
TABLE *const table = table_ref != nullptr
7736+
? table_ref->table
7737+
: down_cast<Item_field *>(item)->field->table;
77377738

77387739
if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT)) {
77397740
my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
@@ -7787,7 +7788,7 @@ bool Item_func_match::fix_index(const THD *thd) {
77877788
uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts = 0, keynr;
77887789
uint max_cnt = 0, mkeys = 0, i;
77897790

7790-
if (!table_ref) goto err;
7791+
if (table_ref == nullptr) goto err;
77917792

77927793
/*
77937794
We will skip execution if the item is not fixed

sql/item_json_func.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ static bool do_json_schema_validation(
717717
assert(!json_schema->const_item() ||
718718
(json_schema->real_item()->type() == Item::FIELD_ITEM &&
719719
down_cast<const Item_field *>(json_schema->real_item())
720-
->table_ref->table->const_table));
720+
->m_table_ref->table->const_table));
721721

722722
assert(is_convertible_to_json(json_schema));
723723

sql/join_optimizer/finalize_plan.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ bool OrderItemsReferenceUnavailableTables(
357357
[materialized_base_tables](Item *item) {
358358
if (item->type() == Item::FIELD_ITEM) {
359359
Item_field *item_field = down_cast<Item_field *>(item);
360-
return item_field->table_ref != nullptr &&
360+
return item_field->m_table_ref != nullptr &&
361361
!item_field->is_outer_reference() &&
362-
Overlaps(item_field->table_ref->map(),
362+
Overlaps(item_field->m_table_ref->map(),
363363
materialized_base_tables);
364364
}
365365
return false;

sql/opt_sum.cc

+5-3
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ bool optimize_aggregated_query(THD *thd, Query_block *select,
472472

473473
ref.key_buff = key_buff;
474474
Item_field *item_field = down_cast<Item_field *>(expr);
475-
Table_ref *tr = item_field->table_ref;
475+
Table_ref *tr = item_field->m_table_ref;
476476
TABLE *table = tr->table;
477477
/*
478478
If table already has been read, we may use the values already
@@ -1067,7 +1067,7 @@ static bool find_key_for_maxmin(bool max_fl, Index_lookup *ref,
10671067
key_part_map key_part_used = 0;
10681068
*range_fl = NO_MIN_RANGE | NO_MAX_RANGE;
10691069
if (matching_cond(max_fl, ref, keyinfo, part, cond,
1070-
item_field->table_ref->map(), &key_part_used,
1070+
item_field->m_table_ref->map(), &key_part_used,
10711071
range_fl, prefix_len) &&
10721072
!(key_part_to_use & ~key_part_used)) {
10731073
if (!max_fl && key_part_used == key_part_to_use && part->null_bit) {
@@ -1156,7 +1156,9 @@ static bool maxmin_in_range(bool max_fl, Item_field *item_field, Item *cond) {
11561156
}
11571157

11581158
// Check that condition actually references the specific table
1159-
if ((cond->used_tables() & item_field->table_ref->map()) == 0) return false;
1159+
if ((cond->used_tables() & item_field->m_table_ref->map()) == 0) {
1160+
return false;
1161+
}
11601162
bool less_fl = false;
11611163
switch (down_cast<Item_func *>(cond)->functype()) {
11621164
case Item_func::BETWEEN:

sql/range_optimizer/range_analysis.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -773,15 +773,15 @@ static SEL_TREE *get_full_func_mm_tree(THD *thd, RANGE_OPT_PARAM *param,
773773
Item_field *item_field = static_cast<Item_field *>(predicand);
774774
Field *field = item_field->field;
775775

776-
if (!((ref_tables | item_field->table_ref->map()) & param_comp))
776+
if (!((ref_tables | item_field->m_table_ref->map()) & param_comp))
777777
ftree = get_func_mm_tree(thd, param, prev_tables, read_tables,
778778
remove_jump_scans, predicand, op, value, inv);
779779
Item_equal *item_equal = item_field->multi_equality();
780780
if (item_equal != nullptr) {
781781
for (Item_field &item : item_equal->get_fields()) {
782782
Field *f = item.field;
783783
if (!field->eq(f) &&
784-
!((ref_tables | item.table_ref->map()) & param_comp)) {
784+
!((ref_tables | item.m_table_ref->map()) & param_comp)) {
785785
tree = get_func_mm_tree(thd, param, prev_tables, read_tables,
786786
remove_jump_scans, &item, op, value, inv);
787787
ftree = !ftree ? tree : tree_and(param, ftree, tree);
@@ -977,7 +977,7 @@ SEL_TREE *get_mm_tree(THD *thd, RANGE_OPT_PARAM *param, table_map prev_tables,
977977
for (Item_field &field_item : item_equal->get_fields()) {
978978
Field *field = field_item.field;
979979
table_map param_comp = ~(prev_tables | read_tables | current_table);
980-
if (!((ref_tables | field_item.table_ref->map()) & param_comp)) {
980+
if (!((ref_tables | field_item.m_table_ref->map()) & param_comp)) {
981981
SEL_TREE *tree =
982982
get_mm_parts(thd, param, prev_tables, read_tables, item_equal,
983983
field, Item_func::EQ_FUNC, value);

sql/sql_base.cc

+10-13
Original file line numberDiff line numberDiff line change
@@ -8010,7 +8010,7 @@ Field *find_field_in_table_ref(THD *thd, Table_ref *table_list,
80108010
return WRONG_GRANT;
80118011
} else {
80128012
assert(ref && *ref && (*ref)->fixed);
8013-
assert(*actual_table == (down_cast<Item_ident *>(*ref))->cached_table);
8013+
assert(*actual_table == down_cast<Item_ident *>(*ref)->m_table_ref);
80148014

80158015
const Column_privilege_tracker tracker(thd, want_privilege);
80168016
if ((*ref)->walk(&Item::check_column_privileges, enum_walk::PREFIX,
@@ -8118,7 +8118,7 @@ Field *find_field_in_tables(THD *thd, Item_ident *item, Table_ref *first_table,
81188118

81198119
allow_rowid = table_name || (first_table && !first_table->next_local);
81208120

8121-
if (item->cached_table) {
8121+
if (item->m_table_ref != nullptr) {
81228122
/*
81238123
This shortcut is used by prepared statements. We assume that
81248124
Table_ref *first_table is not changed during query execution (which
@@ -8128,21 +8128,18 @@ Field *find_field_in_tables(THD *thd, Item_ident *item, Table_ref *first_table,
81288128
field makes some prepared query ambiguous and so erroneous, but we
81298129
accept this trade off.
81308130
*/
8131-
Table_ref *table_ref = item->cached_table;
8131+
Table_ref *table_ref = item->m_table_ref;
81328132

81338133
/*
81348134
@todo WL#6570 - is this reasonable???
8135-
Also refactor this code to replace "cached_table" with "table_ref" -
8136-
as there is no longer need for more than one resolving, hence
8137-
no "caching" as well.
81388135
*/
81398136
if (item->type() == Item::FIELD_ITEM)
81408137
field_index = down_cast<Item_field *>(item)->field_index;
81418138

81428139
/*
8143-
The condition (table_ref->view == NULL) ensures that we will call
8140+
The condition (m_table_ref->view == NULL) ensures that we will call
81448141
find_field_in_table even in the case of information schema tables
8145-
when table_ref->field_translation != NULL.
8142+
when m_table_ref->field_translation != NULL.
81468143
*/
81478144

81488145
if (table_ref->table && !table_ref->is_view()) {
@@ -8205,12 +8202,12 @@ Field *find_field_in_tables(THD *thd, Item_ident *item, Table_ref *first_table,
82058202
if ((cur_field == nullptr && thd->is_error()) || cur_field == WRONG_GRANT)
82068203
return nullptr;
82078204

8208-
if (cur_field) {
8205+
if (cur_field != nullptr) {
82098206
/*
82108207
Store the original table of the field, which may be different from
82118208
cur_table in the case of NATURAL/USING join.
82128209
*/
8213-
item->cached_table =
8210+
item->m_table_ref =
82148211
(!actual_table->cacheable_table || found) ? nullptr : actual_table;
82158212

82168213
// @todo WL#6570 move this assignment to a more strategic place?
@@ -9255,7 +9252,7 @@ bool setup_fields(THD *thd, ulong want_privilege, bool allow_sum_func,
92559252
my_error(ER_INVALID_ASSIGNMENT_TARGET, MYF(0), str.c_ptr());
92569253
return true;
92579254
}
9258-
Table_ref *tr = field->table_ref;
9255+
Table_ref *tr = field->m_table_ref;
92599256
if ((want_privilege & UPDATE_ACL) && !tr->is_updatable()) {
92609257
/*
92619258
The base table of the column may have beeen referenced through a view
@@ -9573,7 +9570,7 @@ bool insert_fields(THD *thd, Query_block *query_block, const char *db_name,
95739570
if (is_hidden) continue;
95749571

95759572
/* cache the table for the Item_fields inserted by expanding stars */
9576-
if (tables->cacheable_table) field->cached_table = tables;
9573+
if (tables->cacheable_table) field->m_table_ref = tables;
95779574
}
95789575

95799576
if (!found) {
@@ -9719,7 +9716,7 @@ bool fill_record(THD *thd, TABLE *table, const mem_root_deque<Item *> &fields,
97199716
auto value_it = VisibleFields(values).begin();
97209717
for (Item *fld : VisibleFields(fields)) {
97219718
Item_field *const field = fld->field_for_view_update();
9722-
assert(field != nullptr && field->table_ref->table == table);
9719+
assert(field != nullptr && field->m_table_ref->table == table);
97239720

97249721
Field *const rfield = field->field;
97259722
Item *value = *value_it++;

0 commit comments

Comments
 (0)