MySQL 8.4.2
Source Code Documentation
UpdateRowsIterator Class Referencefinal

An iterator that performs updates to rows returned by its child iterator. More...

#include <update_rows_iterator.h>

Inheritance diagram for UpdateRowsIterator:
[legend]

Public Member Functions

 UpdateRowsIterator (THD *thd, unique_ptr_destroy_only< RowIterator > source, TABLE *outermost_table, TABLE *immediate_table, Table_ref *update_tables, TABLE **tmp_tables, Copy_field *copy_fields, List< TABLE > unupdated_check_opt_tables, COPY_INFO **update_operations, mem_root_deque< Item * > **fields_for_table, mem_root_deque< Item * > **values_for_table, table_map tables_with_rowid_in_buffer)
 
 ~UpdateRowsIterator () override
 
bool Init () override
 Initialize or reinitialize the iterator. More...
 
int Read () override
 Read a single row. More...
 
void StartPSIBatchMode () override
 Start performance schema batch mode, if supported (otherwise ignored). More...
 
void EndPSIBatchModeIfStarted () override
 Ends performance schema batch mode, if started. More...
 
void SetNullRowFlag (bool is_null_row) override
 Mark the current row buffer as containing a NULL row or not, so that if you read from it and the flag is true, you'll get only NULLs no matter what is actually in the buffer (typically some old leftover row). More...
 
void UnlockRow () override
 
ha_rows found_rows () const
 
ha_rows updated_rows () const
 
- Public Member Functions inherited from RowIterator
 RowIterator (THD *thd)
 
virtual ~RowIterator ()=default
 
 RowIterator (const RowIterator &)=delete
 
 RowIterator (RowIterator &&)=default
 
virtual const IteratorProfilerGetProfiler () const
 Get profiling data for this iterator (for 'EXPLAIN ANALYZE'). More...
 
virtual void SetOverrideProfiler ([[maybe_unused]] const IteratorProfiler *profiler)
 
