MySQL 9.1.0
Source Code Documentation
Prepared_statement Class Referencefinal

Prepared_statement: a statement that can contain placeholders. More...

#include <sql_prepare.h>

Public Types

enum  enum_param_pack_type { PACKED , UNPACKED }
 

Public Member Functions

 Prepared_statement (THD *thd_arg)
 
virtual ~Prepared_statement ()
 Destroy this prepared statement, cleaning up all used memory and resources. More...
 
bool set_name (const LEX_CSTRING &name)
 
const LEX_CSTRINGname () const
 
ulong id () const
 
bool is_in_use () const
 
bool is_sql_prepare () const
 
void set_sql_prepare (bool prepare=true)
 
void deallocate (THD *thd)
 Common part of DEALLOCATE PREPARE and mysqld_stmt_close. More...
 
bool prepare (THD *thd, const char *packet, size_t packet_length, Item_param **orig_param_array)
 Parse statement text, validate the statement, and prepare it for execution. More...
 
bool execute_loop (THD *thd, String *expanded_query, bool open_cursor)
 Execute a prepared statement. More...
 
bool execute_server_runnable (THD *thd, Server_runnable *server_runnable)
 
PSI_prepared_stmtget_PS_prepared_stmt ()
 
bool set_parameters (THD *thd, String *expanded_query, bool has_new_types, PS_PARAM *parameters)
 Assign parameter values from the execute packet. More...
 
bool set_parameters (THD *thd, String *expanded_query, bool has_new_types, PS_PARAM *parameters, enum enum_param_pack_type param_pack_type)
 Assign parameter values from the execute packet. More...
 
bool set_parameters (THD *thd, String *expanded_query)
 Assign parameter values from specified variables. More...
 
void trace_parameter_types (THD *thd)
 
void close_cursor ()
 

Public Attributes

Query_arena m_arena
 Memory allocation arena, for permanent allocations to statement. More...
 
Item_param ** m_param_array {nullptr}
 Array of parameters used for statement, may be NULL if there are none. More...
 
Server_side_cursorm_cursor {nullptr}
 Pointer to cursor, may be NULL if statement never used with a cursor. More...
 
const Protocolm_active_protocol {nullptr}
 Used to check that the protocol is stable during execution. More...
 
uint m_param_count {0}
 Number of parameters expected for statement. More...
 
uint m_last_errno {0}
 
char m_last_error [MYSQL_ERRMSG_SIZE]
 
const ulong m_id
 Uniquely identifies each statement object in thread scope; change during statement lifetime. More...
 
LEXm_lex {nullptr}
 
LEX_CSTRING m_query_string {NULL_CSTR}
 The query string associated with this statement. More...
 
PSI_prepared_stmtm_prepared_stmt {nullptr}
 Performance Schema interface for a prepared statement. More...
 

Private Member Functions

bool prepare_query (THD *thd)
 Perform semantic analysis of query and send a response packet to client. More...
 
void cleanup_stmt (THD *thd)
 
void setup_stmt_logging (THD *thd)
 
bool check_parameter_types ()
 Check resolved parameter types versus actual parameter types. More...
 
void copy_parameter_types (Item_param **from_param_array)
 Copy parameter metada data from parameter array into current prepared stmt. More...
 
bool set_db (const LEX_CSTRING &db_length)
 Remember the current database. More...
 
bool execute (THD *thd, String *expanded_query, bool open_cursor)
 Execute a prepared statement that has already been prepared. More...
 
bool reprepare (THD *thd)
 Reprepare this prepared statement. More...
 
bool validate_metadata (THD *thd, Prepared_statement *copy)
 Validate statement result set metadata (if the statement returns a result set). More...
 
void swap_prepared_statement (Prepared_statement *copy)
 Swap the MEM_ROOT allocated data of two prepared statements. More...
 
bool insert_parameters_from_vars (THD *thd, List< LEX_STRING > &varnames, String *query)
 Assign prepared statement parameters from user variables. More...
 
