Skip to content

Commit d5ee054

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. Reviewed-by: Guilhem Bichot <guilhem.bichot@oracle.com>
1 parent 6dea345 commit d5ee054

File tree

149 files changed

+523
-491
lines changed

Some content is hidden

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

149 files changed

+523
-491
lines changed

sql/aggregate_check.cc

+2-2
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -11185,7 +11185,7 @@ void binlog_prepare_row_images(const THD *thd, TABLE *table) {
1118511185
Field *field = (*ptr);
1118611186
if ((field->type() == MYSQL_TYPE_BLOB) &&
1118711187
!field->is_flag_set(PRI_KEY_FLAG))
11188-
bitmap_clear_bit(&table->tmp_set, field->field_index);
11188+
bitmap_clear_bit(&table->tmp_set, field->field_index());
1118911189
}
1119011190
break;
1119111191
default:

sql/dd_table_share.cc

+1-1
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ Functional_index_error_handler::Functional_index_error_handler(
246246

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

sql/field.cc

+24-13
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,7 @@ Field::Field(uchar *ptr_arg, uint32 length_arg, uchar *null_ptr_arg,
17131713
if (!is_nullable()) set_flag(NOT_NULL_FLAG);
17141714
comment.str = "";
17151715
comment.length = 0;
1716-
field_index = 0;
1716+
m_field_index = 0;
17171717
}
17181718

17191719
/**
@@ -7345,7 +7345,7 @@ const uchar *Field_blob::unpack(uchar *, const uchar *from, uint param_data) {
73457345
param_data > 0 ? param_data & 0xFF : packlength;
73467346
uint32 const length = get_length(from, master_packlength);
73477347
DBUG_DUMP("packed", from, length + master_packlength);
7348-
bitmap_set_bit(table->write_set, field_index);
7348+
bitmap_set_bit(table->write_set, field_index());
73497349
Field_blob::store(pointer_cast<const char *>(from) + master_packlength,
73507350
length, field_charset);
73517351
DBUG_DUMP("field", ptr, pack_length() /* len bytes + ptr bytes */);
@@ -8959,7 +8959,7 @@ const uchar *Field_bit::unpack(uchar *to, const uchar *from, uint param_data) {
89598959
*/
89608960
if ((from_bit_len > 0) && (from_len > 0))
89618961
value[new_len - len] = value[new_len - len] & ((1U << from_bit_len) - 1);
8962-
bitmap_set_bit(table->write_set, field_index);
8962+
bitmap_set_bit(table->write_set, field_index());
89638963
store(value, new_len, system_charset_info);
89648964
return from + len;
89658965
}
@@ -9886,10 +9886,17 @@ void Field_typed_array::init(TABLE *table_arg) {
98869886
return;
98879887
}
98889888