virtual RowIteratorreal_iterator ()
 If this iterator is wrapping a different iterator (e.g. More...
 
virtual const RowIteratorreal_iterator () const
 

Private Member Functions

bool DoImmediateUpdatesAndBufferRowIds (bool *trans_safe, bool *transactional_tables)
 Perform all the immediate updates for the current row returned by the join, and buffer row IDs for the non-immediate tables. More...
 
bool DoDelayedUpdates (bool *trans_safe, bool *transactional_tables)
 Perform all the delayed updates. More...
 

Private Attributes

unique_ptr_destroy_only< RowIteratorm_source
 The iterator producing the rows to update. More...
 
TABLEm_outermost_table
 The outermost table of the join. More...
 
TABLEm_immediate_table
 The table to perform immediate update on, or nullptr if immediate update is not possible. More...
 
Table_refm_update_tables
 Pointer to list of updated tables, linked via 'next_local'. More...
 
TABLE ** m_tmp_tables
 Temporary tables used to store cached updates. More...
 
Copy_fieldm_copy_fields
 Objects that copy the updated values from a temporary table to the update target table, and perform conversions if the types differ. More...
 
List< TABLEm_unupdated_check_opt_tables
 Tables referenced in the CHECK OPTION condition of the updated view excluding the updated table. More...
 
COPY_INFO ** m_update_operations
 The update operations of each table in m_update_tables (indexed in the same order as m_update_tables). More...
 
mem_root_deque< Item * > ** m_fields_for_table
 The fields list decomposed into separate lists per table. More...
 
mem_root_deque< Item * > ** m_values_for_table
 The values list decomposed into separate lists per table. More...
 
ha_rows m_found_rows {0}
 The number of rows matching the WHERE and join conditions. More...
 
ha_rows m_updated_rows {0}
 The number of rows actually updated. More...
 
table_map m_hash_join_tables
 All the tables that are part of a hash join. More...
 

Additional Inherited Members

- Protected Member Functions inherited from RowIterator
THDthd () const
 

Detailed Description

An iterator that performs updates to rows returned by its child iterator.

Constructor & Destructor Documentation

◆ UpdateRowsIterator()

UpdateRowsIterator::UpdateRowsIterator ( THD thd,
unique_ptr_destroy_only< RowIterator source,
TABLE outermost_table,
TABLE immediate_table,
Table_ref update_tables,
TABLE **  tmp_tables,
Copy_field copy_fields,
List< TABLE unupdated_check_opt_tables,
COPY_INFO **  update_operations,
mem_root_deque< Item * > **  fields_for_table,
mem_root_deque< Item * > **  values_for_table,
table_map  tables_with_rowid_in_buffer 
)

◆ ~UpdateRowsIterator()

UpdateRowsIterator::~UpdateRowsIterator ( )
override

Member Function Documentation

◆ DoDelayedUpdates()

bool UpdateRowsIterator::DoDelayedUpdates ( bool *  trans_safe,
bool *  transactional_tables 
)
private

Perform all the delayed updates.

Parameters
[in,out]trans_safeGets set to false if a non-transactional table is updated.
[out]transactional_tablesGets set to true if a transactional table is updated.
Returns
True on error.

< Flag for fatal errors

◆ DoImmediateUpdatesAndBufferRowIds()

bool UpdateRowsIterator::DoImmediateUpdatesAndBufferRowIds ( bool *  trans_safe,
bool *  transactional_tables 
)
private

Perform all the immediate updates for the current row returned by the join, and buffer row IDs for the non-immediate tables.

Parameters
[out]trans_safeGets set to false if a non-transactional table is updated.
[out]transactional_tablesGets set to true if a transactional table is updated.
Returns
True on error.

◆ EndPSIBatchModeIfStarted()

void UpdateRowsIterator::EndPSIBatchModeIfStarted ( )
inlineoverridevirtual

Ends performance schema batch mode, if started.

It's always safe to call this.

Iterators that have children (composite iterators) must forward the EndPSIBatchModeIfStarted() call to every iterator they could conceivably have called StartPSIBatchMode() on. This ensures that after such a call to on the root iterator, all handlers are out of batch mode.

Reimplemented from RowIterator.

◆ found_rows()

ha_rows UpdateRowsIterator::found_rows ( ) const
inline

◆ Init()

bool UpdateRowsIterator::Init ( )
overridevirtual

Initialize or reinitialize the iterator.

You must always call Init() before trying a Read() (but Init() does not imply Read()).

You can call Init() multiple times; subsequent calls will rewind the iterator (or reposition it, depending on whether the iterator takes in e.g. a Index_lookup) and allow you to read the records anew.

Implements RowIterator.

◆ Read()

int UpdateRowsIterator::Read ( )
overridevirtual

Read a single row.

The row data is not actually returned from the function; it is put in the table's (or tables', in case of a join) record buffer, ie., table->records[0].

Return values
0OK
-1End of records
1Error

Implements RowIterator.

◆ SetNullRowFlag()

void UpdateRowsIterator::SetNullRowFlag ( bool  is_null_row)
inlineoverridevirtual

Mark the current row buffer as containing a NULL row or not, so that if you read from it and the flag is true, you'll get only NULLs no matter what is actually in the buffer (typically some old leftover row).

This is used for outer joins, when an iterator hasn't produced any rows and we need to produce a NULL-complemented row. Init() or Read() won't necessarily reset this flag, so if you ever set is to true, make sure to also set it to false when needed.

Note that this can be called without Init() having been called first. For example, NestedLoopIterator can hit EOF immediately on the outer iterator, which means the inner iterator doesn't get an Init() call, but will still forward SetNullRowFlag to both inner and outer iterators.

TODO: We shouldn't need this. See the comments on AggregateIterator for a bit more discussion on abstracting out a row interface.

Implements RowIterator.

◆ StartPSIBatchMode()

void UpdateRowsIterator::StartPSIBatchMode ( )
inlineoverridevirtual

Start performance schema batch mode, if supported (otherwise ignored).

