Skip to content

Commit 9ca3270

Browse files
author
Sergey Glukhov
committed
Bug#31152942 ASSERTION ASSERT(NULLPTR != DYNAMIC_CAST<TARGET>(ARG)); GROUP BY JSON ARRAY.
There are two problems: 1. Field_typed_array field creates internal field for data conversion in Field_typed_array::init() and doesn't set convertion field index correctly while creating the field for temporary table. Fixed by introducing new field method Field::set_field_index() which updates convertion field index. 2. Convertion field and corresponding Item_field are created in TABLE::mem_root. Fixed by replacing TABLE::mem_root with TABLE_SHARE's mem_root for internal temporary tables. Additional changes: Public Field::field_index is replaced with private Field::m_field_index. Added Field::field_index()/Field::set_field_index() methods. Patch for 8.0 only. Reviewed-by: Guilhem Bichot <[email protected]>
1 parent b0d044b commit 9ca3270

File tree

158 files changed

+554
-522
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+554
-522
lines changed

sql/aggregate_check.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ void Group_check::add_to_source_of_mat_table(Item_field *item_field,
626626
}
627627
// Find underlying expression of item_field, in SELECT list of mat_select
628628
Item *const expr_under =
629-
mat_gc->select_expression(item_field->field->field_index);
629+
mat_gc->select_expression(item_field->field->field_index());
630630

631631
// non-nullability of tl's column in tl, is equal to that of expr_under.
632632
if (expr_under && !expr_under->maybe_null) mat_gc->non_null_in_source = true;
@@ -820,7 +820,7 @@ bool Group_check::is_in_fd_of_underlying(Item_ident *item) {
820820
Search if the expression inside 'item' is FD on them.
821821
*/
822822
Item *const expr_under =
823-
mat_gc->select_expression(item_field->field->field_index);
823+
mat_gc->select_expression(item_field->field->field_index());
824824
/*
825825
expr_under is the expression underlying 'item'.
826826
(1) and (4) it is a deterministic expression of mat_gc source

sql/binlog.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11187,7 +11187,7 @@ void binlog_prepare_row_images(const THD *thd, TABLE *table) {
1118711187
Field *field = (*ptr);
1118811188
if ((field->type() == MYSQL_TYPE_BLOB) &&
1118911189
!field->is_flag_set(PRI_KEY_FLAG))
11190-
bitmap_clear_bit(&table->tmp_set, field->field_index);
11190+
bitmap_clear_bit(&table->tmp_set, field->field_index());
1119111191
}
1119211192
break;
1119311193
default:

sql/dd_table_share.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ static bool fill_column_from_dd(THD *thd, TABLE_SHARE *share,
10101010
//
10111011
reg_field =
10121012
make_field(*col_obj, charset, share, rec_pos, null_pos, null_bit_pos);
1013-
reg_field->field_index = field_nr;
1013+
reg_field->set_field_index(field_nr);
10141014
reg_field->stored_in_db = true;
10151015

10161016
// Handle generated columns

sql/error_handler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ Functional_index_error_handler::Functional_index_error_handler(
247247

248248
for (uint j = 0; j < index.actual_key_parts; ++j) {
249249
const KEY_PART_INFO &key_part = index.key_part[j];
250-
if (key_part.field->field_index == field->field_index) {
250+
if (key_part.field->field_index() == field->field_index()) {
251251
m_functional_index_name.assign(index.name);
252252
return;
253253
}

sql/field.cc

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ Field::Field(uchar *ptr_arg, uint32 length_arg, uchar *null_ptr_arg,
16501650
if (!is_nullable()) set_flag(NOT_NULL_FLAG);
16511651
comment.str = "";
16521652
comment.length = 0;
1653-
field_index = 0;
1653+
m_field_index = 0;
16541654
}
16551655

16561656
/**
@@ -7281,7 +7281,7 @@ const uchar *Field_blob::unpack(uchar *, const uchar *from, uint param_data) {
72817281
param_data > 0 ? param_data & 0xFF : packlength;
72827282
uint32 const length = get_length(from, master_packlength);
72837283
DBUG_DUMP("packed", from, length + master_packlength);
7284-
bitmap_set_bit(table->write_set, field_index);
7284+
bitmap_set_bit(table->write_set, field_index());
72857285
Field_blob::store(pointer_cast<const char *>(from) + master_packlength,
72867286
length, field_charset);
72877287
DBUG_DUMP("field", ptr, pack_length() /* len bytes + ptr bytes */);
@@ -8895,7 +8895,7 @@ const uchar *Field_bit::unpack(uchar *to, const uchar *from, uint param_data) {
88958895
*/
88968896
if ((from_bit_len > 0) && (from_len > 0))
88978897
value[new_len - len] = value[new_len - len] & ((1U << from_bit_len) - 1);
8898-
bitmap_set_bit(table->write_set, field_index);
8898+
bitmap_set_bit(table->write_set, field_index());
88998899
store(value, new_len, system_charset_info);
89008900
return from + len;
89018901
}
@@ -9833,10 +9833,17 @@ void Field_typed_array::init(TABLE *table_arg) {
98339833
return;
98349834
}
98359835