bool insert_parameters (THD *thd, String *query, bool has_new_types, PS_PARAM *parameters, enum enum_param_pack_type param_pack_type)
 Assign parameter values from data supplied by the client. More...
 

Private Attributes

bool m_used_as_cursor {false}
 True if statement is used with cursor, false if used in regular execution. More...
 
Query_resultm_regular_result {nullptr}
 Query result used when statement is used in regular execution. More...
 
Query_resultm_cursor_result {nullptr}
 Query result used when statement is used with a cursor. More...
 
Query_resultm_aux_result {nullptr}
 Auxiliary query result object, saved for proper destruction. More...
 
bool m_is_sql_prepare {false}
 Flag that specifies preparation state. More...
 
bool m_in_use {false}
 Flag that prevents recursive invocation of prepared statements. More...
 
bool m_with_log {false}
 
bool m_first_execution {true}
 
LEX_CSTRING m_name {NULL_CSTR}
 Name of the prepared statement. More...
 
LEX_CSTRING m_db {NULL_CSTR}
 Name of the current (default) database. More...
 
MEM_ROOT m_mem_root
 The memory root to allocate parsed tree elements (instances of Item, Query_block and other classes). More...
 

Detailed Description

Prepared_statement: a statement that can contain placeholders.

Member Enumeration Documentation

◆ enum_param_pack_type

Enumerator
PACKED 
UNPACKED 

Constructor & Destructor Documentation

◆ Prepared_statement()

Prepared_statement::Prepared_statement ( THD thd_arg)

◆ ~Prepared_statement()

Prepared_statement::~Prepared_statement ( )
virtual

Destroy this prepared statement, cleaning up all used memory and resources.

This is called from deallocate() to handle COM_STMT_CLOSE and DEALLOCATE PREPARE or when THD ends and all prepared statements are freed.

Member Function Documentation

◆ check_parameter_types()

bool Prepared_statement::check_parameter_types ( )
private

Check resolved parameter types versus actual parameter types.

Assumes that parameter values have been assigned to the parameters.

Returns
true if parameter types are compatible, false otherwise.

◆ cleanup_stmt()

void Prepared_statement::cleanup_stmt ( THD thd)
private

◆ close_cursor()

void Prepared_statement::close_cursor ( )

◆ copy_parameter_types()

void Prepared_statement::copy_parameter_types ( Item_param **  from_param_array)
private

Copy parameter metada data from parameter array into current prepared stmt.

Parameters
from_param_arrayParameter array to copy from.

◆ deallocate()

void Prepared_statement::deallocate ( THD thd)

Common part of DEALLOCATE PREPARE and mysqld_stmt_close.

◆ execute()

bool Prepared_statement::execute ( THD thd,
String expanded_query,
bool  open_cursor 
)
private

Execute a prepared statement that has already been prepared.

Parameters
thdcurrent thread.
expanded_queryA query for binlogging which has all parameter markers ('?') replaced with their actual values.
open_cursorTrue if an attempt to open a cursor should be made. Currently used only in the binary protocol.
Note
Preconditions:
  • Caller must ensure that thd->change_list and thd->item_list are empty; This function will free them after execution.

Postconditions.

  • There are no items in thd->change_list.
  • thd->mem_root may contain memory allocated during execution.
Returns
false if success, true if error

◆ execute_loop()

bool Prepared_statement::execute_loop ( THD thd,
String expanded_query,
bool  open_cursor 
)

Execute a prepared statement.

Re-prepare it a limited number of times if necessary.

Try to execute a prepared statement. If there is a metadata validation error, prepare a new copy of the prepared statement, swap the old and the new statements, and try again. If there is a validation error again, repeat the above, but perform not more than a maximum number of times. Reprepare_observer ensures that a prepared statement execution is retried not more than a maximum number of times.

Note
We have to try several times in a loop since we release metadata locks on tables after prepared statement prepare. Therefore, a DDL statement may sneak in between prepare and execute of a new statement. If a prepared statement execution is retried for a maximum number of times then we give up.
Parameters
thdcurrent thread.
expanded_queryQuery string.
open_cursorFlag to specify if a cursor should be used.
Returns
a bool value representing the function execution status.
Return values
trueerror: either statement execution is retried for a maximum number of times or some general error.
falsesuccessfully executed the statement, perhaps after having reprepared it a few times.

◆ execute_server_runnable()

bool Prepared_statement::execute_server_runnable ( THD thd,
Server_runnable server_runnable 
)

◆ get_PS_prepared_stmt()

PSI_prepared_stmt * Prepared_statement::get_PS_prepared_stmt ( )
inline

◆ id()

ulong Prepared_statement::id ( ) const
inline

◆ insert_parameters()

bool Prepared_statement::insert_parameters ( THD thd,
String query,
bool  has_new_types,
PS_PARAM parameters,
enum enum_param_pack_type  pack_type 
)
private

Assign parameter values from data supplied by the client.

If required, generate a valid non-parameterized query for logging.

Parameters
thdcurrent thread.
queryThe query with parameter markers replaced with values supplied by user that were used to execute the query.
has_new_typesif true, new types of actual parameters are provided, otherwise use the parameters from previous execution.
parametersArray of actual parameter values. Contains parameter types if has_new_types is true.
pack_typeUNPACKED means that the parameter value buffer points to MYSQL_TIME*
Returns
false if success, true if error
Note
m_with_log is set when one of slow or general logs are open. Logging of prepared statements in all cases is performed by means of regular queries: if parameter data was supplied from C API, each placeholder in the query is replaced with its actual value; if we're logging a [Dynamic] SQL prepared statement, parameter markers are replaced with variable names. Example:
   mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
     --> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
   mysqld_stmt_execute(stmt);
     --> general and binary logs get
                           [Execute] UPDATE t1 SET a*1.25 WHERE a=1"

If a statement has been prepared using SQL syntax:

   PREPARE stmt FROM "UPDATE t1 SET a=a*1.25 WHERE a=?"
     --> general log gets [Query] PREPARE stmt FROM "UPDATE ..."
   EXECUTE stmt USING @a
     --> general log gets [Query] EXECUTE stmt USING @a;

◆ insert_parameters_from_vars()

bool Prepared_statement::insert_parameters_from_vars ( THD thd,
List< LEX_STRING > &  varnames,
String query 
)
private

Assign prepared statement parameters from user variables.

If m_with_log is set, also construct query string for binary log.

Parameters
thdCurrent thread.
varnamesList of variables. Caller must ensure that number of variables in the list is equal to number of statement parameters
queryThe query with parameter markers replaced with corresponding user variables that were used to execute the query.
Returns
false if success, true if error

◆ is_in_use()

bool Prepared_statement::is_in_use ( ) const
inline

◆ is_sql_prepare()

bool Prepared_statement::is_sql_prepare ( ) const
inline

◆ name()

const LEX_CSTRING & Prepared_statement::name ( ) const
inline

◆ prepare()

bool Prepared_statement::prepare ( THD thd,
const char *  query_str,
size_t  query_length,
Item_param **  orig_param_array 
)

Parse statement text, validate the statement, and prepare it for execution.

You should not change global THD state in this function, if at all possible: it may be called from any context, e.g. when executing a COM_* command, and SQLCOM_* command, or a stored procedure.

Parameters
thdthread handle
query_strStatement text
query_lengthLength of statement string
orig_param_arrayArray containing pointers to parameter items that contain data type information for query. This is used during reprepare. = NULL: Derive parameter metadata from query only.
Note
Precondition: The caller must ensure that thd->change_list and thd->item_list is empty: this function will not back them up but will free in the end of its execution.
Postcondition: thd->mem_root contains unused memory allocated during validation.

