MySQL  8.0.27
Source Code Documentation
sql_update.cc File Reference
#include "sql/sql_update.h"
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "field_types.h"
#include "lex_string.h"
#include "m_ctype.h"
#include "mem_root_deque.h"
#include "my_alloc.h"
#include "my_bit.h"
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_inttypes.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_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/basic_row_iterators.h"
#include "sql/binlog.h"
#include "sql/composite_iterators.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/join_optimizer/access_path.h"
#include "sql/key.h"
#include "sql/key_spec.h"
#include "sql/locked_tables_list.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/range_optimizer.h"
#include "sql/records.h"
#include "sql/row_iterator.h"
#include "sql/select_lex_visitor.h"
#include "sql/sorting_iterator.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_error.h"
#include "sql/sql_executor.h"
#include "sql/sql_lex.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/timing_iterator.h"
#include "sql/transaction_info.h"
#include "sql/trigger_chain.h"
#include "sql/trigger_def.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 outbut 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 bool unsafe_key_update (TABLE_LIST *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 *select, const TABLE_LIST *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 bool safe_update_on_fly (JOIN_TAB *join_tab, TABLE_LIST *table_ref, TABLE_LIST *all_tables)
 Check if table is safe to update on the fly. More...
 

Function Documentation

◆ check_constant_expressions()

static bool check_constant_expressions ( const mem_root_deque< Item * > &  values)
static

Check if all expressions in list are constant expressions.

Parameters
[in]valuesList of expressions
Return values
trueOnly constant expressions
falseAt least one non-constant expression

◆ compare_records()

bool compare_records ( const TABLE table)

Compares the input and outbut 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.

Parameters
tableThe table to evaluate.
Returns
true if row has changed.
false otherwise.

◆ get_table_map()

static table_map get_table_map ( const mem_root_deque< Item * > &  items)
static

◆ has_json_columns()

static bool has_json_columns ( const mem_root_deque< Item * > &  items)
static

Check if a list of Items contains an Item whose type is JSON.

◆ prepare_partial_update()

static bool prepare_partial_update ( Opt_trace_context trace,
const mem_root_deque< Item * > &  fields,
const mem_root_deque< Item * > &  values 
)
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.

Parameters
tracethe optimizer trace context
fieldsthe fields that are updated by the update statement
valuesthe values they are updated to
Returns
false on success, true on error

◆ records_are_comparable()

bool records_are_comparable ( const TABLE table)

True if the table's input and output record buffers are comparable using compare_records(TABLE*).

◆ safe_update_on_fly()

static bool safe_update_on_fly ( JOIN_TAB join_tab,
TABLE_LIST table_ref,
TABLE_LIST all_tables 
)
static

Check if table is safe to update on the fly.

Parameters
join_tabTable (always the first one in the JOIN plan)
table_refTable reference for 'join_tab'
all_tablesList of tables (updated or not)

We can update the first table in join on the fly if we know that:

  • a row in this table will never be read twice (that depends, among other things, on the access method), and
  • updating this row won't influence the selection of rows in next tables.

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.

Returns
true if it is safe to update on the fly.

◆ should_switch_to_multi_table_if_subqueries()

bool should_switch_to_multi_table_if_subqueries ( const THD thd,
const Query_block select,
const TABLE_LIST 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.

Parameters
thdThread handler
selectQuery block
table_listTable to modify
Returns
true if we should switch

◆ unsafe_key_update()

static bool unsafe_key_update ( TABLE_LIST leaves,
table_map  tables_for_update 
)
static

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.

Parameters
leavesFirst leaf table
tables_for_updateMap of tables that are updated
Returns
true if the update is unsafe, in which case an error message is also set, false otherwise.