9836+
// Set mem_root for conversion field allocation.
9837+
MEM_ROOT *actual_mem_root =
9838+
(table_arg->s->table_category == TABLE_CATEGORY_TEMPORARY)
9839+
? &table_arg->s->mem_root
9840+
: &table_arg->mem_root;
98369841
// Create field for data conversion
98379842
Field *conv_field = ::make_field(
9838-
// Allocate conversion field in table's mem_root
9839-
&table_arg->mem_root,
9843+
// Allocate conversion field in table's mem_root for non-temp
9844+
// tables. Allocate conversion field in TABLE_SHARE's mem_root
9845+
// for internal temporary tables.
9846+
actual_mem_root,
98409847
nullptr, // TABLE_SHARE, not needed
98419848
nullptr, // data buffer, isn't allocated yet
98429849
field_length, // field_length
@@ -9856,21 +9863,20 @@ void Field_typed_array::init(TABLE *table_arg) {
98569863
);
98579864
if (conv_field == nullptr) return;
98589865
uchar *buf =
9859-
table_arg->mem_root.ArrayAlloc<uchar>(conv_field->pack_length() + 1);
9866+
actual_mem_root->ArrayAlloc<uchar>(conv_field->pack_length() + 1);
98609867
if (buf == nullptr) return;
98619868
if (type() == MYSQL_TYPE_NEWDECIMAL)
98629869
(down_cast<Field_new_decimal *>(conv_field))->set_keep_precision(true);
98639870
conv_field->move_field(buf + 1, buf, 0);
98649871
// Allow conv_field to use table->in_use
98659872
conv_field->table = table;
9866-
conv_field->field_index = field_index;
98679873
conv_field->table_name = table_name;
9874+
conv_field->set_field_index(field_index());
98689875

9869-
// Swap arena so that the Item_field is allocated on TABLE::mem_root
9870-
// and so it does not end up in THD's item list which will have a different
9871-
// lifetime than TABLE::mem_root
9872-
Query_arena tmp_arena(&table_arg->mem_root,
9873-
Query_arena::STMT_REGULAR_EXECUTION);
9876+
// Swap arena so that the Item_field is allocated on TABLE::mem_root for
9877+
// non-temp tables and so it does not end up in THD's item list which will
9878+
// have a different lifetime than TABLE::mem_root
9879+
Query_arena tmp_arena(actual_mem_root, Query_arena::STMT_REGULAR_EXECUTION);
98749880
Query_arena backup_arena;
98759881
current_thd->swap_query_arena(tmp_arena, &backup_arena);
98769882
m_conv_item = new Item_field(conv_field);
@@ -9958,6 +9964,11 @@ void Field_typed_array::make_send_field(Send_field *field) const {
99589964
field->type = MYSQL_TYPE_JSON;
99599965
}
99609966

9967+
void Field_typed_array::set_field_index(uint16 field_index) {
9968+
Field::set_field_index(field_index);
9969+
if (m_conv_item) m_conv_item->field->set_field_index(field_index);
9970+
}
9971+
99619972
Key_map Field::get_covering_prefix_keys() const {
99629973
if (table == nullptr) {
99639974
// This function might be called when creating functional indexes. In those
@@ -10137,7 +10148,7 @@ const uchar *Field::unpack_int64(uchar *to, const uchar *from) const {
1013710148

1013810149
bool Field_longstr::is_updatable() const {
1013910150
DBUG_ASSERT(table && table->write_set);
10140-
return bitmap_is_set(table->write_set, field_index);
10151+
return bitmap_is_set(table->write_set, field_index());
1014110152
}
1014210153

1014310154
Field_varstring::Field_varstring(uchar *ptr_arg, uint32 len_arg,

sql/field.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,10 @@ inline type_conversion_status time_warning_to_type_conversion_status(
306306

307307
#define ASSERT_COLUMN_MARKED_FOR_READ \
308308
DBUG_ASSERT(!table || (!table->read_set || \
309-
bitmap_is_set(table->read_set, field_index)))
309+
bitmap_is_set(table->read_set, field_index())))
310310
#define ASSERT_COLUMN_MARKED_FOR_WRITE \
311311
DBUG_ASSERT(!table || (!table->write_set || \
312-
bitmap_is_set(table->write_set, field_index)))
312+
bitmap_is_set(table->write_set, field_index())))
313313

314314
/**
315315
Tests if field type is an integer
@@ -839,6 +839,7 @@ class Field {
839839

840840
private:
841841
uint32 flags{0};
842+
uint16 m_field_index; // field number in fields array
842843

843844
public:
844845
bool is_flag_set(unsigned flag) const { return flags & flag; }
@@ -847,8 +848,7 @@ class Field {
847848
// Avoid using this function as it makes it harder to change the internal
848849
// representation.
849850
uint32 all_flags() const { return flags; }
850-
uint16 field_index; // field number in fields array
851-
uchar null_bit; // Bit used to test null bit
851+
uchar null_bit; // Bit used to test null bit
852852
/**
853853
Bitmap of flags indicating if field value is auto-generated by default
854854
and/or on update, and in which way.
@@ -1844,6 +1844,22 @@ class Field {
18441844
return (is_flag_set(BLOB_FLAG) || is_array()) && is_virtual_gcol();
18451845
}
18461846

1847+
/**
1848+
Sets field index.
1849+
1850+
@param[in] field_index Field index.
1851+
*/
1852+
virtual void set_field_index(uint16 field_index) {
1853+
m_field_index = field_index;
1854+
}
1855+
1856+
/**
1857+
Returns field index.
1858+
1859+
@returns Field index.
1860+
*/
1861+
uint16 field_index() const { return m_field_index; }
1862+
18471863
private:
18481864
/**
18491865
Retrieve the field metadata for fields.
@@ -4362,6 +4378,7 @@ class Field_typed_array final : public Field_json {
43624378
}
43634379
void sql_type(String &str) const final override;
43644380
void make_send_field(Send_field *field) const final;
4381+
void set_field_index(uint16 f_index) final override;
43654382
};
43664383

43674384
class Field_enum : public Field_str {

sql/filesort.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ Addon_fields *Filesort::get_addon_fields(
21452145

21462146
for (Field **pfield = table->field; *pfield != nullptr; ++pfield) {
21472147
Field *field = *pfield;
2148-
if (!bitmap_is_set(table->read_set, field->field_index)) continue;
2148+
if (!bitmap_is_set(table->read_set, field->field_index())) continue;
21492149

21502150
// Having large blobs in addon fields could be very inefficient,
21512151
// but small blobs are OK (where “small” is a bit fuzzy, and relative
@@ -2215,7 +2215,7 @@ Addon_fields *Filesort::get_addon_fields(
22152215
Addon_fields_array::iterator addonf = m_sort_param.addon_fields->begin();
22162216
for (Field **pfield = table->field; *pfield != nullptr; ++pfield) {
22172217
Field *field = *pfield;
2218-
if (!bitmap_is_set(table->read_set, field->field_index)) continue;
2218+
if (!bitmap_is_set(table->read_set, field->field_index())) continue;
22192219
DBUG_ASSERT(addonf != m_sort_param.addon_fields->end());
22202220

22212221
addonf->field = field;

sql/handler.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8010,7 +8010,7 @@ static void extract_blob_space_and_length_from_record_buff(
80108010
int num = 0;
80118011
for (Field **vfield = table->vfield; *vfield; vfield++) {
80128012
// Check if this field should be included
8013-
if (bitmap_is_set(fields, (*vfield)->field_index) &&
8013+
if (bitmap_is_set(fields, (*vfield)->field_index()) &&
80148014
(*vfield)->is_virtual_gcol() && (*vfield)->type() == MYSQL_TYPE_BLOB) {
80158015
auto field = down_cast<Field_blob *>(*vfield);
80168016
blob_len_ptr_array[num].length = field->data_length();
@@ -8049,7 +8049,7 @@ static void copy_blob_data(const TABLE *table, const MY_BITMAP *const fields,
80498049
uint num = 0;
80508050
for (Field **vfield = table->vfield; *vfield; vfield++) {
80518051
// Check if this field should be included
8052-
if (bitmap_is_set(fields, (*vfield)->field_index) &&
8052+
if (bitmap_is_set(fields, (*vfield)->field_index()) &&
80538053
(*vfield)->is_virtual_gcol() && (*vfield)->type() == MYSQL_TYPE_BLOB) {
80548054
DBUG_ASSERT(blob_len_ptr_array[num].length > 0);
80558055
DBUG_ASSERT(blob_len_ptr_array[num].ptr != nullptr);
@@ -8130,9 +8130,9 @@ static bool my_eval_gcolumn_expr_helper(THD *thd, TABLE *table,
81308130
for (Field **vfield_ptr = table->vfield; *vfield_ptr; vfield_ptr++) {
81318131
Field *field = *vfield_ptr;
81328132
// Validate that the field number is less than the bit map size
8133-
DBUG_ASSERT(field->field_index < fields->n_bits);
8133+
DBUG_ASSERT(field->field_index() < fields->n_bits);
81348134

8135-
if (bitmap_is_set(fields, field->field_index)) {
8135+
if (bitmap_is_set(fields, field->field_index())) {
81368136
bitmap_union(&fields_to_evaluate, &field->gcol_info->base_columns_map);
81378137
if (field->is_array()) {
81388138
mv_field = field;
@@ -8162,7 +8162,7 @@ static bool my_eval_gcolumn_expr_helper(THD *thd, TABLE *table,
81628162
Field *field = *vfield_ptr;
81638163

81648164
// Check if we should evaluate this field
8165-
if (bitmap_is_set(&fields_to_evaluate, field->field_index) &&
8165+
if (bitmap_is_set(&fields_to_evaluate, field->field_index()) &&
81668166
field->is_virtual_gcol()) {
81678167
DBUG_ASSERT(field->gcol_info && field->gcol_info->expr_item->fixed);
81688168

sql/hash_join_buffer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ bool StoreFromTableBuffers(const TableCollection &tables, String *buffer) {
257257

258258
for (const Column &column : tbl.columns) {
259259
DBUG_ASSERT(bitmap_is_set(column.field->table->read_set,
260-
column.field->field_index));
260+
column.field->field_index()));
261261
if (!column.field->is_null()) {
262262
// Store the data in packed format. The packed format will also
263263
// include the length of the data if needed.

sql/histograms/histogram.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ static bool prepare_value_maps(
699699
// Overhead for each element
700700
*row_size_bytes += value_map->element_overhead();
701701

702-
value_maps.emplace(field->field_index,
702+
value_maps.emplace(field->field_index(),
703703
std::unique_ptr<histograms::Value_map_base>(value_map));
704704
}
705705

@@ -755,7 +755,7 @@ static bool fill_value_maps(
755755
while (res == 0) {
756756
for (Field *field : fields) {
757757
histograms::Value_map_base *value_map =
758-
value_maps.at(field->field_index).get();
758+
value_maps.at(field->field_index()).get();
759759

760760
switch (histograms::field_type_to_value_map_type(field)) {
761761
case histograms::Value_map_type::STRING: {
@@ -954,9 +954,9 @@ bool update_histogram(THD *thd, TABLE_LIST *table, const columns_set &columns,
954954
}
955955
resolved_fields.push_back(field);
956956

957-
bitmap_set_bit(tbl->read_set, field->field_index);
957+
bitmap_set_bit(tbl->read_set, field->field_index());
958958
if (field->is_gcol()) {
959-
bitmap_set_bit(tbl->write_set, field->field_index);
959+
bitmap_set_bit(tbl->write_set, field->field_index());
960960
/*
961961
The base columns needs to be in the write set in case of nested
962962
generated columns:
@@ -1026,7 +1026,7 @@ bool update_histogram(THD *thd, TABLE_LIST *table, const columns_set &columns,
10261026

10271027
std::string col_name(field->field_name);
10281028
histograms::Histogram *histogram =
1029-
value_maps.at(field->field_index)
1029+
value_maps.at(field->field_index())
10301030
->build_histogram(
10311031
&local_mem_root, num_buckets,
10321032
std::string(table->db, table->db_length),

0 commit comments

Comments
 (0)