◆ prepare_query()

bool Prepared_statement::prepare_query ( THD thd)
private

Perform semantic analysis of query and send a response packet to client.

This function

  • opens all tables and checks privileges to them.
  • validates semantics of statement columns and SQL functions by calling fix_fields.
  • performs global transformations such as semi-join conversion.
Parameters
thdcurrent thread
Return values
falsesuccess, statement metadata is sent to client
trueerror, error message is set in THD (but not sent)

◆ reprepare()

bool Prepared_statement::reprepare ( THD thd)
private

Reprepare this prepared statement.

Performs a light reset of the Prepared_statement object (resets its MEM_ROOT and clears its MEM_ROOT allocated members), and calls prepare() on it again.

The resetting of the MEM_ROOT and clearing of the MEM_ROOT allocated members is performed by a swap operation (swap_prepared_statement()) on this Prepared_statement and a newly created, intermediate Prepared_statement. This both clears the data from this object and stores a backup of the original data in the intermediate object. If the repreparation fails, the original data is swapped back into this Prepared_statement.

Parameters
thdcurrent thread.
Return values
truean error occurred. Possible errors include incompatibility of new and old result set metadata
falsesuccess, the statement has been reprepared

◆ set_db()

bool Prepared_statement::set_db ( const LEX_CSTRING db_arg)
private

Remember the current database.

We must reset/restore the current database during execution of a prepared statement since it affects execution environment: privileges, @character_set_database, and other.

Returns
Returns an error if out of memory.

◆ set_name()

bool Prepared_statement::set_name ( const LEX_CSTRING name)

◆ set_parameters() [1/3]

bool Prepared_statement::set_parameters ( THD thd,
String expanded_query 
)

Assign parameter values from specified variables.

Parameters
thdcurrent thread
expanded_querya container with the original SQL statement. '?' placeholders will be replaced with their values in case of success. The result is used for logging and replication
Returns
false if success, true if error (likely a conversion error or out of memory)

◆ set_parameters() [2/3]

bool Prepared_statement::set_parameters ( THD thd,
String expanded_query,
bool  has_new_types,
PS_PARAM parameters 
)

Assign parameter values from the execute packet.

Parameters
thdcurrent thread
expanded_querya container with the original SQL statement. '?' placeholders will be replaced with their values in case of success. The result is used for logging and replication
has_new_typesflag used to signal that new types are provided.
parametersprepared statement's parsed parameters.
Returns
false if success, true if error (likely a conversion error, out of memory, or malformed packet)

◆ set_parameters() [3/3]

bool Prepared_statement::set_parameters ( THD thd,
String expanded_query,
bool  has_new_types,
PS_PARAM parameters,
enum enum_param_pack_type  param_pack_type 
)

Assign parameter values from the execute packet.

Parameters
thdcurrent thread
expanded_querya container with the original SQL statement. '?' placeholders will be replaced with their values in case of success. The result is used for logging and replication
has_new_typesflag used to signal that new types are provided.
parametersprepared statement's parsed parameters.
param_pack_typeparameters pack type.
Returns
false if success, true if error (likely a conversion error, out of memory, or malformed packet)

◆ set_sql_prepare()

void Prepared_statement::set_sql_prepare ( bool  prepare = true)
inline

◆ setup_stmt_logging()

void Prepared_statement::setup_stmt_logging ( THD thd)
private

◆ swap_prepared_statement()

void Prepared_statement::swap_prepared_statement ( Prepared_statement copy)
private

Swap the MEM_ROOT allocated data of two prepared statements.

This is a private helper that is used as part of statement reprepare. It is used in the beginning of reprepare() to clear the MEM_ROOT of the statement before the new preparation, while keeping the data available as some of it is needed later in the repreparation. It is also used for restoring the original data from the copy, should the repreparation fail.

The operation is symmetric. It can be used both for saving an original statement into a backup, and for restoring the original state of the statement from the backup.