PFS batch mode is a mitigation to reduce the overhead of performance schema, typically applied at the innermost table of the entire join. If you start it before scanning the table and then end it afterwards, the entire set of handler calls will be timed only once, as a group, and the costs will be distributed evenly out. This reduces timer overhead.

If you start PFS batch mode, you must also take care to end it at the end of the scan, one way or the other. Do note that this is true even if the query ends abruptly (LIMIT is reached, or an error happens). The easiest workaround for this is to simply call EndPSIBatchModeIfStarted() on the root iterator at the end of the scan. See the PFSBatchMode class for a useful helper.

The rules for starting batch and ending mode are:

  1. If you are an iterator with exactly one child (FilterIterator etc.), forward any StartPSIBatchMode() calls to it.
  2. If you drive an iterator (read rows from it using a for loop or similar), use PFSBatchMode as described above.
  3. If you have multiple children, ignore the call and do your own handling of batch mode as appropriate. For materialization, #2 would typically apply. For joins, it depends on the join type (e.g., NestedLoopIterator applies batch mode only when scanning the innermost table).

The upshot of this is that when scanning a single table, batch mode will typically be activated for that table (since we call StartPSIBatchMode() on the root iterator, and it will trickle all the way down to the table iterator), but for a join, the call will be ignored and the join iterator will activate batch mode by itself as needed.

Reimplemented from RowIterator.

◆ UnlockRow()

void UpdateRowsIterator::UnlockRow ( )
inlineoverridevirtual

Implements RowIterator.

◆ updated_rows()

ha_rows UpdateRowsIterator::updated_rows ( ) const
inline

Member Data Documentation

◆ m_copy_fields

Copy_field* UpdateRowsIterator::m_copy_fields
private

Objects that copy the updated values from a temporary table to the update target table, and perform conversions if the types differ.

◆ m_fields_for_table

mem_root_deque<Item *>** UpdateRowsIterator::m_fields_for_table
private

The fields list decomposed into separate lists per table.

◆ m_found_rows

ha_rows UpdateRowsIterator::m_found_rows {0}
private

The number of rows matching the WHERE and join conditions.

◆ m_hash_join_tables

table_map UpdateRowsIterator::m_hash_join_tables
private

All the tables that are part of a hash join.

We use this map to find out how to get the row ID from a table when buffering row IDs for delayed update. For those tables that are part of a hash join, the row ID will already be available in handler::ref, and calling handler::position() will overwrite it with an incorrect row ID (most likely the last row read from the table). For those that are not part of a hash join, handler::position() must be called to get the current row ID from the underlying scan.

◆ m_immediate_table

TABLE* UpdateRowsIterator::m_immediate_table
private

The table to perform immediate update on, or nullptr if immediate update is not possible.

◆ m_outermost_table

TABLE* UpdateRowsIterator::m_outermost_table
private

The outermost table of the join.

It may or may not be one of the tables being updated.

◆ m_source

unique_ptr_destroy_only<RowIterator> UpdateRowsIterator::m_source
private

The iterator producing the rows to update.

◆ m_tmp_tables

TABLE** UpdateRowsIterator::m_tmp_tables
private

Temporary tables used to store cached updates.

◆ m_unupdated_check_opt_tables

List<TABLE> UpdateRowsIterator::m_unupdated_check_opt_tables
private

Tables referenced in the CHECK OPTION condition of the updated view excluding the updated table.

◆ m_update_operations

COPY_INFO** UpdateRowsIterator::m_update_operations
private

The update operations of each table in m_update_tables (indexed in the same order as m_update_tables).

◆ m_update_tables

Table_ref* UpdateRowsIterator::m_update_tables
private

Pointer to list of updated tables, linked via 'next_local'.

◆ m_updated_rows

ha_rows UpdateRowsIterator::m_updated_rows {0}
private

The number of rows actually updated.

◆ m_values_for_table

mem_root_deque<Item *>** UpdateRowsIterator::m_values_for_table
private

The values list decomposed into separate lists per table.


The documentation for this class was generated from the following files: