mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Prepared_statement deployed instead of PREP_STMT.
libmysqld/lib_sql.cc: Prepared_statement now resides entirely in sql_prepare.cc Embedded versions of setup_params_data moved to sql_prepare.cc sql/mysql_priv.h: removed declarations for non-existing functions sql/slave.cc: no thd->init_for_queries() any more sql/sql_class.cc: added Statement and Statement_map classes. PREP_STMT replaced with Statement (Prepared_statement) and moved to sql_prepare.cc sql/sql_class.h: added Statement and Statement_map classes. PREP_STMT replaced with Statement (Prepared_statement) and moved to sql_prepare.cc sql/sql_parse.cc: thd->init_for_queries() doesn't exist any more comment moved to proper place sql/sql_prepare.cc: PREP_STMT replaced with Prepared_statement minor code cleanups tests/client_test.c: Later in the test we rely on order of rows, which normally is not defined. My patch changes the order.
This commit is contained in:
208
sql/sql_class.h
208
sql/sql_class.h
@ -328,30 +328,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/* This is a struct as it's allocated in tree_insert */
|
||||
|
||||
typedef struct st_prep_stmt
|
||||
{
|
||||
THD *thd;
|
||||
LEX lex;
|
||||
Item_param **param;
|
||||
Item *free_list;
|
||||
MEM_ROOT mem_root;
|
||||
String *query;
|
||||
ulong stmt_id;
|
||||
uint param_count;
|
||||
uint last_errno;
|
||||
char last_error[MYSQL_ERRMSG_SIZE];
|
||||
bool error_in_prepare, long_data_used;
|
||||
bool log_full_query;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool (*setup_params)(st_prep_stmt *stmt, uchar *pos, uchar *read_pos);
|
||||
#else
|
||||
bool (*setup_params_data)(st_prep_stmt *stmt);
|
||||
#endif
|
||||
} PREP_STMT;
|
||||
|
||||
|
||||
class delayed_insert;
|
||||
class select_result;
|
||||
|
||||
@ -428,12 +404,158 @@ struct system_variables
|
||||
};
|
||||
|
||||
void free_tmp_table(THD *thd, TABLE *entry);
|
||||
|
||||
class Prepared_statement;
|
||||
|
||||
/*
|
||||
State of a single command executed against this connection.
|
||||
One connection can contain a lot of simultaneously running statements,
|
||||
some of which could be:
|
||||
- prepared, that is, contain placeholders,
|
||||
- opened as cursors. We maintain 1 to 1 relationship between
|
||||
statement and cursor - if user wants to create another cursor for his
|
||||
query, we create another statement for it.
|
||||
To perform some action with statement we reset THD part to the state of
|
||||
that statement, do the action, and then save back modified state from THD
|
||||
to the statement. It will be changed in near future, and Statement will
|
||||
be used explicitly.
|
||||
*/
|
||||
|
||||
class Statement
|
||||
{
|
||||
Statement(const Statement &rhs); /* not implemented: */
|
||||
Statement &operator=(const Statement &rhs); /* non-copyable */
|
||||
public:
|
||||
/* FIXME: must be private */
|
||||
LEX main_lex;
|
||||
public:
|
||||
/*
|
||||
Uniquely identifies each statement object in thread scope; change during
|
||||
statement lifetime. FIXME: must be const
|
||||
*/
|
||||
ulong id;
|
||||
|
||||
/*
|
||||
Id of current query. Statement can be reused to execute several queries
|
||||
query_id is global in context of the whole MySQL server.
|
||||
ID is automatically generated from mutex-protected counter.
|
||||
It's used in handler code for various purposes: to check which columns
|
||||
from table are necessary for this select, to check if it's necessary to
|
||||
update auto-updatable fields (like auto_increment and timestamp).
|
||||
*/
|
||||
ulong query_id;
|
||||
/*
|
||||
- if set_query_id=1, we set field->query_id for all fields. In that case
|
||||
field list can not contain duplicates.
|
||||
*/
|
||||
bool set_query_id;
|
||||
/*
|
||||
This variable is used in post-parse stage to declare that sum-functions,
|
||||
or functions which have sense only if GROUP BY is present, are allowed.
|
||||
For example in queries
|
||||
SELECT MIN(i) FROM foo
|
||||
SELECT GROUP_CONCAT(a, b, MIN(i)) FROM ... GROUP BY ...
|
||||
MIN(i) have no sense.
|
||||
Though it's grammar-related issue, it's hard to catch it out during the
|
||||
parse stage because GROUP BY clause goes in the end of query. This
|
||||
variable is mainly used in setup_fields/fix_fields.
|
||||
See item_sum.cc for details.
|
||||
*/
|
||||
bool allow_sum_func;
|
||||
/*
|
||||
Type of current query: COM_PREPARE, COM_QUERY, etc. Set from
|
||||
first byte of the packet in do_command()
|
||||
*/
|
||||
enum enum_server_command command;
|
||||
|
||||
LEX *lex; // parse tree descriptor
|
||||
/*
|
||||
Points to the query associated with this statement. It's const, but
|
||||
we need to declare it char * because all table handlers are written
|
||||
in C and need to point to it.
|
||||
*/
|
||||
char *query;
|
||||
uint32 query_length; // current query length
|
||||
/*
|
||||
List of items created in the parser for this query. Every item puts
|
||||
itself to the list on creation (see Item::Item() for details))
|
||||
*/
|
||||
Item *free_list;
|
||||
MEM_ROOT mem_root;
|
||||
|
||||
public:
|
||||
/* We build without RTTI, so dynamic_cast can't be used. */
|
||||
enum Type
|
||||
{
|
||||
STATEMENT,
|
||||
PREPARED_STATEMENT
|
||||
};
|
||||
|
||||
/*
|
||||
This constructor is called when statement is a subobject of THD:
|
||||
some variables are initialized in THD::init due to locking problems
|
||||
*/
|
||||
Statement();
|
||||
|
||||
Statement(THD *thd);
|
||||
virtual ~Statement();
|
||||
|
||||
/* Assign execution context (note: not all members) of given stmt to self */
|
||||
void set_statement(Statement *stmt);
|
||||
/* return class type */
|
||||
virtual Type type() const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Used to seek all existing statements in the connection
|
||||
Deletes all statements in destructor.
|
||||
*/
|
||||
|
||||
class Statement_map
|
||||
{
|
||||
public:
|
||||
Statement_map();
|
||||
|
||||
int insert(Statement *statement)
|
||||
{
|
||||
int rc= my_hash_insert(&st_hash, (byte *) statement);
|
||||
if (rc == 0)
|
||||
last_found_statement= statement;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Statement *find(ulong id)
|
||||
{
|
||||
if (last_found_statement == 0 || id != last_found_statement->id)
|
||||
last_found_statement= (Statement *) hash_search(&st_hash, (byte *) &id,
|
||||
sizeof(id));
|
||||
return last_found_statement;
|
||||
}
|
||||
void erase(Statement *statement)
|
||||
{
|
||||
if (statement == last_found_statement)
|
||||
last_found_statement= 0;
|
||||
hash_delete(&st_hash, (byte *) statement);
|
||||
}
|
||||
|
||||
~Statement_map()
|
||||
{
|
||||
hash_free(&st_hash);
|
||||
}
|
||||
private:
|
||||
HASH st_hash;
|
||||
Statement *last_found_statement;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
For each client connection we create a separate thread with THD serving as
|
||||
a thread/connection descriptor
|
||||
*/
|
||||
|
||||
class THD :public ilink
|
||||
class THD :public ilink,
|
||||
public Statement
|
||||
{
|
||||
public:
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
@ -446,23 +568,25 @@ public:
|
||||
ulong extra_length;
|
||||
#endif
|
||||
NET net; // client connection descriptor
|
||||
LEX main_lex;
|
||||
LEX *lex; // parse tree descriptor
|
||||
MEM_ROOT mem_root; // 1 command-life memory pool
|
||||
MEM_ROOT con_root; // connection-life memory
|
||||
MEM_ROOT warn_root; // For warnings and errors
|
||||
Protocol *protocol; // Current protocol
|
||||
Protocol_simple protocol_simple; // Normal protocol
|
||||
Protocol_prep protocol_prep; // Binary protocol
|
||||
HASH user_vars; // hash for user variables
|
||||
TREE prepared_statements;
|
||||
String packet; // dynamic buffer for network I/O
|
||||
struct sockaddr_in remote; // client socket address
|
||||
struct rand_struct rand; // used for authentication
|
||||
struct system_variables variables; // Changeable local variables
|
||||
pthread_mutex_t LOCK_delete; // Locked before thd is deleted
|
||||
|
||||
char *query; // Points to the current query,
|
||||
/* all prepared statements and cursors of this connection */
|
||||
Statement_map stmt_map;
|
||||
/*
|
||||
keeps THD state while it is used for active statement
|
||||
Note, that double free_root() is safe, so we don't need to do any
|
||||
special cleanup for it in THD destructor.
|
||||
*/
|
||||
Statement stmt_backup;
|
||||
/*
|
||||
A pointer to the stack frame of handle_one_connection(),
|
||||
which is called first in the thread for handling a client
|
||||
@ -502,7 +626,6 @@ public:
|
||||
and are still in use by this thread
|
||||
*/
|
||||
TABLE *open_tables,*temporary_tables, *handler_tables, *derived_tables;
|
||||
// TODO: document the variables below
|
||||
MYSQL_LOCK *lock; /* Current locks */
|
||||
MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */
|
||||
/*
|
||||
@ -511,12 +634,10 @@ public:
|
||||
chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
|
||||
*/
|
||||
ULL *ull;
|
||||
PREP_STMT *last_prepared_stmt;
|
||||
#ifndef DBUG_OFF
|
||||
uint dbug_sentry; // watch out for memory corruption
|
||||
#endif
|
||||
struct st_my_thread_var *mysys_var;
|
||||
enum enum_server_command command;
|
||||
uint32 server_id;
|
||||
uint32 file_id; // for LOAD DATA INFILE
|
||||
/*
|
||||
@ -549,7 +670,6 @@ public:
|
||||
free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
}
|
||||
} transaction;
|
||||
Item *free_list, *handler_items;
|
||||
Field *dupp_field;
|
||||
#ifndef __WIN__
|
||||
sigset_t signals,block_signals;
|
||||
@ -580,18 +700,25 @@ public:
|
||||
USER_CONN *user_connect;
|
||||
CHARSET_INFO *db_charset;
|
||||
List<TABLE> temporary_tables_should_be_free; // list of temporary tables
|
||||
/*
|
||||
FIXME: this, and some other variables like 'count_cuted_fields'
|
||||
maybe should be statement/cursor local, that is, moved to Statement
|
||||
class. With current implementation warnings produced in each prepared
|
||||
statement/cursor settle here.
|
||||
*/
|
||||
List <MYSQL_ERROR> warn_list;
|
||||
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
||||
uint total_warn_count;
|
||||
ulong query_id, warn_id, version, options, thread_id, col_access;
|
||||
ulong current_stmt_id;
|
||||
ulong warn_id, version, options, thread_id, col_access;
|
||||
|
||||
/* Statement id is thread-wide. This counter is used to generate ids */
|
||||
ulong statement_id_counter;
|
||||
ulong rand_saved_seed1, rand_saved_seed2;
|
||||
ulong row_count; // Row counter, mainly for errors and warnings
|
||||
long dbug_thread_id;
|
||||
pthread_t real_id;
|
||||
uint current_tablenr,tmp_table;
|
||||
uint server_status,open_options,system_thread;
|
||||
uint32 query_length;
|
||||
uint32 db_length;
|
||||
uint select_number; //number of select (used for EXPLAIN)
|
||||
/* variables.transaction_isolation is reset to this after each commit */
|
||||
@ -604,9 +731,9 @@ public:
|
||||
char scramble[SCRAMBLE_LENGTH+1];
|
||||
|
||||
bool slave_thread;
|
||||
bool set_query_id,locked,some_tables_deleted;
|
||||
bool locked, some_tables_deleted;
|
||||
bool last_cuted_field;
|
||||
bool no_errors, allow_sum_func, password, is_fatal_error;
|
||||
bool no_errors, password, is_fatal_error;
|
||||
bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
|
||||
bool in_lock_tables,global_read_lock;
|
||||
bool query_error, bootstrap, cleanup_done;
|
||||
@ -634,7 +761,6 @@ public:
|
||||
|
||||
void init(void);
|
||||
void change_user(void);
|
||||
void init_for_queries();
|
||||
void cleanup(void);
|
||||
bool store_globals();
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
|
Reference in New Issue
Block a user