◆ trace_parameter_types()

void Prepared_statement::trace_parameter_types ( THD thd)

◆ validate_metadata()

bool Prepared_statement::validate_metadata ( THD thd,
Prepared_statement copy 
)
private

Validate statement result set metadata (if the statement returns a result set).

Currently we only check that the number of columns of the result set did not change. This is a helper method used during re-prepare.

Parameters
thdcurrent thread.
copythe re-prepared prepared statement to verify the metadata of
Return values
trueerror, ER_PS_REBIND is reported
falsestatement return no or compatible metadata

If this is an SQL prepared statement or EXPLAIN, return false – the metadata of the original SELECT, if any, has not been sent to the client.

Column counts mismatch, update the client

Member Data Documentation

◆ m_active_protocol

const Protocol* Prepared_statement::m_active_protocol {nullptr}

Used to check that the protocol is stable during execution.

◆ m_arena

Query_arena Prepared_statement::m_arena

Memory allocation arena, for permanent allocations to statement.

◆ m_aux_result

Query_result* Prepared_statement::m_aux_result {nullptr}
private

Auxiliary query result object, saved for proper destruction.

◆ m_cursor

Server_side_cursor* Prepared_statement::m_cursor {nullptr}

Pointer to cursor, may be NULL if statement never used with a cursor.

◆ m_cursor_result

Query_result* Prepared_statement::m_cursor_result {nullptr}
private

Query result used when statement is used with a cursor.

◆ m_db

LEX_CSTRING Prepared_statement::m_db {NULL_CSTR}
private

Name of the current (default) database.

If there is the current (default) database, "db" contains its name. If there is no current (default) database, "db" is NULL and "db_length" is 0. In other words, "db", "db_length" must either be NULL, or contain a valid database name.

Note
this attribute is set and allocated by the slave SQL thread (for the THD of that thread); that thread is (and must remain, for now) the only responsible for freeing this member.

◆ m_first_execution

bool Prepared_statement::m_first_execution {true}
private

◆ m_id

const ulong Prepared_statement::m_id

Uniquely identifies each statement object in thread scope; change during statement lifetime.

◆ m_in_use

bool Prepared_statement::m_in_use {false}
private

Flag that prevents recursive invocation of prepared statements.

◆ m_is_sql_prepare

bool Prepared_statement::m_is_sql_prepare {false}
private

Flag that specifies preparation state.

◆ m_last_errno

uint Prepared_statement::m_last_errno {0}

◆ m_last_error

char Prepared_statement::m_last_error[MYSQL_ERRMSG_SIZE]

◆ m_lex

LEX* Prepared_statement::m_lex {nullptr}

◆ m_mem_root

MEM_ROOT Prepared_statement::m_mem_root
private

The memory root to allocate parsed tree elements (instances of Item, Query_block and other classes).

◆ m_name

LEX_CSTRING Prepared_statement::m_name {NULL_CSTR}
private

Name of the prepared statement.

◆ m_param_array

Item_param** Prepared_statement::m_param_array {nullptr}

Array of parameters used for statement, may be NULL if there are none.

◆ m_param_count

uint Prepared_statement::m_param_count {0}

Number of parameters expected for statement.

◆ m_prepared_stmt

PSI_prepared_stmt* Prepared_statement::m_prepared_stmt {nullptr}

Performance Schema interface for a prepared statement.

◆ m_query_string

LEX_CSTRING Prepared_statement::m_query_string {NULL_CSTR}

The query string associated with this statement.

◆ m_regular_result

Query_result* Prepared_statement::m_regular_result {nullptr}
private

Query result used when statement is used in regular execution.

◆ m_used_as_cursor

bool Prepared_statement::m_used_as_cursor {false}
private

True if statement is used with cursor, false if used in regular execution.

◆ m_with_log

bool Prepared_statement::m_with_log {false}
private

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