9889+
// Set mem_root for conversion field allocation.
9890+
MEM_ROOT *actual_mem_root =
9891+
(table_arg->s->table_category == TABLE_CATEGORY_TEMPORARY)
9892+
? &table_arg->s->mem_root
9893+
: &table_arg->mem_root;
98899894
// Create field for data conversion
98909895
Field *conv_field = ::make_field(
9891-
// Allocate conversion field in table's mem_root
9892-
&table_arg->mem_root,
9896+
// Allocate conversion field in table's mem_root for non-temp
9897+
// tables. Allocate conversion field in TABLE_SHARE's mem_root
9898+
// for internal temporary tables.
9899+
actual_mem_root,
98939900
nullptr, // TABLE_SHARE, not needed
98949901
nullptr, // data buffer, isn't allocated yet
98959902
field_length, // field_length
@@ -9909,21 +9916,20 @@ void Field_typed_array::init(TABLE *table_arg) {
99099916
);
99109917
if (conv_field == nullptr) return;
99119918
uchar *buf =
9912-
table_arg->mem_root.ArrayAlloc<uchar>(conv_field->pack_length() + 1);
9919+
actual_mem_root->ArrayAlloc<uchar>(conv_field->pack_length() + 1);
99139920
if (buf == nullptr) return;
99149921
if (type() == MYSQL_TYPE_NEWDECIMAL)
99159922
(down_cast<Field_new_decimal *>(conv_field))->set_keep_precision(true);
99169923
conv_field->move_field(buf + 1, buf, 0);
99179924
// Allow conv_field to use table->in_use
99189925
conv_field->table = table;
9919-
conv_field->field_index = field_index;
99209926
conv_field->table_name = table_name;
9927+
conv_field->set_field_index(field_index());
99219928

9922-
// Swap arena so that the Item_field is allocated on TABLE::mem_root
9923-
// and so it does not end up in THD's item list which will have a different
9924-
// lifetime than TABLE::mem_root
9925-
Query_arena tmp_arena(&table_arg->mem_root,
9926-
Query_arena::STMT_REGULAR_EXECUTION);
9929+
// Swap arena so that the Item_field is allocated on TABLE::mem_root for
9930+
// non-temp tables and so it does not end up in THD's item list which will
9931+
// have a different lifetime than TABLE::mem_root
9932+
Query_arena tmp_arena(actual_mem_root, Query_arena::STMT_REGULAR_EXECUTION);
99279933
Query_arena backup_arena;
99289934
current_thd->swap_query_arena(tmp_arena, &backup_arena);
99299935
m_conv_item = new Item_field(conv_field);
@@ -10011,6 +10017,11 @@ void Field_typed_array::make_send_field(Send_field *field) const {
1001110017
field->type = MYSQL_TYPE_JSON;
1001210018
}
1001310019

10020+
void Field_typed_array::set_field_index(uint16 field_index) {
10021+
Field::set_field_index(field_index);
10022+
if (m_conv_item) m_conv_item->field->set_field_index(field_index);
10023+
}
10024+
1001410025
Key_map Field::get_covering_prefix_keys() const {
1001510026
if (table == nullptr) {
1001610027
// This function might be called when creating functional indexes. In those
@@ -10190,7 +10201,7 @@ const uchar *Field::unpack_int64(uchar *to, const uchar *from) const {
1019010201

1019110202
bool Field_longstr::is_updatable() const {
1019210203
DBUG_ASSERT(table && table->write_set);
10193-
return bitmap_is_set(table->write_set, field_index);
10204+
return bitmap_is_set(table->write_set, field_index());
1019410205
}
1019510206

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

sql/field.h

+21-4
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,10 @@ inline type_conversion_status time_warning_to_type_conversion_status(
307307

308308
#define ASSERT_COLUMN_MARKED_FOR_READ \
309309
DBUG_ASSERT(!table || (!table->read_set || \
310-
bitmap_is_set(table->read_set, field_index)))
310+
bitmap_is_set(table->read_set, field_index())))
311311
#define ASSERT_COLUMN_MARKED_FOR_WRITE \
312312
DBUG_ASSERT(!table || (!table->write_set || \
313-
bitmap_is_set(table->write_set, field_index)))
313+
bitmap_is_set(table->write_set, field_index())))
314314

315315
/**
316316
Tests if field type is an integer
@@ -871,6 +871,7 @@ class Field {
871871

872872
private:
873873
uint32 flags{0};
874+
uint16 m_field_index; // field number in fields array
874875

875876
public:
876877
bool is_flag_set(unsigned flag) const { return flags & flag; }
@@ -879,8 +880,7 @@ class Field {
879880
// Avoid using this function as it makes it harder to change the internal
880881
// representation.
881882
uint32 all_flags() const { return flags; }
882-
uint16 field_index; // field number in fields array
883-
uchar null_bit; // Bit used to test null bit
883+
uchar null_bit; // Bit used to test null bit
884884
/**
885885
Bitmap of flags indicating if field value is auto-generated by default
886886
and/or on update, and in which way.
@@ -1885,6 +1885,22 @@ class Field {
18851885
return (is_flag_set(BLOB_FLAG) || is_array()) && is_virtual_gcol();
18861886
}
18871887

1888+
/**
1889+
Sets field index.
1890+
1891+
@param[in] field_index Field index.
1892+
*/
1893+
virtual void set_field_index(uint16 field_index) {
1894+
m_field_index = field_index;
1895+
}
1896+
1897+
/**
1898+
Returns field index.
1899+
1900+
@returns Field index.
1901+
*/
1902+
uint16 field_index() const { return m_field_index; }
1903+
18881904
private:
18891905
/**
18901906
Retrieve the field metadata for fields.
@@ -4444,6 +4460,7 @@ class Field_typed_array final : public Field_json {
44444460
}
44454461
void sql_type(String &str) const final override;
44464462
void make_send_field(Send_field *field) const final;
4463+
void set_field_index(uint16 f_index) final override;
44474464
};
44484465

44494466
class Field_enum : public Field_str {

sql/filesort.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -2123,7 +2123,7 @@ Addon_fields *Filesort::get_addon_fields(
21232123

21242124
for (Field **pfield = table->field; *pfield != nullptr; ++pfield) {
21252125
Field *field = *pfield;
2126-
if (!bitmap_is_set(table->read_set, field->field_index)) continue;
2126+
if (!bitmap_is_set(table->read_set, field->field_index())) continue;
21272127

21282128
// Having large blobs in addon fields could be very inefficient,
21292129
// but small blobs are OK (where “small” is a bit fuzzy, and relative
@@ -2193,7 +2193,7 @@ Addon_fields *Filesort::get_addon_fields(
21932193
Addon_fields_array::iterator addonf = m_sort_param.addon_fields->begin();
21942194
for (Field **pfield = table->field; *pfield != nullptr; ++pfield) {
21952195
Field *field = *pfield;
2196-
if (!bitmap_is_set(table->read_set, field->field_index)) continue;
2196+
if (!bitmap_is_set(table->read_set, field->field_index())) continue;
21972197
DBUG_ASSERT(addonf != m_sort_param.addon_fields->end());
21982198

21992199
addonf->field = field;

sql/handler.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -7995,7 +7995,7 @@ static void extract_blob_space_and_length_from_record_buff(
79957995
int num = 0;
79967996
for (Field **vfield = table->vfield; *vfield; vfield++) {
79977997
// Check if this field should be included
7998-
if (bitmap_is_set(fields, (*vfield)->field_index) &&
7998+
if (bitmap_is_set(fields, (*vfield)->field_index()) &&
79997999
(*vfield)->is_virtual_gcol() && (*vfield)->type() == MYSQL_TYPE_BLOB) {
80008000
auto field = down_cast<Field_blob *>(*vfield);
80018001
blob_len_ptr_array[num].length = field->data_length();
@@ -8034,7 +8034,7 @@ static void copy_blob_data(const TABLE *table, const MY_BITMAP *const fields,
80348034
uint num = 0;
80358035
for (Field **vfield = table->vfield; *vfield; vfield++) {
80368036
// Check if this field should be included
8037-
if (bitmap_is_set(fields, (*vfield)->field_index) &&
8037+
if (bitmap_is_set(fields, (*vfield)->field_index()) &&
80388038
(*vfield)->is_virtual_gcol() && (*vfield)->type() == MYSQL_TYPE_BLOB) {
80398039
DBUG_ASSERT(blob_len_ptr_array[num].length > 0);
80408040
DBUG_ASSERT(blob_len_ptr_array[num].ptr != nullptr);
@@ -8115,9 +8115,9 @@ static bool my_eval_gcolumn_expr_helper(THD *thd, TABLE *table,
81158115
for (Field **vfield_ptr = table->vfield; *vfield_ptr; vfield_ptr++) {
81168116
Field *field = *vfield_ptr;
81178117
// Validate that the field number is less than the bit map size
8118-
DBUG_ASSERT(field->field_index < fields->n_bits);
8118+
DBUG_ASSERT(field->field_index() < fields->n_bits);
81198119

8120-
if (bitmap_is_set(fields, field->field_index)) {
8120+
if (bitmap_is_set(fields, field->field_index())) {
81218121
bitmap_union(&fields_to_evaluate, &field->gcol_info->base_columns_map);
81228122
if (field->is_array()) {
81238123
mv_field = field;
@@ -8147,7 +8147,7 @@ static bool my_eval_gcolumn_expr_helper(THD *thd, TABLE *table,
81478147
Field *field = *vfield_ptr;
81488148

81498149
// Check if we should evaluate this field
8150-
if (bitmap_is_set(&fields_to_evaluate, field->field_index) &&
8150+
if (bitmap_is_set(&fields_to_evaluate, field->field_index()) &&
81518151
field->is_virtual_gcol()) {
81528152
DBUG_ASSERT(field->gcol_info && field->gcol_info->expr_item->fixed);
81538153

sql/hash_join_buffer.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ bool StoreFromTableBuffers(const TableCollection &tables, String *buffer) {
259259

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

sql/histograms/histogram.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ static bool prepare_value_maps(
701701
// Overhead for each element
702702
*row_size_bytes += value_map->element_overhead();
703703

704-
value_maps.emplace(field->field_index,
704+
value_maps.emplace(field->field_index(),
705705
std::unique_ptr<histograms::Value_map_base>(value_map));
706706
}
707707

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

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

958-
bitmap_set_bit(tbl->read_set, field->field_index);
958+
bitmap_set_bit(tbl->read_set, field->field_index());
959959
if (field->is_gcol()) {
960-
bitmap_set_bit(tbl->write_set, field->field_index);
960+
bitmap_set_bit(tbl->write_set, field->field_index());
961961
/*
962962
The base columns needs to be in the write set in case of nested
963963
generated columns:
@@ -1027,7 +1027,7 @@ bool update_histogram(THD *thd, TABLE_LIST *table, const columns_set &columns,
10271027

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

sql/item.cc

+9-9
Original file line numberDiff line numberDiff line change
@@ -837,20 +837,20 @@ bool Item_field::add_field_to_set_processor(uchar *arg) {
837837
DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname"));
838838
TABLE *table = (TABLE *)arg;
839839
if (table_ref->table == table)
840-
bitmap_set_bit(&table->tmp_set, field->field_index);
840+
bitmap_set_bit(&table->tmp_set, field->field_index());
841841
return false;
842842
}
843843

844844
bool Item_field::add_field_to_cond_set_processor(uchar *) {
845845
DBUG_TRACE;
846846
DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname"));
847-
bitmap_set_bit(&field->table->cond_set, field->field_index);
847+
bitmap_set_bit(&field->table->cond_set, field->field_index());
848848
return false;
849849
}
850850

851851
bool Item_field::remove_column_from_bitmap(uchar *argument) {
852852
MY_BITMAP *bitmap = reinterpret_cast<MY_BITMAP *>(argument);
853-
bitmap_clear_bit(bitmap, field->field_index);
853+
bitmap_clear_bit(bitmap, field->field_index());
854854
return false;
855855
}
856856

@@ -903,7 +903,7 @@ bool Item_field::check_function_as_value_generator(uchar *checker_args) {
903903
if ((func_args->source != VGS_CHECK_CONSTRAINT) &&
904904
(field->is_gcol() ||
905905
field->has_insert_default_general_value_expression()) &&
906-
field->field_index >= fld_idx) {
906+
field->field_index() >= fld_idx) {
907907
func_args->err_code = (func_args->source == VGS_GENERATED_COLUMN)
908908
? ER_GENERATED_COLUMN_NON_PRIOR
909909
: ER_DEFAULT_VAL_GENERATED_NON_PRIOR;
@@ -2619,8 +2619,8 @@ inline static uint32 adjust_max_effective_column_length(Field *field_par,
26192619
void Item_field::set_field(Field *field_par) {
26202620
table_ref = field_par->table->pos_in_table_list;
26212621
DBUG_ASSERT(table_ref == nullptr || table_ref->table == field_par->table);
2622-
DBUG_ASSERT(field_par->field_index != NO_FIELD_INDEX);
2623-
field_index = field_par->field_index;
2622+
DBUG_ASSERT(field_par->field_index() != NO_FIELD_INDEX);
2623+
field_index = field_par->field_index();
26242624

26252625
field = result_field = field_par; // for easy coding with fields
26262626
maybe_null = field->is_nullable() || field->is_tmp_nullable() ||
@@ -5556,8 +5556,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference) {
55565556
current_bitmap = table->write_set;
55575557
other_bitmap = table->read_set;
55585558
}
5559-
if (!bitmap_test_and_set(current_bitmap, field->field_index))
5560-
DBUG_ASSERT(bitmap_is_set(other_bitmap, field->field_index));
5559+
if (!bitmap_test_and_set(current_bitmap, field->field_index()))
5560+
DBUG_ASSERT(bitmap_is_set(other_bitmap, field->field_index()));
55615561
}
55625562
if (any_privileges) {
55635563
const char *db, *tab;
@@ -7487,7 +7487,7 @@ float Item_field::get_filtering_effect(THD *, table_map filter_for_table,
74877487
const MY_BITMAP *fields_to_ignore,
74887488
double rows_in_table) {
74897489
if (used_tables() != filter_for_table ||
7490-
bitmap_is_set(fields_to_ignore, field->field_index))
7490+
bitmap_is_set(fields_to_ignore, field->field_index()))
74917491
return COND_FILTER_ALLPASS;
74927492

74937493
return 1.0f - get_cond_filter_default_probability(rows_in_table,

0 commit comments

Comments
 (0)