Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
748 changes: 167 additions & 581 deletions include/mem_root_deque.h

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion sql/item_func.cc
Original file line number Diff line number Diff line change
Expand Up @@ -575,9 +575,10 @@ inline bool param_type_uses_non_param_inner(THD *thd, uint arg_count,
return false;
if (args[j]->type() == Item::ROW_ITEM)
arguments[j] = down_cast<Item_row *>(args[j])->element_index(i);
else if (args[j]->type() == Item::SUBSELECT_ITEM)
else if (args[j]->type() == Item::SUBSELECT_ITEM) {
arguments[j] = (*down_cast<Item_subselect *>(args[j])
->unit->get_unit_column_types())[i];
}
}
if (param_type_uses_non_param_inner(thd, arg_count, arguments, def))
return true;
Expand Down
3 changes: 2 additions & 1 deletion sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9482,7 +9482,8 @@ bool insert_fields(THD *thd, Query_block *query_block, const char *db_name,
**it = item; /* Replace '*' with the first found item. */
} else {
/* Add 'item' to the SELECT list, after the current one. */
*it = fields->insert(*it + 1, item);
mem_root_deque<Item *>::iterator next_it = ++(*it);
*it = fields->insert(next_it, item);
}

/*
Expand Down
5 changes: 2 additions & 3 deletions sql/sql_derived.cc
Original file line number Diff line number Diff line change
Expand Up @@ -545,10 +545,9 @@ bool copy_field_info(THD *thd, Item *orig_expr, Item *cloned_expr) {
}
if (inner_item->type() == Item::FIELD_ITEM) {
Item_field *field = down_cast<Item_field *>(inner_item);
if (field_info.push_back(
field_info.push_back(
Field_info(context, field->table_ref, depended_from,
field->cached_table, field->field)))
return true;
field->cached_table, field->field));
}
return false;
}))
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_executor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4344,7 +4344,7 @@ bool change_to_use_tmp_fields(mem_root_deque<Item *> *fields, THD *thd,
Item_field *new_field = new Item_field(field);
if (!suv || !new_field) return true; // Fatal error
mem_root_deque<Item *> list(thd->mem_root);
if (list.push_back(new_field)) return true;
list.push_back(new_field);
if (suv->set_arguments(&list, true)) return true;
new_item = suv;
} else
Expand Down
6 changes: 4 additions & 2 deletions sql/sql_optimizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7049,11 +7049,13 @@ static uint get_semi_join_select_list_index(Item_field *item_field) {
if (emb_sj_nest && emb_sj_nest->is_sj_or_aj_nest()) {
const mem_root_deque<Item *> &items =
emb_sj_nest->nested_join->sj_inner_exprs;
for (size_t i = 0; i < items.size(); i++) {
const Item *sel_item = items[i];
size_t i = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-identifier-length ⚠️
variable name i is too short, expected at least 2 characters

for (auto it = items.begin(); it != items.end(); ++it) {
const Item *sel_item = *it;
if (sel_item->type() == Item::FIELD_ITEM &&
down_cast<const Item_field *>(sel_item)->field->eq(item_field->field))
return i;
i++;
}
}
return UINT_MAX;
Expand Down
4 changes: 3 additions & 1 deletion sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,9 @@ void free_items(Item *item) {
*/
void cleanup_items(Item *item) {
DBUG_TRACE;
for (; item; item = item->next_free) item->cleanup();
for (; item; item = item->next_free) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-implicit-bool-conversion ⚠️
implicit conversion Item * -> bool

Suggested change
for (; item; item = item->next_free) {
for (; item != nullptr; item = item->next_free) {

item->cleanup();
}
}

/**
Expand Down
32 changes: 18 additions & 14 deletions sql/sql_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5327,6 +5327,7 @@ bool Query_block::resolve_table_value_constructor_values(THD *thd) {
}

size_t item_index = 0;
auto field_it = fields.begin();
for (auto it = values_row->begin(); it != values_row->end(); ++it) {
Item *item = *it;
if ((!item->fixed && item->fix_fields(thd, &*it)) ||
Expand Down Expand Up @@ -5359,7 +5360,9 @@ bool Query_block::resolve_table_value_constructor_values(THD *thd) {
// Make sure to also replace the reference in item_list. In the case
// where fix_fields transforms an item, it.ref() will only update the
// reference of values_row.
if (first_execution) fields[item_index] = item;
if (first_execution) {
*field_it = item;
}
} else {
Item_values_column *column = down_cast<Item_values_column *>(
GetNthVisibleField(fields, item_index));
Expand All @@ -5368,6 +5371,7 @@ bool Query_block::resolve_table_value_constructor_values(THD *thd) {
column->fixed = true; // Does not have regular fix_fields()
}

field_it++;
++item_index;
}

Expand Down Expand Up @@ -5564,8 +5568,12 @@ bool Query_block::transform_table_subquery_to_join_with_derived(

// Append inner expressions of decorrelated equalities to the SELECT
// list. Correct context info of outer expressions.
auto it_outer = sj_outer_exprs.begin() + initial_sj_inner_exprs_count;
auto it_inner = sj_inner_exprs.begin() + initial_sj_inner_exprs_count;
auto it_outer = sj_outer_exprs.begin();
auto it_inner = sj_inner_exprs.begin();
for (int i = 0; i < initial_sj_inner_exprs_count; i++) {
it_outer++;
it_inner++;
}
for (int i = 0; it_outer != sj_outer_exprs.end();
++it_outer, ++it_inner, ++i) {
Item *inner = *it_inner;
Expand Down Expand Up @@ -6742,12 +6750,13 @@ bool Query_block::nest_derived(THD *thd, Item *join_cond,
return tl->join_cond() == join_cond;
});
assert(it != copy_list.end()); // assert that we found it
const size_t idx = it - copy_list.begin();

// Insert back all outer tables to the inner containing the condition.
// Normally only one.
for (size_t i = 0; i < idx; i++) {
jlist.push_front(copy_list[i]);
size_t idx = 0;
for (auto tmp = copy_list.begin(); tmp != copy_list.end(); ++tmp) {
if (it == tmp) {
break;
}
jlist.push_front(*tmp);
idx++;
}

// Insert the derived table and nest it with the outer(s)
Expand Down Expand Up @@ -6858,11 +6867,6 @@ bool Query_block::decorrelate_derived_scalar_subquery_pre(
if (selected_field == nullptr || f->field != selected_field->field) {
m_added_non_hidden_fields++;

// If f->hidden, f should be among the hidden fields in 'fields'.
assert(std::any_of(fields.cbegin(), fields.cbegin() + first_non_hidden,
[&f](const Item *item) { return f == item; }) ==
f->hidden);

Item_field *inner_field;

if (f->hidden) {
Expand Down
3 changes: 2 additions & 1 deletion sql/sql_update.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,8 @@ static bool AddRowIdAsTempTableField(THD *thd, TABLE *table,
Item_field *ifield = new (thd->mem_root) Item_field(field);
if (ifield == nullptr) return true;
ifield->set_nullable(false);
return fields->push_back(ifield);
fields->push_back(ifield);
return false;
}

/// Stores the current row ID of "table" in the specified field of "tmp_table".
Expand Down
60 changes: 50 additions & 10 deletions storage/innobase/include/read0types.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class MVCC;
/** Read view lists the trx ids of those transactions for which a consistent
read should not see the modifications to the database. */

#define MAX_TOP_ACTIVE_BYTES 8192

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ cppcoreguidelines-macro-usage ⚠️
macro MAX_TOP_ACTIVE_BYTES used to declare a constant; consider using a constexpr constant

#define MAX_SHORT_ACTIVE_BYTES 65536

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ cppcoreguidelines-macro-usage ⚠️
macro MAX_SHORT_ACTIVE_BYTES used to declare a constant; consider using a constexpr constant


class ReadView {
/** This is similar to a std::vector but it is not a drop
in replacement. It is specific to ReadView. */
Expand Down Expand Up @@ -173,14 +176,33 @@ class ReadView {

if (id >= m_low_limit_id) {
return (false);

} else if (m_ids.empty()) {
} else if (empty()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ llvm-else-after-return ⚠️
do not use else after return

Suggested change
} else if (empty()) {
} if (empty()) {

return (true);
}

const ids_t::value_type *p = m_ids.data();
/* first search short bitmap */
if (m_has_short_actives && id >= m_short_min_id) {
if (id > m_short_max_id) {
return false;
}
unsigned int trim_id = id & 0x7FFFF;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-magic-numbers ⚠️
0x7FFFF is a magic number; consider replacing it with a named constant

unsigned int trim_min_id = m_short_min_id & 0x7FFFF;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-magic-numbers ⚠️
0x7FFFF is a magic number; consider replacing it with a named constant

unsigned int array_index = (trim_id >> 3);
unsigned int array_min_index = (trim_min_id >> 3);
array_index = (MAX_SHORT_ACTIVE_BYTES + array_index - array_min_index) %
MAX_TOP_ACTIVE_BYTES;
unsigned int array_remainder = trim_id & (0x7);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-magic-numbers ⚠️
0x7 is a magic number; consider replacing it with a named constant

int is_value_set = top_active[array_index] & (1 << (7 - array_remainder));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-magic-numbers ⚠️
7 is a magic number; consider replacing it with a named constant

if (is_value_set) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-implicit-bool-conversion ⚠️
implicit conversion int -> bool

return false;
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ llvm-else-after-return ⚠️
do not use else after return

return true;
}
Comment on lines +196 to +200

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-simplify-boolean-expr ⚠️
redundant boolean literal in conditional return statement

Suggested change
if (is_value_set) {
return false;
} else {
return true;
}
return is_value_set == 0;

}

const ids_t::value_type *p = m_long_ids.data();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-identifier-length ⚠️
variable name p is too short, expected at least 2 characters


return (!std::binary_search(p, p + m_ids.size(), id));
return (!std::binary_search(p, p + m_long_ids.size(), id));
}

/**
Expand Down Expand Up @@ -235,7 +257,18 @@ class ReadView {

/**
@return true if there are no transaction ids in the snapshot */
bool empty() const { return (m_ids.empty()); }
bool empty() const {
bool long_empty = m_long_ids.empty();
if (long_empty) {
if (!m_has_short_actives) {
return true;
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ llvm-else-after-return ⚠️
do not use else after return

return false;
}
Comment on lines +263 to +267

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-simplify-boolean-expr ⚠️
redundant boolean literal in conditional return statement

Suggested change
if (!m_has_short_actives) {
return true;
} else {
return false;
}
return !m_has_short_actives;

} else {
return false;
}
}

/**
Clones a read view object. The resulting read view has identical change
Expand Down Expand Up @@ -264,17 +297,19 @@ class ReadView {
fprintf(file, "Read view low limit trx n:o " TRX_ID_FMT "\n",
low_limit_no());
print_limits(file);
fprintf(file, "Read view individually stored trx ids:\n");
for (ulint i = 0; i < m_ids.size(); i++)
fprintf(file, "Read view trx id " TRX_ID_FMT "\n", m_ids.data()[i]);
fprintf(file, "Read view individually stored long trx ids:\n");
for (ulint i = 0; i < m_long_ids.size(); i++)
fprintf(file, "Read view trx id " TRX_ID_FMT "\n", m_long_ids.data()[i]);
}

bool is_cloned() const noexcept { return (m_cloned); }

private:
/**
Copy the transaction ids from the source vector */
inline void copy_trx_ids(const trx_ids_t &trx_ids);
inline void copy_long_trx_ids(const trx_ids_t &trx_ids,
trx_id_t min_short_id);
inline void copy_short_trx_ids();

/**
Opens a read view where exactly the transactions serialized before this
Expand Down Expand Up @@ -307,6 +342,7 @@ class ReadView {
ReadView &operator=(const ReadView &);

private:
unsigned char top_active[MAX_TOP_ACTIVE_BYTES];
/** The read should not see any transaction with trx id >= this
value. In other words, this is the "high water mark". */
trx_id_t m_low_limit_id;
Expand All @@ -322,7 +358,7 @@ class ReadView {

/** Set of RW transactions that was active when this snapshot
was taken */
ids_t m_ids;
ids_t m_long_ids;

/** The view does not need to see the undo logs for transactions
whose transaction number is strictly smaller (<) than this value:
Expand All @@ -337,6 +373,10 @@ class ReadView {
trx_id_t m_view_low_limit_no;
#endif /* UNIV_DEBUG */

trx_id_t m_short_min_id;
trx_id_t m_short_max_id;
bool m_has_short_actives;

/** AC-NL-RO transaction view that has been "closed". */
bool m_closed;

Expand Down
33 changes: 0 additions & 33 deletions storage/innobase/include/row0sel.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,39 +420,6 @@ enum row_sel_match_mode {
of a fixed length column) */
};

/** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
function is row_mysql_store_col_in_innobase_format() in row0mysql.cc.
@param[in,out] dest buffer where to store; NOTE
that BLOBs are not in themselves stored
here: the caller must allocate and copy
the BLOB into buffer before, and pass
the pointer to the BLOB in 'data'
@param[in] templ MySQL column template. Its following fields
are referenced: type, is_unsigned,
mysql_col_len, mbminlen, mbmaxlen
@param[in] index InnoDB index
@param[in] field_no templ->rec_field_no or templ->clust_rec_field_no
or templ->icp_rec_field_no
@param[in] data data to store
@param[in] len length of the data
@param[in] compress_heap
@param[in] sec_field secondary index field no if the secondary index
record but the prebuilt template is in
clustered index format and used only for end
range comparison. */
void row_sel_field_store_in_mysql_format_func(
byte *dest, const mysql_row_templ_t *templ, const dict_index_t *index,
IF_DEBUG(ulint field_no, ) const byte *data,
ulint len, mem_heap_t **compress_heap IF_DEBUG(, ulint sec_field));

/** Convert a non-SQL-NULL field from Innobase format to MySQL format. */
static inline void row_sel_field_store_in_mysql_format(
byte *dest, const mysql_row_templ_t *templ, const dict_index_t *idx,
ulint field, const byte *src, ulint len, mem_heap_t **compress_heap, ulint sec) {
row_sel_field_store_in_mysql_format_func(
dest, templ, idx, IF_DEBUG(field, ) src, len, compress_heap IF_DEBUG(, sec));
}

/** Search the record present in innodb_table_stats table using
db_name, table_name and fill it in table stats structure.
@param[in] db_name database name
Expand Down
Loading
Loading