MySQL 9.1.0
Source Code Documentation
|
#include "sql/sql_update.h"
#include <algorithm>
#include <atomic>
#include <bit>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <memory>
#include <utility>
#include "field_types.h"
#include "lex_string.h"
#include "mem_root_deque.h"
#include "my_alloc.h"
#include "my_base.h"
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_io.h"
#include "my_sys.h"
#include "my_table_map.h"
#include "mysql/components/services/bits/psi_bits.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql/strings/m_ctype.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "prealloced_array.h"
#include "scope_guard.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/binlog.h"
#include "sql/debug_sync.h"
#include "sql/derror.h"
#include "sql/field.h"
#include "sql/filesort.h"
#include "sql/handler.h"
#include "sql/item.h"
#include "sql/item_json_func.h"
#include "sql/item_subselect.h"
#include "sql/iterators/basic_row_iterators.h"
#include "sql/iterators/row_iterator.h"
#include "sql/iterators/timing_iterator.h"
#include "sql/iterators/update_rows_iterator.h"
#include "sql/join_optimizer/access_path.h"
#include "sql/join_optimizer/bit_utils.h"
#include "sql/join_optimizer/walk_access_paths.h"
#include "sql/key.h"
#include "sql/key_spec.h"
#include "sql/locked_tables_list.h"
#include "sql/mdl.h"
#include "sql/mem_root_array.h"
#include "sql/mysqld.h"
#include "sql/opt_explain.h"
#include "sql/opt_explain_format.h"
#include "sql/opt_trace.h"
#include "sql/opt_trace_context.h"
#include "sql/parse_tree_node_base.h"
#include "sql/partition_info.h"
#include "sql/protocol.h"
#include "sql/psi_memory_key.h"
#include "sql/query_options.h"
#include "sql/range_optimizer/partition_pruning.h"
#include "sql/range_optimizer/path_helpers.h"
#include "sql/range_optimizer/range_optimizer.h"
#include "sql/select_lex_visitor.h"
#include "sql/sql_array.h"
#include "sql/sql_base.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_data_change.h"
#include "sql/sql_delete.h"
#include "sql/sql_error.h"
#include "sql/sql_executor.h"
#include "sql/sql_lex.h"
#include "sql/sql_list.h"
#include "sql/sql_opt_exec_shared.h"
#include "sql/sql_optimizer.h"
#include "sql/sql_partition.h"
#include "sql/sql_resolver.h"
#include "sql/sql_select.h"
#include "sql/sql_tmp_table.h"
#include "sql/sql_view.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/table_trigger_dispatcher.h"
#include "sql/temp_table_param.h"
#include "sql/thd_raii.h"
#include "sql/transaction_info.h"
#include "sql/trigger_chain.h"
#include "sql/trigger_def.h"
#include "sql/visible_fields.h"
#include "template_utils.h"
#include "thr_lock.h"
Functions | |
static bool | prepare_partial_update (Opt_trace_context *trace, const mem_root_deque< Item * > &fields, const mem_root_deque< Item * > &values) |
Mark the columns that can possibly be updated in-place using partial update. More... | |
bool | records_are_comparable (const TABLE *table) |
True if the table's input and output record buffers are comparable using compare_records(TABLE*). More... | |
bool | compare_records (const TABLE *table) |
Compares the input and output record buffers of the table to see if a row has changed. More... | |
static bool | check_constant_expressions (const mem_root_deque< Item * > &values) |
Check if all expressions in list are constant expressions. More... | |
static table_map | get_table_map (const mem_root_deque< Item * > &items) |
static TABLE * | GetOutermostTable (const JOIN *join) |
Returns the outermost (leftmost) table of a join. More... | |
static bool | unsafe_key_update (Table_ref *leaves, table_map tables_for_update) |
If one row is updated through two different aliases and the first update physically moves the row, the second update will error because the row is no longer located where expected. More... | |
static bool | has_json_columns (const mem_root_deque< Item * > &items) |
Check if a list of Items contains an Item whose type is JSON. More... | |
bool | should_switch_to_multi_table_if_subqueries (const THD *thd, const Query_block *qb, const Table_ref *table_list) |
Decides if a single-table UPDATE/DELETE statement should switch to the multi-table code path, if there are subqueries which might benefit from semijoin or subquery materialization, and if no feature specific to the single-table path are used. More... | |
static void | CollectColumnsReferencedInJoinConditions (const JOIN *join, const Table_ref *table_ref) |
static bool | safe_update_on_fly (const QEP_TAB *join_tab, const Table_ref *table_ref, Table_ref *all_tables) |
Check if table is safe to update on the fly. More... | |
static bool | AddRowIdAsTempTableField (THD *thd, TABLE *table, mem_root_deque< Item * > *fields) |
Adds a field for storing row IDs from "table" to "fields". More... | |
static void | StoreRowId (TABLE *table, TABLE *tmp_table, int field_num, table_map hash_join_tables) |
Stores the current row ID of "table" in the specified field of "tmp_table". More... | |
static bool | PositionScanOnRow (TABLE *updated_table, TABLE *table, TABLE *tmp_table, int field_num) |
Position the scan of "table" using the row ID stored in the specified field of "tmp_table". More... | |
table_map | GetImmediateUpdateTable (const JOIN *join, bool single_target) |
Find out which of the target tables can be updated immediately while scanning. More... | |
bool | FinalizeOptimizationForUpdate (JOIN *join) |
Makes the TABLE and handler objects ready for being used in an UPDATE statement. More... | |
unique_ptr_destroy_only< RowIterator > | CreateUpdateRowsIterator (THD *thd, MEM_ROOT *mem_root, JOIN *join, unique_ptr_destroy_only< RowIterator > source) |
Creates an UpdateRowsIterator which updates the rows returned by the given "source" iterator. More... | |
|
static |
Adds a field for storing row IDs from "table" to "fields".
|
static |
Check if all expressions in list are constant expressions.
[in] | values | List of expressions |
true | Only constant expressions |
false | At least one non-constant expression |
|
static |
bool compare_records | ( | const TABLE * | table | ) |
Compares the input and output record buffers of the table to see if a row has changed.
The algorithm iterates over updated columns and if they are nullable compares NULL bits in the buffer before comparing actual data. Special care must be taken to compare only the relevant NULL bits and mask out all others as they may be undefined. The storage engine will not and should not touch them.
table | The table to evaluate. |
unique_ptr_destroy_only< RowIterator > CreateUpdateRowsIterator | ( | THD * | thd, |
MEM_ROOT * | mem_root, | ||
JOIN * | join, | ||
unique_ptr_destroy_only< RowIterator > | source | ||
) |
Creates an UpdateRowsIterator which updates the rows returned by the given "source" iterator.
bool FinalizeOptimizationForUpdate | ( | JOIN * | join | ) |
Makes the TABLE and handler objects ready for being used in an UPDATE statement.
Called at the beginning of each execution.
join | The top-level JOIN object of the UPDATE operation. |
|
static |
Find out which of the target tables can be updated immediately while scanning.
This is used by the old optimizer after the plan has been created. The hypergraph optimizer does not use this function, as it makes the decision about immediate update during planning, not after planning.
join | The top-level JOIN object of the UPDATE statement. |
single_target | True if the UPDATE statement has exactly one target table. |
Returns the outermost (leftmost) table of a join.
|
static |
Check if a list of Items contains an Item whose type is JSON.
|
static |
Position the scan of "table" using the row ID stored in the specified field of "tmp_table".
updated_table | The table that is being updated. |
table | The table to position on a given row. |
tmp_table | The temporary table that holds the row ID. |
field_num | The field of tmp_table that holds the row ID. |
|
static |
Mark the columns that can possibly be updated in-place using partial update.
Only JSON columns can be updated in-place, and only if all the updates of the column are on the form
json_col = JSON_SET(json_col, ...) json_col = JSON_REPLACE(json_col, ...) json_col = JSON_REMOVE(json_col, ...)
Even though a column is marked for partial update, it is not necessarily updated as a partial update during execution. It depends on the actual data in the column if it is possible to do it as a partial update. Also, for multi-table updates, it is only possible to perform partial updates in the first table of the join operation, and it is not determined until later (in Query_result_update::optimize()) which table it is.
trace | the optimizer trace context |
fields | the fields that are updated by the update statement |
values | the values they are updated to |
bool records_are_comparable | ( | const TABLE * | table | ) |
True if the table's input and output record buffers are comparable using compare_records(TABLE*).
|
static |
Check if table is safe to update on the fly.
join_tab | Table (always the first one in the JOIN plan) |
table_ref | Table reference for 'join_tab' |
all_tables | List of tables (updated or not) |
We can update the first table in join on the fly if we know that:
This function gets information about fields to be updated from the TABLE::write_set bitmap. And it gets information about which fields influence the selection of rows in next tables, from the TABLE::tmp_set bitmap.
bool should_switch_to_multi_table_if_subqueries | ( | const THD * | thd, |
const Query_block * | qb, | ||
const Table_ref * | table_list | ||
) |
Decides if a single-table UPDATE/DELETE statement should switch to the multi-table code path, if there are subqueries which might benefit from semijoin or subquery materialization, and if no feature specific to the single-table path are used.
thd | Thread handler |
qb | Query block |
table_list | Table to modify |
|
static |
Stores the current row ID of "table" in the specified field of "tmp_table".
table | The table to get a row ID from. |
tmp_table | The temporary table in which to store the row ID. |
field_num | The field of tmp_table in which to store the row ID. |
hash_join_tables | A map of all tables that are part of a hash join. |
If one row is updated through two different aliases and the first update physically moves the row, the second update will error because the row is no longer located where expected.
This function checks if the multiple-table update is about to do that and if so returns with an error.
The following update operations physically moves rows: 1) Update of a column in a clustered primary key 2) Update of a column used to calculate which partition the row belongs to
This function returns with an error if both of the following are true:
a) A table in the multiple-table update statement is updated through multiple aliases (including views) b) At least one of the updates on the table from a) may physically moves the row. Note: Updating a column used to calculate which partition a row belongs to does not necessarily mean that the row is moved. The new value may or may not belong to the same partition.
leaves | First leaf table |
tables_for_update | Map of tables that are updated |